use of org.datanucleus.store.connection.ManagedConnection in project datanucleus-rdbms by datanucleus.
the class RDBMSStoreManager method getNucleusConnection.
/**
* Method to return a NucleusConnection for the ExecutionContext.
* @param ec execution context
* @return The NucleusConnection
*/
public NucleusConnection getNucleusConnection(final ExecutionContext ec) {
ManagedConnection mc = connectionMgr.getConnection(ec.getTransaction().isActive(), ec, ec.getTransaction());
// Lock the connection now that it is in use by the user
mc.lock();
Runnable closeRunnable = new Runnable() {
public void run() {
// Unlock the connection now that the user has finished with it
mc.unlock();
if (!ec.getTransaction().isActive()) {
// Close the (unenlisted) connection (committing its statements)
try {
((Connection) mc.getConnection()).close();
} catch (SQLException sqle) {
throw new NucleusDataStoreException(sqle.getMessage());
}
}
}
};
return new NucleusConnectionImpl(mc.getConnection(), closeRunnable);
}
use of org.datanucleus.store.connection.ManagedConnection in project datanucleus-rdbms by datanucleus.
the class SQLController method getStatementForUpdate.
/**
* Convenience method to create a new PreparedStatement for an update.
* @param conn The Connection to use for the statement
* @param stmtText Statement text
* @param batchable Whether this statement is batchable. Whether we will process the statement before any other statement
* @param getGeneratedKeysFlag whether to request getGeneratedKeys for this statement
* @return The PreparedStatement
* @throws SQLException thrown if an error occurs creating the statement
*/
public PreparedStatement getStatementForUpdate(ManagedConnection conn, String stmtText, boolean batchable, boolean getGeneratedKeysFlag) throws SQLException {
Connection c = (Connection) conn.getConnection();
if (supportsBatching) {
ConnectionStatementState state = getConnectionStatementState(conn);
if (state != null) {
if (state.processable) {
// We have a batchable statement in the queue that could be processed now if necessary
if (!batchable) {
// This new statement isnt batchable so process the existing one before returning our new statement
processConnectionStatement(conn);
} else {
// Check if we could batch onto this existing statement
if (state.stmtText.equals(stmtText)) {
// We can batch onto this statement
if (maxBatchSize == -1 || state.batchSize < maxBatchSize) {
state.batchSize++;
// Have to wait til we process this part til processable again
state.processable = false;
if (NucleusLogger.DATASTORE_PERSIST.isDebugEnabled()) {
NucleusLogger.DATASTORE_PERSIST.debug(Localiser.msg("052100", stmtText, "" + state.batchSize));
}
return state.stmt;
}
// Reached max batch size so process it now and start again for this one
if (NucleusLogger.DATASTORE_PERSIST.isDebugEnabled()) {
NucleusLogger.DATASTORE_PERSIST.debug(Localiser.msg("052101", state.stmtText));
}
processConnectionStatement(conn);
} else {
// We cant batch using the current batch statement so process it first and return our new one
processConnectionStatement(conn);
}
}
} else {
if (batchable) {
// The current statement is being batched so we cant batch this since cant process the current statement now
if (NucleusLogger.DATASTORE_PERSIST.isDebugEnabled()) {
NucleusLogger.DATASTORE_PERSIST.debug(Localiser.msg("052102", state.stmtText, stmtText));
}
batchable = false;
}
}
}
}
PreparedStatement ps = getGeneratedKeysFlag ? c.prepareStatement(stmtText, Statement.RETURN_GENERATED_KEYS) : c.prepareStatement(stmtText);
// In case using statement caching and given one with batched statements left hanging (C3P0)
ps.clearBatch();
if (!jdbcStatements) {
// Wrap with our parameter logger
ps = new ParamLoggingPreparedStatement(ps, stmtText);
((ParamLoggingPreparedStatement) ps).setParamsInAngleBrackets(paramValuesInBrackets);
}
if (NucleusLogger.DATASTORE.isDebugEnabled()) {
NucleusLogger.DATASTORE.debug(Localiser.msg("052109", ps, StringUtils.toJVMIDString(c)));
}
if (batchable && supportsBatching) {
// This statement is batchable so save it as the current batchable
if (NucleusLogger.DATASTORE_PERSIST.isDebugEnabled()) {
NucleusLogger.DATASTORE_PERSIST.debug(Localiser.msg("052103", stmtText));
}
ConnectionStatementState state = new ConnectionStatementState();
state.stmt = ps;
state.stmtText = stmtText;
state.batchSize = 1;
setConnectionStatementState(conn, state);
}
return ps;
}
use of org.datanucleus.store.connection.ManagedConnection in project datanucleus-rdbms by datanucleus.
the class NucleusSequenceImpl method setGenerator.
/**
* Method to set the value generator.
* Uses "sequence" if the datastore supports it, otherwise "increment".
*/
public void setGenerator() {
// Allocate the ValueGenerationManager for this sequence
String valueGeneratorName = null;
if (((RDBMSStoreManager) storeManager).getDatastoreAdapter().supportsOption(DatastoreAdapter.SEQUENCES)) {
valueGeneratorName = ValueGenerationStrategy.SEQUENCE.toString();
} else {
valueGeneratorName = ValueGenerationStrategy.INCREMENT.toString();
}
// Create the controlling properties for this sequence
Properties props = new Properties();
Map<String, String> seqExtensions = seqMetaData.getExtensions();
if (seqExtensions != null && seqExtensions.size() > 0) {
props.putAll(seqExtensions);
}
props.put(ValueGenerator.PROPERTY_SEQUENCE_NAME, seqMetaData.getDatastoreSequence());
if (seqMetaData.getAllocationSize() > 0) {
props.put(ValueGenerator.PROPERTY_KEY_CACHE_SIZE, "" + seqMetaData.getAllocationSize());
}
if (seqMetaData.getInitialValue() > 0) {
props.put(ValueGenerator.PROPERTY_KEY_INITIAL_VALUE, "" + seqMetaData.getInitialValue());
}
// Get a ValueGenerationManager to create the generator
ValueGenerationManager mgr = storeManager.getValueGenerationManager();
ValueGenerationConnectionProvider connProvider = new ValueGenerationConnectionProvider() {
ManagedConnection mconn;
public ManagedConnection retrieveConnection() {
// Obtain a new connection
// Note : it may be worthwhile to use the PM's connection here however where a Sequence doesnt yet
// exist the connection would then be effectively dead until the end of the tx
// The way around this would be to find a way of checking for existence of the sequence
Configuration conf = ec.getNucleusContext().getConfiguration();
int isolationLevel = TransactionUtils.getTransactionIsolationLevelForName(conf.getStringProperty(PropertyNames.PROPERTY_VALUEGEN_TXN_ISOLATION));
this.mconn = ((RDBMSStoreManager) storeManager).getConnectionManager().getConnection(isolationLevel);
return mconn;
}
public void releaseConnection() {
try {
// Release the connection
mconn.release();
} catch (NucleusException e) {
NucleusLogger.PERSISTENCE.error(Localiser.msg("017007", e));
throw e;
}
}
};
generator = mgr.createValueGenerator(valueGeneratorName, seqMetaData.getName(), props, connProvider);
if (NucleusLogger.PERSISTENCE.isDebugEnabled()) {
NucleusLogger.PERSISTENCE.debug(Localiser.msg("017003", seqMetaData.getName(), valueGeneratorName));
}
}
use of org.datanucleus.store.connection.ManagedConnection in project datanucleus-rdbms by datanucleus.
the class RDBMSStoreHelper method getClassNameForIdUsingDiscriminator.
/**
* 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(ec);
// Select the discriminator
JavaTypeMapping discrimMapping = primaryTable.getSurrogateMapping(SurrogateColumnType.DISCRIMINATOR, 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.getConnectionManager().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 {
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;
}
use of org.datanucleus.store.connection.ManagedConnection in project datanucleus-rdbms by datanucleus.
the class RDBMSStoreHelper method getClassNameForIdUsingUnion.
/**
* 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();
// Metadata for sample class in the tree so we can check if needs locking
AbstractClassMetaData sampleCmd = null;
SelectStatement sqlStmtMain = null;
while (rootCmdIter.hasNext()) {
AbstractClassMetaData rootCmd = rootCmdIter.next();
DatastoreClass rootTbl = storeMgr.getDatastoreClass(rootCmd.getFullClassName(), clr);
InheritanceMetaData rootInhmd = rootCmd.getBaseAbstractClassMetaData().getInheritanceMetaData();
if (rootInhmd.getStrategy() == InheritanceStrategy.COMPLETE_TABLE) {
// COMPLETE TABLE so use one branch of UNION for each possible class
if (rootTbl != null) {
UnionStatementGenerator stmtGen = new UnionStatementGenerator(storeMgr, clr, clr.classForName(rootCmd.getFullClassName()), false, null, null);
stmtGen.setOption(SelectStatementGenerator.OPTION_SELECT_DN_TYPE);
if (sqlStmtMain == null) {
sampleCmd = rootCmd;
sqlStmtMain = stmtGen.getStatement(ec);
// 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(ec);
// 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);
}
}
Collection<String> rootSubclassNames = storeMgr.getSubClassesForClass(rootCmd.getFullClassName(), true, clr);
for (String rootSubclassName : rootSubclassNames) {
AbstractClassMetaData rootSubclassCmd = storeMgr.getMetaDataManager().getMetaDataForClass(rootSubclassName, clr);
DatastoreClass rootSubclassTbl = storeMgr.getDatastoreClass(rootSubclassCmd.getFullClassName(), clr);
if (rootSubclassTbl != null) {
UnionStatementGenerator stmtGen = new UnionStatementGenerator(storeMgr, clr, clr.classForName(rootSubclassCmd.getFullClassName()), false, null, null);
stmtGen.setOption(SelectStatementGenerator.OPTION_SELECT_DN_TYPE);
if (sqlStmtMain == null) {
sampleCmd = rootSubclassCmd;
sqlStmtMain = stmtGen.getStatement(ec);
// 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(ec);
// 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);
}
}
}
continue;
}
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_DN_TYPE);
if (sqlStmtMain == null) {
sampleCmd = subcmds[i];
sqlStmtMain = stmtGen.getStatement(ec);
// 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(ec);
// 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_DN_TYPE);
if (sqlStmtMain == null) {
sampleCmd = rootCmd;
sqlStmtMain = stmtGen.getStatement(ec);
// 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(ec);
// 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
if (sqlStmtMain != null) {
try {
ManagedConnection mconn = storeMgr.getConnectionManager().getConnection(ec);
SQLController sqlControl = storeMgr.getSQLController();
if (sampleCmd != null && 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 {
while (rs.next()) {
try {
return rs.getString(UnionStatementGenerator.DN_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;
}
Aggregations