Search in sources :

Example 1 with IndexOptions

use of com.torodb.mongodb.commands.pojos.index.IndexOptions in project torodb by torodb.

the class CreateIndexesReplImpl method apply.

@Override
public Status<CreateIndexesResult> apply(Request req, Command<? super CreateIndexesArgument, ? super CreateIndexesResult> command, CreateIndexesArgument arg, SharedWriteTorodTransaction trans) {
    int indexesBefore = (int) trans.getIndexesInfo(req.getDatabase(), arg.getCollection()).count();
    int indexesAfter = indexesBefore;
    try {
        boolean existsCollection = trans.existsCollection(req.getDatabase(), arg.getCollection());
        final boolean createdCollectionAutomatically = !existsCollection;
        if (!existsCollection) {
            LOGGER.info("Creating collection {} on {}.{}", req.getDatabase(), arg.getCollection());
            trans.createIndex(req.getDatabase(), arg.getCollection(), Constants.ID_INDEX, ImmutableList.<IndexFieldInfo>of(new IndexFieldInfo(new AttributeReference(Arrays.asList(new Key[] { new ObjectKey(Constants.ID) })), FieldIndexOrdering.ASC.isAscending())), true);
        }
        for (IndexOptions indexOptions : arg.getIndexesToCreate()) {
            if (!replicationFilters.getIndexPredicate().test(req.getDatabase(), arg.getCollection(), indexOptions.getName(), indexOptions.isUnique(), indexOptions.getKeys())) {
                LOGGER.info("Skipping filtered index {}.{}.{}.", req.getDatabase(), arg.getCollection(), indexOptions.getName());
                continue;
            }
            if (indexOptions.getKeys().size() < 1) {
                return Status.from(ErrorCode.CANNOT_CREATE_INDEX, "Index keys cannot be empty.");
            }
            if (indexOptions.isBackground()) {
                LOGGER.info("Building index in background is not supported. Ignoring option");
            }
            if (indexOptions.isSparse()) {
                LOGGER.info("Sparse index are not supported. Ignoring option");
            }
            boolean skipIndex = false;
            List<IndexFieldInfo> fields = new ArrayList<>(indexOptions.getKeys().size());
            for (IndexOptions.Key indexKey : indexOptions.getKeys()) {
                AttributeReference.Builder attRefBuilder = new AttributeReference.Builder();
                for (String key : indexKey.getKeys()) {
                    attRefBuilder.addObjectKey(key);
                }
                IndexType indexType = indexKey.getType();
                if (!KnownType.contains(indexType)) {
                    String note = "Bad index key pattern: Unknown index type '" + indexKey.getType().getName() + "'. Skipping index.";
                    LOGGER.info(note);
                    skipIndex = true;
                    break;
                }
                Optional<FieldIndexOrdering> ordering = indexType.accept(filedIndexOrderingConverterVisitor, null);
                if (!ordering.isPresent()) {
                    String note = "Index of type " + indexType.getName() + " is not supported. Skipping index.";
                    LOGGER.info(note);
                    skipIndex = true;
                    break;
                }
                fields.add(new IndexFieldInfo(attRefBuilder.build(), ordering.get().isAscending()));
            }
            if (skipIndex) {
                continue;
            }
            try {
                LOGGER.info("Creating index {} on collection {}.{}", req.getDatabase(), arg.getCollection(), indexOptions.getName());
                if (trans.createIndex(req.getDatabase(), arg.getCollection(), indexOptions.getName(), fields, indexOptions.isUnique())) {
                    indexesAfter++;
                }
            } catch (UnsupportedCompoundIndexException ex) {
                String note = "Compound indexes are not supported. Skipping index.";
                LOGGER.info(note);
                continue;
            } catch (UnsupportedUniqueIndexException ex) {
                String note = "Unique index with keys on distinct subdocuments is not supported. Skipping index.";
                LOGGER.info(note);
                continue;
            }
        }
        String note = null;
        if (indexesAfter == indexesBefore) {
            note = "all indexes already exist";
        }
        return Status.ok(new CreateIndexesResult(indexesBefore, indexesAfter, note, createdCollectionAutomatically));
    } catch (UserException ex) {
        return Status.from(ErrorCode.COMMAND_FAILED, ex.getLocalizedMessage());
    }
}
Also used : IndexOptions(com.torodb.mongodb.commands.pojos.index.IndexOptions) AttributeReference(com.torodb.core.language.AttributeReference) ObjectKey(com.torodb.core.language.AttributeReference.ObjectKey) ArrayList(java.util.ArrayList) UnsupportedUniqueIndexException(com.torodb.core.exceptions.user.UnsupportedUniqueIndexException) UnsupportedCompoundIndexException(com.torodb.core.exceptions.user.UnsupportedCompoundIndexException) CreateIndexesResult(com.torodb.mongodb.commands.signatures.admin.CreateIndexesCommand.CreateIndexesResult) IndexFieldInfo(com.torodb.torod.IndexFieldInfo) UserException(com.torodb.core.exceptions.user.UserException) AscIndexType(com.torodb.mongodb.commands.pojos.index.type.AscIndexType) DescIndexType(com.torodb.mongodb.commands.pojos.index.type.DescIndexType) IndexType(com.torodb.mongodb.commands.pojos.index.type.IndexType) FieldIndexOrdering(com.torodb.core.transaction.metainf.FieldIndexOrdering)

