KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > versant > core > jdbc > ParColFetchUtil


1
2 /*
3  * Copyright (c) 1998 - 2005 Versant Corporation
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  * Versant Corporation - initial API and implementation
11  */

12 package com.versant.core.jdbc;
13
14 import com.versant.core.jdbc.query.SqlStruct;
15 import com.versant.core.jdbc.query.JdbcJDOQLCompiler;
16 import com.versant.core.jdbc.metadata.*;
17 import com.versant.core.jdbc.sql.exp.SelectExp;
18 import com.versant.core.jdbc.sql.exp.SqlExp;
19 import com.versant.core.metadata.ClassMetaData;
20 import com.versant.core.metadata.ModelMetaData;
21
22 import java.sql.SQLException JavaDoc;
23 import java.sql.PreparedStatement JavaDoc;
24 import java.sql.Connection JavaDoc;
25 import java.sql.ResultSet JavaDoc;
26 import java.util.*;
27
28 import com.versant.core.common.*;
29 import com.versant.core.server.StateContainer;
30
31 /**
32  * This helps to keep track of a parallel collection fetch operation.
33  */

34 public final class ParColFetchUtil {
35
36     private final JdbcStorageManager sm;
37     private final boolean forUpdate;
38     private final StateContainer container;
39     private final ClassMetaData cmd;
40     private final ModelMetaData jmd;
41     private JdbcOID lastOID;
42
43     public ParColFetchUtil(JdbcStorageManager sm, boolean forUpdate,
44             StateContainer container, ClassMetaData cmd, JdbcOID lastOID) {
45         this.sm = sm;
46         this.forUpdate = forUpdate;
47         this.container = container;
48         this.cmd = cmd;
49         this.lastOID = lastOID;
50         jmd = sm.getJmd();
51     }
52
53     /**
54      * A map of {@link ColFHKey} to {@link com.versant.core.jdbc.ColFieldHolder}. A ColFieldHolder is
55      * added to the map once some or all of its results have been processed.
56      */

57     private Map colHMap = new HashMap();
58
59     private Connection JavaDoc con() {
60         return sm.con();
61     }
62
63     /**
64      * Execute a query for a collection.
65      */

66     private void exectureQ(SqlStruct sqlStruct, ColFieldHolder colHolder)
67             throws SQLException JavaDoc {
68         PreparedStatement JavaDoc p2Ps = con().prepareStatement(sqlStruct.getSql());
69         lastOID.setParams(p2Ps, 1);
70         colHolder.ps = p2Ps;
71         colHolder.rs = p2Ps.executeQuery();
72     }
73
74     private SqlStruct createSqlStruct(ColFieldHolder colHolder,
75             JoinStructure ds) {
76         final SqlStruct sqlStruct = new SqlStruct();
77
78         // generate a join query to get the group
79
SelectExp root = new SelectExp();
80         JdbcClass jdbcClass = (JdbcClass)cmd.storeClass;
81         root.table = jdbcClass.table;
82         root.whereExp = jdbcClass.table.createPkEqualsParamExp(root);
83
84         SelectExp se = colHolder.createSE(sm, root);
85
86 // add the root table pk to the front of the select list
87
SqlExp e = JdbcColumn.toSqlExp(((JdbcClass)cmd.storeClass).table.pk, root,
88                 root.selectList);
89         root.selectList = e;
90
91         root.appendOrderByExp(se.orderByList);
92         JdbcJDOQLCompiler.doFinalSql(sqlStruct, root,
93                 sm.getSqlDriver());
94
95         return sqlStruct;
96     }
97
98     /**
99      * This must be called on a root JoinStructure.
100      */

101     public void processParallelFetch(JoinStructure rootJs, int level, boolean valueJoin,
102             ColFieldHolder parent, OID oid, State state,
103             boolean doCrossJoin, ResultSet JavaDoc masterRs,
104             int colIndex, FgDs fgDs) throws SQLException JavaDoc {
105         if (rootJs == null) return;
106         rootJs.finish();
107         if (!rootJs.rootJoinStructure) {
108             throw BindingSupportImpl.getInstance().internal("");
109         }
110
111         List l = rootJs.colJoinStructs;
112         if (l == null) return;
113         for (int i = 0; i < l.size(); i++) {
114             JoinStructure js2 = (JoinStructure)l.get(i);
115             ColFHKey key = new ColFHKey(level, valueJoin, js2, parent);
116             ColFieldHolder colFHolder = (ColFieldHolder)colHMap.get(key);
117             if (colFHolder == null) {
118                 colFHolder = new ColFieldHolder(parent, valueJoin, js2);
119                 colHMap.put(key, colFHolder);
120                 if (level == 1) {
121                     if (js2.parent == rootJs
122                             && js2.fgField == rootJs.fetchGroup.crossJoinedCollectionField
123                             && doCrossJoin) {
124                         int size = ((JdbcCollectionField)js2.fgField.fmd.storeField).fetchFrom(
125                                 masterRs,
126                                 oid, state, js2.fgField, forUpdate,
127                                 container, false, colIndex, new FetchInfo(), sm);
128
129                         colFHolder.valueJs = fgDs.valueJs;
130                         colFHolder.keyJs = fgDs.keyJs;
131
132                         if (size == 0) {
133                             colFHolder.returnState = JdbcCollectionField.STATUS_CLOSED;
134                         } else {
135                             colFHolder.returnState = JdbcCollectionField.STATUS_VALID_ROWS
136                                     + JdbcCollectionField.STATUS_DATA_ADDED;
137                         }
138                     } else {
139                         //find the oid-state pair for the collections owner.
140
State ss = state;
141                         OID refOID = oid;
142
143                         //if there is any intermediate refs that lead to the collection
144
if (js2.parent != rootJs) {
145                             ArrayList jslist = new ArrayList();
146                             JoinStructure js = js2.parent;
147                             for (; ;) {
148                                 jslist.add(js);
149                                 if (js.parent == rootJs) break;
150                                 js = js.parent;
151                             }
152
153                             for (int k = jslist.size() - 1; k >= 0; k--) {
154                                 JoinStructure tjs = (JoinStructure)jslist.get(
155                                         k);
156                                 if (Debug.DEBUG) {
157                                     if (!tjs.isRefField()) {
158                                         throw BindingSupportImpl.getInstance().internal(
159                                                 "");
160                                     }
161                                 }
162
163                                 if (ss.getClassMetaData(jmd).isAncestorOrSelf(
164                                         tjs.fgField.fmd.classMetaData)) {
165                                     refOID = (OID)ss.getInternalObjectField(
166                                             tjs.fgField.fmd.stateFieldNo);
167                                     if (refOID != null) {
168                                         ss = container.get(refOID);
169                                     } else {
170                                         ss = null;
171                                         break;
172                                     }
173                                 } else {
174                                     ss = null;
175                                     break;
176                                 }
177                             }
178
179                             if (ss != null
180                                     && !ss.getClassMetaData(jmd).isAncestorOrSelf(
181                                             js2.fgField.fmd.classMetaData)) {
182                                 ss = null;
183                             }
184                         } else {
185                             if (ss.getClassMetaData(jmd).isAncestorOrSelf(
186                                     js2.fgField.fmd.classMetaData)) {
187                                 //this is a sub class field so ignore
188
ss = state;
189                             } else {
190                                 ss = null;
191                             }
192                         }
193
194                         int amount = 0;
195                         if (refOID != null && ss != null) {
196                             amount = sm.fetchPass2Field(refOID, ss,
197                                     colFHolder.js.fgField, forUpdate, container,
198                                     false, colFHolder);
199                         }
200                         if (amount <= 0) {
201                             colFHolder.returnState = JdbcCollectionField.STATUS_CLOSED;
202                         } else {
203                             colFHolder.returnState = JdbcCollectionField.STATUS_VALID_ROWS
204                                     + JdbcCollectionField.STATUS_DATA_ADDED;
205                         }
206                     }
207                 } else {
208                     SqlStruct sqlStr = createSqlStruct(colFHolder, js2);
209                     exectureQ(sqlStr, colFHolder);
210                 }
211             }
212
213             if ((colFHolder.returnState & JdbcCollectionField.STATUS_CLOSED)
214                     == JdbcCollectionField.STATUS_CLOSED) {
215 // System.out.println("--- CONTINUE ON STATUS_CLOSED");
216
continue;
217             }
218
219             //fetch the coll
220
if (level > 1) {
221                 colFHolder.returnState = ((JdbcCollectionField)js2.fgField.fmd.storeField).
222                         fetchWithFilter(sm, container, js2.fgField,
223                                 colFHolder.rs, forUpdate, lastOID,
224                                 colFHolder.lastOIDs, cmd,
225                                 colFHolder);
226             }
227
228             if ((colFHolder.returnState & JdbcCollectionField.STATUS_VALID_ROWS)
229                     != JdbcCollectionField.STATUS_VALID_ROWS) {
230 // System.out.println("--- CONTINUE ON STATUS_VALID_ROWS");
231
continue;
232             }
233
234             if ((colFHolder.returnState & JdbcCollectionField.STATUS_DATA_ADDED)
235                     != JdbcCollectionField.STATUS_DATA_ADDED) {
236 // System.out.println("--- CONTINUE ON STATUS_DATA_ADDED");
237
continue;
238             }
239
240             //for a normal collection
241
if (js2.fgField.nextFetchGroup != null) {
242 // System.out.println("--- DOING VALUE FIELD");
243
processParallelFetch(colFHolder.valueJs, level + 1, true,
244                         colFHolder, oid, state, false, null, colIndex, null);
245             }
246
247             //for a map with pc keys
248
if (js2.fgField.nextKeyFetchGroup != null) {
249 // System.out.println("--- DOING KEY FIELD");
250
processParallelFetch(colFHolder.keyJs, level + 1, false,
251                         colFHolder, oid, state, false, null, colIndex, null);
252             }
253         }
254     }
255
256     /**
257      * Close these results.
258      */

259     public void close() {
260         if (colHMap != null) {
261             Collection col = colHMap.values();
262             for (Iterator iterator = col.iterator(); iterator.hasNext();) {
263                 ColFieldHolder holder = (ColFieldHolder)iterator.next();
264                 if (holder != null) {
265                     holder.close();
266                 }
267             }
268             colHMap.clear();
269         }
270     }
271
272     /**
273      * This is a key for a {@link ColFieldHolder}.
274      */

275     public static class ColFHKey {
276
277         private int level;
278         private boolean valueJoin;
279         private JoinStructure js;
280         private ColFieldHolder parent;
281
282         public ColFHKey(int level, boolean valueJoin, JoinStructure js, ColFieldHolder parent) {
283             this.level = level;
284             this.valueJoin = valueJoin;
285             this.js = js;
286             this.parent = parent;
287         }
288
289         public boolean equals(Object JavaDoc o) {
290             if (this == o) return true;
291             if (!(o instanceof ColFHKey)) return false;
292
293             final ColFHKey colFHKey = (ColFHKey) o;
294
295             if (parent != colFHKey.parent) return false;
296             if (level != colFHKey.level) return false;
297             if (valueJoin != colFHKey.valueJoin) return false;
298             if (!js.equals(colFHKey.js)) return false;
299
300             return true;
301         }
302
303         public int hashCode() {
304             int result;
305             result = level;
306             result = 29 * result + (valueJoin ? 1 : 0);
307             result = 29 * result + js.hashCode();
308             return result;
309         }
310
311     }
312 }
313
Popular Tags