Search in sources :

Example 26 with DatastoreIdentifier

use of org.datanucleus.store.rdbms.identifier.DatastoreIdentifier in project datanucleus-rdbms by datanucleus.

the class TableImpl method getSQLAddFKStatements.

/**
 * Get SQL statements to add expected Foreign Keys that are not yet at the table.
 * If the returned Map is empty, the current FK setup is correct.
 * @param actualForeignKeysByName Actual Map of foreign keys
 * @param clr The ClassLoaderResolver
 * @return a Map with the SQL statements
 */
protected Map<String, String> getSQLAddFKStatements(Map actualForeignKeysByName, ClassLoaderResolver clr) {
    assertIsInitialized();
    Map<String, String> stmtsByFKName = new HashMap<>();
    List<ForeignKey> expectedForeignKeys = getExpectedForeignKeys(clr);
    Iterator<ForeignKey> i = expectedForeignKeys.iterator();
    int n = 1;
    IdentifierFactory idFactory = storeMgr.getIdentifierFactory();
    while (i.hasNext()) {
        ForeignKey fk = i.next();
        if (!actualForeignKeysByName.containsValue(fk)) {
            // If no name assigned, make one up
            if (fk.getName() == null) {
                // Use the ForeignKeyIdentifier to generate the name
                DatastoreIdentifier fkName;
                do {
                    fkName = idFactory.newForeignKeyIdentifier(this, n++);
                } while (actualForeignKeysByName.containsKey(fkName));
                fk.setName(fkName.getName());
            }
            String stmtText = dba.getAddForeignKeyStatement(fk, idFactory);
            if (stmtText != null) {
                stmtsByFKName.put(fk.getName(), stmtText);
            }
        }
    }
    return stmtsByFKName;
}
Also used : HashMap(java.util.HashMap) DatastoreIdentifier(org.datanucleus.store.rdbms.identifier.DatastoreIdentifier) ForeignKey(org.datanucleus.store.rdbms.key.ForeignKey) IdentifierFactory(org.datanucleus.store.rdbms.identifier.IdentifierFactory)

Example 27 with DatastoreIdentifier

use of org.datanucleus.store.rdbms.identifier.DatastoreIdentifier in project datanucleus-rdbms by datanucleus.

the class TableImpl method getSQLCreateIndexStatements.

/**
 * Accessor for the CREATE INDEX statements for this table.
 * @param actualIndicesByName Map of actual indexes
 * @param clr The ClassLoaderResolver
 * @return Map of statements
 */
protected Map<String, String> getSQLCreateIndexStatements(Map actualIndicesByName, ClassLoaderResolver clr) {
    assertIsInitialized();
    Map<String, String> stmtsByIdxName = new HashMap<>();
    Set<Index> expectedIndices = getExpectedIndices(clr);
    int n = 1;
    Iterator<Index> indexIter = expectedIndices.iterator();
    IdentifierFactory idFactory = storeMgr.getIdentifierFactory();
    while (indexIter.hasNext()) {
        Index idx = indexIter.next();
        if (isIndexReallyNeeded(idx, actualIndicesByName.values())) {
            // If no name assigned, make one up
            if (idx.getName() == null) {
                // Use IndexIdentifier to generate the name.
                DatastoreIdentifier idxName;
                do {
                    idxName = idFactory.newIndexIdentifier(this, idx.getUnique(), n++);
                    idx.setName(idxName.getName());
                } while (actualIndicesByName.containsKey(idxName));
            }
            String stmtText = dba.getCreateIndexStatement(idx, idFactory);
            stmtsByIdxName.put(idx.getName(), stmtText);
        }
    }
    return stmtsByIdxName;
}
Also used : HashMap(java.util.HashMap) DatastoreIdentifier(org.datanucleus.store.rdbms.identifier.DatastoreIdentifier) Index(org.datanucleus.store.rdbms.key.Index) IdentifierFactory(org.datanucleus.store.rdbms.identifier.IdentifierFactory)

Example 28 with DatastoreIdentifier

use of org.datanucleus.store.rdbms.identifier.DatastoreIdentifier in project datanucleus-rdbms by datanucleus.

the class TableImpl method getExistingForeignKeys.