Example 2 with IndexOptions

use of com.torodb.mongodb.commands.pojos.index.IndexOptions in project torodb by torodb.

the class AkkaDbCloner method cloneIndex.

private void cloneIndex(MongodServer localServer, String fromDb, String dstDb, MongoConnection remoteConnection, CloneOptions opts, String fromCol, String toCol) throws CloningException {
    WriteMongodTransaction transaction = createWriteMongodTransaction(localServer);
    try {
        try {
            List<IndexOptions> indexesToClone = getIndexesToClone(Lists.newArrayList(ListIndexesRequester.getListCollections(remoteConnection, dstDb, fromCol).getFirstBatch()), dstDb, toCol, fromDb, fromCol, opts);
            if (indexesToClone.isEmpty()) {
                return;
            }
            Status<CreateIndexesResult> status = transaction.execute(new Request(dstDb, null, true, null), CreateIndexesCommand.INSTANCE, new CreateIndexesArgument(fromCol, indexesToClone));
            if (!status.isOk()) {
                throw new CloningException("Error while cloning indexes: " + status.getErrorMsg());
            }
            transaction.commit();
        } catch (UserException | MongoException ex) {
            throw new CloningException("Unexpected error while cloning indexes", ex);
        }
    } finally {
        transaction.close();
    }
}
Also used : CreateIndexesResult(com.torodb.mongodb.commands.signatures.admin.CreateIndexesCommand.CreateIndexesResult) WriteMongodTransaction(com.torodb.mongodb.core.WriteMongodTransaction) MongoException(com.eightkdata.mongowp.exceptions.MongoException) CreateIndexesArgument(com.torodb.mongodb.commands.signatures.admin.CreateIndexesCommand.CreateIndexesArgument) IndexOptions(com.torodb.mongodb.commands.pojos.index.IndexOptions) Request(com.eightkdata.mongowp.server.api.Request) UserException(com.torodb.core.exceptions.user.UserException)

Example 3 with IndexOptions

use of com.torodb.mongodb.commands.pojos.index.IndexOptions in project torodb by torodb.

the class TransactionalDbCloner method cloneIndex.

