1 10 11 package com.triactive.jdo.store; 12 13 import com.triactive.jdo.PersistenceManager; 14 import com.triactive.jdo.model.ClassMetaData; 15 import com.triactive.jdo.util.IntArrayList; 16 import java.util.HashMap ; 17 import java.util.Iterator ; 18 import javax.jdo.Extent; 19 import org.apache.log4j.Category; 20 21 22 30 31 class ClassBaseTableExtent implements Extent, Queryable 32 { 33 private static final Category LOG = Category.getInstance(ClassBaseTableExtent.class); 34 35 private final PersistenceManager pm; 36 private final ClassBaseTable table; 37 private final boolean subclasses; 38 private final StoreManager storeMgr; 39 private final DatabaseAdapter dba; 40 private final Query query; 41 private final int[] prefetchFieldNumbers; 42 private final ColumnMapping[] prefetchFieldMappings; 43 44 private HashMap queryResultsByIterator = new HashMap (); 45 46 47 public ClassBaseTableExtent(PersistenceManager pm, ClassBaseTable table, boolean subclasses) 48 { 49 this.pm = pm; 50 this.table = table; 51 this.subclasses = subclasses; 52 53 storeMgr = table.getStoreManager(); 54 dba = storeMgr.getDatabaseAdapter(); 55 query = storeMgr.getQuery(pm, null); 56 57 Class candidateClass = getCandidateClass(); 58 59 query.setClass(candidateClass); 60 query.setCandidates(this); 61 62 ClassMetaData cmd = ClassMetaData.forClass(candidateClass); 63 int fieldCount = cmd.getInheritedFieldCount() + cmd.getFieldCount(); 64 IntArrayList colfn = new IntArrayList(fieldCount); 65 ColumnMapping[] colfm = new ColumnMapping[fieldCount]; 66 67 boolean[] defaultFetchGroupFields = cmd.getDefaultFetchGroupFieldFlags(); 68 69 for (int i = 0; i < fieldCount; ++i) 70 { 71 if (defaultFetchGroupFields[i]) 72 { 73 Mapping m = table.getFieldMapping(i); 74 75 if (m instanceof ColumnMapping) 76 { 77 colfn.add(i); 78 colfm[i] = (ColumnMapping)m; 79 } 80 } 81 } 82 83 if (colfn.isEmpty()) 84 { 85 prefetchFieldNumbers = null; 86 prefetchFieldMappings = null; 87 } 88 else 89 { 90 prefetchFieldNumbers = colfn.toArray(); 91 prefetchFieldMappings = colfm; 92 } 93 } 94 95 96 101 102 public Iterator iterator() 103 { 104 QueryResult qr = (QueryResult)query.execute(); 105 Iterator i = qr.iterator(); 106 107 queryResultsByIterator.put(i, qr); 108 109 return i; 110 } 111 112 113 119 120 public boolean hasSubclasses() 121 { 122 return subclasses; 123 } 124 125 126 132 133 public Class getCandidateClass() 134 { 135 return table.getType(); 136 } 137 138 139 145 146 public javax.jdo.PersistenceManager getPersistenceManager() 147 { 148 return pm; 149 } 150 151 152 161 162 public void close(Iterator it) 163 { 164 QueryResult qr = (QueryResult)queryResultsByIterator.remove(it); 165 166 qr.close(); 167 } 168 169 170 176 177 public void closeAll() 178 { 179 Iterator i = queryResultsByIterator.values().iterator(); 180 181 while (i.hasNext()) 182 { 183 QueryResult qr = (QueryResult)i.next(); 184 185 qr.close(); 186 i.remove(); 187 } 188 } 189 190 191 public QueryStatement newQueryStatement(Class candidateClass) 192 { 193 Class extentType = table.getType(); 194 195 if (!extentType.isAssignableFrom(candidateClass)) 196 throw new IncompatibleQueryElementTypeException(extentType, candidateClass); 197 198 ClassBaseTable candidateTable = storeMgr.getClassBaseTable(candidateClass); 199 QueryStatement stmt = dba.newQueryStatement(candidateTable); 200 201 ColumnMapping idMapping = table.getIDMapping(); 202 Column idColumn = idMapping.getColumn(); 203 204 if (!subclasses) 205 { 206 if (!table.equals(candidateTable)) 207 LOG.warn("Query over extent will never return results w/o including subclasses: extent = " + this + ", candidate class = " + candidateClass); 208 209 int classID = table.getTableID(); 210 211 BooleanExpression filterByClass = 212 new OIDRangeTestExpression(stmt, stmt.getColumn(idColumn), 213 new OID(classID, 0, 0), 214 new OID(classID, OID.MAX_OBJIDHI, OID.MAX_OBJIDLO)); 215 216 stmt.andCondition(filterByClass); 217 } 218 219 stmt.select(idColumn); 220 221 return stmt; 222 } 223 224 225 public Query.ResultObjectFactory newResultObjectFactory(QueryStatement stmt) 226 { 227 if (stmt.getDistinctResults() || prefetchFieldMappings == null) 228 return new PersistentIDROF(pm, getCandidateClass()); 229 else 230 { 231 int[] columnNumbersByField = new int[prefetchFieldMappings.length]; 232 233 for (int i = 0; i < prefetchFieldMappings.length; ++i) 234 { 235 ColumnMapping m = prefetchFieldMappings[i]; 236 237 if (m != null) 238 columnNumbersByField[i] = stmt.select(m.getColumn()); 239 } 240 241 return new PersistentIDROF(pm, 242 getCandidateClass(), 243 prefetchFieldNumbers, 244 prefetchFieldMappings, 245 columnNumbersByField); 246 } 247 } 248 249 250 public String toString() 251 { 252 return "Extent of " + getCandidateClass() + (subclasses ? "(including" : "(excluding") + " subclasses)"; 253 } 254 } 255 | Popular Tags |