use of org.datanucleus.store.rdbms.key.Index in project datanucleus-rdbms by datanucleus.
the class MapTable 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.
* @param clr The ClassLoaderResolver
* @return The indices
*/
protected Set getExpectedIndices(ClassLoaderResolver clr) {
Set 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 the key FK (if required)
if (keyMapping instanceof EmbeddedKeyPCMapping) {
// Add all indices required by fields of the embedded key
EmbeddedKeyPCMapping embMapping = (EmbeddedKeyPCMapping) keyMapping;
for (int i = 0; i < embMapping.getNumberOfJavaTypeMappings(); i++) {
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 {
KeyMetaData keymd = mmd.getKeyMetaData();
if (keymd != null && keymd.getIndexMetaData() != null) {
IndexMetaData idxmd = mmd.getKeyMetaData().getIndexMetaData();
Index index = TableUtils.getIndexForField(this, idxmd, keyMapping);
if (index != null) {
indices.add(index);
}
} else {
// Fallback to an index for any foreign-key to the key
if (keyMapping instanceof PersistableMapping) {
Index index = TableUtils.getIndexForField(this, null, keyMapping);
if (index != null) {
indices.add(index);
}
}
}
}
// Index for the value FK (if required)
if (valueMapping instanceof EmbeddedValuePCMapping) {
// Add all indices required by fields of the embedded value
EmbeddedValuePCMapping embMapping = (EmbeddedValuePCMapping) valueMapping;
for (int i = 0; i < embMapping.getNumberOfJavaTypeMappings(); i++) {
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 {
ValueMetaData valmd = mmd.getValueMetaData();
if (valmd != null && valmd.getIndexMetaData() != null) {
IndexMetaData idxmd = mmd.getValueMetaData().getIndexMetaData();
Index index = TableUtils.getIndexForField(this, idxmd, valueMapping);
if (index != null) {
indices.add(index);
}
} else {
// Fallback to an index for any foreign-key to the value
if (valueMapping instanceof PersistableMapping) {
Index index = TableUtils.getIndexForField(this, null, valueMapping);
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 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, "indices", new Object[] { this });
IdentifierFactory idFactory = storeMgr.getIdentifierFactory();
Iterator indexIter = tableIndexInfo.getChildren().iterator();
while (indexIter.hasNext()) {
IndexInfo indexInfo = (IndexInfo) indexIter.next();
short idxType = ((Short) indexInfo.getProperty("type")).shortValue();
if (idxType == DatabaseMetaData.tableIndexStatistic) {
// Ignore
continue;
}
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;
}
use of org.datanucleus.store.rdbms.key.Index in project datanucleus-rdbms by datanucleus.
the class TableUtils method getIndexForField.
/**
* Convenience method to create an Index for a field.
* @param table Container for the index
* @param imd The Index MetaData
* @param fieldMapping Mapping for the field
* @return The Index
*/
public static Index getIndexForField(Table table, IndexMetaData imd, JavaTypeMapping fieldMapping) {
if (fieldMapping.getNumberOfDatastoreMappings() == 0) {
// No columns in this mapping so we can hardly index it!
return null;
}
if (!table.getStoreManager().getDatastoreAdapter().validToIndexMapping(fieldMapping)) {
return null;
}
// Verify if a unique index is needed
boolean unique = (imd == null ? false : imd.isUnique());
Index index = new Index(table, unique, (imd != null ? imd.getExtensions() : null));
// Set the index name if required
if (imd != null && imd.getName() != null) {
IdentifierFactory idFactory = table.getStoreManager().getIdentifierFactory();
DatastoreIdentifier idxId = idFactory.newIdentifier(IdentifierType.INDEX, imd.getName());
index.setName(idxId.toString());
}
// Field-level index so use all columns for the field
int countFields = fieldMapping.getNumberOfDatastoreMappings();
for (int j = 0; j < countFields; j++) {
index.addColumn(fieldMapping.getDatastoreMapping(j).getColumn());
}
return index;
}
use of org.datanucleus.store.rdbms.key.Index in project datanucleus-rdbms by datanucleus.
the class ClassTable 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<Index> getExpectedIndices(ClassLoaderResolver clr) {
// Auto mode allows us to decide which indices are needed as well as using what is in the users MetaData
boolean autoMode = false;
if (storeMgr.getStringProperty(RDBMSPropertyNames.PROPERTY_RDBMS_CONSTRAINT_CREATE_MODE).equals("DataNucleus")) {
autoMode = true;
}
Set<Index> indices = new HashSet();
// Add on any user-required indices for the fields/properties
Set memberNumbersSet = memberMappingsMap.keySet();
Iterator iter = memberNumbersSet.iterator();
while (iter.hasNext()) {
AbstractMemberMetaData fmd = (AbstractMemberMetaData) iter.next();
JavaTypeMapping fieldMapping = memberMappingsMap.get(fmd);
if (fieldMapping instanceof EmbeddedPCMapping) {
// Add indexes for fields of this embedded PC object
EmbeddedPCMapping embMapping = (EmbeddedPCMapping) fieldMapping;
for (int i = 0; i < embMapping.getNumberOfJavaTypeMappings(); i++) {
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 if (fieldMapping instanceof SerialisedMapping) {
// Don't index these
} else {
// Add any required index for this field
IndexMetaData imd = fmd.getIndexMetaData();
if (imd != null) {
// Index defined so add it
Index index = TableUtils.getIndexForField(this, imd, fieldMapping);
if (index != null) {
indices.add(index);
}
} else if (autoMode) {
if (fmd.getIndexed() == null) {
// Indexing not set, so add where we think it is appropriate
if (// Ignore PKs since they will be indexed anyway
!fmd.isPrimaryKey()) {
// TODO Some RDBMS create index automatically for all FK cols so we don't need to really
RelationType relationType = fmd.getRelationType(clr);
if (relationType == RelationType.ONE_TO_ONE_UNI) {
// 1-1 with FK at this side so index the FK
if (fieldMapping instanceof ReferenceMapping) {
ReferenceMapping refMapping = (ReferenceMapping) fieldMapping;
if (refMapping.getMappingStrategy() == ReferenceMapping.PER_IMPLEMENTATION_MAPPING) {
// Cols per implementation : index each of implementations
if (refMapping.getJavaTypeMapping() != null) {
int colNum = 0;
JavaTypeMapping[] implMappings = refMapping.getJavaTypeMapping();
for (int i = 0; i < implMappings.length; i++) {
int numColsInImpl = implMappings[i].getNumberOfDatastoreMappings();
Index index = new Index(this, false, null);
for (int j = 0; j < numColsInImpl; j++) {
index.setColumn(j, fieldMapping.getDatastoreMapping(colNum++).getColumn());
}
indices.add(index);
}
}
}
} else {
Index index = new Index(this, false, null);
for (int i = 0; i < fieldMapping.getNumberOfDatastoreMappings(); i++) {
index.setColumn(i, fieldMapping.getDatastoreMapping(i).getColumn());
}
indices.add(index);
}
} else if (relationType == RelationType.ONE_TO_ONE_BI && fmd.getMappedBy() == null) {
// 1-1 with FK at this side so index the FK
Index index = new Index(this, false, null);
for (int i = 0; i < fieldMapping.getNumberOfDatastoreMappings(); i++) {
index.setColumn(i, fieldMapping.getDatastoreMapping(i).getColumn());
}
indices.add(index);
} else if (relationType == RelationType.MANY_TO_ONE_BI) {
// N-1 with FK at this side so index the FK
AbstractMemberMetaData relMmd = fmd.getRelatedMemberMetaData(clr)[0];
if (relMmd.getJoinMetaData() == null && fmd.getJoinMetaData() == null) {
if (fieldMapping.getNumberOfDatastoreMappings() > 0) {
Index index = new Index(this, false, null);
for (int i = 0; i < fieldMapping.getNumberOfDatastoreMappings(); i++) {
index.setColumn(i, fieldMapping.getDatastoreMapping(i).getColumn());
}
indices.add(index);
} else {
// TODO How do we get this?
NucleusLogger.DATASTORE_SCHEMA.warn("Table " + this + " manages member " + fmd.getFullFieldName() + " which is a N-1 but there is no column for this mapping so not adding index!");
}
}
}
}
}
}
}
}
// Check if any version column needs indexing
if (versionMapping != null) {
IndexMetaData idxmd = getVersionMetaData().getIndexMetaData();
if (idxmd != null) {
Index index = new Index(this, idxmd.isUnique(), idxmd.getExtensions());
if (idxmd.getName() != null) {
index.setName(idxmd.getName());
}
int countVersionFields = versionMapping.getNumberOfDatastoreMappings();
for (int i = 0; i < countVersionFields; i++) {
index.addColumn(versionMapping.getDatastoreMapping(i).getColumn());
}
indices.add(index);
}
}
// Check if any discriminator column needs indexing
if (discriminatorMapping != null) {
DiscriminatorMetaData dismd = getDiscriminatorMetaData();
IndexMetaData idxmd = dismd.getIndexMetaData();
if (idxmd != null) {
Index index = new Index(this, idxmd.isUnique(), idxmd.getExtensions());
if (idxmd.getName() != null) {
index.setName(idxmd.getName());
}
int countDiscrimFields = discriminatorMapping.getNumberOfDatastoreMappings();
for (int i = 0; i < countDiscrimFields; i++) {
index.addColumn(discriminatorMapping.getDatastoreMapping(i).getColumn());
}
indices.add(index);
}
}
// Add on any order fields (for lists, arrays, collections) that need indexing
Set orderMappingsEntries = getExternalOrderMappings().entrySet();
Iterator orderMappingsEntriesIter = orderMappingsEntries.iterator();
while (orderMappingsEntriesIter.hasNext()) {
Map.Entry entry = (Map.Entry) orderMappingsEntriesIter.next();
AbstractMemberMetaData fmd = (AbstractMemberMetaData) entry.getKey();
JavaTypeMapping mapping = (JavaTypeMapping) entry.getValue();
OrderMetaData omd = fmd.getOrderMetaData();
if (omd != null && omd.getIndexMetaData() != null) {
Index index = getIndexForIndexMetaDataAndMapping(omd.getIndexMetaData(), mapping);
if (index != null) {
indices.add(index);
}
}
}
// Add on any user-required indices for the class(es) as a whole (subelement of <class>)
Iterator<AbstractClassMetaData> cmdIter = managedClassMetaData.iterator();
while (cmdIter.hasNext()) {
AbstractClassMetaData thisCmd = cmdIter.next();
List<IndexMetaData> classIndices = thisCmd.getIndexMetaData();
if (classIndices != null) {
for (IndexMetaData idxmd : classIndices) {
Index index = getIndexForIndexMetaData(idxmd);
if (index != null) {
indices.add(index);
}
}
}
}
if (cmd.getIdentityType() == IdentityType.APPLICATION) {
// Make sure there is no reuse of PK fields that cause a duplicate index for the PK. Remove it if required
PrimaryKey pk = getPrimaryKey();
Iterator<Index> indicesIter = indices.iterator();
while (indicesIter.hasNext()) {
Index idx = indicesIter.next();
if (idx.getColumnList().equals(pk.getColumnList())) {
NucleusLogger.DATASTORE_SCHEMA.debug("Index " + idx + " is for the same columns as the PrimaryKey so being removed from expected set of indices. PK is always indexed");
indicesIter.remove();
}
}
}
return indices;
}
use of org.datanucleus.store.rdbms.key.Index in project datanucleus-rdbms by datanucleus.
the class ClassTable method getIndexForIndexMetaData.
/**
* Convenience method to convert an IndexMetaData into an Index.
* @param imd The Index MetaData
* @return The Index
*/
private Index getIndexForIndexMetaData(IndexMetaData imd) {
// 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());
}
// Class-level index so use its column definition
if (imd.getNumberOfColumns() > 0) {
// a). Columns specified directly
String[] columnNames = imd.getColumnNames();
for (String columnName : columnNames) {
DatastoreIdentifier colName = storeMgr.getIdentifierFactory().newColumnIdentifier(columnName);
Column col = columnsByIdentifier.get(colName);
if (col == null) {
NucleusLogger.DATASTORE_SCHEMA.warn(Localiser.msg("058001", toString(), index.getName(), columnName));
break;
}
index.addColumn(col);
}
// Apply any user-provided ordering of the columns
String idxOrdering = imd.getValueForExtension(Index.EXTENSION_INDEX_COLUMN_ORDERING);
if (!StringUtils.isWhitespace(idxOrdering)) {
index.setColumnOrdering(idxOrdering);
}
} else if (imd.getNumberOfMembers() > 0) {
// b). Columns specified using members
String[] memberNames = imd.getMemberNames();
for (int i = 0; i < memberNames.length; i++) {
// Find the metadata for the actual field with the same name as this "index" field
AbstractMemberMetaData realMmd = getMetaDataForMember(memberNames[i]);
if (realMmd == null) {
throw new NucleusUserException("Table " + this + " has index specified on member " + memberNames[i] + " but that member does not exist in the class that this table represents");
}
JavaTypeMapping fieldMapping = memberMappingsMap.get(realMmd);
int countFields = fieldMapping.getNumberOfDatastoreMappings();
for (int j = 0; j < countFields; j++) {
index.addColumn(fieldMapping.getDatastoreMapping(j).getColumn());
}
// Apply any user-provided ordering of the columns
String idxOrdering = imd.getValueForExtension(Index.EXTENSION_INDEX_COLUMN_ORDERING);
if (!StringUtils.isWhitespace(idxOrdering)) {
index.setColumnOrdering(idxOrdering);
}
}
} else {
// We can't have an index of no columns
NucleusLogger.DATASTORE_SCHEMA.warn(Localiser.msg("058002", toString(), index.getName()));
return null;
}
return index;
}
Aggregations