private void cloneIndex(String dstDb, MongoConnection remoteConnection, WriteMongodTransaction transaction, CloneOptions opts, String fromCol, CollectionOptions collOptions) throws CloningException {
    try {
        String fromDb = opts.getDbToClone();
        HostAndPort remoteAddress = remoteConnection.getClientOwner().getAddress();
        String remoteAddressString = remoteAddress != null ? remoteAddress.toString() : "local";
        LOGGER.info("copying indexes from {}.{} on {} to {}.{} on local server", fromDb, fromCol, remoteAddressString, dstDb, fromCol);
        Status<?> status;
        List<IndexOptions> indexes = Lists.newArrayList(ListIndexesRequester.getListCollections(remoteConnection, dstDb, fromCol).getFirstBatch());
        if (indexes.isEmpty()) {
            return;
        }
        status = transaction.execute(new Request(dstDb, null, true, null), CreateIndexesCommand.INSTANCE, new CreateIndexesArgument(fromCol, indexes));
        if (!status.isOk()) {
            throw new CloningException("Error while trying to fetch indexes from remote: " + status);
        }
    } catch (MongoException ex) {
        throw new CloningException("Error while trying to fetch indexes from remote", ex);
    }
}
Also used : HostAndPort(com.google.common.net.HostAndPort) MongoException(com.eightkdata.mongowp.exceptions.MongoException) CreateIndexesArgument(com.torodb.mongodb.commands.signatures.admin.CreateIndexesCommand.CreateIndexesArgument) IndexOptions(com.torodb.mongodb.commands.pojos.index.IndexOptions) Request(com.eightkdata.mongowp.server.api.Request)

Example 4 with IndexOptions

use of com.torodb.mongodb.commands.pojos.index.IndexOptions in project torodb by torodb.

the class CreateIndexesImplementation method apply.

@Override
public Status<CreateIndexesResult> apply(Request req, Command<? super CreateIndexesArgument, ? super CreateIndexesResult> command, CreateIndexesArgument arg, WriteMongodTransaction context) {
    int indexesBefore = (int) context.getTorodTransaction().getIndexesInfo(req.getDatabase(), arg.getCollection()).count();
    int indexesAfter = indexesBefore;
    try {
        boolean existsCollection = context.getTorodTransaction().existsCollection(req.getDatabase(), arg.getCollection());
        if (!existsCollection) {
            context.getTorodTransaction().createIndex(req.getDatabase(), arg.getCollection(), Constants.ID_INDEX, ImmutableList.<IndexFieldInfo>of(new IndexFieldInfo(new AttributeReference(Arrays.asList(new Key[] { new ObjectKey(Constants.ID) })), FieldIndexOrdering.ASC.isAscending())), true);
        }
        boolean createdCollectionAutomatically = !existsCollection;
        for (IndexOptions indexOptions : arg.getIndexesToCreate()) {
            if (indexOptions.getKeys().size() < 1) {
                return Status.from(ErrorCode.CANNOT_CREATE_INDEX, "Index keys cannot be empty.");
            }
            if (indexOptions.isBackground()) {
                throw new CommandFailed("createIndexes", "Building index in background is not supported right now");
            }
            if (indexOptions.isSparse()) {
                throw new CommandFailed("createIndexes", "Sparse index are not supported right now");
            }
            List<IndexFieldInfo> fields = new ArrayList<>(indexOptions.getKeys().size());
            for (IndexOptions.Key indexKey : indexOptions.getKeys()) {
                AttributeReference.Builder attRefBuilder = new AttributeReference.Builder();
                for (String key : indexKey.getKeys()) {
                    attRefBuilder.addObjectKey(key);
                }
                IndexType indexType = indexKey.getType();
                if (!KnownType.contains(indexType)) {
                    return Status.from(ErrorCode.CANNOT_CREATE_INDEX, "bad index key pattern: Unknown index plugin '" + indexKey.getType().getName() + "'");
                }
                Optional<FieldIndexOrdering> ordering = indexType.accept(filedIndexOrderingConverterVisitor, null);
                if (!ordering.isPresent()) {
                    throw new CommandFailed("createIndexes", "Index of type " + indexType.getName() + " is not supported right now");
                }
                fields.add(new IndexFieldInfo(attRefBuilder.build(), ordering.get().isAscending()));
            }
            if (context.getTorodTransaction().createIndex(req.getDatabase(), arg.getCollection(), indexOptions.getName(), fields, indexOptions.isUnique())) {
                indexesAfter++;
            }
        }
        String note = null;
        if (indexesAfter == indexesBefore) {
            note = "all indexes already exist";
        }
        return Status.ok(new CreateIndexesResult(indexesBefore, indexesAfter, note, createdCollectionAutomatically));
    } catch (UserException ex) {
        return Status.from(ErrorCode.COMMAND_FAILED, ex.getLocalizedMessage());
    } catch (CommandFailed ex) {
        return Status.from(ex);
    }
}
Also used : IndexOptions(com.torodb.mongodb.commands.pojos.index.IndexOptions) AttributeReference(com.torodb.core.language.AttributeReference) ObjectKey(com.torodb.core.language.AttributeReference.ObjectKey) ArrayList(java.util.ArrayList) CreateIndexesResult(com.torodb.mongodb.commands.signatures.admin.CreateIndexesCommand.CreateIndexesResult) CommandFailed(com.eightkdata.mongowp.exceptions.CommandFailed) IndexFieldInfo(com.torodb.torod.IndexFieldInfo) UserException(com.torodb.core.exceptions.user.UserException) AscIndexType(com.torodb.mongodb.commands.pojos.index.type.AscIndexType) DescIndexType(com.torodb.mongodb.commands.pojos.index.type.DescIndexType) IndexType(com.torodb.mongodb.commands.pojos.index.type.IndexType) FieldIndexOrdering(com.torodb.core.transaction.metainf.FieldIndexOrdering)

