Search in sources :

Example 36 with DatastoreClass

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);
    }
}
Also used : ExecutionContext(org.datanucleus.ExecutionContext) ClassLoaderResolver(org.datanucleus.ClassLoaderResolver) SecondaryDatastoreClass(org.datanucleus.store.rdbms.table.SecondaryDatastoreClass) DatastoreClass(org.datanucleus.store.rdbms.table.DatastoreClass) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData)

Example 37 with DatastoreClass

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);
}
Also used : ExecutionContext(org.datanucleus.ExecutionContext) ClassLoaderResolver(org.datanucleus.ClassLoaderResolver) SecondaryDatastoreClass(org.datanucleus.store.rdbms.table.SecondaryDatastoreClass) DatastoreClass(org.datanucleus.store.rdbms.table.DatastoreClass)

Example 38 with DatastoreClass

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);
    }
}
Also used : ClassView(org.datanucleus.store.rdbms.table.ClassView) NucleusUserException(org.datanucleus.exceptions.NucleusUserException) SecondaryDatastoreClass(org.datanucleus.store.rdbms.table.SecondaryDatastoreClass) SecondaryDatastoreClass(org.datanucleus.store.rdbms.table.SecondaryDatastoreClass) DatastoreClass(org.datanucleus.store.rdbms.table.DatastoreClass)

Example 39 with DatastoreClass

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);
                }
            }
        }
    }
}
Also used : ElementContainerTable(org.datanucleus.store.rdbms.table.ElementContainerTable) Table(org.datanucleus.store.rdbms.table.Table) MapTable(org.datanucleus.store.rdbms.table.MapTable) InterfaceMapping(org.datanucleus.store.rdbms.mapping.java.InterfaceMapping) JavaTypeMapping(org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping) ClassLoaderResolver(org.datanucleus.ClassLoaderResolver) MapTable(org.datanucleus.store.rdbms.table.MapTable) ExecutionContext(org.datanucleus.ExecutionContext) Collection(java.util.Collection) DatastoreClass(org.datanucleus.store.rdbms.table.DatastoreClass) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData) Map(java.util.Map) ElementContainerTable(org.datanucleus.store.rdbms.table.ElementContainerTable)

Example 40 with DatastoreClass

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());
}
Also used : ForeignKeyInfo(org.datanucleus.store.rdbms.schema.ForeignKeyInfo) JDOPersistenceManager(org.datanucleus.api.jdo.JDOPersistenceManager) PersistenceManager(javax.jdo.PersistenceManager) RDBMSTableFKInfo(org.datanucleus.store.rdbms.schema.RDBMSTableFKInfo) ClassLoaderResolver(org.datanucleus.ClassLoaderResolver) Connection(java.sql.Connection) SchemaClass1(org.jpox.samples.rdbms.schema.SchemaClass1) DatastoreClass(org.datanucleus.store.rdbms.table.DatastoreClass) StoreSchemaHandler(org.datanucleus.store.schema.StoreSchemaHandler) RDBMSStoreManager(org.datanucleus.store.rdbms.RDBMSStoreManager)

Aggregations

DatastoreClass (org.datanucleus.store.rdbms.table.DatastoreClass)87 JavaTypeMapping (org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping)60 AbstractClassMetaData (org.datanucleus.metadata.AbstractClassMetaData)49 AbstractMemberMetaData (org.datanucleus.metadata.AbstractMemberMetaData)48 ClassLoaderResolver (org.datanucleus.ClassLoaderResolver)44 RDBMSStoreManager (org.datanucleus.store.rdbms.RDBMSStoreManager)41 SQLExpression (org.datanucleus.store.rdbms.sql.expression.SQLExpression)35 SQLTable (org.datanucleus.store.rdbms.sql.SQLTable)32 SQLExpressionFactory (org.datanucleus.store.rdbms.sql.expression.SQLExpressionFactory)28 NucleusUserException (org.datanucleus.exceptions.NucleusUserException)26 SelectStatement (org.datanucleus.store.rdbms.sql.SelectStatement)21 MapTable (org.datanucleus.store.rdbms.table.MapTable)19 NucleusException (org.datanucleus.exceptions.NucleusException)18 SecondaryDatastoreClass (org.datanucleus.store.rdbms.table.SecondaryDatastoreClass)15 ArrayList (java.util.ArrayList)14 ExecutionContext (org.datanucleus.ExecutionContext)13 JoinTable (org.datanucleus.store.rdbms.table.JoinTable)13 Table (org.datanucleus.store.rdbms.table.Table)13 NucleusDataStoreException (org.datanucleus.exceptions.NucleusDataStoreException)11 UnboundExpression (org.datanucleus.store.rdbms.sql.expression.UnboundExpression)11