use of com.eightkdata.mongowp.server.api.Command in project torodb by torodb.
the class FindImplementation method apply.
@Override
public Status<FindResult> apply(Request req, Command<? super FindArgument, ? super FindResult> command, FindArgument arg, MongodTransaction context) {
logFindCommand(arg);
BsonDocument filter = arg.getFilter();
Cursor<BsonDocument> cursor;
switch(filter.size()) {
case 0:
{
cursor = context.getTorodTransaction().findAll(req.getDatabase(), arg.getCollection()).asDocCursor().transform(t -> t.getRoot()).transform(ToBsonDocumentTranslator.getInstance());
break;
}
case 1:
{
try {
cursor = getByAttributeCursor(context.getTorodTransaction(), req.getDatabase(), arg.getCollection(), filter).transform(ToBsonDocumentTranslator.getInstance());
} catch (CommandFailed ex) {
return Status.from(ex);
}
break;
}
default:
{
return Status.from(ErrorCode.COMMAND_FAILED, "The given query is not supported right now");
}
}
if (Long.valueOf(arg.getBatchSize()) > (long) Integer.MAX_VALUE) {
return Status.from(ErrorCode.COMMAND_FAILED, "Only batchSize equals or lower than " + Integer.MAX_VALUE + " is supported");
}
OptionalLong batchSize = arg.getEffectiveBatchSize();
List<BsonDocument> batch = cursor.getNextBatch(batchSize.isPresent() ? (int) batchSize.getAsLong() : 101);
cursor.close();
return Status.ok(new FindResult(CursorResult.createSingleBatchCursor(req.getDatabase(), arg.getCollection(), batch.iterator())));
}
use of com.eightkdata.mongowp.server.api.Command in project torodb by torodb.
the class UpdateImplementation method apply.
@Override
public Status<UpdateResult> apply(Request req, Command<? super UpdateArgument, ? super UpdateResult> command, UpdateArgument arg, WriteMongodTransaction context) {
UpdateStatus updateStatus = new UpdateStatus();
try {
if (!context.getTorodTransaction().existsCollection(req.getDatabase(), arg.getCollection())) {
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);
}
for (UpdateStatement updateStatement : arg.getStatements()) {
BsonDocument query = updateStatement.getQuery();
UpdateAction updateAction = UpdateActionTranslator.translate(updateStatement.getUpdate());
Cursor<ToroDocument> candidatesCursor;
switch(query.size()) {
case 0:
{
candidatesCursor = context.getTorodTransaction().findAll(req.getDatabase(), arg.getCollection()).asDocCursor();
break;
}
case 1:
{
try {
candidatesCursor = findByAttribute(context.getTorodTransaction(), req.getDatabase(), arg.getCollection(), query);
} catch (CommandFailed ex) {
return Status.from(ex);
}
break;
}
default:
{
return Status.from(ErrorCode.COMMAND_FAILED, "The given query is not supported right now");
}
}
if (candidatesCursor.hasNext()) {
try {
Stream<List<ToroDocument>> candidatesbatchStream;
if (updateStatement.isMulti()) {
candidatesbatchStream = StreamSupport.stream(Spliterators.spliteratorUnknownSize(candidatesCursor.batch(100), Spliterator.ORDERED), false);
} else {
candidatesbatchStream = Stream.of(ImmutableList.of(candidatesCursor.next()));
}
Stream<KvDocument> updatedCandidates = candidatesbatchStream.map(candidates -> {
updateStatus.increaseCandidates(candidates.size());
context.getTorodTransaction().delete(req.getDatabase(), arg.getCollection(), candidates);
return candidates;
}).flatMap(l -> l.stream()).map(candidate -> {
try {
updateStatus.increaseUpdated();
return update(updateAction, candidate);
} catch (UserException userException) {
throw new UserWrappedException(userException);
}
});
context.getTorodTransaction().insert(req.getDatabase(), arg.getCollection(), updatedCandidates);
} catch (UserWrappedException userWrappedException) {
throw userWrappedException.getCause();
}
} else if (updateStatement.isUpsert()) {
KvDocument toInsertCandidate;
if (updateAction instanceof SetDocumentUpdateAction) {
toInsertCandidate = ((SetDocumentUpdateAction) updateAction).getNewValue();
} else {
toInsertCandidate = update(updateAction, new ToroDocument(-1, (KvDocument) MongoWpConverter.translate(query)));
}
if (!toInsertCandidate.containsKey(Constants.ID)) {
KvDocument.Builder builder = new KvDocument.Builder();
for (DocEntry<?> entry : toInsertCandidate) {
builder.putValue(entry.getKey(), entry.getValue());
}
builder.putValue(Constants.ID, MongoWpConverter.translate(objectIdFactory.consumeObjectId()));
toInsertCandidate = builder.build();
}
updateStatus.increaseCandidates(1);
updateStatus.increaseCreated(toInsertCandidate.get(Constants.ID));
Stream<KvDocument> toInsertCandidates = Stream.of(toInsertCandidate);
context.getTorodTransaction().insert(req.getDatabase(), arg.getCollection(), toInsertCandidates);
}
}
} catch (UserException ex) {
//TODO: Improve error reporting
return Status.from(ErrorCode.COMMAND_FAILED, ex.getLocalizedMessage());
}
mongodMetrics.getUpdateModified().mark(updateStatus.updated);
mongodMetrics.getUpdateMatched().mark(updateStatus.candidates);
mongodMetrics.getUpdateUpserted().mark(updateStatus.upsertResults.size());
return Status.ok(new UpdateResult(updateStatus.updated, updateStatus.candidates, ImmutableList.copyOf(updateStatus.upsertResults)));
}
use of com.eightkdata.mongowp.server.api.Command in project torodb by torodb.
the class DropIndexesImplementation method apply.
@Override
public Status<DropIndexesResult> apply(Request req, Command<? super DropIndexesArgument, ? super DropIndexesResult> command, DropIndexesArgument arg, WriteMongodTransaction context) {
int indexesBefore = (int) context.getTorodTransaction().getIndexesInfo(req.getDatabase(), arg.getCollection()).count();
List<String> indexesToDrop;
if (!arg.isDropAllIndexes()) {
if (!arg.isDropByKeys()) {
if (Constants.ID_INDEX.equals(arg.getIndexToDrop())) {
return Status.from(ErrorCode.INVALID_OPTIONS, "cannot drop _id index");
}
indexesToDrop = Arrays.asList(arg.getIndexToDrop());
} else {
if (arg.getKeys().stream().anyMatch(key -> !(KnownType.contains(key.getType())) || (key.getType() != KnownType.asc.getIndexType() && key.getType() != KnownType.desc.getIndexType()))) {
return getStatusForIndexNotFoundWithKeys(arg);
}
indexesToDrop = context.getTorodTransaction().getIndexesInfo(req.getDatabase(), arg.getCollection()).filter(index -> indexFieldsMatchKeys(index, arg.getKeys())).map(index -> index.getName()).collect(Collectors.toList());
if (indexesToDrop.isEmpty()) {
return getStatusForIndexNotFoundWithKeys(arg);
}
}
} else {
indexesToDrop = context.getTorodTransaction().getIndexesInfo(req.getDatabase(), arg.getCollection()).filter(indexInfo -> !Constants.ID_INDEX.equals(indexInfo.getName())).map(indexInfo -> indexInfo.getName()).collect(Collectors.toList());
}
for (String indexToDrop : indexesToDrop) {
boolean dropped = context.getTorodTransaction().dropIndex(req.getDatabase(), arg.getCollection(), indexToDrop);
if (!dropped) {
return Status.from(ErrorCode.INDEX_NOT_FOUND, "index not found with name [" + indexToDrop + "]");
}
}
return Status.ok(new DropIndexesResult(indexesBefore));
}
use of com.eightkdata.mongowp.server.api.Command in project torodb by torodb.
the class ServerStatusImplementation method apply.
@Override
public Status<ServerStatusReply> apply(Request req, Command<? super ServerStatusArgument, ? super ServerStatusReply> command, ServerStatusArgument arg, MongodConnection context) {
ServerStatusReply.Builder replyBuilder = new ServerStatusReply.Builder();
//TODO: improve and complete
if (arg.isHost()) {
try {
replyBuilder.setHost(InetAddress.getLocalHost().getHostName() + ":" + selfHostAndPort.getPort());
} catch (Throwable throwable) {
replyBuilder.setHost("localhost:" + selfHostAndPort.getPort());
}
}
if (arg.isVersion()) {
replyBuilder.setVersion(MongoLayerConstants.VERSION_STRING);
}
if (arg.isProcess()) {
replyBuilder.setProcess("mongod");
}
if (arg.isPid()) {
try {
replyBuilder.setPid(Integer.valueOf(ManagementFactory.getRuntimeMXBean().getName().split("@")[0]));
} catch (Throwable throwable) {
LOGGER.warn("Cannot get PID: " + throwable.getMessage());
}
}
if (arg.isUptime()) {
replyBuilder.setUptime(ManagementFactory.getRuntimeMXBean().getUptime());
}
if (arg.isUptimeEstimate()) {
replyBuilder.setUptimeEstimate(ManagementFactory.getRuntimeMXBean().getUptime());
}
if (arg.isLocalTime()) {
replyBuilder.setLocalTime(Instant.now());
}
if (arg.isLocks()) {
Locks.Count dummyCount = new Locks.Count(0, 0, 0, 0);
Locks.Lock dummyLock = new Locks.Lock(dummyCount, dummyCount, dummyCount, dummyCount);
replyBuilder.setLocks(new Locks(dummyLock, dummyLock, dummyLock, dummyLock, dummyLock, dummyLock));
}
if (arg.isGlobalLock()) {
GlobalLock.GlobalLockStats dummyGlobalLockStats = new GlobalLock.GlobalLockStats(0, 0, 0);
replyBuilder.setGlobalLock(new GlobalLock(0, dummyGlobalLockStats, dummyGlobalLockStats));
}
if (arg.isMem()) {
replyBuilder.setMem(new Mem(0, 0, 0, false, 0, 0, ""));
}
if (arg.isConnections()) {
replyBuilder.setConnections(new Connections(0, 0, 0));
}
if (arg.isExtraInfo()) {
replyBuilder.setExtraInfo(new ExtraInfo("", 0, 0));
}
if (arg.isBackgroundFlushing()) {
replyBuilder.setBackgroundFlushing(new BackgroundFlushing(0, 0, 0, 0, Instant.now()));
}
if (arg.isCursors()) {
replyBuilder.setCursors(new Cursors("", 0, 0, 0, 0, 0));
}
if (arg.isNetwork()) {
replyBuilder.setNetwork(new Network(0, 0, 0));
}
//}
if (arg.isOpcountersRepl()) {
replyBuilder.setOpcountersRepl(new Opcounters(0, 0, 0, 0, 0, 0));
}
if (arg.isOpcounters()) {
replyBuilder.setOpcounters(new Opcounters(0, 0, 0, 0, 0, 0));
}
if (arg.isRangeDeleter()) {
ImmutableList.Builder<RangeDeleter.LastDeletedStat> builder = ImmutableList.builder();
replyBuilder.setRangeDeleter(new RangeDeleter(builder.build()));
}
if (arg.isSecurity()) {
replyBuilder.setSecurity(new Security(null, false, null));
}
if (arg.isStorageEngine()) {
replyBuilder.setStorageEngine(new StorageEngine("ToroDB"));
}
if (arg.isAsserts()) {
replyBuilder.setAsserts(new Asserts(0, 0, 0, 0, 0));
}
if (arg.isDur()) {
replyBuilder.setDur(new Dur(0, 0, 0, 0, 0, 0, new Dur.TimeMs(0, 0, 0, 0, 0, 0, 0)));
}
if (arg.isWriteBacksQueued()) {
replyBuilder.setWritebacksQueued(0);
}
if (arg.isMetrics()) {
ImmutableList.Builder<Metrics.Command> builder = ImmutableList.builder();
Metrics.Stats dummyStats = new Metrics.Stats(0, 0);
replyBuilder.setMetrics(new Metrics(builder.build(), new Metrics.Document(0, 0, 0, 0), new Metrics.GetLastError(dummyStats, 0), new Metrics.Operation(0, 0, 0), new Metrics.QueryExecutor(0), new Metrics.Record(0), new Metrics.Repl(new Metrics.Repl.Apply(dummyStats, 0), new Metrics.Repl.Buffer(0, 0, 0), new Metrics.Repl.Network(0, dummyStats, 0, 0), new Metrics.Repl.Oplog(dummyStats, 0), new Metrics.Repl.Preload(dummyStats, dummyStats)), new Metrics.Storage(new Metrics.Storage.Freelist(new Metrics.Storage.Freelist.Search(0, 0, 0))), new Metrics.Ttl(0, 0)));
}
return Status.ok(replyBuilder.build());
}
use of com.eightkdata.mongowp.server.api.Command in project torodb by torodb.
the class DropIndexesReplImpl method apply.
@Override
public Status<DropIndexesResult> apply(Request req, Command<? super DropIndexesArgument, ? super DropIndexesResult> command, DropIndexesArgument arg, SharedWriteTorodTransaction trans) {
int indexesBefore = (int) trans.getIndexesInfo(req.getDatabase(), arg.getCollection()).count();
List<String> indexesToDrop;
if (!arg.isDropAllIndexes()) {
if (!arg.isDropByKeys()) {
if (Constants.ID_INDEX.equals(arg.getIndexToDrop())) {
LOGGER.warn("Trying to drop index {}. Ignoring the whole request", arg.getIndexToDrop());
return Status.ok(new DropIndexesResult(indexesBefore));
}
indexesToDrop = Arrays.asList(arg.getIndexToDrop());
} else {
indexesToDrop = trans.getIndexesInfo(req.getDatabase(), arg.getCollection()).filter(index -> indexFieldsMatchKeys(index, arg.getKeys())).map(index -> index.getName()).collect(Collectors.toList());
if (indexesToDrop.isEmpty()) {
LOGGER.warn("Index not found with keys [" + arg.getKeys().stream().map(key -> '"' + key.getKeys().stream().collect(Collectors.joining(".")) + "\" :" + key.getType().getName()).collect(Collectors.joining(", ")) + "]. Ignoring the whole request", arg.getIndexToDrop());
return Status.ok(new DropIndexesResult(indexesBefore));
}
}
} else {
indexesToDrop = trans.getIndexesInfo(req.getDatabase(), arg.getCollection()).filter(indexInfo -> !Constants.ID_INDEX.equals(indexInfo.getName())).map(indexInfo -> indexInfo.getName()).collect(Collectors.toList());
}
for (String indexToDrop : indexesToDrop) {
LOGGER.info("Dropping index {} on collection {}.{}", req.getDatabase(), arg.getCollection(), indexToDrop);
boolean dropped = trans.dropIndex(req.getDatabase(), arg.getCollection(), indexToDrop);
if (!dropped) {
LOGGER.info("Trying to drop index {}, but it has not been " + "found. This is normal since the index could have been filtered or " + "we are reapplying oplog during a recovery. Ignoring it", indexToDrop);
}
}
return Status.ok(new DropIndexesResult(indexesBefore));
}
Aggregations