io.helidon.dbclient.mongodb.MongoDbCommandExecutor Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of helidon-dbclient-mongodb Show documentation
Show all versions of helidon-dbclient-mongodb Show documentation
Helidon Database Client MongoDB Support
/*
* Copyright (c) 2019, 2020 Oracle and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.helidon.dbclient.mongodb;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import java.util.concurrent.Flow;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Logger;
import io.helidon.common.reactive.Multi;
import io.helidon.common.reactive.Single;
import io.helidon.dbclient.DbClientServiceContext;
import io.helidon.dbclient.DbRow;
import io.helidon.dbclient.DbStatementType;
import io.helidon.dbclient.common.DbClientContext;
import com.mongodb.reactivestreams.client.MongoDatabase;
import org.bson.Document;
import org.reactivestreams.Publisher;
import static io.helidon.dbclient.mongodb.MongoDbStatement.READER_FACTORY;
/**
* Executes Mongo specific database command and returns result.
* Utility class with static methods only.
*/
final class MongoDbCommandExecutor {
/** Local logger instance. */
private static final Logger LOGGER = Logger.getLogger(MongoDbCommandExecutor.class.getName());
private MongoDbCommandExecutor() {
throw new UnsupportedOperationException("Utility class MongoDbCommandExecutor instances are not allowed!");
}
static Multi executeCommand(MongoDbStatement dbStatement,
CompletionStage dbContextFuture,
CompletableFuture statementFuture,
CompletableFuture commandFuture) {
dbContextFuture.exceptionally(throwable -> {
statementFuture.completeExceptionally(throwable);
commandFuture.completeExceptionally(throwable);
return null;
});
CompletionStage mongoStmtFuture = dbContextFuture.thenApply(dbContext -> {
MongoDbStatement.MongoStatement stmt
= new MongoDbStatement.MongoStatement(DbStatementType.COMMAND, READER_FACTORY, dbStatement.build());
if (stmt.getOperation() == MongoDbStatement.MongoOperation.COMMAND) {
return stmt;
} else {
throw new UnsupportedOperationException(
String.format("Operation %s is not supported", stmt.getOperation().toString()));
}
});
return executeCommandInMongoDB(dbStatement, mongoStmtFuture, statementFuture, commandFuture);
}
private static Multi executeCommandInMongoDB(MongoDbStatement dbStatement,
CompletionStage stmtFuture,
CompletableFuture statementFuture,
CompletableFuture commandFuture) {
return Single.create(stmtFuture)
.flatMap(mongoStmt -> callStatement(dbStatement, mongoStmt, statementFuture, commandFuture));
}
private static Flow.Publisher callStatement(MongoDbStatement dbStatement,
MongoDbStatement.MongoStatement mongoStmt,
CompletableFuture statementFuture,
CompletableFuture commandFuture) {
MongoDatabase db = dbStatement.db();
Document command = mongoStmt.getQuery();
LOGGER.fine(() -> String.format("Command: %s", command.toString()));
Publisher publisher = dbStatement.noTx()
? db.runCommand(command)
: db.runCommand(dbStatement.txManager().tx(), command);
return new CommandRows(publisher,
dbStatement,
statementFuture,
commandFuture)
.publisher();
}
static final class CommandRows {
private final AtomicBoolean resultRequested = new AtomicBoolean(false);
private final Publisher publisher;
private final DbClientContext clientContext;
private final MongoDbStatement dbStatement;
private final CompletableFuture statementFuture;
private final CompletableFuture commandFuture;
CommandRows(Publisher publisher,
MongoDbStatement dbStatement,
CompletableFuture statementFuture,
CompletableFuture commandFuture) {
this.clientContext = dbStatement.clientContext();
this.publisher = publisher;
this.dbStatement = dbStatement;
this.statementFuture = statementFuture;
this.commandFuture = commandFuture;
}
public Flow.Publisher publisher() {
checkResult();
return toDbPublisher();
}
private Flow.Publisher toDbPublisher() {
MongoDbQueryProcessor qp = new MongoDbQueryProcessor(clientContext,
dbStatement,
statementFuture,
commandFuture);
publisher.subscribe(qp);
return qp;
}
private void checkResult() {
if (resultRequested.get()) {
throw new IllegalStateException("Result has already been requested");
}
resultRequested.set(true);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy