Search in sources :

Example 1 with StoreSchemaHandler

use of org.datanucleus.store.schema.StoreSchemaHandler in project datanucleus-rdbms by datanucleus.

the class TableImpl method getExistingIndices.

/**
 * Accessor for indices on the actual table.
 * @param conn The JDBC Connection
 * @return Map of indices (keyed by the index name)
 * @throws SQLException Thrown when an error occurs in the JDBC call.
 */
private Map<DatastoreIdentifier, Index> getExistingIndices(Connection conn) throws SQLException {
    Map<DatastoreIdentifier, Index> indicesByName = new HashMap<>();
    if (tableExistsInDatastore(conn)) {
        StoreSchemaHandler handler = storeMgr.getSchemaHandler();
        RDBMSTableIndexInfo tableIndexInfo = (RDBMSTableIndexInfo) handler.getSchemaData(conn, RDBMSSchemaHandler.TYPE_INDICES, new Object[] { this });
        IdentifierFactory idFactory = storeMgr.getIdentifierFactory();
        Iterator indexIter = tableIndexInfo.getChildren().iterator();
        while (indexIter.hasNext()) {
            // No idea of why this was being used, so commented out (H2 v2 fails if enabled)
            // short idxType = ((Short)indexInfo.getProperty("type")).shortValue();
            // if (idxType == DatabaseMetaData.tableIndexStatistic)
            // {
            // // Ignore
            // continue;
            // }
            IndexInfo indexInfo = (IndexInfo) indexIter.next();
            String indexName = (String) indexInfo.getProperty("index_name");
            DatastoreIdentifier indexIdentifier = idFactory.newIdentifier(IdentifierType.CANDIDATE_KEY, indexName);
            Index idx = indicesByName.get(indexIdentifier);
            if (idx == null) {
                boolean isUnique = !((Boolean) indexInfo.getProperty("non_unique")).booleanValue();
                idx = new Index(this, isUnique, null);
                idx.setName(indexName);
                indicesByName.put(indexIdentifier, idx);
            }
            // Set the column
            int colSeq = ((Short) indexInfo.getProperty("ordinal_position")).shortValue() - 1;
            DatastoreIdentifier colName = idFactory.newIdentifier(IdentifierType.COLUMN, (String) indexInfo.getProperty("column_name"));
            Column col = columnsByIdentifier.get(colName);
            if (col != null) {
                idx.setColumn(colSeq, col);
            }
        }
    }
    return indicesByName;
}
Also used : HashMap(java.util.HashMap) RDBMSTableIndexInfo(org.datanucleus.store.rdbms.schema.RDBMSTableIndexInfo) Index(org.datanucleus.store.rdbms.key.Index) StoreSchemaHandler(org.datanucleus.store.schema.StoreSchemaHandler) RDBMSTableIndexInfo(org.datanucleus.store.rdbms.schema.RDBMSTableIndexInfo) IndexInfo(org.datanucleus.store.rdbms.schema.IndexInfo) IdentifierFactory(org.datanucleus.store.rdbms.identifier.IdentifierFactory) DatastoreIdentifier(org.datanucleus.store.rdbms.identifier.DatastoreIdentifier) Iterator(java.util.Iterator)

Example 2 with StoreSchemaHandler

use of org.datanucleus.store.schema.StoreSchemaHandler in project datanucleus-rdbms by datanucleus.

the class TableImpl method getExistingCandidateKeys.

/**
 * Accessor for the candidate keys for this table.
 * @param conn The JDBC Connection
 * @return Map of candidate keys
 * @throws SQLException Thrown when an error occurs in the JDBC call.
 */