/**
 * Accessor for the foreign keys for this table.
 * @param conn The JDBC Connection
 * @return Map of foreign keys
 * @throws SQLException Thrown when an error occurs in the JDBC call.
 */
private Map<DatastoreIdentifier, ForeignKey> getExistingForeignKeys(Connection conn) throws SQLException {
    Map<DatastoreIdentifier, ForeignKey> foreignKeysByName = new HashMap<>();
    if (tableExistsInDatastore(conn)) {
        StoreSchemaHandler handler = storeMgr.getSchemaHandler();
        IdentifierFactory idFactory = storeMgr.getIdentifierFactory();
        RDBMSTableFKInfo tableFkInfo = (RDBMSTableFKInfo) handler.getSchemaData(conn, RDBMSSchemaHandler.TYPE_FKS, new Object[] { this });
        Iterator fksIter = tableFkInfo.getChildren().iterator();
        while (fksIter.hasNext()) {
            ForeignKeyInfo fkInfo = (ForeignKeyInfo) fksIter.next();
            DatastoreIdentifier fkIdentifier;
            String fkName = (String) fkInfo.getProperty("fk_name");
            if (fkName == null) {
                fkIdentifier = idFactory.newForeignKeyIdentifier(this, foreignKeysByName.size());
            } else {
                fkIdentifier = idFactory.newIdentifier(IdentifierType.FOREIGN_KEY, fkName);
            }
            short deferrability = ((Short) fkInfo.getProperty("deferrability")).shortValue();
            boolean initiallyDeferred = deferrability == DatabaseMetaData.importedKeyInitiallyDeferred;
            ForeignKey fk = foreignKeysByName.get(fkIdentifier);
            if (fk == null) {
                fk = new ForeignKey(dba, initiallyDeferred);
                fk.setName(fkIdentifier.getName());
                foreignKeysByName.put(fkIdentifier, fk);
            }
            // Find the referenced table from the provided name
            String pkTableName = (String) fkInfo.getProperty("pk_table_name");
            DatastoreIdentifier refTableId = idFactory.newTableIdentifier(pkTableName);
            DatastoreClass refTable = storeMgr.getDatastoreClass(refTableId);
            if (refTable == null) {
                // Try with same catalog/schema as this table since some JDBC don't provide this info
                if (getSchemaName() != null) {
                    refTableId.setSchemaName(getSchemaName());
                }
                if (getCatalogName() != null) {
                    refTableId.setCatalogName(getCatalogName());
                }
                refTable = storeMgr.getDatastoreClass(refTableId);
            }
            if (refTable != null) {
                String fkColumnName = (String) fkInfo.getProperty("fk_column_name");
                String pkColumnName = (String) fkInfo.getProperty("pk_column_name");
                DatastoreIdentifier colName = idFactory.newIdentifier(IdentifierType.COLUMN, fkColumnName);
                DatastoreIdentifier refColName = idFactory.newIdentifier(IdentifierType.COLUMN, pkColumnName);
                Column col = columnsByIdentifier.get(colName);
                Column refCol = refTable.getColumn(refColName);
                if (col != null && refCol != null) {
                    fk.addColumn(col, refCol);
                } else {
                // TODO throw exception?
                }
            } else {
                NucleusLogger.DATASTORE_SCHEMA.warn("Retrieved ForeignKey from datastore for table=" + toString() + " referencing table " + pkTableName + " but not found internally. Is there some catalog/schema or quoting causing problems?");
            }
        }
    }
    return foreignKeysByName;
}
Also used : HashMap(java.util.HashMap) RDBMSTableFKInfo(org.datanucleus.store.rdbms.schema.RDBMSTableFKInfo) StoreSchemaHandler(org.datanucleus.store.schema.StoreSchemaHandler) ForeignKey(org.datanucleus.store.rdbms.key.ForeignKey) IdentifierFactory(org.datanucleus.store.rdbms.identifier.IdentifierFactory) ForeignKeyInfo(org.datanucleus.store.rdbms.schema.ForeignKeyInfo) DatastoreIdentifier(org.datanucleus.store.rdbms.identifier.DatastoreIdentifier) Iterator(java.util.Iterator)

Example 29 with DatastoreIdentifier

use of org.datanucleus.store.rdbms.identifier.DatastoreIdentifier in project datanucleus-rdbms by datanucleus.

