/** * Method to reserve a block of identities. Note : Only allocates a single id always. * * @param size The block size * @return The reserved block */ public ValueGenerationBlock reserveBlock(long size) { // search an Id in the database PreparedStatement ps = null; ResultSet rs = null; RDBMSStoreManager rdbmsMgr = (RDBMSStoreManager) storeMgr; SQLController sqlControl = rdbmsMgr.getSQLController(); try { String stmt = getStatement(); ps = sqlControl.getStatementForUpdate(connection, stmt, false); rs = sqlControl.executeStatementQuery(null, connection, stmt, ps); if (!rs.next()) { return new ValueGenerationBlock(new Object[] {Long.valueOf(1)}); } return new ValueGenerationBlock(new Object[] {Long.valueOf(rs.getLong(1) + 1)}); } catch (SQLException e) { // TODO adds a message correspondent to the exception. // we need to work to create user friendly messages throw new ValueGenerationException(e.getMessage()); } finally { try { if (rs != null) { rs.close(); } if (ps != null) { sqlControl.closeStatement(connection, ps); } } catch (SQLException e) { // no recoverable error } } }
public void executeClear(ObjectProvider ownerOP) { String clearStmt = getClearStmt(); try { ExecutionContext ec = ownerOP.getExecutionContext(); ManagedConnection mconn = storeMgr.getConnection(ec); SQLController sqlControl = storeMgr.getSQLController(); try { PreparedStatement ps = sqlControl.getStatementForUpdate(mconn, clearStmt, false); try { int jdbcPosition = 1; jdbcPosition = BackingStoreHelper.populateOwnerInStatement(ownerOP, ec, ps, jdbcPosition, this); if (getRelationDiscriminatorMapping() != null) { BackingStoreHelper.populateRelationDiscriminatorInStatement(ec, ps, jdbcPosition, this); } sqlControl.executeStatementUpdate(ec, mconn, clearStmt, ps, true); } finally { sqlControl.closeStatement(mconn, ps); } } finally { mconn.release(); } } catch (SQLException e) { throw new NucleusDataStoreException(Localiser.msg("056013", clearStmt), e); } }
/** * Clear the association from owner to all elements. Provides cascade-delete when the elements * being deleted are PC types. * * @param ownerOP ObjectProvider for the container. */ public void clear(ObjectProvider ownerOP) { Collection dependentElements = null; CollectionMetaData collmd = ownerMemberMetaData.getCollection(); boolean dependent = collmd.isDependentElement(); if (ownerMemberMetaData.isCascadeRemoveOrphans()) { dependent = true; } if (dependent && !collmd.isEmbeddedElement() && !collmd.isSerializedElement()) { // Retain the dependent elements that need deleting after clearing dependentElements = new HashSet(); Iterator iter = iterator(ownerOP); while (iter.hasNext()) { dependentElements.add(iter.next()); } } String clearStmt = getClearStmt(); try { ExecutionContext ec = ownerOP.getExecutionContext(); ManagedConnection mconn = storeMgr.getConnection(ec); SQLController sqlControl = storeMgr.getSQLController(); try { PreparedStatement ps = sqlControl.getStatementForUpdate(mconn, clearStmt, false); try { int jdbcPosition = 1; jdbcPosition = BackingStoreHelper.populateOwnerInStatement(ownerOP, ec, ps, jdbcPosition, this); if (relationDiscriminatorMapping != null) { BackingStoreHelper.populateRelationDiscriminatorInStatement(ec, ps, jdbcPosition, this); } sqlControl.executeStatementUpdate(ec, mconn, clearStmt, ps, true); } finally { sqlControl.closeStatement(mconn, ps); } } finally { mconn.release(); } } catch (SQLException e) { throw new NucleusDataStoreException(Localiser.msg("056013", clearStmt), e); } // Cascade-delete if (dependentElements != null && dependentElements.size() > 0) { Iterator iter = dependentElements.iterator(); while (iter.hasNext()) { Object obj = iter.next(); if (ownerOP.getExecutionContext().getApiAdapter().isDeleted(obj)) { // Element is tagged for deletion so will be deleted at flush(), and we dont need it // immediately } else { ownerOP.getExecutionContext().deleteObjectInternal(obj); } } } }
public int getSize(ObjectProvider ownerOP) { int numRows; String sizeStmt = getSizeStmt(); try { ExecutionContext ec = ownerOP.getExecutionContext(); ManagedConnection mconn = storeMgr.getConnection(ec); SQLController sqlControl = storeMgr.getSQLController(); try { PreparedStatement ps = sqlControl.getStatementForQuery(mconn, sizeStmt); try { int jdbcPosition = 1; jdbcPosition = BackingStoreHelper.populateOwnerInStatement(ownerOP, ec, ps, jdbcPosition, this); if (getElementInfo() != null && getElementInfo().length == 1) { // TODO Allow for multiple element types (e.g interface implementations) for (int i = 0; i < getElementInfo().length; i++) { if (getElementInfo()[i].getDiscriminatorMapping() != null) { jdbcPosition = BackingStoreHelper.populateElementDiscriminatorInStatement( ec, ps, jdbcPosition, true, getElementInfo()[i], clr); } } } if (getRelationDiscriminatorMapping() != null) { jdbcPosition = BackingStoreHelper.populateRelationDiscriminatorInStatement( ec, ps, jdbcPosition, this); } ResultSet rs = sqlControl.executeStatementQuery(ec, mconn, sizeStmt, ps); try { if (!rs.next()) { throw new NucleusDataStoreException(Localiser.msg("056007", sizeStmt)); } numRows = rs.getInt(1); JDBCUtils.logWarnings(rs); } finally { rs.close(); } } finally { sqlControl.closeStatement(mconn, ps); } } finally { mconn.release(); } } catch (SQLException e) { throw new NucleusDataStoreException(Localiser.msg("056007", sizeStmt), e); } return numRows; }
/** * Method to create a PreparedStatement for use with the query. * * @param conn the Connection * @param queryStmt The statement text for the query * @param query The query * @return the PreparedStatement * @throws SQLException Thrown if an error occurs creating the statement */ public static PreparedStatement getPreparedStatementForQuery( ManagedConnection conn, String queryStmt, Query query) throws SQLException { // Apply any non-standard result set definition if required (either from the PMF, or via query // extensions) String rsTypeString = RDBMSQueryUtils.getResultSetTypeForQuery(query); if (rsTypeString != null && (!rsTypeString.equals("scroll-sensitive") && !rsTypeString.equals("forward-only") && !rsTypeString.equals("scroll-insensitive"))) { throw new NucleusUserException(LOCALISER.msg("052510")); } if (rsTypeString != null) { DatastoreAdapter dba = ((RDBMSStoreManager) query.getStoreManager()).getDatastoreAdapter(); // Add checks on what the DatastoreAdapter supports if (rsTypeString.equals("scroll-sensitive") && !dba.supportsOption(DatastoreAdapter.RESULTSET_TYPE_SCROLL_SENSITIVE)) { NucleusLogger.DATASTORE_RETRIEVE.info( "Query requested to run with result-set type of " + rsTypeString + " yet not supported by adapter. Using forward-only"); rsTypeString = "forward-only"; } else if (rsTypeString.equals("scroll-insensitive") && !dba.supportsOption(DatastoreAdapter.RESULTSET_TYPE_SCROLL_INSENSITIVE)) { NucleusLogger.DATASTORE_RETRIEVE.info( "Query requested to run with result-set type of " + rsTypeString + " yet not supported by adapter. Using forward-only"); rsTypeString = "forward-only"; } else if (rsTypeString.equals("forward-only") && !dba.supportsOption(DatastoreAdapter.RESULTSET_TYPE_FORWARD_ONLY)) { NucleusLogger.DATASTORE_RETRIEVE.info( "Query requested to run with result-set type of " + rsTypeString + " yet not supported by adapter. Using scroll-sensitive"); rsTypeString = "scroll-sensitive"; } } String rsConcurrencyString = RDBMSQueryUtils.getResultSetConcurrencyForQuery(query); if (rsConcurrencyString != null && (!rsConcurrencyString.equals("read-only") && !rsConcurrencyString.equals("updateable"))) { throw new NucleusUserException(LOCALISER.msg("052511")); } SQLController sqlControl = ((RDBMSStoreManager) query.getStoreManager()).getSQLController(); PreparedStatement ps = sqlControl.getStatementForQuery(conn, queryStmt, rsTypeString, rsConcurrencyString); return ps; }
/** * Utility that does a discriminator candidate query for the specified candidate and subclasses * and returns the class name of the instance that has the specified identity (if any). * * @param storeMgr RDBMS StoreManager * @param ec execution context * @param id The id * @param cmd Metadata for the root candidate class * @return Name of the class with this identity (or null if none found) */ public static String getClassNameForIdUsingDiscriminator( RDBMSStoreManager storeMgr, ExecutionContext ec, Object id, AbstractClassMetaData cmd) { // Check for input error if (cmd == null || id == null) { return null; } SQLExpressionFactory exprFactory = storeMgr.getSQLExpressionFactory(); ClassLoaderResolver clr = ec.getClassLoaderResolver(); DatastoreClass primaryTable = storeMgr.getDatastoreClass(cmd.getFullClassName(), clr); // Form the query to find which one of these classes has the instance with this id DiscriminatorStatementGenerator stmtGen = new DiscriminatorStatementGenerator( storeMgr, clr, clr.classForName(cmd.getFullClassName()), true, null, null); stmtGen.setOption(SelectStatementGenerator.OPTION_RESTRICT_DISCRIM); SelectStatement sqlStmt = stmtGen.getStatement(); // Select the discriminator JavaTypeMapping discrimMapping = primaryTable.getDiscriminatorMapping(true); SQLTable discrimSqlTbl = SQLStatementHelper.getSQLTableForMappingOfTable( sqlStmt, sqlStmt.getPrimaryTable(), discrimMapping); sqlStmt.select(discrimSqlTbl, discrimMapping, null); // Restrict to this id JavaTypeMapping idMapping = primaryTable.getIdMapping(); JavaTypeMapping idParamMapping = new PersistableIdMapping((PersistableMapping) idMapping); SQLExpression sqlFldExpr = exprFactory.newExpression(sqlStmt, sqlStmt.getPrimaryTable(), idMapping); SQLExpression sqlFldVal = exprFactory.newLiteralParameter(sqlStmt, idParamMapping, id, "ID"); sqlStmt.whereAnd(sqlFldExpr.eq(sqlFldVal), true); // Perform the query try { ManagedConnection mconn = storeMgr.getConnection(ec); SQLController sqlControl = storeMgr.getSQLController(); if (ec.getSerializeReadForClass(cmd.getFullClassName())) { sqlStmt.addExtension(SQLStatement.EXTENSION_LOCK_FOR_UPDATE, true); } try { PreparedStatement ps = SQLStatementHelper.getPreparedStatementForSQLStatement(sqlStmt, ec, mconn, null, null); String statement = sqlStmt.getSQLText().toSQL(); try { ResultSet rs = sqlControl.executeStatementQuery(ec, mconn, statement, ps); try { if (rs != null) { while (rs.next()) { DiscriminatorMetaData dismd = discrimMapping.getTable().getDiscriminatorMetaData(); return RDBMSQueryUtils.getClassNameFromDiscriminatorResultSetRow( discrimMapping, dismd, rs, ec); } } } finally { rs.close(); } } finally { sqlControl.closeStatement(mconn, ps); } } finally { mconn.release(); } } catch (SQLException sqe) { NucleusLogger.DATASTORE.error("Exception thrown on querying of discriminator for id", sqe); throw new NucleusDataStoreException(sqe.toString(), sqe); } return null; }
/** * Utility that does a union candidate query for the specified candidate(s) and subclasses and * returns the class name of the instance that has the specified identity (if any). * * @param storeMgr RDBMS StoreManager * @param ec execution context * @param id The id * @param rootCmds Metadata for the classes at the root * @return Name of the class with this identity (or null if none found) */ public static String getClassNameForIdUsingUnion( RDBMSStoreManager storeMgr, ExecutionContext ec, Object id, List<AbstractClassMetaData> rootCmds) { // Check for input error if (rootCmds == null || rootCmds.isEmpty() || id == null) { return null; } SQLExpressionFactory exprFactory = storeMgr.getSQLExpressionFactory(); ClassLoaderResolver clr = ec.getClassLoaderResolver(); // Form a query UNIONing all possible root candidates (and their subclasses) Iterator<AbstractClassMetaData> rootCmdIter = rootCmds.iterator(); AbstractClassMetaData sampleCmd = null; // Metadata for sample class in the tree so we can check if needs locking SelectStatement sqlStmtMain = null; while (rootCmdIter.hasNext()) { AbstractClassMetaData rootCmd = rootCmdIter.next(); DatastoreClass rootTbl = storeMgr.getDatastoreClass(rootCmd.getFullClassName(), clr); if (rootTbl == null) { // Class must be using "subclass-table" (no table of its own) so find where it is AbstractClassMetaData[] subcmds = storeMgr.getClassesManagingTableForClass(rootCmd, clr); if (subcmds == null || subcmds.length == 0) { // No table for this class so ignore } else { for (int i = 0; i < subcmds.length; i++) { UnionStatementGenerator stmtGen = new UnionStatementGenerator( storeMgr, clr, clr.classForName(subcmds[i].getFullClassName()), true, null, null); stmtGen.setOption(SelectStatementGenerator.OPTION_SELECT_NUCLEUS_TYPE); if (sqlStmtMain == null) { sampleCmd = subcmds[i]; sqlStmtMain = stmtGen.getStatement(); // WHERE (object id) = ? JavaTypeMapping idMapping = sqlStmtMain.getPrimaryTable().getTable().getIdMapping(); JavaTypeMapping idParamMapping = new PersistableIdMapping((PersistableMapping) idMapping); SQLExpression fieldExpr = exprFactory.newExpression(sqlStmtMain, sqlStmtMain.getPrimaryTable(), idMapping); SQLExpression fieldVal = exprFactory.newLiteralParameter(sqlStmtMain, idParamMapping, id, "ID"); sqlStmtMain.whereAnd(fieldExpr.eq(fieldVal), true); } else { SelectStatement sqlStmt = stmtGen.getStatement(); // WHERE (object id) = ? JavaTypeMapping idMapping = sqlStmt.getPrimaryTable().getTable().getIdMapping(); JavaTypeMapping idParamMapping = new PersistableIdMapping((PersistableMapping) idMapping); SQLExpression fieldExpr = exprFactory.newExpression(sqlStmt, sqlStmt.getPrimaryTable(), idMapping); SQLExpression fieldVal = exprFactory.newLiteralParameter(sqlStmt, idParamMapping, id, "ID"); sqlStmt.whereAnd(fieldExpr.eq(fieldVal), true); sqlStmtMain.union(sqlStmt); } } } } else { UnionStatementGenerator stmtGen = new UnionStatementGenerator( storeMgr, clr, clr.classForName(rootCmd.getFullClassName()), true, null, null); stmtGen.setOption(SelectStatementGenerator.OPTION_SELECT_NUCLEUS_TYPE); if (sqlStmtMain == null) { sampleCmd = rootCmd; sqlStmtMain = stmtGen.getStatement(); // WHERE (object id) = ? JavaTypeMapping idMapping = sqlStmtMain.getPrimaryTable().getTable().getIdMapping(); JavaTypeMapping idParamMapping = new PersistableIdMapping((PersistableMapping) idMapping); SQLExpression fieldExpr = exprFactory.newExpression(sqlStmtMain, sqlStmtMain.getPrimaryTable(), idMapping); SQLExpression fieldVal = exprFactory.newLiteralParameter(sqlStmtMain, idParamMapping, id, "ID"); sqlStmtMain.whereAnd(fieldExpr.eq(fieldVal), true); } else { SelectStatement sqlStmt = stmtGen.getStatement(); // WHERE (object id) = ? JavaTypeMapping idMapping = sqlStmt.getPrimaryTable().getTable().getIdMapping(); JavaTypeMapping idParamMapping = new PersistableIdMapping((PersistableMapping) idMapping); SQLExpression fieldExpr = exprFactory.newExpression(sqlStmt, sqlStmt.getPrimaryTable(), idMapping); SQLExpression fieldVal = exprFactory.newLiteralParameter(sqlStmt, idParamMapping, id, "ID"); sqlStmt.whereAnd(fieldExpr.eq(fieldVal), true); sqlStmtMain.union(sqlStmt); } } } // Perform the query try { ManagedConnection mconn = storeMgr.getConnection(ec); SQLController sqlControl = storeMgr.getSQLController(); if (ec.getSerializeReadForClass(sampleCmd.getFullClassName())) { sqlStmtMain.addExtension(SQLStatement.EXTENSION_LOCK_FOR_UPDATE, true); } try { PreparedStatement ps = SQLStatementHelper.getPreparedStatementForSQLStatement( sqlStmtMain, ec, mconn, null, null); String statement = sqlStmtMain.getSQLText().toSQL(); try { ResultSet rs = sqlControl.executeStatementQuery(ec, mconn, statement, ps); try { if (rs != null) { while (rs.next()) { try { return rs.getString(UnionStatementGenerator.NUC_TYPE_COLUMN).trim(); } catch (SQLException sqle) { } } } } finally { rs.close(); } } finally { sqlControl.closeStatement(mconn, ps); } } finally { mconn.release(); } } catch (SQLException sqe) { NucleusLogger.DATASTORE.error("Exception with UNION statement", sqe); throw new NucleusDataStoreException(sqe.toString()); } return null; }
public int getSize(ObjectProvider ownerOP) { int numRows; String sizeStmt = getSizeStmt(); try { ExecutionContext ec = ownerOP.getExecutionContext(); ManagedConnection mconn = storeMgr.getConnection(ec); SQLController sqlControl = storeMgr.getSQLController(); try { PreparedStatement ps = sqlControl.getStatementForQuery(mconn, sizeStmt); try { int jdbcPosition = 1; if (elementInfo == null) { jdbcPosition = BackingStoreHelper.populateOwnerInStatement(ownerOP, ec, ps, jdbcPosition, this); } else { if (usingJoinTable()) { jdbcPosition = BackingStoreHelper.populateOwnerInStatement(ownerOP, ec, ps, jdbcPosition, this); if (elementInfo[0].getDiscriminatorMapping() != null) { jdbcPosition = BackingStoreHelper.populateElementDiscriminatorInStatement( ec, ps, jdbcPosition, true, elementInfo[0], clr); } if (relationDiscriminatorMapping != null) { jdbcPosition = BackingStoreHelper.populateRelationDiscriminatorInStatement( ec, ps, jdbcPosition, this); } } else { for (int i = 0; i < elementInfo.length; i++) { jdbcPosition = BackingStoreHelper.populateOwnerInStatement( ownerOP, ec, ps, jdbcPosition, this); if (elementInfo[i].getDiscriminatorMapping() != null) { jdbcPosition = BackingStoreHelper.populateElementDiscriminatorInStatement( ec, ps, jdbcPosition, true, elementInfo[i], clr); } if (relationDiscriminatorMapping != null) { jdbcPosition = BackingStoreHelper.populateRelationDiscriminatorInStatement( ec, ps, jdbcPosition, this); } } } } ResultSet rs = sqlControl.executeStatementQuery(ec, mconn, sizeStmt, ps); try { if (!rs.next()) { throw new NucleusDataStoreException(Localiser.msg("056007", sizeStmt)); } numRows = rs.getInt(1); if (elementInfo != null && elementInfo.length > 1) { while (rs.next()) { numRows = numRows + rs.getInt(1); } } JDBCUtils.logWarnings(rs); } finally { rs.close(); } } catch (SQLException sqle) { NucleusLogger.GENERAL.error("Exception in size", sqle); throw sqle; } finally { sqlControl.closeStatement(mconn, ps); } } finally { mconn.release(); } } catch (SQLException e) { throw new NucleusDataStoreException(Localiser.msg("056007", sizeStmt), e); } return numRows; }