private Map<DatastoreIdentifier, CandidateKey> getExistingCandidateKeys(Connection conn) throws SQLException {
    Map<DatastoreIdentifier, CandidateKey> candidateKeysByName = new HashMap<>();
    if (tableExistsInDatastore(conn)) {
        StoreSchemaHandler handler = storeMgr.getSchemaHandler();
        RDBMSTableIndexInfo tableIndexInfo = (RDBMSTableIndexInfo) handler.getSchemaData(conn, RDBMSSchemaHandler.TYPE_INDICES, new Object[] { this });
        IdentifierFactory idFactory = storeMgr.getIdentifierFactory();
        Iterator indexIter = tableIndexInfo.getChildren().iterator();
        while (indexIter.hasNext()) {
            IndexInfo indexInfo = (IndexInfo) indexIter.next();
            boolean isUnique = !((Boolean) indexInfo.getProperty("non_unique")).booleanValue();
            if (isUnique) {
                // No idea of why this was being used, so commented out (H2 v2 fails if enabled)
                // short idxType = ((Short)indexInfo.getProperty("type")).shortValue();
                // if (idxType == DatabaseMetaData.tableIndexStatistic)
                // {
                // // Ignore
                // continue;
                // }
                // Only utilise unique indexes
                String keyName = (String) indexInfo.getProperty("index_name");
                DatastoreIdentifier idxName = idFactory.newIdentifier(IdentifierType.CANDIDATE_KEY, keyName);
                CandidateKey key = candidateKeysByName.get(idxName);
                if (key == null) {
                    key = new CandidateKey(this, null);
                    key.setName(keyName);
                    candidateKeysByName.put(idxName, key);
                }
                // Set the column
                int colSeq = ((Short) indexInfo.getProperty("ordinal_position")).shortValue() - 1;
                DatastoreIdentifier colName = idFactory.newIdentifier(IdentifierType.COLUMN, (String) indexInfo.getProperty("column_name"));
                Column col = columnsByIdentifier.get(colName);
                if (col != null) {
                    key.setColumn(colSeq, col);
                }
            }
        }
    }
    return candidateKeysByName;
}
Also used : HashMap(java.util.HashMap) RDBMSTableIndexInfo(org.datanucleus.store.rdbms.schema.RDBMSTableIndexInfo) StoreSchemaHandler(org.datanucleus.store.schema.StoreSchemaHandler) RDBMSTableIndexInfo(org.datanucleus.store.rdbms.schema.RDBMSTableIndexInfo) IndexInfo(org.datanucleus.store.rdbms.schema.IndexInfo) IdentifierFactory(org.datanucleus.store.rdbms.identifier.IdentifierFactory) CandidateKey(org.datanucleus.store.rdbms.key.CandidateKey) DatastoreIdentifier(org.datanucleus.store.rdbms.identifier.DatastoreIdentifier) Iterator(java.util.Iterator)

Example 3 with StoreSchemaHandler

use of org.datanucleus.store.schema.StoreSchemaHandler in project datanucleus-rdbms by datanucleus.

the class TableImpl method dropConstraints.

/**
 * Method to drop the constraints for the table from the datastore.
 * @param conn The JDBC Connection
 * @throws SQLException Thrown when an error occurs in the JDBC call.
 */
public void dropConstraints(Connection conn) throws SQLException {
    assertIsInitialized();
    boolean drop_using_constraint = dba.supportsOption(DatastoreAdapter.ALTER_TABLE_DROP_CONSTRAINT_SYNTAX);
    boolean drop_using_foreign_key = dba.supportsOption(DatastoreAdapter.ALTER_TABLE_DROP_FOREIGN_KEY_CONSTRAINT);
    if (!drop_using_constraint && !drop_using_foreign_key) {
        return;
    }
    // There's no need to drop indices; we assume they'll go away quietly when the table is dropped.
    Set<String> fkNames = new HashSet<>();
    StoreSchemaHandler handler = storeMgr.getSchemaHandler();
    RDBMSTableFKInfo fkInfo = (RDBMSTableFKInfo) handler.getSchemaData(conn, RDBMSSchemaHandler.TYPE_FKS, new Object[] { this });
    Iterator iter = fkInfo.getChildren().iterator();
    while (iter.hasNext()) {
        // JDBC drivers can return null names for foreign keys, so we then skip the DROP CONSTRAINT.
        ForeignKeyInfo fki = (ForeignKeyInfo) iter.next();
        String fkName = (String) fki.getProperty("fk_name");
        if (fkName != null) {
            fkNames.add(fkName);
        }
    }
    int numFKs = fkNames.size();
    if (numFKs > 0) {
        if (NucleusLogger.DATASTORE_SCHEMA.isDebugEnabled()) {
            NucleusLogger.DATASTORE_SCHEMA.debug(Localiser.msg("058102", "" + numFKs, this));
        }
        iter = fkNames.iterator();
        IdentifierFactory idFactory = storeMgr.getIdentifierFactory();
        Statement stmt = conn.createStatement();
        try {
            while (iter.hasNext()) {
                String constraintName = (String) iter.next();
                String stmtText = null;
                if (drop_using_constraint) {
                    stmtText = "ALTER TABLE " + toString() + " DROP CONSTRAINT " + idFactory.getIdentifierInAdapterCase(constraintName);
                } else {
                    stmtText = "ALTER TABLE " + toString() + " DROP FOREIGN KEY " + idFactory.getIdentifierInAdapterCase(constraintName);
                }
                executeDdlStatement(stmt, stmtText);
            }
        } finally {
            stmt.close();
        }
    }
}
Also used : ForeignKeyInfo(org.datanucleus.store.rdbms.schema.ForeignKeyInfo) RDBMSTableFKInfo(org.datanucleus.store.rdbms.schema.RDBMSTableFKInfo) Statement(java.sql.Statement) Iterator(java.util.Iterator) StoreSchemaHandler(org.datanucleus.store.schema.StoreSchemaHandler) IdentifierFactory(org.datanucleus.store.rdbms.identifier.IdentifierFactory) HashSet(java.util.HashSet)

