use of org.datanucleus.store.rdbms.adapter.DatastoreAdapter in project datanucleus-rdbms by datanucleus.
the class RDBMSSchemaHandler method getRDBMSTablePKInfoForTable.
/**
* Convenience method to get the PrimaryKey info for the specified table from the datastore.
* @param conn Connection to use
* @param table The table
* @return The primary key info
*/
protected RDBMSTablePKInfo getRDBMSTablePKInfoForTable(Connection conn, Table table) {
// Calculate the catalog/schema names since we need to search fully qualified
DatastoreAdapter dba = getDatastoreAdapter();
String[] c = splitTableIdentifierName(dba.getCatalogSeparator(), table.getIdentifier().getName());
String catalogName = table.getCatalogName();
String schemaName = table.getSchemaName();
String tableName = table.getIdentifier().getName();
if (c[0] != null) {
catalogName = c[0];
}
if (c[1] != null) {
schemaName = c[1];
}
if (c[2] != null) {
tableName = c[2];
}
catalogName = getIdentifierForUseWithDatabaseMetaData(catalogName);
schemaName = getIdentifierForUseWithDatabaseMetaData(schemaName);
tableName = getIdentifierForUseWithDatabaseMetaData(tableName);
return getRDBMSTablePKInfoForTable(conn, catalogName, schemaName, tableName);
}
use of org.datanucleus.store.rdbms.adapter.DatastoreAdapter in project datanucleus-rdbms by datanucleus.
the class RDBMSSchemaHandler method getRDBMSTypesInfo.
/**
* Convenience method to read and cache the types information for this datastore.
* @param conn Connection to the datastore
* @return The RDBMSTypesInfo
*/
protected RDBMSTypesInfo getRDBMSTypesInfo(Connection conn) {
RDBMSTypesInfo info = new RDBMSTypesInfo();
try {
if (conn == null) {
// No connection provided so nothing to return
return null;
}
DatabaseMetaData dmd = conn.getMetaData();
ResultSet rs = dmd.getTypeInfo();
try {
DatastoreAdapter dba = getDatastoreAdapter();
while (rs.next()) {
SQLTypeInfo sqlType = dba.newSQLTypeInfo(rs);
if (sqlType != null) {
String key = "" + sqlType.getDataType();
JDBCTypeInfo jdbcType = (JDBCTypeInfo) info.getChild(key);
if (jdbcType == null) {
// New SQL type for new JDBC type
jdbcType = new JDBCTypeInfo(sqlType.getDataType());
jdbcType.addChild(sqlType);
info.addChild(jdbcType);
} else {
// New SQL type for existing JDBC type
jdbcType.addChild(sqlType);
}
}
}
} finally {
rs.close();
}
} catch (SQLException sqle) {
throw new NucleusDataStoreException("Exception thrown retrieving type information from datastore", sqle);
}
// Cache it
schemaDataByName.put(TYPE_TYPES, info);
return info;
}
use of org.datanucleus.store.rdbms.adapter.DatastoreAdapter in project datanucleus-rdbms by datanucleus.
the class RDBMSSchemaHandler method getRDBMSTableIndexInfoForTable.
/**
* Convenience method to get the index info for the catalog+schema+tableName in the datastore.
* Returns ALL indexes regardless of whether unique or not.
* @param conn Connection to use
* @param catalogName Catalog
* @param schemaName Schema
* @param tableName Name of the table
* @return The index info
*/
protected RDBMSTableIndexInfo getRDBMSTableIndexInfoForTable(Connection conn, String catalogName, String schemaName, String tableName) {
// We don't cache Index info, so retrieve it directly
RDBMSTableIndexInfo info = new RDBMSTableIndexInfo(catalogName, schemaName, tableName);
DatastoreAdapter dba = getDatastoreAdapter();
try {
// Note : the table name has no quotes here.
String schemaNameTmp = schemaName;
if (schemaName == null && rdbmsStoreMgr.getSchemaName() != null) {
// This is a hack for the DatabaseAdapter method that requires a schema for Oracle
schemaNameTmp = rdbmsStoreMgr.getSchemaName();
schemaNameTmp = getIdentifierForUseWithDatabaseMetaData(schemaNameTmp);
}
ResultSet rs = dba.getExistingIndexes(conn, catalogName, schemaNameTmp, tableName);
if (rs == null) {
rs = conn.getMetaData().getIndexInfo(catalogName, schemaName, tableName, false, true);
}
try {
while (rs.next()) {
IndexInfo idxInfo = new IndexInfo(rs);
if (!info.getChildren().contains(idxInfo)) {
// Ignore any duplicate indices
info.addChild(idxInfo);
}
}
} finally {
if (rs != null) {
Statement st = rs.getStatement();
rs.close();
if (st != null) {
st.close();
}
}
}
} catch (SQLException sqle) {
NucleusLogger.DATASTORE_SCHEMA.warn("Exception thrown while querying indices for table=" + tableName, sqle);
throw new NucleusDataStoreException("Exception thrown while querying indices for table=" + tableName, sqle);
}
return info;
}
use of org.datanucleus.store.rdbms.adapter.DatastoreAdapter in project datanucleus-rdbms by datanucleus.
the class JPQLQuery method processesRangeInDatastoreQuery.
/* (non-Javadoc)
* @see org.datanucleus.store.query.Query#processesRangeInDatastoreQuery()
*/
@Override
public boolean processesRangeInDatastoreQuery() {
if (range == null) {
// No range specified so makes no difference
return true;
}
RDBMSStoreManager storeMgr = (RDBMSStoreManager) getStoreManager();
DatastoreAdapter dba = storeMgr.getDatastoreAdapter();
boolean using_limit_where_clause = (dba.getRangeByLimitEndOfStatementClause(fromInclNo, toExclNo, !StringUtils.isWhitespace(ordering)).length() > 0);
boolean using_rownum = (dba.getRangeByRowNumberColumn().length() > 0) || (dba.getRangeByRowNumberColumn2().length() > 0);
return using_limit_where_clause || using_rownum;
}
use of org.datanucleus.store.rdbms.adapter.DatastoreAdapter 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