Example 5 with IndexOptions

use of com.torodb.mongodb.commands.pojos.index.IndexOptions in project torodb by torodb.

the class OplogOperationApplier method insertIndex.

private void insertIndex(BsonDocument indexDoc, String database, ExclusiveWriteMongodTransaction trans) throws OplogApplyingException {
    try {
        CreateIndexesCommand command = CreateIndexesCommand.INSTANCE;
        IndexOptions indexOptions = IndexOptions.unmarshall(indexDoc);
        CreateIndexesArgument arg = new CreateIndexesArgument(indexOptions.getCollection(), Arrays.asList(new IndexOptions[] { indexOptions }));
        Status executionResult = executeReplCommand(database, command, arg, trans.getTorodTransaction());
        if (!executionResult.isOk()) {
            throw new OplogApplyingException(new MongoException(executionResult));
        }
    } catch (MongoException ex) {
        throw new OplogApplyingException(ex);
    }
}
Also used : Status(com.eightkdata.mongowp.Status) MongoException(com.eightkdata.mongowp.exceptions.MongoException) CreateIndexesArgument(com.torodb.mongodb.commands.signatures.admin.CreateIndexesCommand.CreateIndexesArgument) IndexOptions(com.torodb.mongodb.commands.pojos.index.IndexOptions) CreateIndexesCommand(com.torodb.mongodb.commands.signatures.admin.CreateIndexesCommand)

Aggregations

IndexOptions (com.torodb.mongodb.commands.pojos.index.IndexOptions)6 MongoException (com.eightkdata.mongowp.exceptions.MongoException)3 UserException (com.torodb.core.exceptions.user.UserException)3 CreateIndexesArgument (com.torodb.mongodb.commands.signatures.admin.CreateIndexesCommand.CreateIndexesArgument)3 CreateIndexesResult (com.torodb.mongodb.commands.signatures.admin.CreateIndexesCommand.CreateIndexesResult)3 ArrayList (java.util.ArrayList)3 Request (com.eightkdata.mongowp.server.api.Request)2 AttributeReference (com.torodb.core.language.AttributeReference)2 ObjectKey (com.torodb.core.language.AttributeReference.ObjectKey)2 FieldIndexOrdering (com.torodb.core.transaction.metainf.FieldIndexOrdering)2 AscIndexType (com.torodb.mongodb.commands.pojos.index.type.AscIndexType)2 DescIndexType (com.torodb.mongodb.commands.pojos.index.type.DescIndexType)2 IndexType (com.torodb.mongodb.commands.pojos.index.type.IndexType)2 IndexFieldInfo (com.torodb.torod.IndexFieldInfo)2 Status (com.eightkdata.mongowp.Status)1 CommandFailed (com.eightkdata.mongowp.exceptions.CommandFailed)1 HostAndPort (com.google.common.net.HostAndPort)1 UnsupportedCompoundIndexException (com.torodb.core.exceptions.user.UnsupportedCompoundIndexException)1 UnsupportedUniqueIndexException (com.torodb.core.exceptions.user.UnsupportedUniqueIndexException)1 CreateIndexesCommand (com.torodb.mongodb.commands.signatures.admin.CreateIndexesCommand)1