Example 4 with StoreSchemaHandler

use of org.datanucleus.store.schema.StoreSchemaHandler 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)

Example 5 with StoreSchemaHandler

use of org.datanucleus.store.schema.StoreSchemaHandler in project tests by datanucleus.

the class SchemaHandlerTest method testColumnRetrieval.

/**
 * Test of the retrieval of columns.
 */
public void testColumnRetrieval() {
    addClassesToSchema(new Class[] { SchemaClass1.class, SchemaClass2.class });
    PersistenceManager pm = pmf.getPersistenceManager();
    RDBMSStoreManager databaseMgr = (RDBMSStoreManager) storeMgr;
    StoreSchemaHandler handler = databaseMgr.getSchemaHandler();
    ClassLoaderResolver clr = storeMgr.getNucleusContext().getClassLoaderResolver(null);
    Connection con = (Connection) databaseMgr.getConnectionManager().getConnection(((JDOPersistenceManager) pm).getExecutionContext()).getConnection();
    // Retrieve and check the table for SchemaClass1
    DatastoreClass table1 = databaseMgr.getDatastoreClass(SchemaClass1.class.getName(), clr);
    RDBMSTableInfo tableInfo1 = (RDBMSTableInfo) handler.getSchemaData(con, "columns", new Object[] { table1 });
    assertNotNull("TableInfo from getColumns is NULL!", tableInfo1);
    assertEquals("Number of columns for table " + table1 + " is wrong", 4, tableInfo1.getNumberOfChildren());
    Iterator colsIter = tableInfo1.getChildren().iterator();
    Collection colNamesPresent = new HashSet();
    colNamesPresent.add("TABLE1_ID1");
    colNamesPresent.add("TABLE1_ID2");
    colNamesPresent.add("NAME");
    colNamesPresent.add("OTHER_ID");
    while (colsIter.hasNext()) {
        RDBMSColumnInfo colInfo = (RDBMSColumnInfo) colsIter.next();
        String colInfoName = colInfo.getColumnName().toUpperCase();
        if (colInfoName.equals("TABLE1_ID1") || colInfoName.equals("TABLE1_ID2") || colInfoName.equals("NAME") || colInfoName.equals("OTHER_ID")) {
            colNamesPresent.remove(colInfoName);
        }
    }
    assertTrue("Some columns expected were not present in the datastore table : " + StringUtils.collectionToString(colNamesPresent), colNamesPresent.size() == 0);
    // Retrieve and check the table for SchemaClass2
    DatastoreClass table2 = databaseMgr.getDatastoreClass(SchemaClass2.class.getName(), clr);
    RDBMSTableInfo tableInfo2 = (RDBMSTableInfo) handler.getSchemaData(con, "columns", new Object[] { table2 });
    assertEquals("Number of columns for table " + table2 + " is wrong", 3, tableInfo2.getNumberOfChildren());
    colsIter = tableInfo2.getChildren().iterator();
    colNamesPresent.clear();
    colNamesPresent.add("TABLE2_ID");
    colNamesPresent.add("NAME");
    colNamesPresent.add("VALUE");
    while (colsIter.hasNext()) {
        RDBMSColumnInfo colInfo = (RDBMSColumnInfo) colsIter.next();
        String colInfoName = colInfo.getColumnName().toUpperCase();
        if (colInfoName.equals("TABLE2_ID")) {
            colNamesPresent.remove(colInfoName);
        }
        if (colInfoName.equals("NAME")) {
            colNamesPresent.remove(colInfoName);
            assertEquals("Length of column " + colInfo.getColumnName() + " has incorrect length", 20, colInfo.getColumnSize());
        }
        if (colInfoName.equals("VALUE")) {
            colNamesPresent.remove(colInfoName);
        }
    }
    assertTrue("Some columns expected were not present in the datastore table : " + StringUtils.collectionToString(colNamesPresent), colNamesPresent.size() == 0);
    // Now check retrieval of a column for a table
    RDBMSColumnInfo colInfo = (RDBMSColumnInfo) handler.getSchemaData(con, "column", new Object[] { table2, "VALUE" });
    if (colInfo == null) {
        colInfo = (RDBMSColumnInfo) handler.getSchemaData(con, "column", new Object[] { table2, "value" });
    }
    assertNotNull("Column VALUE for table " + table2 + " was not found", colInfo);
    assertEquals("Column name is wrong", "VALUE", colInfo.getColumnName().toUpperCase());
}
Also used : RDBMSColumnInfo(org.datanucleus.store.rdbms.schema.RDBMSColumnInfo) RDBMSTableInfo(org.datanucleus.store.rdbms.schema.RDBMSTableInfo) JDOPersistenceManager(org.datanucleus.api.jdo.JDOPersistenceManager) PersistenceManager(javax.jdo.PersistenceManager) ClassLoaderResolver(org.datanucleus.ClassLoaderResolver) Connection(java.sql.Connection) SchemaClass1(org.jpox.samples.rdbms.schema.SchemaClass1) StoreSchemaHandler(org.datanucleus.store.schema.StoreSchemaHandler) SchemaClass2(org.jpox.samples.rdbms.schema.SchemaClass2) RDBMSStoreManager(org.datanucleus.store.rdbms.RDBMSStoreManager) Iterator(java.util.Iterator) Collection(java.util.Collection) DatastoreClass(org.datanucleus.store.rdbms.table.DatastoreClass) HashSet(java.util.HashSet)

