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