Search in sources :

Example 1 with MissingColumnException

use of org.datanucleus.store.rdbms.exceptions.MissingColumnException in project datanucleus-rdbms by datanucleus.

the class TableImpl method validateColumns.

/**
 * Utility to validate the columns of the table.
 * Will throw a MissingColumnException if a column is not found (and is not required to auto create it)
 * @param conn Connection to use for validation
 * @param validateColumnStructure Whether to validate down to the structure of the columns, or just their existence
 * @param autoCreate Whether to auto create any missing columns
 * @param autoCreateErrors Exceptions found in the "auto-create" process
 * @return Whether it validates
 * @throws SQLException Thrown if an error occurs in the validation process
 */
public boolean validateColumns(Connection conn, boolean validateColumnStructure, boolean autoCreate, Collection autoCreateErrors) throws SQLException {
    Map<DatastoreIdentifier, Column> unvalidated = new HashMap(columnsByIdentifier);
    List<StoreSchemaData> tableColInfo = storeMgr.getColumnInfoForTable(this, conn);
    Iterator i = tableColInfo.iterator();
    while (i.hasNext()) {
        RDBMSColumnInfo ci = (RDBMSColumnInfo) i.next();
        // Create an identifier to use for the real column - use "CUSTOM" because we don't want truncation
        DatastoreIdentifier colIdentifier = storeMgr.getIdentifierFactory().newColumnIdentifier(ci.getColumnName(), this.storeMgr.getNucleusContext().getTypeManager().isDefaultEmbeddedType(String.class), null, true);
        Column col = unvalidated.get(colIdentifier);
        if (col != null) {
            if (validateColumnStructure) {
                col.initializeColumnInfoFromDatastore(ci);
                col.validate(ci);
                unvalidated.remove(colIdentifier);
            } else {
                unvalidated.remove(colIdentifier);
            }
        }
    }
    if (unvalidated.size() > 0) {
        if (autoCreate) {
            // Add all missing columns
            List<String> stmts = new ArrayList<>();
            Iterator<Map.Entry<DatastoreIdentifier, Column>> columnsIter = unvalidated.entrySet().iterator();
            while (columnsIter.hasNext()) {
                Map.Entry<DatastoreIdentifier, Column> entry = columnsIter.next();
                Column col = entry.getValue();
                String addColStmt = dba.getAddColumnStatement(this, col);
                stmts.add(addColStmt);
            }
            try {
                executeDdlStatementList(stmts, conn);
            } catch (SQLException sqle) {
                if (autoCreateErrors != null) {
                    autoCreateErrors.add(sqle);
                } else {
                    throw sqle;
                }
            }
            // Invalidate the cached information for this table since it now has a new column
            storeMgr.invalidateColumnInfoForTable(this);
        } else {
            MissingColumnException mce = new MissingColumnException(this, unvalidated.values());
            if (autoCreateErrors != null) {
                autoCreateErrors.add(mce);
            } else {
                throw mce;
            }
        }
    }
    state = TABLE_STATE_VALIDATED;
    return true;
}
Also used : RDBMSColumnInfo(org.datanucleus.store.rdbms.schema.RDBMSColumnInfo) HashMap(java.util.HashMap) SQLException(java.sql.SQLException) MissingColumnException(org.datanucleus.store.rdbms.exceptions.MissingColumnException) ArrayList(java.util.ArrayList) DatastoreIdentifier(org.datanucleus.store.rdbms.identifier.DatastoreIdentifier) Iterator(java.util.Iterator) StoreSchemaData(org.datanucleus.store.schema.StoreSchemaData) HashMap(java.util.HashMap) Map(java.util.Map)

Example 2 with MissingColumnException

use of org.datanucleus.store.rdbms.exceptions.MissingColumnException 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 autoCreateErrors) throws SQLException {
    assertIsInitialized();
    // 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);
    }
    long startTime = System.currentTimeMillis();
    if (NucleusLogger.DATASTORE.isDebugEnabled()) {
        NucleusLogger.DATASTORE.debug(Localiser.msg("031004", this));
    }
    // 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)

Aggregations

HashMap (java.util.HashMap)2 Iterator (java.util.Iterator)2 MissingColumnException (org.datanucleus.store.rdbms.exceptions.MissingColumnException)2 DatastoreIdentifier (org.datanucleus.store.rdbms.identifier.DatastoreIdentifier)2 RDBMSColumnInfo (org.datanucleus.store.rdbms.schema.RDBMSColumnInfo)2 SQLException (java.sql.SQLException)1 ArrayList (java.util.ArrayList)1 Map (java.util.Map)1 MissingTableException (org.datanucleus.store.rdbms.exceptions.MissingTableException)1 NotAViewException (org.datanucleus.store.rdbms.exceptions.NotAViewException)1 UnexpectedColumnException (org.datanucleus.store.rdbms.exceptions.UnexpectedColumnException)1 RDBMSSchemaHandler (org.datanucleus.store.rdbms.schema.RDBMSSchemaHandler)1 StoreSchemaData (org.datanucleus.store.schema.StoreSchemaData)1