Search in sources :

Example 1 with IndexField

use of jetbrains.exodus.query.metadata.IndexField in project xodus by JetBrains.

the class UniqueKeyIndicesEngine method createUniqueKeyIndex.

private void createUniqueKeyIndex(@NotNull final PersistentStoreTransaction txn, @NotNull final PersistentStoreTransaction snapshot, @NotNull final Index index) {
    if (logger.isDebugEnabled()) {
        logger.debug("Create index [" + index + ']');
    }
    final Environment environment = persistentStore.getEnvironment();
    final PersistentEntityStoreConfig config = persistentStore.getConfig();
    final PropertyTypes propertyTypes = persistentStore.getPropertyTypes();
    final List<IndexField> fields = index.getFields();
    final int propCount = fields.size();
    if (propCount == 0) {
        throw new EntityStoreException("Can't create unique key index on empty list of keys.");
    }
    SingleColumnTable indexTable = null;
    Comparable[] props = new Comparable[propCount];
    for (final String entityType : getEntityTypesToIndex(index)) {
        int i = 0;
        for (final Entity entity : snapshot.getAll(entityType)) {
            for (int j = 0; j < propCount; ++j) {
                final IndexField field = fields.get(j);
                if (field.isProperty()) {
                    if ((props[j] = persistentStore.getProperty(txn, (PersistentEntity) entity, field.getName())) == null) {
                        throw new EntityStoreException("Can't create unique key index with null property value: " + entityType + '.' + field.getName());
                    }
                } else {
                    if ((props[j] = entity.getLink(field.getName())) == null) {
                        throw new EntityStoreException("Can't create unique key index with null link: " + entityType + '.' + field.getName());
                    }
                }
            }
            if (indexTable == null) {
                final String uniqueKeyIndexName = getUniqueKeyIndexName(index);
                indexTable = new SingleColumnTable(txn, uniqueKeyIndexName, environment.storeExists(uniqueKeyIndexName, txn.getEnvironmentTransaction()) ? StoreConfig.USE_EXISTING : StoreConfig.WITHOUT_DUPLICATES_WITH_PREFIXING);
            }
            ArrayByteIterable propsEntry = propertyTypes.dataArrayToEntry(props);
            if (!indexTable.getDatabase().add(txn.getEnvironmentTransaction(), propsEntry, LongBinding.longToCompressedEntry(entity.getId().getLocalId()))) {
                ByteIterable oldEntityIdEntry = indexTable.getDatabase().get(txn.getEnvironmentTransaction(), propsEntry);
                assert oldEntityIdEntry != null;
                long oldEntityId = LongBinding.compressedEntryToLong(oldEntityIdEntry);
                throw new EntityStoreException("Failed to insert unique key (already exists), index: " + index + ", values = " + Arrays.toString(props) + ", new entity = " + entity + ", old entity id = " + oldEntityId + ", index owner entity type = " + index.getOwnerEntityType());
            }
            if (++i % 100 == 0) {
                txn.flush();
            }
        }
        txn.flush();
    }
}
Also used : PropertyTypes(jetbrains.exodus.entitystore.tables.PropertyTypes) ArrayByteIterable(jetbrains.exodus.ArrayByteIterable) ByteIterable(jetbrains.exodus.ByteIterable) ArrayByteIterable(jetbrains.exodus.ArrayByteIterable) Environment(jetbrains.exodus.env.Environment) SingleColumnTable(jetbrains.exodus.entitystore.tables.SingleColumnTable) IndexField(jetbrains.exodus.query.metadata.IndexField)

Example 2 with IndexField

use of jetbrains.exodus.query.metadata.IndexField in project xodus by JetBrains.

the class UniqueKeyIndicesEngine method getUniqueKeyIndexName.

private String getUniqueKeyIndexName(@NotNull final Index index) {
    final List<IndexField> fields = index.getFields();
    final int fieldCount = fields.size();
    if (fieldCount < 1) {
        throw new EntityStoreException("Can't define unique key on empty set of fields");
    }
    final LinkedHashMap<String, Boolean> names = new LinkedHashMap<>();
    for (final IndexField field : fields) {
        final String name = field.getName();
        final Boolean b = names.get(name);
        if (b != null && b == field.isProperty()) {
            throw new EntityStoreException("Can't define unique key, field is used twice: " + name);
        }
        names.put(name, field.isProperty());
    }
    return getUniqueKeyIndexName(index.getOwnerEntityType(), names);
}
Also used : IndexField(jetbrains.exodus.query.metadata.IndexField) LinkedHashMap(jetbrains.exodus.core.dataStructures.hash.LinkedHashMap)

Aggregations

IndexField (jetbrains.exodus.query.metadata.IndexField)2 ArrayByteIterable (jetbrains.exodus.ArrayByteIterable)1 ByteIterable (jetbrains.exodus.ByteIterable)1 LinkedHashMap (jetbrains.exodus.core.dataStructures.hash.LinkedHashMap)1 PropertyTypes (jetbrains.exodus.entitystore.tables.PropertyTypes)1 SingleColumnTable (jetbrains.exodus.entitystore.tables.SingleColumnTable)1 Environment (jetbrains.exodus.env.Environment)1