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;
}
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;
}
Aggregations