use of org.datanucleus.store.rdbms.table.DatastoreClass in project datanucleus-rdbms by datanucleus.
the class RDBMSPersistenceHandler method updateObject.
// ------------------------------ Update ----------------------------------
/**
* Updates a persistent object in the database.
* The update can take place in several steps, one update per table that it is stored in (depending on
* which fields are updated).
* e.g When updating an object that uses "new-table" inheritance for each level of the inheritance tree
* then will get an UPDATE into each table. When updating an object that uses "complete-table"
* inheritance then will get a single UPDATE into its table.
* @param op The ObjectProvider of the object to be updated.
* @param fieldNumbers The numbers of the fields to be updated.
* @throws NucleusDataStoreException when an error occurs in the datastore communication
*/
public void updateObject(ObjectProvider op, int[] fieldNumbers) {
// Check if read-only so update not permitted
assertReadOnlyForUpdateOfObject(op);
// Check if we need to do any updates to the schema before updating this object
checkForSchemaUpdatesForFieldsOfObject(op, fieldNumbers);
AbstractMemberMetaData[] mmds = null;
if (fieldNumbers != null && fieldNumbers.length > 0) {
// Convert the field numbers for this class into their metadata for the table
ExecutionContext ec = op.getExecutionContext();
mmds = new AbstractMemberMetaData[fieldNumbers.length];
for (int i = 0; i < mmds.length; i++) {
mmds[i] = op.getClassMetaData().getMetaDataForManagedMemberAtAbsolutePosition(fieldNumbers[i]);
}
if (ec.getStatistics() != null) {
ec.getStatistics().incrementUpdateCount();
}
ClassLoaderResolver clr = ec.getClassLoaderResolver();
DatastoreClass dc = getDatastoreClass(op.getObject().getClass().getName(), clr);
updateObjectInTable(dc, op, clr, mmds);
}
}
use of org.datanucleus.store.rdbms.table.DatastoreClass in project datanucleus-rdbms by datanucleus.
the class RDBMSPersistenceHandler method deleteObject.
// ------------------------------ Delete ----------------------------------
/**
* Deletes a persistent object from the database.
* The delete can take place in several steps, one delete per table that it is stored in.
* e.g When deleting an object that uses "new-table" inheritance for each level of the inheritance tree
* then will get an DELETE for each table. When deleting an object that uses "complete-table"
* inheritance then will get a single DELETE for its table.
* @param op The ObjectProvider of the object to be deleted.
* @throws NucleusDataStoreException when an error occurs in the datastore communication
*/
public void deleteObject(ObjectProvider op) {
// Check if read-only so update not permitted
assertReadOnlyForUpdateOfObject(op);
ExecutionContext ec = op.getExecutionContext();
if (ec.getStatistics() != null) {
ec.getStatistics().incrementDeleteCount();
}
ClassLoaderResolver clr = op.getExecutionContext().getClassLoaderResolver();
DatastoreClass dc = getDatastoreClass(op.getClassMetaData().getFullClassName(), clr);
deleteObjectFromTable(dc, op, clr);
}
use of org.datanucleus.store.rdbms.table.DatastoreClass in project datanucleus-rdbms by datanucleus.
the class RDBMSPersistenceHandler method deleteObjectFromTable.
/**
* Convenience method to handle the delete from the various tables that this object is persisted into.
* @param table The table to process
* @param sm ObjectProvider for the object being deleted
* @param clr ClassLoader resolver
*/
private void deleteObjectFromTable(DatastoreClass table, ObjectProvider sm, ClassLoaderResolver clr) {
if (table instanceof ClassView) {
throw new NucleusUserException("Cannot perform DeleteRequest on RDBMS view " + table);
}
// Delete any secondary tables
Collection<SecondaryDatastoreClass> secondaryTables = table.getSecondaryDatastoreClasses();
if (secondaryTables != null) {
for (SecondaryDatastoreClass secTable : secondaryTables) {
// Process the secondary table
deleteObjectFromTable(secTable, sm, clr);
}
}
// Do the actual delete of this table
getDeleteRequest(table, sm.getClassMetaData(), clr).execute(sm);
DatastoreClass supertable = table.getSuperDatastoreClass();
if (supertable != null) {
// Process the superclass table last
deleteObjectFromTable(supertable, sm, clr);
}
}
use of org.datanucleus.store.rdbms.table.DatastoreClass in project datanucleus-rdbms by datanucleus.
the class DynamicSchemaFieldManager method storeObjectField.
/**
* Method to store an object field into the attached instance.
* @param fieldNumber Number of the field to store
* @param value the value in the detached instance
*/
public void storeObjectField(int fieldNumber, Object value) {
if (value == null) {
// No value so nothing to do
return;
}
ExecutionContext ec = op.getExecutionContext();
ClassLoaderResolver clr = ec.getClassLoaderResolver();
AbstractMemberMetaData mmd = op.getClassMetaData().getMetaDataForManagedMemberAtAbsolutePosition(fieldNumber);
if (mmd != null) {
DatastoreClass table = rdbmsMgr.getDatastoreClass(op.getObject().getClass().getName(), clr);
JavaTypeMapping fieldMapping = table.getMemberMapping(mmd);
if (fieldMapping != null) {
if (fieldMapping instanceof InterfaceMapping) {
// 1-1 Interface field
InterfaceMapping intfMapping = (InterfaceMapping) fieldMapping;
if (mmd.getFieldTypes() != null || mmd.hasExtension(MetaData.EXTENSION_MEMBER_IMPLEMENTATION_CLASSES)) {
// Field is defined to not accept this type so just return
return;
}
processInterfaceMappingForValue(intfMapping, value, mmd, ec);
} else if (mmd.hasCollection() || mmd.hasArray()) {
boolean hasJoin = false;
if (mmd.getJoinMetaData() != null) {
hasJoin = true;
} else {
AbstractMemberMetaData[] relMmds = mmd.getRelatedMemberMetaData(clr);
if (relMmds != null && relMmds[0].getJoinMetaData() != null) {
hasJoin = true;
}
}
if (!hasJoin) {
// Not join table so no supported schema updates
return;
}
Table joinTbl = fieldMapping.getStoreManager().getTable(mmd);
ElementContainerTable collTbl = (ElementContainerTable) joinTbl;
JavaTypeMapping elemMapping = collTbl.getElementMapping();
if (elemMapping instanceof InterfaceMapping) {
InterfaceMapping intfMapping = (InterfaceMapping) elemMapping;
if (mmd.hasCollection()) {
Collection coll = (Collection) value;
if (coll.isEmpty()) {
return;
}
// Update value mapping using first element. Maybe we should do the same for all elements?
Object elementValue = coll.iterator().next();
processInterfaceMappingForValue(intfMapping, elementValue, mmd, ec);
} else if (mmd.hasArray()) {
if (Array.getLength(value) == 0) {
return;
}
// Update value mapping using first element. Maybe we should do the same for all elements?
Object elementValue = Array.get(value, 0);
processInterfaceMappingForValue(intfMapping, elementValue, mmd, ec);
}
}
} else if (mmd.hasMap()) {
boolean hasJoin = false;
if (mmd.getJoinMetaData() != null) {
hasJoin = true;
} else {
AbstractMemberMetaData[] relMmds = mmd.getRelatedMemberMetaData(clr);
if (relMmds != null && relMmds[0].getJoinMetaData() != null) {
hasJoin = true;
}
}
if (!hasJoin) {
// Not join table so no supported schema updates
return;
}
Map map = (Map) value;
if (map.isEmpty()) {
return;
}
Table joinTbl = fieldMapping.getStoreManager().getTable(mmd);
MapTable mapTbl = (MapTable) joinTbl;
JavaTypeMapping keyMapping = mapTbl.getKeyMapping();
if (keyMapping instanceof InterfaceMapping) {
// Update key mapping using first key. Maybe we should do the same for all keys?
InterfaceMapping intfMapping = (InterfaceMapping) keyMapping;
Object keyValue = map.keySet().iterator().next();
processInterfaceMappingForValue(intfMapping, keyValue, mmd, ec);
}
JavaTypeMapping valMapping = mapTbl.getValueMapping();
if (valMapping instanceof InterfaceMapping) {
// Update value mapping using first value. Maybe we should do the same for all values?
InterfaceMapping intfMapping = (InterfaceMapping) valMapping;
Object valValue = map.values().iterator().next();
processInterfaceMappingForValue(intfMapping, valValue, mmd, ec);
}
}
}
}
}
use of org.datanucleus.store.rdbms.table.DatastoreClass in project tests by datanucleus.
the class SchemaHandlerTest method testForeignKeyRetrieval.
/**
* Test of the retrieval of FKs.
*/
public void testForeignKeyRetrieval() {
addClassesToSchema(new Class[] { SchemaClass1.class, SchemaClass2.class });
PersistenceManager pm = pmf.getPersistenceManager();
RDBMSStoreManager databaseMgr = (RDBMSStoreManager) storeMgr;
// Retrieve the table for SchemaClass1
ClassLoaderResolver clr = storeMgr.getNucleusContext().getClassLoaderResolver(null);
DatastoreClass table1 = databaseMgr.getDatastoreClass(SchemaClass1.class.getName(), clr);
// Check for the FK using the schema handler
StoreSchemaHandler handler = databaseMgr.getSchemaHandler();
Connection con = (Connection) databaseMgr.getConnectionManager().getConnection(((JDOPersistenceManager) pm).getExecutionContext()).getConnection();
RDBMSTableFKInfo fkInfo = (RDBMSTableFKInfo) handler.getSchemaData(con, "foreign-keys", new Object[] { table1 });
// Expecting single FK between SchemaClass1.other and SchemaClass2
assertEquals("Number of FKs for table " + table1 + " is wrong", 1, fkInfo.getNumberOfChildren());
// Check the FK details
ForeignKeyInfo fk = (ForeignKeyInfo) fkInfo.getChild(0);
assertEquals("FK Name is wrong", "TABLE1_FK1", ((String) fk.getProperty("fk_name")).toUpperCase());
assertEquals("PK Table Name is wrong", "SCHEMA_TABLE_2", ((String) fk.getProperty("pk_table_name")).toUpperCase());
assertEquals("FK Table Name is wrong", "SCHEMA_TABLE_1", ((String) fk.getProperty("fk_table_name")).toUpperCase());
assertEquals("PK Column Name is wrong", "TABLE2_ID", ((String) fk.getProperty("pk_column_name")).toUpperCase());
assertEquals("FK Column Name is wrong", "OTHER_ID", ((String) fk.getProperty("fk_column_name")).toUpperCase());
}
Aggregations