Aggregations

StoreSchemaHandler (org.datanucleus.store.schema.StoreSchemaHandler)9 Iterator (java.util.Iterator)7 IdentifierFactory (org.datanucleus.store.rdbms.identifier.IdentifierFactory)5 Connection (java.sql.Connection)4 HashMap (java.util.HashMap)4 PersistenceManager (javax.jdo.PersistenceManager)4 ClassLoaderResolver (org.datanucleus.ClassLoaderResolver)4 JDOPersistenceManager (org.datanucleus.api.jdo.JDOPersistenceManager)4 RDBMSStoreManager (org.datanucleus.store.rdbms.RDBMSStoreManager)4 DatastoreIdentifier (org.datanucleus.store.rdbms.identifier.DatastoreIdentifier)4 DatastoreClass (org.datanucleus.store.rdbms.table.DatastoreClass)4 SchemaClass1 (org.jpox.samples.rdbms.schema.SchemaClass1)4 ForeignKeyInfo (org.datanucleus.store.rdbms.schema.ForeignKeyInfo)3 IndexInfo (org.datanucleus.store.rdbms.schema.IndexInfo)3 RDBMSTableFKInfo (org.datanucleus.store.rdbms.schema.RDBMSTableFKInfo)3 RDBMSTableIndexInfo (org.datanucleus.store.rdbms.schema.RDBMSTableIndexInfo)3 SchemaClass2 (org.jpox.samples.rdbms.schema.SchemaClass2)3 HashSet (java.util.HashSet)2 PrimaryKeyInfo (org.datanucleus.store.rdbms.schema.PrimaryKeyInfo)2 RDBMSTablePKInfo (org.datanucleus.store.rdbms.schema.RDBMSTablePKInfo)2