the class ViewImpl method validate.

/**
 * Method to validate the view in the datastore. Validates the existence of the table, and then the specifications of the Columns.
 * @param conn The JDBC Connection
 * @param validateColumnStructure Whether to validate down to column structure, or just their existence
 * @param autoCreate Whether to update the view to fix errors (not used).
 * @param autoCreateErrors Errors found during the auto-create process
 * @return Whether the database was modified
 * @throws SQLException Thrown when an error occurs in the JDBC calls
 */
public boolean validate(Connection conn, boolean validateColumnStructure, boolean autoCreate, Collection<Throwable> autoCreateErrors) throws SQLException {
    assertIsInitialized();
    long startTime = System.currentTimeMillis();
    if (NucleusLogger.DATASTORE.isDebugEnabled()) {
        NucleusLogger.DATASTORE.debug(Localiser.msg("031004", this));
    }
    // Check existence and validity
    RDBMSSchemaHandler handler = (RDBMSSchemaHandler) storeMgr.getSchemaHandler();
    String tableType = handler.getTableType(conn, this);
    if (tableType == null) {
        throw new MissingTableException(getCatalogName(), getSchemaName(), this.toString());
    } else if (// TODO Allow "MATERIALIZED VIEW" that some RDBMS support (e.g PostgreSQL)
    !tableType.equals("VIEW")) {
        throw new NotAViewException(this.toString(), tableType);
    }
    // Validate the column(s)
    Map<DatastoreIdentifier, Column> unvalidated = new HashMap(columnsByIdentifier);
    Iterator i = storeMgr.getColumnInfoForTable(this, conn).iterator();
    while (i.hasNext()) {
        RDBMSColumnInfo ci = (RDBMSColumnInfo) i.next();
        DatastoreIdentifier colIdentifier = storeMgr.getIdentifierFactory().newIdentifier(IdentifierType.COLUMN, ci.getColumnName());
        Column col = unvalidated.get(colIdentifier);
        if (col == null) {
            if (!hasColumnName(colIdentifier)) {
                throw new UnexpectedColumnException(this.toString(), ci.getColumnName(), this.getSchemaName(), this.getCatalogName());
            }
        // Otherwise it's a duplicate column name in the metadata and we ignore it.  Cloudscape is known to do this, although I think that's probably a bug.
        } else {
            if (validateColumnStructure) {
                col.validate(ci);
                unvalidated.remove(colIdentifier);
            } else {
                unvalidated.remove(colIdentifier);
            }
        }
    }
    if (unvalidated.size() > 0) {
        throw new MissingColumnException(this, unvalidated.values());
    }
    state = TABLE_STATE_VALIDATED;
    if (NucleusLogger.DATASTORE.isDebugEnabled()) {
        NucleusLogger.DATASTORE.debug(Localiser.msg("045000", (System.currentTimeMillis() - startTime)));
    }
    return false;
}
Also used : RDBMSColumnInfo(org.datanucleus.store.rdbms.schema.RDBMSColumnInfo) NotAViewException(org.datanucleus.store.rdbms.exceptions.NotAViewException) HashMap(java.util.HashMap) MissingColumnException(org.datanucleus.store.rdbms.exceptions.MissingColumnException) RDBMSSchemaHandler(org.datanucleus.store.rdbms.schema.RDBMSSchemaHandler) DatastoreIdentifier(org.datanucleus.store.rdbms.identifier.DatastoreIdentifier) Iterator(java.util.Iterator) MissingTableException(org.datanucleus.store.rdbms.exceptions.MissingTableException) UnexpectedColumnException(org.datanucleus.store.rdbms.exceptions.UnexpectedColumnException)

Example 30 with DatastoreIdentifier

use of org.datanucleus.store.rdbms.identifier.DatastoreIdentifier in project datanucleus-rdbms by datanucleus.

the class TableGenerator method initialiseSequenceTable.

/**
 * Method to initialise the sequence table used for storing the sequence values.
 */
