1 2 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 ; 23 import java.sql.PreparedStatement ; 24 import java.sql.Connection ; 25 import java.sql.ResultSet ; 26 import java.util.*; 27 28 import com.versant.core.common.*; 29 import com.versant.core.server.StateContainer; 30 31 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 57 private Map colHMap = new HashMap(); 58 59 private Connection con() { 60 return sm.con(); 61 } 62 63 66 private void exectureQ(SqlStruct sqlStruct, ColFieldHolder colHolder) 67 throws SQLException { 68 PreparedStatement 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 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 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 101 public void processParallelFetch(JoinStructure rootJs, int level, boolean valueJoin, 102 ColFieldHolder parent, OID oid, State state, 103 boolean doCrossJoin, ResultSet masterRs, 104 int colIndex, FgDs fgDs) throws SQLException { 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 State ss = state; 141 OID refOID = oid; 142 143 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 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 continue; 217 } 218 219 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 continue; 232 } 233 234 if ((colFHolder.returnState & JdbcCollectionField.STATUS_DATA_ADDED) 235 != JdbcCollectionField.STATUS_DATA_ADDED) { 236 continue; 238 } 239 240 if (js2.fgField.nextFetchGroup != null) { 242 processParallelFetch(colFHolder.valueJs, level + 1, true, 244 colFHolder, oid, state, false, null, colIndex, null); 245 } 246 247 if (js2.fgField.nextKeyFetchGroup != null) { 249 processParallelFetch(colFHolder.keyJs, level + 1, false, 251 colFHolder, oid, state, false, null, colIndex, null); 252 } 253 } 254 } 255 256 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 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 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 |