use of org.datanucleus.store.rdbms.key.Index in project datanucleus-rdbms by datanucleus.
the class ClassTable method getIndexForIndexMetaDataAndMapping.
/**
* Convenience method to convert an IndexMetaData and a mapping into an Index.
* @param imd The Index MetaData
* @param mapping The mapping
* @return The Index
*/
private Index getIndexForIndexMetaDataAndMapping(IndexMetaData imd, JavaTypeMapping mapping) {
// Verify if a unique index is needed
boolean unique = imd.isUnique();
Index index = new Index(this, unique, imd.getExtensions());
// Set the index name if required
if (imd.getName() != null) {
index.setName(imd.getName());
}
int numCols = mapping.getNumberOfDatastoreMappings();
for (int i = 0; i < numCols; i++) {
index.addColumn(mapping.getDatastoreMapping(i).getColumn());
}
return index;
}
use of org.datanucleus.store.rdbms.key.Index in project datanucleus-rdbms by datanucleus.
the class ElementContainerTable method getExpectedIndices.
/**
* Accessor for the indices for this table.
* This includes both the user-defined indices (via MetaData), and the ones required by
* foreign keys (required by relationships).
* @param clr The ClassLoaderResolver
* @return The indices
*/
protected Set getExpectedIndices(ClassLoaderResolver clr) {
assertIsInitialized();
Set<Index> indices = new HashSet();
// Index for FK back to owner
if (mmd.getIndexMetaData() != null) {
Index index = TableUtils.getIndexForField(this, mmd.getIndexMetaData(), ownerMapping);
if (index != null) {
indices.add(index);
}
} else if (mmd.getJoinMetaData() != null && mmd.getJoinMetaData().getIndexMetaData() != null) {
Index index = TableUtils.getIndexForField(this, mmd.getJoinMetaData().getIndexMetaData(), ownerMapping);
if (index != null) {
indices.add(index);
}
} else {
// Fallback to an index for the foreign-key to the owner
Index index = TableUtils.getIndexForField(this, null, ownerMapping);
if (index != null) {
indices.add(index);
}
}
// Index for FK to element (if required)
if (elementMapping instanceof EmbeddedElementPCMapping) {
// Add all indices required by fields of the embedded element
EmbeddedElementPCMapping embMapping = (EmbeddedElementPCMapping) elementMapping;
for (int i = 0; i < embMapping.getNumberOfJavaTypeMappings(); i++) {
// Add indexes for fields of this embedded PC object
JavaTypeMapping embFieldMapping = embMapping.getJavaTypeMapping(i);
IndexMetaData imd = embFieldMapping.getMemberMetaData().getIndexMetaData();
if (imd != null) {
Index index = TableUtils.getIndexForField(this, imd, embFieldMapping);
if (index != null) {
indices.add(index);
}
}
}
} else {
ElementMetaData elemmd = mmd.getElementMetaData();
if (elemmd != null && elemmd.getIndexMetaData() != null) {
Index index = TableUtils.getIndexForField(this, elemmd.getIndexMetaData(), elementMapping);
if (index != null) {
indices.add(index);
}
} else {
// Fallback to an index for any foreign-key to the element
if (elementMapping instanceof PersistableMapping) {
Index index = TableUtils.getIndexForField(this, null, elementMapping);
if (index != null) {
indices.add(index);
}
}
}
}
if (orderMapping != null) {
// Index for ordering?
if (mmd.getOrderMetaData() != null && mmd.getOrderMetaData().getIndexMetaData() != null) {
Index index = TableUtils.getIndexForField(this, mmd.getOrderMetaData().getIndexMetaData(), orderMapping);
if (index != null) {
indices.add(index);
}
}
}
return indices;
}
use of org.datanucleus.store.rdbms.key.Index in project datanucleus-rdbms by datanucleus.
the class TableImpl method validateIndices.
/**
* Method to validate any indices for this table, and auto create any missing ones where required.
* @param conn The JDBC Connection
* @param autoCreate Whether to auto create any missing indices
* @param autoCreateErrors Errors found during the auto-create process
* @return Whether the database was changed
* @throws SQLException Thrown when an error occurs in the JDBC calls
*/
private boolean validateIndices(Connection conn, boolean autoCreate, Collection autoCreateErrors, ClassLoaderResolver clr) throws SQLException {
boolean dbWasModified = false;
// Retrieve the number of indexes in the datastore for this table.
Map actualIndicesByName = null;
int numActualIdxs = 0;
if (storeMgr.getCompleteDDL()) {
actualIndicesByName = new HashMap();
} else {
actualIndicesByName = getExistingIndices(conn);
Iterator<Map.Entry> iter = actualIndicesByName.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry entry = iter.next();
Index idx = (Index) entry.getValue();
if (idx.getTable().getIdentifier().toString().equals(identifier.toString())) {
// Table of the index is the same as this table so must be ours
++numActualIdxs;
}
}
if (NucleusLogger.DATASTORE_SCHEMA.isDebugEnabled()) {
NucleusLogger.DATASTORE_SCHEMA.debug(Localiser.msg("058004", "" + numActualIdxs, this));
}
}
// Auto Create any missing indices
if (autoCreate) {
dbWasModified = createIndices(conn, autoCreateErrors, clr, actualIndicesByName);
} else {
Map stmtsByIdxName = getSQLCreateIndexStatements(actualIndicesByName, clr);
if (stmtsByIdxName.isEmpty()) {
if (numActualIdxs > 0) {
if (NucleusLogger.DATASTORE_SCHEMA.isDebugEnabled()) {
NucleusLogger.DATASTORE_SCHEMA.debug(Localiser.msg("058005", "" + numActualIdxs, this));
}
}
} else {
// We support existing schemas so don't raise an exception.
NucleusLogger.DATASTORE_SCHEMA.warn(Localiser.msg("058003", this, stmtsByIdxName.values()));
}
}
return dbWasModified;
}
use of org.datanucleus.store.rdbms.key.Index 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;
}
use of org.datanucleus.store.rdbms.key.Index in project datanucleus-rdbms by datanucleus.
the class TableImpl method getExpectedIndices.
/**
* Accessor for the indices for this table in the datastore.
* @param clr The ClassLoaderResolver
* @return Set of indices expected.
*/
protected Set<Index> getExpectedIndices(ClassLoaderResolver clr) {
assertIsInitialized();
/*
* For each foreign key, add to the list an index made up of the "from"
* column(s) of the key, *unless* those columns also happen to be
* equal to the primary key (then they are indexed anyway).
* Ensure that we have separate indices for foreign key columns
* if the primary key is the combination of foreign keys, e.g. in join tables.
* This greatly decreases deadlock probability e.g. on Oracle.
*/
Set<Index> indices = new HashSet<>();
PrimaryKey pk = getPrimaryKey();
Iterator<ForeignKey> i = getExpectedForeignKeys(clr).iterator();
while (i.hasNext()) {
ForeignKey fk = i.next();
if (!pk.getColumnList().equals(fk.getColumnList())) {
indices.add(new Index(fk));
}
}
return indices;
}
Aggregations