protected synchronized void initialiseSequenceTable() {
    // Set catalog/schema name (using properties, and if not specified using the values for the table)
    String catalogName = properties.getProperty(ValueGenerator.PROPERTY_SEQUENCETABLE_CATALOG);
    if (catalogName == null) {
        catalogName = properties.getProperty(ValueGenerator.PROPERTY_CATALOG_NAME);
    }
    String schemaName = properties.getProperty(ValueGenerator.PROPERTY_SEQUENCETABLE_SCHEMA);
    if (schemaName == null) {
        schemaName = properties.getProperty(ValueGenerator.PROPERTY_SCHEMA_NAME);
    }
    String tableName = (properties.getProperty(ValueGenerator.PROPERTY_SEQUENCETABLE_TABLE) == null ? DEFAULT_TABLE_NAME : properties.getProperty(ValueGenerator.PROPERTY_SEQUENCETABLE_TABLE));
    RDBMSStoreManager storeMgr = (RDBMSStoreManager) this.storeMgr;
    DatastoreAdapter dba = storeMgr.getDatastoreAdapter();
    DatastoreIdentifier identifier = storeMgr.getIdentifierFactory().newTableIdentifier(tableName);
    if (dba.supportsOption(DatastoreAdapter.CATALOGS_IN_TABLE_DEFINITIONS) && catalogName != null) {
        identifier.setCatalogName(catalogName);
    }
    if (dba.supportsOption(DatastoreAdapter.SCHEMAS_IN_TABLE_DEFINITIONS) && schemaName != null) {
        identifier.setSchemaName(schemaName);
    }
    DatastoreClass table = storeMgr.getDatastoreClass(identifier);
    if (table != null) {
        sequenceTable = (SequenceTable) table;
    } else {
        String sequenceNameColumnName = DEFAULT_SEQUENCE_COLUMN_NAME;
        if (properties.containsKey(ValueGenerator.PROPERTY_SEQUENCETABLE_NAME_COLUMN)) {
            sequenceNameColumnName = properties.getProperty(ValueGenerator.PROPERTY_SEQUENCETABLE_NAME_COLUMN);
        }
        String nextValColumnName = DEFAULT_NEXTVALUE_COLUMN_NAME;
        if (properties.containsKey(ValueGenerator.PROPERTY_SEQUENCETABLE_NEXTVAL_COLUMN)) {
            nextValColumnName = properties.getProperty(ValueGenerator.PROPERTY_SEQUENCETABLE_NEXTVAL_COLUMN);
        }
        sequenceTable = new SequenceTable(identifier, storeMgr, sequenceNameColumnName, nextValColumnName);
        sequenceTable.initialize(storeMgr.getNucleusContext().getClassLoaderResolver(null));
    }
}
Also used : DatastoreIdentifier(org.datanucleus.store.rdbms.identifier.DatastoreIdentifier) DatastoreAdapter(org.datanucleus.store.rdbms.adapter.DatastoreAdapter) DatastoreClass(org.datanucleus.store.rdbms.table.DatastoreClass) RDBMSStoreManager(org.datanucleus.store.rdbms.RDBMSStoreManager)

Aggregations

DatastoreIdentifier (org.datanucleus.store.rdbms.identifier.DatastoreIdentifier)45 IdentifierFactory (org.datanucleus.store.rdbms.identifier.IdentifierFactory)19 HashMap (java.util.HashMap)18 AbstractMemberMetaData (org.datanucleus.metadata.AbstractMemberMetaData)12 ColumnMetaData (org.datanucleus.metadata.ColumnMetaData)11 Iterator (java.util.Iterator)10 NucleusUserException (org.datanucleus.exceptions.NucleusUserException)10 AbstractClassMetaData (org.datanucleus.metadata.AbstractClassMetaData)9 JavaTypeMapping (org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping)8 MacroString (org.datanucleus.util.MacroString)6 ArrayList (java.util.ArrayList)5 NucleusException (org.datanucleus.exceptions.NucleusException)5 RDBMSStoreManager (org.datanucleus.store.rdbms.RDBMSStoreManager)4 Index (org.datanucleus.store.rdbms.key.Index)4 RDBMSColumnInfo (org.datanucleus.store.rdbms.schema.RDBMSColumnInfo)4 StoreSchemaHandler (org.datanucleus.store.schema.StoreSchemaHandler)4 SQLException (java.sql.SQLException)3 HashSet (java.util.HashSet)3 List (java.util.List)3 Map (java.util.Map)3