/** Convenience method to mark PK fields as loaded (if using app id). */ protected void markPKFieldsAsLoaded() { if (cmd.getIdentityType() == IdentityType.APPLICATION) { int[] pkPositions = cmd.getPKMemberPositions(); for (int i = 0; i < pkPositions.length; i++) { loadedFields[pkPositions[i]] = true; } } }
/** * Convenience method to get all objects of the specified type. * * @param ec Execution Context * @param mconn Managed Connection * @param cmd Metadata for the type to return * @param ignoreCache Whether to ignore the cache * @param fp Fetch Plan * @param filter Optional filter for the candidates * @param storeMgr StoreManager in use * @return List of objects of the candidate type */ private static List getObjectsOfType( final ExecutionContext ec, final HBaseManagedConnection mconn, final AbstractClassMetaData cmd, boolean ignoreCache, FetchPlan fp, final Filter filter, final StoreManager storeMgr) { List results = new ArrayList(); if (!storeMgr.managesClass(cmd.getFullClassName())) { storeMgr.manageClasses(ec.getClassLoaderResolver(), cmd.getFullClassName()); } final Table table = storeMgr.getStoreDataForClass(cmd.getFullClassName()).getTable(); final String tableName = table.getName(); final int[] fpMembers = fp.getFetchPlanForClass(cmd).getMemberNumbers(); try { final ClassLoaderResolver clr = ec.getClassLoaderResolver(); Iterator<Result> it = (Iterator<Result>) AccessController.doPrivileged( new PrivilegedExceptionAction() { public Object run() throws Exception { Scan scan = new Scan(); if (filter != null) { scan.setFilter(filter); } // Retrieve all fetch-plan fields for (int i = 0; i < fpMembers.length; i++) { AbstractMemberMetaData mmd = cmd.getMetaDataForManagedMemberAtAbsolutePosition(fpMembers[i]); RelationType relationType = mmd.getRelationType(clr); if (relationType != RelationType.NONE && MetaDataUtils.getInstance() .isMemberEmbedded( ec.getMetaDataManager(), clr, mmd, relationType, null)) { if (RelationType.isRelationSingleValued(relationType)) { // 1-1 embedded List<AbstractMemberMetaData> embMmds = new ArrayList<AbstractMemberMetaData>(); embMmds.add(mmd); addColumnsToScanForEmbeddedMember(scan, embMmds, table, ec); } } else { Column col = table .getMemberColumnMappingForMember(mmd) .getColumn(0); // TODO Support multicol mapping byte[] familyName = HBaseUtils.getFamilyNameForColumn(col).getBytes(); byte[] qualifName = HBaseUtils.getQualifierNameForColumn(col).getBytes(); scan.addColumn(familyName, qualifName); } } VersionMetaData vermd = cmd.getVersionMetaDataForClass(); if (cmd.isVersioned() && vermd.getFieldName() == null) { // Add version column byte[] familyName = HBaseUtils.getFamilyNameForColumn(table.getVersionColumn()).getBytes(); byte[] qualifName = HBaseUtils.getQualifierNameForColumn(table.getVersionColumn()) .getBytes(); scan.addColumn(familyName, qualifName); } if (cmd.hasDiscriminatorStrategy()) { // Add discriminator column byte[] familyName = HBaseUtils.getFamilyNameForColumn(table.getDiscriminatorColumn()) .getBytes(); byte[] qualifName = HBaseUtils.getQualifierNameForColumn(table.getDiscriminatorColumn()) .getBytes(); scan.addColumn(familyName, qualifName); } if (cmd.getIdentityType() == IdentityType.DATASTORE) { // Add datastore identity column byte[] familyName = HBaseUtils.getFamilyNameForColumn(table.getDatastoreIdColumn()) .getBytes(); byte[] qualifName = HBaseUtils.getQualifierNameForColumn(table.getDatastoreIdColumn()) .getBytes(); scan.addColumn(familyName, qualifName); } HTableInterface htable = mconn.getHTable(tableName); ResultScanner scanner = htable.getScanner(scan); if (ec.getStatistics() != null) { // Add to statistics ec.getStatistics().incrementNumReads(); } Iterator<Result> it = scanner.iterator(); return it; } }); // Instantiate the objects if (cmd.getIdentityType() == IdentityType.APPLICATION) { while (it.hasNext()) { final Result result = it.next(); Object obj = getObjectUsingApplicationIdForResult( result, cmd, ec, ignoreCache, fpMembers, tableName, storeMgr, table); if (obj != null) { results.add(obj); } } } else if (cmd.getIdentityType() == IdentityType.DATASTORE) { while (it.hasNext()) { final Result result = it.next(); Object obj = getObjectUsingDatastoreIdForResult( result, cmd, ec, ignoreCache, fpMembers, tableName, storeMgr, table); if (obj != null) { results.add(obj); } } } else { while (it.hasNext()) { final Result result = it.next(); Object obj = getObjectUsingNondurableIdForResult( result, cmd, ec, ignoreCache, fpMembers, tableName, storeMgr, table); if (obj != null) { results.add(obj); } } } } catch (PrivilegedActionException e) { throw new NucleusDataStoreException(e.getMessage(), e.getCause()); } return results; }
/** * Method to return a statement selecting the candidate table(s) required to cover all possible * types for this candidates inheritance strategy. * * @param storeMgr RDBMS StoreManager * @param parentStmt Parent statement (if there is one) * @param cmd Metadata for the class * @param clsMapping Mapping for the results of the statement * @param ec ExecutionContext * @param candidateCls Candidate class * @param subclasses Whether to create a statement for subclasses of the candidate too * @param result The result clause * @param candidateAlias alias for the candidate (if any) * @param candidateTableGroupName TableGroup name for the candidate (if any) * @return The SQLStatement * @throws NucleusException if there are no tables for concrete classes in this query (hence would * return null) */ public static SQLStatement getStatementForCandidates( RDBMSStoreManager storeMgr, SQLStatement parentStmt, AbstractClassMetaData cmd, StatementClassMapping clsMapping, ExecutionContext ec, Class candidateCls, boolean subclasses, String result, String candidateAlias, String candidateTableGroupName) { SQLStatement stmt = null; DatastoreIdentifier candidateAliasId = null; if (candidateAlias != null) { candidateAliasId = storeMgr.getIdentifierFactory().newTableIdentifier(candidateAlias); } ClassLoaderResolver clr = ec.getClassLoaderResolver(); List<DatastoreClass> candidateTables = new ArrayList<DatastoreClass>(); if (cmd.getInheritanceMetaData().getStrategy() == InheritanceStrategy.COMPLETE_TABLE) { DatastoreClass candidateTable = storeMgr.getDatastoreClass(cmd.getFullClassName(), clr); if (candidateTable != null) { candidateTables.add(candidateTable); } if (subclasses) { Collection<String> subclassNames = storeMgr.getSubClassesForClass(cmd.getFullClassName(), subclasses, clr); if (subclassNames != null) { Iterator<String> subclassIter = subclassNames.iterator(); while (subclassIter.hasNext()) { String subclassName = subclassIter.next(); DatastoreClass tbl = storeMgr.getDatastoreClass(subclassName, clr); if (tbl != null) { candidateTables.add(tbl); } } } } Iterator<DatastoreClass> iter = candidateTables.iterator(); int maxClassNameLength = cmd.getFullClassName().length(); while (iter.hasNext()) { DatastoreClass cls = iter.next(); String className = cls.getType(); if (className.length() > maxClassNameLength) { maxClassNameLength = className.length(); } } iter = candidateTables.iterator(); while (iter.hasNext()) { DatastoreClass cls = iter.next(); SQLStatement tblStmt = new SQLStatement(parentStmt, storeMgr, cls, candidateAliasId, candidateTableGroupName); tblStmt.setClassLoaderResolver(clr); tblStmt.setCandidateClassName(cls.getType()); // Add SELECT of dummy column accessible as "NUCLEUS_TYPE" containing the classname JavaTypeMapping m = storeMgr.getMappingManager().getMapping(String.class); String nuctypeName = cls.getType(); if (maxClassNameLength > nuctypeName.length()) { nuctypeName = StringUtils.leftAlignedPaddedString(nuctypeName, maxClassNameLength); } StringLiteral lit = new StringLiteral(tblStmt, m, nuctypeName, null); tblStmt.select(lit, UnionStatementGenerator.NUC_TYPE_COLUMN); if (stmt == null) { stmt = tblStmt; } else { stmt.union(tblStmt); } } if (clsMapping != null) { clsMapping.setNucleusTypeColumnName(UnionStatementGenerator.NUC_TYPE_COLUMN); } } else { // "new-table", "superclass-table", "subclass-table" List<Class> candidateClasses = new ArrayList<Class>(); if (ClassUtils.isReferenceType(candidateCls)) { // Persistent interface, so find all persistent implementations String[] clsNames = storeMgr .getNucleusContext() .getMetaDataManager() .getClassesImplementingInterface(candidateCls.getName(), clr); for (int i = 0; i < clsNames.length; i++) { Class cls = clr.classForName(clsNames[i]); DatastoreClass table = storeMgr.getDatastoreClass(clsNames[i], clr); candidateClasses.add(cls); candidateTables.add(table); AbstractClassMetaData implCmd = storeMgr.getNucleusContext().getMetaDataManager().getMetaDataForClass(cls, clr); if (implCmd.getIdentityType() != cmd.getIdentityType()) { throw new NucleusUserException( "You are querying an interface (" + cmd.getFullClassName() + ") " + "yet one of its implementations (" + implCmd.getFullClassName() + ") " + " uses a different identity type!"); } else if (cmd.getIdentityType() == IdentityType.APPLICATION) { if (cmd.getPKMemberPositions().length != implCmd.getPKMemberPositions().length) { throw new NucleusUserException( "You are querying an interface (" + cmd.getFullClassName() + ") " + "yet one of its implementations (" + implCmd.getFullClassName() + ") " + " has a different number of PK members!"); } } } } else { DatastoreClass candidateTable = storeMgr.getDatastoreClass(cmd.getFullClassName(), clr); if (candidateTable != null) { // Candidate has own table candidateClasses.add(candidateCls); candidateTables.add(candidateTable); } else { // Candidate stored in subclass tables AbstractClassMetaData[] cmds = storeMgr.getClassesManagingTableForClass(cmd, clr); if (cmds != null && cmds.length > 0) { for (int i = 0; i < cmds.length; i++) { DatastoreClass table = storeMgr.getDatastoreClass(cmds[i].getFullClassName(), clr); Class cls = clr.classForName(cmds[i].getFullClassName()); candidateClasses.add(cls); candidateTables.add(table); } } else { throw new UnsupportedOperationException( "No tables for query of " + cmd.getFullClassName()); } } } for (int i = 0; i < candidateTables.size(); i++) { DatastoreClass tbl = candidateTables.get(i); Class cls = candidateClasses.get(i); StatementGenerator stmtGen = null; if (tbl.getDiscriminatorMapping(true) != null || QueryUtils.resultHasOnlyAggregates(result)) { // Either has a discriminator, or only selecting aggregates so need single select stmtGen = new DiscriminatorStatementGenerator( storeMgr, clr, cls, subclasses, candidateAliasId, candidateTableGroupName); stmtGen.setOption(StatementGenerator.OPTION_RESTRICT_DISCRIM); } else { stmtGen = new UnionStatementGenerator( storeMgr, clr, cls, subclasses, candidateAliasId, candidateTableGroupName); if (result == null) { // Returning one row per candidate so include distinguisher column stmtGen.setOption(StatementGenerator.OPTION_SELECT_NUCLEUS_TYPE); clsMapping.setNucleusTypeColumnName(UnionStatementGenerator.NUC_TYPE_COLUMN); } } stmtGen.setParentStatement(parentStmt); SQLStatement tblStmt = stmtGen.getStatement(); if (stmt == null) { stmt = tblStmt; } else { stmt.union(tblStmt); } } } return stmt; }