use of org.datanucleus.store.rdbms.query.StatementMappingIndex in project datanucleus-rdbms by datanucleus.
the class SQLStatementHelper method selectIdentityOfCandidateInStatement.
/**
* Method to select the identity for the candidate class.
* The supplied statement and mapping definition are updated during this method.
* Selects the datastore id (if using datastore id) as "DN_DATASTOREID",
* the version (if present) as "DN_VERSION", the discriminator (if present) as "DN_DISCRIM",
* and the application id (if using application id) as "DN_APPID_{i}"
* @param stmt The statement
* @param mappingDefinition Mapping definition for result columns
* @param candidateCmd The candidate class meta-data
*/
public static void selectIdentityOfCandidateInStatement(SelectStatement stmt, StatementClassMapping mappingDefinition, AbstractClassMetaData candidateCmd) {
DatastoreClass candidateTbl = (DatastoreClass) stmt.getPrimaryTable().getTable();
if (candidateCmd.getIdentityType() == IdentityType.DATASTORE) {
// Datastore-identity surrogate column
JavaTypeMapping idMapping = candidateTbl.getSurrogateMapping(SurrogateColumnType.DATASTORE_ID, false);
int[] colNumbers = stmt.select(stmt.getPrimaryTable(), idMapping, "DN_DATASTOREID", false);
if (mappingDefinition != null) {
StatementMappingIndex datastoreIdIdx = new StatementMappingIndex(idMapping);
datastoreIdIdx.setColumnPositions(colNumbers);
mappingDefinition.addMappingForMember(SurrogateColumnType.DATASTORE_ID.getFieldNumber(), datastoreIdIdx);
}
} else if (candidateCmd.getIdentityType() == IdentityType.APPLICATION) {
// Application-identity column(s)
int[] pkPositions = candidateCmd.getPKMemberPositions();
String alias = "DN_APPID";
for (int i = 0; i < pkPositions.length; i++) {
AbstractMemberMetaData pkMmd = candidateCmd.getMetaDataForManagedMemberAtAbsolutePosition(pkPositions[i]);
JavaTypeMapping pkMapping = candidateTbl.getMemberMapping(pkMmd);
SQLTable sqlTbl = SQLStatementHelper.getSQLTableForMappingOfTable(stmt, stmt.getPrimaryTable(), pkMapping);
if (pkPositions.length > 1) {
alias = "DN_APPID" + i;
}
int[] colNumbers = stmt.select(sqlTbl, pkMapping, alias, false);
if (mappingDefinition != null) {
StatementMappingIndex appIdIdx = new StatementMappingIndex(pkMapping);
appIdIdx.setColumnPositions(colNumbers);
mappingDefinition.addMappingForMember(pkPositions[i], appIdIdx);
}
}
}
JavaTypeMapping verMapping = candidateTbl.getSurrogateMapping(SurrogateColumnType.VERSION, true);
if (verMapping != null) {
// Version surrogate column (adds inner join to any required superclass table)
SQLTable versionSqlTbl = SQLStatementHelper.getSQLTableForMappingOfTable(stmt, stmt.getPrimaryTable(), verMapping);
int[] colNumbers = stmt.select(versionSqlTbl, verMapping, "DN_VERSION", false);
if (mappingDefinition != null) {
StatementMappingIndex versionIdx = new StatementMappingIndex(verMapping);
versionIdx.setColumnPositions(colNumbers);
mappingDefinition.addMappingForMember(SurrogateColumnType.VERSION.getFieldNumber(), versionIdx);
}
}
JavaTypeMapping discrimMapping = candidateTbl.getSurrogateMapping(SurrogateColumnType.DISCRIMINATOR, true);
if (discrimMapping != null) {
// Discriminator surrogate column (adds inner join to any required superclass table)
SQLTable discrimSqlTbl = SQLStatementHelper.getSQLTableForMappingOfTable(stmt, stmt.getPrimaryTable(), discrimMapping);
int[] colNumbers = stmt.select(discrimSqlTbl, discrimMapping, "DN_DISCRIM", false);
if (mappingDefinition != null) {
StatementMappingIndex discrimIdx = new StatementMappingIndex(discrimMapping);
discrimIdx.setColumnPositions(colNumbers);
mappingDefinition.addMappingForMember(SurrogateColumnType.DISCRIMINATOR.getFieldNumber(), discrimIdx);
}
}
List<SelectStatement> unionStmts = stmt.getUnions();
if (unionStmts != null) {
Iterator<SelectStatement> iter = unionStmts.iterator();
while (iter.hasNext()) {
SelectStatement unionStmt = iter.next();
selectIdentityOfCandidateInStatement(unionStmt, null, candidateCmd);
}
}
}
use of org.datanucleus.store.rdbms.query.StatementMappingIndex in project datanucleus-rdbms by datanucleus.
the class SQLStatementHelper method selectFetchPlanOfSourceClassInStatement.
/**
* Method to select all fetch plan members for the "source" class.
* If the passed FetchPlan is null then the default fetch group fields will be selected.
* The source class is defined by the supplied meta-data, and the SQLTable that we are selecting from.
* The supplied statement and mapping definition are updated during this method.
* @param stmt The statement
* @param mappingDefinition Mapping definition for result columns (populated with column positions
* of any selected mappings if provided as input)
* @param fetchPlan FetchPlan in use
* @param sourceSqlTbl SQLTable for the source class that we select from
* @param sourceCmd Meta-data for the source class
* @param maxFetchDepth Max fetch depth from this point to select (0 implies no other objects)
* @param inputJoinType Optional join type to use for subobjects (otherwise decide join type internally)
*/
public static void selectFetchPlanOfSourceClassInStatement(SelectStatement stmt, StatementClassMapping mappingDefinition, FetchPlan fetchPlan, SQLTable sourceSqlTbl, AbstractClassMetaData sourceCmd, int maxFetchDepth, JoinType inputJoinType) {
DatastoreClass sourceTbl = (DatastoreClass) sourceSqlTbl.getTable();
int[] fieldNumbers;
if (fetchPlan != null) {
// Use FetchPlan fields
fieldNumbers = fetchPlan.getFetchPlanForClass(sourceCmd).getMemberNumbers();
} else {
// Use DFG fields
fieldNumbers = sourceCmd.getDFGMemberPositions();
}
ClassLoaderResolver clr = stmt.getRDBMSManager().getNucleusContext().getClassLoaderResolver(null);
for (int fieldNumber : fieldNumbers) {
AbstractMemberMetaData mmd = sourceCmd.getMetaDataForManagedMemberAtAbsolutePosition(fieldNumber);
selectMemberOfSourceInStatement(stmt, mappingDefinition, fetchPlan, sourceSqlTbl, mmd, clr, maxFetchDepth, inputJoinType);
}
if (sourceCmd.getIdentityType() == IdentityType.DATASTORE) {
// Datastore-identity surrogate column
JavaTypeMapping idMapping = sourceTbl.getSurrogateMapping(SurrogateColumnType.DATASTORE_ID, false);
int[] colNumbers = stmt.select(sourceSqlTbl, idMapping, null);
if (mappingDefinition != null) {
StatementMappingIndex datastoreIdIdx = new StatementMappingIndex(idMapping);
datastoreIdIdx.setColumnPositions(colNumbers);
mappingDefinition.addMappingForMember(SurrogateColumnType.DATASTORE_ID.getFieldNumber(), datastoreIdIdx);
}
}
JavaTypeMapping verMapping = sourceTbl.getSurrogateMapping(SurrogateColumnType.VERSION, true);
if (verMapping != null) {
// Version surrogate column (adds inner join to any required superclass table)
SQLTable versionSqlTbl = SQLStatementHelper.getSQLTableForMappingOfTable(stmt, sourceSqlTbl, verMapping);
int[] colNumbers = stmt.select(versionSqlTbl, verMapping, null);
if (mappingDefinition != null) {
StatementMappingIndex versionIdx = new StatementMappingIndex(verMapping);
versionIdx.setColumnPositions(colNumbers);
mappingDefinition.addMappingForMember(SurrogateColumnType.VERSION.getFieldNumber(), versionIdx);
}
}
JavaTypeMapping discrimMapping = sourceTbl.getSurrogateMapping(SurrogateColumnType.DISCRIMINATOR, true);
if (discrimMapping != null) {
// Discriminator surrogate column (adds inner join to any required superclass table)
SQLTable discrimSqlTbl = SQLStatementHelper.getSQLTableForMappingOfTable(stmt, sourceSqlTbl, discrimMapping);
int[] colNumbers = stmt.select(discrimSqlTbl, discrimMapping, null);
if (mappingDefinition != null) {
StatementMappingIndex discrimIdx = new StatementMappingIndex(discrimMapping);
discrimIdx.setColumnPositions(colNumbers);
mappingDefinition.addMappingForMember(SurrogateColumnType.DISCRIMINATOR.getFieldNumber(), discrimIdx);
}
}
}
use of org.datanucleus.store.rdbms.query.StatementMappingIndex in project datanucleus-rdbms by datanucleus.
the class LocateBulkRequest method getStatement.
protected String getStatement(DatastoreClass table, ObjectProvider[] ops, boolean lock) {
RDBMSStoreManager storeMgr = table.getStoreManager();
ClassLoaderResolver clr = storeMgr.getNucleusContext().getClassLoaderResolver(null);
SQLExpressionFactory exprFactory = storeMgr.getSQLExpressionFactory();
cmd = storeMgr.getMetaDataManager().getMetaDataForClass(table.getType(), clr);
ExecutionContext ec = ops[0].getExecutionContext();
SelectStatement sqlStatement = new SelectStatement(storeMgr, table, null, null);
// SELECT fields we require
resultMapping = new StatementClassMapping();
// a). PK fields
if (table.getIdentityType() == IdentityType.DATASTORE) {
JavaTypeMapping datastoreIdMapping = table.getSurrogateMapping(SurrogateColumnType.DATASTORE_ID, false);
SQLExpression expr = exprFactory.newExpression(sqlStatement, sqlStatement.getPrimaryTable(), datastoreIdMapping);
int[] cols = sqlStatement.select(expr, null);
StatementMappingIndex datastoreIdx = new StatementMappingIndex(datastoreIdMapping);
datastoreIdx.setColumnPositions(cols);
resultMapping.addMappingForMember(SurrogateColumnType.DATASTORE_ID.getFieldNumber(), datastoreIdx);
} else if (table.getIdentityType() == IdentityType.APPLICATION) {
int[] pkNums = cmd.getPKMemberPositions();
for (int i = 0; i < pkNums.length; i++) {
AbstractMemberMetaData mmd = cmd.getMetaDataForManagedMemberAtAbsolutePosition(pkNums[i]);
JavaTypeMapping pkMapping = table.getMemberMappingInDatastoreClass(mmd);
if (pkMapping == null) {
pkMapping = table.getMemberMapping(mmd);
}
SQLExpression expr = exprFactory.newExpression(sqlStatement, sqlStatement.getPrimaryTable(), pkMapping);
int[] cols = sqlStatement.select(expr, null);
StatementMappingIndex pkIdx = new StatementMappingIndex(pkMapping);
pkIdx.setColumnPositions(cols);
resultMapping.addMappingForMember(mmd.getAbsoluteFieldNumber(), pkIdx);
}
} else {
throw new NucleusUserException("Cannot locate objects using nondurable identity");
}
JavaTypeMapping verMapping = table.getSurrogateMapping(SurrogateColumnType.VERSION, false);
if (verMapping != null) {
VersionMetaData currentVermd = table.getVersionMetaData();
if (currentVermd != null && currentVermd.getFieldName() == null) {
// Surrogate version column
SQLExpression expr = exprFactory.newExpression(sqlStatement, sqlStatement.getPrimaryTable(), verMapping);
int[] cols = sqlStatement.select(expr, null);
StatementMappingIndex mapIdx = new StatementMappingIndex(verMapping);
mapIdx.setColumnPositions(cols);
resultMapping.addMappingForMember(SurrogateColumnType.VERSION.getFieldNumber(), mapIdx);
}
}
int[] nonPkFieldNums = cmd.getNonPKMemberPositions();
if (nonPkFieldNums != null) {
for (int i = 0; i < nonPkFieldNums.length; i++) {
AbstractMemberMetaData mmd = cmd.getMetaDataForManagedMemberAtAbsolutePosition(nonPkFieldNums[i]);
JavaTypeMapping mapping = table.getMemberMapping(mmd);
if (mapping != null && mapping.includeInFetchStatement()) {
if (mapping instanceof PersistableMapping) {
// Ignore 1-1/N-1 for now
continue;
}
SQLExpression expr = exprFactory.newExpression(sqlStatement, sqlStatement.getPrimaryTable(), mapping);
int[] cols = sqlStatement.select(expr, null);
StatementMappingIndex mapIdx = new StatementMappingIndex(mapping);
mapIdx.setColumnPositions(cols);
resultMapping.addMappingForMember(mmd.getAbsoluteFieldNumber(), mapIdx);
}
}
}
JavaTypeMapping multitenancyMapping = table.getSurrogateMapping(SurrogateColumnType.MULTITENANCY, false);
if (multitenancyMapping != null) {
// Add WHERE clause restricting to tenant
SQLExpression tenantExpr = exprFactory.newExpression(sqlStatement, sqlStatement.getPrimaryTable(), multitenancyMapping);
SQLExpression tenantVal = exprFactory.newLiteral(sqlStatement, multitenancyMapping, ec.getNucleusContext().getMultiTenancyId(ec, cmd));
sqlStatement.whereAnd(tenantExpr.eq(tenantVal), true);
}
JavaTypeMapping softDeleteMapping = table.getSurrogateMapping(SurrogateColumnType.SOFTDELETE, false);
if (softDeleteMapping != null) {
// Add WHERE clause restricting to soft-delete unset
SQLExpression softDeleteExpr = exprFactory.newExpression(sqlStatement, sqlStatement.getPrimaryTable(), softDeleteMapping);
SQLExpression softDeleteVal = exprFactory.newLiteral(sqlStatement, softDeleteMapping, Boolean.FALSE);
sqlStatement.whereAnd(softDeleteExpr.eq(softDeleteVal), true);
}
// Add WHERE clause restricting to the identities of the objects
mappingDefinitions = new StatementClassMapping[ops.length];
int inputParamNum = 1;
for (int i = 0; i < ops.length; i++) {
mappingDefinitions[i] = new StatementClassMapping();
if (table.getIdentityType() == IdentityType.DATASTORE) {
// Datastore identity value for input
JavaTypeMapping datastoreIdMapping = table.getSurrogateMapping(SurrogateColumnType.DATASTORE_ID, false);
SQLExpression expr = exprFactory.newExpression(sqlStatement, sqlStatement.getPrimaryTable(), datastoreIdMapping);
SQLExpression val = exprFactory.newLiteralParameter(sqlStatement, datastoreIdMapping, null, "ID");
sqlStatement.whereOr(expr.eq(val), true);
StatementMappingIndex datastoreIdx = new StatementMappingIndex(datastoreIdMapping);
mappingDefinitions[i].addMappingForMember(SurrogateColumnType.DATASTORE_ID.getFieldNumber(), datastoreIdx);
datastoreIdx.addParameterOccurrence(new int[] { inputParamNum++ });
} else if (table.getIdentityType() == IdentityType.APPLICATION) {
// Application identity value(s) for input
BooleanExpression pkExpr = null;
int[] pkNums = cmd.getPKMemberPositions();
for (int j = 0; j < pkNums.length; j++) {
AbstractMemberMetaData mmd = cmd.getMetaDataForManagedMemberAtAbsolutePosition(pkNums[j]);
JavaTypeMapping pkMapping = table.getMemberMappingInDatastoreClass(mmd);
if (pkMapping == null) {
pkMapping = table.getMemberMapping(mmd);
}
SQLExpression expr = exprFactory.newExpression(sqlStatement, sqlStatement.getPrimaryTable(), pkMapping);
SQLExpression val = exprFactory.newLiteralParameter(sqlStatement, pkMapping, null, "PK" + j);
BooleanExpression fieldEqExpr = expr.eq(val);
if (pkExpr == null) {
pkExpr = fieldEqExpr;
} else {
pkExpr = pkExpr.and(fieldEqExpr);
}
StatementMappingIndex pkIdx = new StatementMappingIndex(pkMapping);
mappingDefinitions[i].addMappingForMember(mmd.getAbsoluteFieldNumber(), pkIdx);
int[] inputParams = new int[pkMapping.getNumberOfDatastoreMappings()];
for (int k = 0; k < pkMapping.getNumberOfDatastoreMappings(); k++) {
inputParams[k] = inputParamNum++;
}
pkIdx.addParameterOccurrence(inputParams);
}
if (pkExpr == null) {
throw new NucleusException("Unable to generate PK expression for WHERE clause of locate statement");
}
pkExpr = (BooleanExpression) pkExpr.encloseInParentheses();
sqlStatement.whereOr(pkExpr, true);
}
}
// Generate the appropriate JDBC statement allowing for locking
if (lock) {
sqlStatement.addExtension(SQLStatement.EXTENSION_LOCK_FOR_UPDATE, Boolean.TRUE);
return sqlStatement.getSQLText().toSQL();
}
return sqlStatement.getSQLText().toSQL();
}
use of org.datanucleus.store.rdbms.query.StatementMappingIndex in project datanucleus-rdbms by datanucleus.
the class JoinMapStore method getSQLStatementForGet.
/**
* Method to return an SQLStatement for retrieving the value for a key.
* Selects the join table and optionally joins to the value table if it has its own table.
* @param ownerOP ObjectProvider for the owning object
* @return The SQLStatement
*/
protected SelectStatement getSQLStatementForGet(ObjectProvider ownerOP) {
SelectStatement sqlStmt = null;
ExecutionContext ec = ownerOP.getExecutionContext();
final ClassLoaderResolver clr = ownerOP.getExecutionContext().getClassLoaderResolver();
Class valueCls = clr.classForName(this.valueType);
if (valuesAreEmbedded || valuesAreSerialised) {
// Value is stored in join table
sqlStmt = new SelectStatement(storeMgr, mapTable, null, null);
sqlStmt.setClassLoaderResolver(clr);
sqlStmt.select(sqlStmt.getPrimaryTable(), valueMapping, null);
} else {
// Value is stored in own table
getMappingDef = new StatementClassMapping();
if (!valueCmd.getFullClassName().equals(valueCls.getName())) {
valueCls = clr.classForName(valueCmd.getFullClassName());
}
UnionStatementGenerator stmtGen = new UnionStatementGenerator(storeMgr, clr, valueCls, true, null, null, mapTable, null, valueMapping);
stmtGen.setOption(SelectStatementGenerator.OPTION_SELECT_DN_TYPE);
getMappingDef.setNucleusTypeColumnName(UnionStatementGenerator.DN_TYPE_COLUMN);
sqlStmt = stmtGen.getStatement(ec);
// Select the value field(s)
SQLTable valueSqlTbl = sqlStmt.getTable(valueTable, sqlStmt.getPrimaryTable().getGroupName());
if (valueSqlTbl == null) {
// Root value candidate has no table, so try to find a value candidate with a table that exists in this statement
Collection<String> valueSubclassNames = storeMgr.getSubClassesForClass(valueType, true, clr);
if (valueSubclassNames != null && !valueSubclassNames.isEmpty()) {
for (String valueSubclassName : valueSubclassNames) {
DatastoreClass valueTbl = storeMgr.getDatastoreClass(valueSubclassName, clr);
if (valueTbl != null) {
valueSqlTbl = sqlStmt.getTable(valueTbl, sqlStmt.getPrimaryTable().getGroupName());
if (valueSqlTbl != null) {
break;
}
}
}
}
}
SQLStatementHelper.selectFetchPlanOfSourceClassInStatement(sqlStmt, getMappingDef, ec.getFetchPlan(), valueSqlTbl, valueCmd, ec.getFetchPlan().getMaxFetchDepth());
}
// Apply condition on owner field to filter by owner
SQLExpressionFactory exprFactory = storeMgr.getSQLExpressionFactory();
SQLTable ownerSqlTbl = SQLStatementHelper.getSQLTableForMappingOfTable(sqlStmt, sqlStmt.getPrimaryTable(), ownerMapping);
SQLExpression ownerExpr = exprFactory.newExpression(sqlStmt, ownerSqlTbl, ownerMapping);
SQLExpression ownerVal = exprFactory.newLiteralParameter(sqlStmt, ownerMapping, null, "OWNER");
sqlStmt.whereAnd(ownerExpr.eq(ownerVal), true);
// Apply condition on key
if (keyMapping instanceof SerialisedMapping) {
// if the keyMapping contains a BLOB column (or any other column not supported by the database
// as primary key), uses like instead of the operator OP_EQ (=)
// in future do not check if the keyMapping is of ObjectMapping, but use the database
// adapter to check the data types not supported as primary key
// if object mapping (BLOB) use like
SQLExpression keyExpr = exprFactory.newExpression(sqlStmt, sqlStmt.getPrimaryTable(), keyMapping);
SQLExpression keyVal = exprFactory.newLiteralParameter(sqlStmt, keyMapping, null, "KEY");
sqlStmt.whereAnd(new org.datanucleus.store.rdbms.sql.expression.BooleanExpression(keyExpr, Expression.OP_LIKE, keyVal), true);
} else {
SQLExpression keyExpr = exprFactory.newExpression(sqlStmt, sqlStmt.getPrimaryTable(), keyMapping);
SQLExpression keyVal = exprFactory.newLiteralParameter(sqlStmt, keyMapping, null, "KEY");
sqlStmt.whereAnd(keyExpr.eq(keyVal), true);
}
// Input parameter(s) - owner, key
int inputParamNum = 1;
StatementMappingIndex ownerIdx = new StatementMappingIndex(ownerMapping);
StatementMappingIndex keyIdx = new StatementMappingIndex(keyMapping);
if (sqlStmt.getNumberOfUnions() > 0) {
// Add parameter occurrence for each union of statement
for (int j = 0; j < sqlStmt.getNumberOfUnions() + 1; j++) {
int[] ownerPositions = new int[ownerMapping.getNumberOfDatastoreMappings()];
for (int k = 0; k < ownerPositions.length; k++) {
ownerPositions[k] = inputParamNum++;
}
ownerIdx.addParameterOccurrence(ownerPositions);
int[] keyPositions = new int[keyMapping.getNumberOfDatastoreMappings()];
for (int k = 0; k < keyPositions.length; k++) {
keyPositions[k] = inputParamNum++;
}
keyIdx.addParameterOccurrence(keyPositions);
}
} else {
int[] ownerPositions = new int[ownerMapping.getNumberOfDatastoreMappings()];
for (int k = 0; k < ownerPositions.length; k++) {
ownerPositions[k] = inputParamNum++;
}
ownerIdx.addParameterOccurrence(ownerPositions);
int[] keyPositions = new int[keyMapping.getNumberOfDatastoreMappings()];
for (int k = 0; k < keyPositions.length; k++) {
keyPositions[k] = inputParamNum++;
}
keyIdx.addParameterOccurrence(keyPositions);
}
getMappingParams = new StatementParameterMapping();
getMappingParams.addMappingForParameter("owner", ownerIdx);
getMappingParams.addMappingForParameter("key", keyIdx);
return sqlStmt;
}
use of org.datanucleus.store.rdbms.query.StatementMappingIndex in project datanucleus-rdbms by datanucleus.
the class OracleBlobRDBMSMapping method updateBlobColumn.
/**
* Convenience method to update the contents of a BLOB column.
* Oracle requires that a BLOB is initialised with EMPTY_BLOB() and then you retrieve
* the column and update its BLOB value. Performs a statement
* <pre>
* SELECT {blobColumn} FROM TABLE WHERE ID=? FOR UPDATE
* </pre>
* and then updates the Blob value returned.
* @param op ObjectProvider of the object
* @param table Table storing the BLOB column
* @param mapping Datastore mapping for the BLOB column
* @param bytes The bytes to store in the BLOB
* @throws NucleusObjectNotFoundException thrown if an object isnt found
* @throws NucleusDataStoreException thrown if an error occurs in datastore communication
*/
@SuppressWarnings("deprecation")
public static void updateBlobColumn(ObjectProvider op, Table table, DatastoreMapping mapping, byte[] bytes) {
ExecutionContext ec = op.getExecutionContext();
RDBMSStoreManager storeMgr = table.getStoreManager();
// Don't support join tables yet
DatastoreClass classTable = (DatastoreClass) table;
SQLExpressionFactory exprFactory = storeMgr.getSQLExpressionFactory();
// Generate "SELECT {blobColumn} FROM TABLE WHERE ID=? FOR UPDATE" statement
SelectStatement sqlStmt = new SelectStatement(storeMgr, table, null, null);
sqlStmt.setClassLoaderResolver(ec.getClassLoaderResolver());
sqlStmt.addExtension(SQLStatement.EXTENSION_LOCK_FOR_UPDATE, true);
SQLTable blobSqlTbl = SQLStatementHelper.getSQLTableForMappingOfTable(sqlStmt, sqlStmt.getPrimaryTable(), mapping.getJavaTypeMapping());
sqlStmt.select(blobSqlTbl, mapping.getColumn(), null);
StatementClassMapping mappingDefinition = new StatementClassMapping();
AbstractClassMetaData cmd = op.getClassMetaData();
int inputParamNum = 1;
if (cmd.getIdentityType() == IdentityType.DATASTORE) {
// Datastore identity value for input
JavaTypeMapping datastoreIdMapping = classTable.getSurrogateMapping(SurrogateColumnType.DATASTORE_ID, false);
SQLExpression expr = exprFactory.newExpression(sqlStmt, sqlStmt.getPrimaryTable(), datastoreIdMapping);
SQLExpression val = exprFactory.newLiteralParameter(sqlStmt, datastoreIdMapping, null, "ID");
sqlStmt.whereAnd(expr.eq(val), true);
StatementMappingIndex datastoreIdx = mappingDefinition.getMappingForMemberPosition(SurrogateColumnType.DATASTORE_ID.getFieldNumber());
if (datastoreIdx == null) {
datastoreIdx = new StatementMappingIndex(datastoreIdMapping);
mappingDefinition.addMappingForMember(SurrogateColumnType.DATASTORE_ID.getFieldNumber(), datastoreIdx);
}
datastoreIdx.addParameterOccurrence(new int[] { inputParamNum });
} else if (cmd.getIdentityType() == IdentityType.APPLICATION) {
// Application identity value(s) for input
int[] pkNums = cmd.getPKMemberPositions();
for (int i = 0; i < pkNums.length; i++) {
AbstractMemberMetaData mmd = cmd.getMetaDataForManagedMemberAtAbsolutePosition(pkNums[i]);
JavaTypeMapping pkMapping = classTable.getMemberMapping(mmd);
SQLExpression expr = exprFactory.newExpression(sqlStmt, sqlStmt.getPrimaryTable(), pkMapping);
SQLExpression val = exprFactory.newLiteralParameter(sqlStmt, pkMapping, null, "PK" + i);
sqlStmt.whereAnd(expr.eq(val), true);
StatementMappingIndex pkIdx = mappingDefinition.getMappingForMemberPosition(pkNums[i]);
if (pkIdx == null) {
pkIdx = new StatementMappingIndex(pkMapping);
mappingDefinition.addMappingForMember(pkNums[i], pkIdx);
}
int[] inputParams = new int[pkMapping.getNumberOfDatastoreMappings()];
for (int j = 0; j < pkMapping.getNumberOfDatastoreMappings(); j++) {
inputParams[j] = inputParamNum++;
}
pkIdx.addParameterOccurrence(inputParams);
}
}
String textStmt = sqlStmt.getSQLText().toSQL();
if (op.isEmbedded()) {
// This mapping is embedded, so navigate back to the real owner since that is the "id" in the table
ObjectProvider[] embeddedOwners = ec.getOwnersForEmbeddedObjectProvider(op);
if (embeddedOwners != null) {
// Just use the first owner
// TODO Should check if the owner is stored in this table
op = embeddedOwners[0];
}
}
try {
ManagedConnection mconn = storeMgr.getConnectionManager().getConnection(ec);
SQLController sqlControl = storeMgr.getSQLController();
try {
PreparedStatement ps = sqlControl.getStatementForQuery(mconn, textStmt);
try {
// Provide the primary key field(s) to the JDBC statement
if (cmd.getIdentityType() == IdentityType.DATASTORE) {
StatementMappingIndex datastoreIdx = mappingDefinition.getMappingForMemberPosition(SurrogateColumnType.DATASTORE_ID.getFieldNumber());
for (int i = 0; i < datastoreIdx.getNumberOfParameterOccurrences(); i++) {
classTable.getSurrogateMapping(SurrogateColumnType.DATASTORE_ID, false).setObject(ec, ps, datastoreIdx.getParameterPositionsForOccurrence(i), op.getInternalObjectId());
}
} else if (cmd.getIdentityType() == IdentityType.APPLICATION) {
op.provideFields(cmd.getPKMemberPositions(), new ParameterSetter(op, ps, mappingDefinition));
}
ResultSet rs = sqlControl.executeStatementQuery(ec, mconn, textStmt, ps);
try {
if (!rs.next()) {
throw new NucleusObjectNotFoundException("No such database row", op.getInternalObjectId());
}
DatastoreAdapter dba = storeMgr.getDatastoreAdapter();
int jdbcMajorVersion = dba.getDriverMajorVersion();
if (dba.getDatastoreDriverName().equalsIgnoreCase(OracleAdapter.OJDBC_DRIVER_NAME) && jdbcMajorVersion < 10) {
// Oracle JDBC drivers version 9 and below use some sh*tty Oracle-specific BLOB type
// we have to cast to that, face west, pray whilst saying ommmmmmmmmmm
oracle.sql.BLOB blob = null;
if (jdbcMajorVersion <= 8) {
OracleResultSet ors = (OracleResultSet) rs;
blob = ors.getBLOB(1);
} else {
blob = (oracle.sql.BLOB) rs.getBlob(1);
}
if (blob != null) {
// Deprecated but what can you do
blob.putBytes(1, bytes);
}
} else {
// Oracle JDBC drivers 10 and above supposedly use the JDBC standard class for Blobs
java.sql.Blob blob = rs.getBlob(1);
if (blob != null) {
blob.setBytes(1, bytes);
}
}
} finally {
rs.close();
}
} finally {
sqlControl.closeStatement(mconn, ps);
}
} finally {
mconn.release();
}
} catch (SQLException e) {
throw new NucleusDataStoreException("Update of BLOB value failed: " + textStmt, e);
}
}
Aggregations