diff --git a/driver-core/src/main/com/mongodb/ClientBulkWriteException.java b/driver-core/src/main/com/mongodb/ClientBulkWriteException.java new file mode 100644 index 00000000000..b964961d754 --- /dev/null +++ b/driver-core/src/main/com/mongodb/ClientBulkWriteException.java @@ -0,0 +1,138 @@ +/* + * Copyright 2008-present MongoDB, Inc. + * + * 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 com.mongodb; + +import com.mongodb.bulk.WriteConcernError; +import com.mongodb.client.model.bulk.ClientBulkWriteResult; +import com.mongodb.client.model.bulk.ClientNamespacedWriteModel; +import com.mongodb.lang.Nullable; + +import java.util.List; +import java.util.Map; +import java.util.Optional; + +import static com.mongodb.assertions.Assertions.isTrueArgument; +import static java.util.Collections.emptyList; +import static java.util.Collections.emptyMap; +import static java.util.Collections.unmodifiableList; +import static java.util.Collections.unmodifiableMap; +import static java.util.Optional.ofNullable; + +/** + * The result of an unsuccessful or partially unsuccessful client-level bulk write operation. + * Note that the {@linkplain #getCode() code} and {@linkplain #getErrorLabels() labels} from this exception are not useful. + * An application should use those from the {@linkplain #getError() top-level error}. + * + * @see ClientBulkWriteResult + * @since 5.3 + * @serial exclude + */ +public final class ClientBulkWriteException extends MongoServerException { + private static final long serialVersionUID = 1; + + @Nullable + private final MongoException error; + private final List writeConcernErrors; + private final Map writeErrors; + @Nullable + private final ClientBulkWriteResult partialResult; + + /** + * Constructs a new instance. + * + * @param error The {@linkplain #getError() top-level error}. + * @param writeConcernErrors The {@linkplain #getWriteConcernErrors() write concern errors}. + * @param writeErrors The {@linkplain #getWriteErrors() write errors}. + * @param partialResult The {@linkplain #getPartialResult() partial result}. + * @param serverAddress The {@linkplain MongoServerException#getServerAddress() server address}. + */ + public ClientBulkWriteException( + @Nullable final MongoException error, + @Nullable final List writeConcernErrors, + @Nullable final Map writeErrors, + @Nullable final ClientBulkWriteResult partialResult, + final ServerAddress serverAddress) { + super(message(error, writeConcernErrors, writeErrors, partialResult, serverAddress), serverAddress); + isTrueArgument("At least one of `writeConcernErrors`, `writeErrors`, `partialResult` must be non-null or non-empty", + !(writeConcernErrors == null || writeConcernErrors.isEmpty()) + || !(writeErrors == null || writeErrors.isEmpty()) + || partialResult != null); + this.error = error; + this.writeConcernErrors = writeConcernErrors == null ? emptyList() : unmodifiableList(writeConcernErrors); + this.writeErrors = writeErrors == null ? emptyMap() : unmodifiableMap(writeErrors); + this.partialResult = partialResult; + } + + private static String message( + @Nullable final MongoException error, + @Nullable final List writeConcernErrors, + @Nullable final Map writeErrors, + @Nullable final ClientBulkWriteResult partialResult, + final ServerAddress serverAddress) { + return "Client-level bulk write operation error on server " + serverAddress + "." + + (error == null ? "" : " Top-level error: " + error + ".") + + (writeErrors == null || writeErrors.isEmpty() ? "" : " Write errors: " + writeErrors + ".") + + (writeConcernErrors == null || writeConcernErrors.isEmpty() ? "" : " Write concern errors: " + writeConcernErrors + ".") + + (partialResult == null ? "" : " Partial result: " + partialResult + "."); + } + + /** + * The top-level error. That is an error that is neither a {@linkplain #getWriteConcernErrors() write concern error}, + * nor is an {@linkplain #getWriteErrors() error of an individual write operation}. + * + * @return The top-level error. {@linkplain Optional#isPresent() Present} only if a top-level error occurred. + */ + public Optional getError() { + return ofNullable(error); + } + + /** + * The {@link WriteConcernError}s that occurred while executing the client-level bulk write operation. + *

+ * There are no guarantees on mutability of the {@link List} returned.

+ * + * @return The {@link WriteConcernError}s. + */ + public List getWriteConcernErrors() { + return writeConcernErrors; + } + + /** + * The indexed {@link WriteError}s. + * The {@linkplain Map#keySet() keys} are the indexes of the corresponding {@link ClientNamespacedWriteModel}s + * in the corresponding client-level bulk write operation. + *

+ * There are no guarantees on mutability or iteration order of the {@link Map} returned.

+ * + * @return The indexed {@link WriteError}s. + * @see ClientBulkWriteResult.VerboseResults#getInsertResults() + * @see ClientBulkWriteResult.VerboseResults#getUpdateResults() + * @see ClientBulkWriteResult.VerboseResults#getDeleteResults() + */ + public Map getWriteErrors() { + return writeErrors; + } + + /** + * The result of the part of a client-level bulk write operation that is known to be successful. + * + * @return The successful partial result. {@linkplain Optional#isPresent() Present} only if the client received a response indicating success + * of at least one {@linkplain ClientNamespacedWriteModel individual write operation}. + */ + public Optional getPartialResult() { + return ofNullable(partialResult); + } +} diff --git a/driver-core/src/main/com/mongodb/client/model/bulk/ClientBulkWriteOptions.java b/driver-core/src/main/com/mongodb/client/model/bulk/ClientBulkWriteOptions.java new file mode 100644 index 00000000000..942a37c43df --- /dev/null +++ b/driver-core/src/main/com/mongodb/client/model/bulk/ClientBulkWriteOptions.java @@ -0,0 +1,90 @@ +/* + * Copyright 2008-present MongoDB, Inc. + * + * 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 com.mongodb.client.model.bulk; + +import com.mongodb.annotations.Sealed; +import com.mongodb.client.model.Filters; +import com.mongodb.internal.client.model.bulk.ConcreteClientBulkWriteOptions; +import com.mongodb.lang.Nullable; +import org.bson.BsonValue; +import org.bson.conversions.Bson; + +/** + * The options to apply when executing a client-level bulk write operation. + * + * @since 5.3 + */ +@Sealed +public interface ClientBulkWriteOptions { + /** + * Creates the default options. + * + * @return The default options. + */ + static ClientBulkWriteOptions clientBulkWriteOptions() { + return new ConcreteClientBulkWriteOptions(); + } + + /** + * Enables or disables ordered execution of {@linkplain ClientNamespacedWriteModel individual write operations}. + * In an ordered execution a failure of an individual operation prevents the rest of them + * from being executed. + * In an unordered execution failures of individual operations do not prevent the rest of them + * from being executed. + * + * @param ordered The ordered flag. If {@code null}, the client defaults to {@code true}. + * @return {@code this}. + */ + ClientBulkWriteOptions ordered(@Nullable Boolean ordered); + + /** + * Disables or enables checking against document validation rules, a.k.a., schema validation. + * + * @param bypassDocumentValidation The flag specifying whether to bypass the document validation rules. + * {@code null} represents the server default. + * @return {@code this}. + */ + ClientBulkWriteOptions bypassDocumentValidation(@Nullable Boolean bypassDocumentValidation); + + /** + * Sets variables that can be referenced from {@linkplain ClientNamespacedWriteModel individual write operations} + * with the {@code "$$"} syntax, which in turn requires using {@link Filters#expr(Object)} when specifying filters. + * Values must be constants or expressions that do not reference fields. + * + * @param let The variables. {@code null} represents the server default. + * @return {@code this}. + * @mongodb.driver.manual reference/aggregation-variables/ Variables in Aggregation Expressions + */ + ClientBulkWriteOptions let(@Nullable Bson let); + + /** + * Sets the comment to attach to the {@code bulkWrite} administration command. + * + * @param comment The comment. {@code null} represents the server default. + * @return {@code this}. + */ + ClientBulkWriteOptions comment(@Nullable BsonValue comment); + + /** + * Enables or disables requesting {@linkplain ClientBulkWriteResult#getVerboseResults() verbose results}. + * + * @param verboseResults The flag specifying whether to request verbose results. + * If {@code null}, the client defaults to {@code false}. + * This value corresponds inversely to the {@code errorsOnly} field of the {@code bulkWrite} administration command. + * @return {@code this}. + */ + ClientBulkWriteOptions verboseResults(@Nullable Boolean verboseResults); +} diff --git a/driver-core/src/main/com/mongodb/client/model/bulk/ClientBulkWriteResult.java b/driver-core/src/main/com/mongodb/client/model/bulk/ClientBulkWriteResult.java new file mode 100644 index 00000000000..04257cb8460 --- /dev/null +++ b/driver-core/src/main/com/mongodb/client/model/bulk/ClientBulkWriteResult.java @@ -0,0 +1,136 @@ +/* + * Copyright 2008-present MongoDB, Inc. + * + * 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 com.mongodb.client.model.bulk; + +import com.mongodb.ClientBulkWriteException; +import com.mongodb.WriteConcern; +import com.mongodb.annotations.Evolving; + +import java.util.Map; +import java.util.Optional; + +/** + * The result of a successful or partially successful client-level bulk write operation. + * Note that if a client-level bulk write operation fails while some of the + * {@linkplain ClientNamespacedWriteModel individual write operations} are known to be successful, + * then the successful partial result is still accessible via {@link ClientBulkWriteException#getPartialResult()}. + * + * @see ClientBulkWriteException + * @since 5.3 + */ +@Evolving +public interface ClientBulkWriteResult { + /** + * Indicates whether this result was {@linkplain WriteConcern#isAcknowledged() acknowledged}. + * If not, then all other methods throw {@link UnsupportedOperationException}. + * + * @return Whether this result was acknowledged. + */ + boolean isAcknowledged(); + + /** + * The number of documents that were inserted across all insert operations. + * + * @return The number of documents that were inserted. + * @throws UnsupportedOperationException If this result is not {@linkplain #isAcknowledged() acknowledged}. + */ + long getInsertedCount(); + + /** + * The number of documents that were upserted across all update and replace operations. + * + * @return The number of documents that were upserted. + * @throws UnsupportedOperationException If this result is not {@linkplain #isAcknowledged() acknowledged}. + */ + long getUpsertedCount(); + + /** + * The number of documents that matched the filters across all operations with filters. + * + * @return The number of documents that were matched. + * @throws UnsupportedOperationException If this result is not {@linkplain #isAcknowledged() acknowledged}. + */ + long getMatchedCount(); + + /** + * The number of documents that were modified across all update and replace operations. + * + * @return The number of documents that were modified. + * @throws UnsupportedOperationException If this result is not {@linkplain #isAcknowledged() acknowledged}. + */ + long getModifiedCount(); + + /** + * The number of documents that were deleted across all delete operations. + * + * @return The number of documents that were deleted. + * @throws UnsupportedOperationException If this result is not {@linkplain #isAcknowledged() acknowledged}. + */ + long getDeletedCount(); + + /** + * The verbose results of individual operations. + * + * @return {@link Optional} verbose results of individual operations. + * @throws UnsupportedOperationException If this result is not {@linkplain #isAcknowledged() acknowledged}. + * @see ClientBulkWriteOptions#verboseResults(Boolean) + */ + Optional getVerboseResults(); + + /** + * The {@linkplain ClientBulkWriteResult#getVerboseResults() verbose results} of individual operations. + * + * @since 5.3 + */ + @Evolving + interface VerboseResults { + /** + * The indexed {@link ClientInsertOneResult}s. + * The {@linkplain Map#keySet() keys} are the indexes of the corresponding {@link ClientNamespacedWriteModel}s + * in the client-level bulk write operation. + *

+ * There are no guarantees on mutability or iteration order of the {@link Map} returned.

+ * + * @return The indexed {@link ClientInsertOneResult}s. + * @see ClientBulkWriteException#getWriteErrors() + */ + Map getInsertResults(); + + /** + * The indexed {@link ClientUpdateResult}s. + * The {@linkplain Map#keySet() keys} are the indexes of the corresponding {@link ClientNamespacedWriteModel}s + * in the client-level bulk write operation. + *

+ * There are no guarantees on mutability or iteration order of the {@link Map} returned.

+ * + * @return The indexed {@link ClientUpdateResult}s. + * @see ClientBulkWriteException#getWriteErrors() + */ + Map getUpdateResults(); + + /** + * The indexed {@link ClientDeleteResult}s. + * The {@linkplain Map#keySet() keys} are the indexes of the corresponding {@link ClientNamespacedWriteModel}s + * in the client-level bulk write operation. + *

+ * There are no guarantees on mutability or iteration order of the {@link Map} returned.

+ * + * @return The indexed {@link ClientDeleteResult}s. + * @see ClientBulkWriteException#getWriteErrors() + */ + Map getDeleteResults(); + } +} diff --git a/driver-core/src/main/com/mongodb/client/model/bulk/ClientDeleteOptions.java b/driver-core/src/main/com/mongodb/client/model/bulk/ClientDeleteOptions.java new file mode 100644 index 00000000000..54b941776e0 --- /dev/null +++ b/driver-core/src/main/com/mongodb/client/model/bulk/ClientDeleteOptions.java @@ -0,0 +1,65 @@ +/* + * Copyright 2008-present MongoDB, Inc. + * + * 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 com.mongodb.client.model.bulk; + +import com.mongodb.annotations.Sealed; +import com.mongodb.client.model.Collation; +import com.mongodb.internal.client.model.bulk.ConcreteClientDeleteOptions; +import com.mongodb.lang.Nullable; +import org.bson.conversions.Bson; + +/** + * The options to apply when deleting documents. + * + * @since 5.3 + */ +@Sealed +public interface ClientDeleteOptions { + /** + * Creates the default options. + * + * @return The default options. + */ + static ClientDeleteOptions clientDeleteOptions() { + return new ConcreteClientDeleteOptions(); + } + + /** + * Sets the collation. + * + * @param collation The collation. {@code null} represents the server default. + * @return {@code this}. + */ + ClientDeleteOptions collation(@Nullable Collation collation); + + /** + * Sets the index specification, + * {@code null}-ifies {@linkplain #hintString(String) hint string}. + * + * @param hint The index specification. {@code null} represents the server default. + * @return {@code this}. + */ + ClientDeleteOptions hint(@Nullable Bson hint); + + /** + * Sets the index name, + * {@code null}-ifies {@linkplain #hint(Bson) hint}. + * + * @param hintString The index name. {@code null} represents the server default. + * @return {@code this}. + */ + ClientDeleteOptions hintString(@Nullable String hintString); +} diff --git a/driver-core/src/main/com/mongodb/client/model/bulk/ClientDeleteResult.java b/driver-core/src/main/com/mongodb/client/model/bulk/ClientDeleteResult.java new file mode 100644 index 00000000000..fcf66488114 --- /dev/null +++ b/driver-core/src/main/com/mongodb/client/model/bulk/ClientDeleteResult.java @@ -0,0 +1,35 @@ +/* + * Copyright 2008-present MongoDB, Inc. + * + * 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 com.mongodb.client.model.bulk; + +import com.mongodb.annotations.Evolving; +import com.mongodb.bulk.WriteConcernError; + +/** + * The result of a successful {@linkplain ClientNamespacedWriteModel individual delete operation}. + * Note that {@link WriteConcernError}s are not considered as making individual operations unsuccessful. + * + * @since 5.3 + */ +@Evolving +public interface ClientDeleteResult { + /** + * The number of documents that were deleted. + * + * @return The number of documents that were deleted. + */ + long getDeletedCount(); +} diff --git a/driver-core/src/main/com/mongodb/client/model/bulk/ClientInsertOneResult.java b/driver-core/src/main/com/mongodb/client/model/bulk/ClientInsertOneResult.java new file mode 100644 index 00000000000..960078c6be5 --- /dev/null +++ b/driver-core/src/main/com/mongodb/client/model/bulk/ClientInsertOneResult.java @@ -0,0 +1,42 @@ +/* + * Copyright 2008-present MongoDB, Inc. + * + * 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 com.mongodb.client.model.bulk; + +import com.mongodb.annotations.Evolving; +import com.mongodb.bulk.WriteConcernError; +import org.bson.BsonValue; +import org.bson.RawBsonDocument; + +import java.util.Optional; + +/** + * The result of a successful {@linkplain ClientNamespacedWriteModel individual insert one operation}. + * Note that {@link WriteConcernError}s are not considered as making individual operations unsuccessful. + * + * @since 5.3 + */ +@Evolving +public interface ClientInsertOneResult { + /** + * The {@code "_id"} of the inserted document. + * + * @return The {@code "_id"} of the inserted document. + * {@linkplain Optional#isPresent() Present} unless a {@link RawBsonDocument} is inserted, + * because the driver neither generates the missing {@code "_id"} field for a {@link RawBsonDocument}, + * nor does it read the {@code "_id"} field from a {@link RawBsonDocument} when inserting it. + */ + Optional getInsertedId(); +} diff --git a/driver-core/src/main/com/mongodb/client/model/bulk/ClientNamespacedDeleteManyModel.java b/driver-core/src/main/com/mongodb/client/model/bulk/ClientNamespacedDeleteManyModel.java new file mode 100644 index 00000000000..a4e445e5e86 --- /dev/null +++ b/driver-core/src/main/com/mongodb/client/model/bulk/ClientNamespacedDeleteManyModel.java @@ -0,0 +1,28 @@ +/* + * Copyright 2008-present MongoDB, Inc. + * + * 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 com.mongodb.client.model.bulk; + +import com.mongodb.annotations.Sealed; + +/** + * A model for deleting all documents matching a filter. + * + * @since 5.3 + */ +@Sealed +public interface ClientNamespacedDeleteManyModel extends ClientNamespacedWriteModel { +} diff --git a/driver-core/src/main/com/mongodb/client/model/bulk/ClientNamespacedDeleteOneModel.java b/driver-core/src/main/com/mongodb/client/model/bulk/ClientNamespacedDeleteOneModel.java new file mode 100644 index 00000000000..0ba508007a6 --- /dev/null +++ b/driver-core/src/main/com/mongodb/client/model/bulk/ClientNamespacedDeleteOneModel.java @@ -0,0 +1,28 @@ +/* + * Copyright 2008-present MongoDB, Inc. + * + * 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 com.mongodb.client.model.bulk; + +import com.mongodb.annotations.Sealed; + +/** + * A model for deleting at most one document matching a filter. + * + * @since 5.3 + */ +@Sealed +public interface ClientNamespacedDeleteOneModel extends ClientNamespacedWriteModel { +} diff --git a/driver-core/src/main/com/mongodb/client/model/bulk/ClientNamespacedInsertOneModel.java b/driver-core/src/main/com/mongodb/client/model/bulk/ClientNamespacedInsertOneModel.java new file mode 100644 index 00000000000..66d9f39c74d --- /dev/null +++ b/driver-core/src/main/com/mongodb/client/model/bulk/ClientNamespacedInsertOneModel.java @@ -0,0 +1,28 @@ +/* + * Copyright 2008-present MongoDB, Inc. + * + * 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 com.mongodb.client.model.bulk; + +import com.mongodb.annotations.Sealed; + +/** + * A model for inserting a document. + * + * @since 5.3 + */ +@Sealed +public interface ClientNamespacedInsertOneModel extends ClientNamespacedWriteModel { +} diff --git a/driver-core/src/main/com/mongodb/client/model/bulk/ClientNamespacedReplaceOneModel.java b/driver-core/src/main/com/mongodb/client/model/bulk/ClientNamespacedReplaceOneModel.java new file mode 100644 index 00000000000..a4edf9b716a --- /dev/null +++ b/driver-core/src/main/com/mongodb/client/model/bulk/ClientNamespacedReplaceOneModel.java @@ -0,0 +1,28 @@ +/* + * Copyright 2008-present MongoDB, Inc. + * + * 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 com.mongodb.client.model.bulk; + +import com.mongodb.annotations.Sealed; + +/** + * A model for replacing at most one document matching a filter. + * + * @since 5.3 + */ +@Sealed +public interface ClientNamespacedReplaceOneModel extends ClientNamespacedWriteModel { +} diff --git a/driver-core/src/main/com/mongodb/client/model/bulk/ClientNamespacedUpdateManyModel.java b/driver-core/src/main/com/mongodb/client/model/bulk/ClientNamespacedUpdateManyModel.java new file mode 100644 index 00000000000..3900c8779f7 --- /dev/null +++ b/driver-core/src/main/com/mongodb/client/model/bulk/ClientNamespacedUpdateManyModel.java @@ -0,0 +1,28 @@ +/* + * Copyright 2008-present MongoDB, Inc. + * + * 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 com.mongodb.client.model.bulk; + +import com.mongodb.annotations.Sealed; + +/** + * A model for updating all documents matching a filter. + * + * @since 5.3 + */ +@Sealed +public interface ClientNamespacedUpdateManyModel extends ClientNamespacedWriteModel { +} diff --git a/driver-core/src/main/com/mongodb/client/model/bulk/ClientNamespacedUpdateOneModel.java b/driver-core/src/main/com/mongodb/client/model/bulk/ClientNamespacedUpdateOneModel.java new file mode 100644 index 00000000000..3d9e785004f --- /dev/null +++ b/driver-core/src/main/com/mongodb/client/model/bulk/ClientNamespacedUpdateOneModel.java @@ -0,0 +1,28 @@ +/* + * Copyright 2008-present MongoDB, Inc. + * + * 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 com.mongodb.client.model.bulk; + +import com.mongodb.annotations.Sealed; + +/** + * A model for updating at most one document matching a filter. + * + * @since 5.3 + */ +@Sealed +public interface ClientNamespacedUpdateOneModel extends ClientNamespacedWriteModel { +} diff --git a/driver-core/src/main/com/mongodb/client/model/bulk/ClientNamespacedWriteModel.java b/driver-core/src/main/com/mongodb/client/model/bulk/ClientNamespacedWriteModel.java new file mode 100644 index 00000000000..5a2e0a672c4 --- /dev/null +++ b/driver-core/src/main/com/mongodb/client/model/bulk/ClientNamespacedWriteModel.java @@ -0,0 +1,325 @@ +/* + * Copyright 2008-present MongoDB, Inc. + * + * 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 com.mongodb.client.model.bulk; + +import com.mongodb.MongoNamespace; +import com.mongodb.annotations.Sealed; +import com.mongodb.client.model.Aggregates; +import com.mongodb.client.model.Filters; +import com.mongodb.client.model.Updates; +import com.mongodb.internal.client.model.bulk.ConcreteClientDeleteManyModel; +import com.mongodb.internal.client.model.bulk.ConcreteClientDeleteOneModel; +import com.mongodb.internal.client.model.bulk.ConcreteClientInsertOneModel; +import com.mongodb.internal.client.model.bulk.ConcreteClientNamespacedDeleteManyModel; +import com.mongodb.internal.client.model.bulk.ConcreteClientNamespacedDeleteOneModel; +import com.mongodb.internal.client.model.bulk.ConcreteClientNamespacedInsertOneModel; +import com.mongodb.internal.client.model.bulk.ConcreteClientNamespacedReplaceOneModel; +import com.mongodb.internal.client.model.bulk.ConcreteClientNamespacedUpdateManyModel; +import com.mongodb.internal.client.model.bulk.ConcreteClientNamespacedUpdateOneModel; +import com.mongodb.internal.client.model.bulk.ConcreteClientReplaceOneModel; +import com.mongodb.internal.client.model.bulk.ConcreteClientUpdateManyModel; +import com.mongodb.internal.client.model.bulk.ConcreteClientUpdateOneModel; +import org.bson.Document; +import org.bson.conversions.Bson; + +import static com.mongodb.assertions.Assertions.notNull; + +/** + * A combination of an individual write operation and a {@linkplain MongoNamespace namespace} + * the operation is targeted at. + * + * @since 5.3 + */ +@Sealed +public interface ClientNamespacedWriteModel { + /** + * Creates a model for inserting the {@code document} into the {@code namespace}. + * + * @param namespace The namespace. + * @param document The document. + * @return The requested {@link ClientNamespacedInsertOneModel}. + * @param The document type, for example {@link Document}. + */ + static ClientNamespacedInsertOneModel insertOne(final MongoNamespace namespace, final TDocument document) { + notNull("namespace", namespace); + notNull("document", document); + return new ConcreteClientNamespacedInsertOneModel(namespace, new ConcreteClientInsertOneModel(document)); + } + + /** + * Creates a model for updating at most one document in the {@code namespace} matching the {@code filter}. + * This method is functionally equivalent to {@link #updateOne(MongoNamespace, Bson, Bson, ClientUpdateOptions)} + * with the {@linkplain ClientUpdateOptions#clientUpdateOptions() default options}. + * + * @param namespace The namespace. + * @param filter The filter. + * @param update The update. + * @return The requested {@link ClientNamespacedUpdateOneModel}. + * @see Filters + * @see Updates + */ + static ClientNamespacedUpdateOneModel updateOne(final MongoNamespace namespace, final Bson filter, final Bson update) { + notNull("namespace", namespace); + notNull("filter", filter); + notNull("update", update); + return new ConcreteClientNamespacedUpdateOneModel(namespace, new ConcreteClientUpdateOneModel(filter, update, null, null)); + } + + /** + * Creates a model for updating at most one document in the {@code namespace} matching the {@code filter}. + * + * @param namespace The namespace. + * @param filter The filter. + * @param update The update. + * @param options The options. + * @return The requested {@link ClientNamespacedUpdateOneModel}. + * @see Filters + * @see Updates + */ + static ClientNamespacedUpdateOneModel updateOne( + final MongoNamespace namespace, final Bson filter, final Bson update, final ClientUpdateOptions options) { + notNull("namespace", namespace); + notNull("filter", filter); + notNull("update", update); + notNull("options", options); + return new ConcreteClientNamespacedUpdateOneModel(namespace, new ConcreteClientUpdateOneModel(filter, update, null, options)); + } + + /** + * Creates a model for updating at most one document in the {@code namespace} matching the {@code filter}. + * This method is functionally equivalent to {@link #updateOne(MongoNamespace, Bson, Iterable, ClientUpdateOptions)} + * with the {@linkplain ClientUpdateOptions#clientUpdateOptions() default options}. + * + * @param namespace The namespace. + * @param filter The filter. + * @param updatePipeline The update pipeline. + * @return The requested {@link ClientNamespacedUpdateOneModel}. + * @see Filters + * @see Aggregates + */ + static ClientNamespacedUpdateOneModel updateOne( + final MongoNamespace namespace, final Bson filter, final Iterable updatePipeline) { + notNull("namespace", namespace); + notNull("filter", filter); + notNull("updatePipeline", updatePipeline); + return new ConcreteClientNamespacedUpdateOneModel(namespace, new ConcreteClientUpdateOneModel(filter, null, updatePipeline, null)); + } + + /** + * Creates a model for updating at most one document in the {@code namespace} matching the {@code filter}. + * + * @param namespace The namespace. + * @param filter The filter. + * @param updatePipeline The update pipeline. + * @param options The options. + * @return The requested {@link ClientNamespacedUpdateOneModel}. + * @see Filters + * @see Aggregates + */ + static ClientNamespacedUpdateOneModel updateOne( + final MongoNamespace namespace, final Bson filter, final Iterable updatePipeline, final ClientUpdateOptions options) { + notNull("namespace", namespace); + notNull("filter", filter); + notNull("updatePipeline", updatePipeline); + notNull("options", options); + return new ConcreteClientNamespacedUpdateOneModel(namespace, new ConcreteClientUpdateOneModel(filter, null, updatePipeline, options)); + } + + /** + * Creates a model for updating all documents in the {@code namespace} matching the {@code filter}. + * This method is functionally equivalent to {@link #updateMany(MongoNamespace, Bson, Bson, ClientUpdateOptions)} + * with the {@linkplain ClientUpdateOptions#clientUpdateOptions() default}. + * + * @param namespace The namespace. + * @param filter The filter. + * @param update The update. + * @return The requested {@link ClientNamespacedUpdateManyModel}. + * @see Filters + * @see Updates + */ + static ClientNamespacedUpdateManyModel updateMany(final MongoNamespace namespace, final Bson filter, final Bson update) { + notNull("namespace", namespace); + notNull("filter", filter); + notNull("update", update); + return new ConcreteClientNamespacedUpdateManyModel(namespace, new ConcreteClientUpdateManyModel(filter, update, null, null)); + } + + /** + * Creates a model for updating all documents in the {@code namespace} matching the {@code filter}. + * + * @param namespace The namespace. + * @param filter The filter. + * @param update The update. + * @param options The options. + * @return The requested {@link ClientNamespacedUpdateManyModel}. + * @see Filters + * @see Updates + */ + static ClientNamespacedUpdateManyModel updateMany( + final MongoNamespace namespace, final Bson filter, final Bson update, final ClientUpdateOptions options) { + notNull("namespace", namespace); + notNull("filter", filter); + notNull("update", update); + notNull("options", options); + return new ConcreteClientNamespacedUpdateManyModel(namespace, new ConcreteClientUpdateManyModel(filter, update, null, options)); + } + + /** + * Creates a model for updating all documents in the {@code namespace} matching the {@code filter}. + * This method is functionally equivalent to {@link #updateMany(MongoNamespace, Bson, Iterable, ClientUpdateOptions)} + * with the {@linkplain ClientUpdateOptions#clientUpdateOptions() default options}. + * + * @param namespace The namespace. + * @param filter The filter. + * @param updatePipeline The update pipeline. + * @return The requested {@link ClientNamespacedUpdateManyModel}. + * @see Filters + * @see Aggregates + */ + static ClientNamespacedUpdateManyModel updateMany( + final MongoNamespace namespace, final Bson filter, final Iterable updatePipeline) { + notNull("namespace", namespace); + notNull("filter", filter); + notNull("updatePipeline", updatePipeline); + return new ConcreteClientNamespacedUpdateManyModel(namespace, new ConcreteClientUpdateManyModel(filter, null, updatePipeline, null)); + } + + /** + * Creates a model for updating all documents in the {@code namespace} matching the {@code filter}. + * + * @param namespace The namespace. + * @param filter The filter. + * @param updatePipeline The update pipeline. + * @param options The options. + * @return The requested {@link ClientNamespacedUpdateManyModel}. + * @see Filters + * @see Aggregates + */ + static ClientNamespacedUpdateManyModel updateMany( + final MongoNamespace namespace, final Bson filter, final Iterable updatePipeline, final ClientUpdateOptions options) { + notNull("namespace", namespace); + notNull("filter", filter); + notNull("updatePipeline", updatePipeline); + notNull("options", options); + return new ConcreteClientNamespacedUpdateManyModel(namespace, new ConcreteClientUpdateManyModel(filter, null, updatePipeline, options)); + } + + /** + * Creates a model for replacing at most one document in the {@code namespace} matching the {@code filter}. + * This method is functionally equivalent to {@link #replaceOne(MongoNamespace, Bson, Object, ClientReplaceOptions)} + * with the {@linkplain ClientReplaceOptions#clientReplaceOptions() default options}. + * + * @param namespace The namespace. + * @param filter The filter. + * @param replacement The replacement. + * The keys of this document must not start with {@code $}, unless they express a {@linkplain com.mongodb.DBRef database reference}. + * @return The requested {@link ClientNamespacedReplaceOneModel}. + * @param The document type, for example {@link Document}. + * @see Filters + */ + static ClientNamespacedReplaceOneModel replaceOne(final MongoNamespace namespace, final Bson filter, final TDocument replacement) { + notNull("namespace", namespace); + notNull("filter", filter); + notNull("replacement", replacement); + return new ConcreteClientNamespacedReplaceOneModel(namespace, new ConcreteClientReplaceOneModel(filter, replacement, null)); + } + + /** + * Creates a model for replacing at most one document in the {@code namespace} matching the {@code filter}. + * + * @param namespace The namespace. + * @param filter The filter. + * @param replacement The replacement. + * The keys of this document must not start with {@code $}, unless they express a {@linkplain com.mongodb.DBRef database reference}. + * @param options The options. + * @return The requested {@link ClientNamespacedReplaceOneModel}. + * @param The document type, for example {@link Document}. + * @see Filters + */ + static ClientNamespacedReplaceOneModel replaceOne( + final MongoNamespace namespace, final Bson filter, final TDocument replacement, final ClientReplaceOptions options) { + notNull("namespace", namespace); + notNull("filter", filter); + notNull("replacement", replacement); + notNull("options", options); + return new ConcreteClientNamespacedReplaceOneModel(namespace, new ConcreteClientReplaceOneModel(filter, replacement, options)); + } + + /** + * Creates a model for deleting at most one document from the {@code namespace} matching the {@code filter}. + * This method is functionally equivalent to {@link #deleteOne(MongoNamespace, Bson, ClientDeleteOptions)} + * with the {@linkplain ClientDeleteOptions#clientDeleteOptions() default options}. + * + * @param namespace The namespace. + * @param filter The filter. + * @return The requested {@link ClientNamespacedDeleteOneModel}. + * @see Filters + */ + static ClientNamespacedDeleteOneModel deleteOne(final MongoNamespace namespace, final Bson filter) { + notNull("namespace", namespace); + notNull("filter", filter); + return new ConcreteClientNamespacedDeleteOneModel(namespace, new ConcreteClientDeleteOneModel(filter, null)); + } + + /** + * Creates a model for deleting at most one document from the {@code namespace} matching the {@code filter}. + * + * @param namespace The namespace. + * @param filter The filter. + * @param options The options. + * @return The requested {@link ClientNamespacedDeleteOneModel}. + * @see Filters + */ + static ClientNamespacedDeleteOneModel deleteOne(final MongoNamespace namespace, final Bson filter, final ClientDeleteOptions options) { + notNull("namespace", namespace); + notNull("filter", filter); + notNull("options", options); + return new ConcreteClientNamespacedDeleteOneModel(namespace, new ConcreteClientDeleteOneModel(filter, options)); + } + + /** + * Creates a model for deleting all documents from the {@code namespace} matching the {@code filter}. + * This method is functionally equivalent to {@link #deleteMany(MongoNamespace, Bson, ClientDeleteOptions)} + * with the {@linkplain ClientDeleteOptions#clientDeleteOptions() default options}. + * + * @param namespace The namespace. + * @param filter The filter. + * @return The requested {@link ClientNamespacedDeleteManyModel}. + * @see Filters + */ + static ClientNamespacedDeleteManyModel deleteMany(final MongoNamespace namespace, final Bson filter) { + notNull("namespace", namespace); + notNull("filter", filter); + return new ConcreteClientNamespacedDeleteManyModel(namespace, new ConcreteClientDeleteManyModel(filter, null)); + } + + /** + * Creates a model for deleting all documents from the {@code namespace} matching the {@code filter}. + * + * @param namespace The namespace. + * @param filter The filter. + * @param options The options. + * @return The requested {@link ClientNamespacedDeleteManyModel}. + * @see Filters + */ + static ClientNamespacedDeleteManyModel deleteMany(final MongoNamespace namespace, final Bson filter, final ClientDeleteOptions options) { + notNull("namespace", namespace); + notNull("filter", filter); + notNull("options", options); + return new ConcreteClientNamespacedDeleteManyModel(namespace, new ConcreteClientDeleteManyModel(filter, options)); + } +} diff --git a/driver-core/src/main/com/mongodb/client/model/bulk/ClientReplaceOptions.java b/driver-core/src/main/com/mongodb/client/model/bulk/ClientReplaceOptions.java new file mode 100644 index 00000000000..b6ad2c9c048 --- /dev/null +++ b/driver-core/src/main/com/mongodb/client/model/bulk/ClientReplaceOptions.java @@ -0,0 +1,73 @@ +/* + * Copyright 2008-present MongoDB, Inc. + * + * 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 com.mongodb.client.model.bulk; + +import com.mongodb.annotations.Sealed; +import com.mongodb.client.model.Collation; +import com.mongodb.internal.client.model.bulk.ConcreteClientReplaceOptions; +import com.mongodb.lang.Nullable; +import org.bson.conversions.Bson; + +/** + * The options to apply when replacing documents. + * + * @since 5.3 + */ +@Sealed +public interface ClientReplaceOptions { + /** + * Creates the default options. + * + * @return The default options. + */ + static ClientReplaceOptions clientReplaceOptions() { + return new ConcreteClientReplaceOptions(); + } + + /** + * Sets the collation. + * + * @param collation The collation. {@code null} represents the server default. + * @return {@code this}. + */ + ClientReplaceOptions collation(@Nullable Collation collation); + + /** + * Sets the index specification, + * {@code null}-ifies {@linkplain #hintString(String) hint string}. + * + * @param hint The index specification. {@code null} represents the server default. + * @return {@code this}. + */ + ClientReplaceOptions hint(@Nullable Bson hint); + + /** + * Sets the index name, + * {@code null}-ifies {@linkplain #hint(Bson) hint}. + * + * @param hintString The index name. {@code null} represents the server default. + * @return {@code this}. + */ + ClientReplaceOptions hintString(@Nullable String hintString); + + /** + * Enables or disables creation of a document if no documents match the filter. + * + * @param upsert The upsert flag. {@code null} represents the server default. + * @return {@code this}. + */ + ClientReplaceOptions upsert(@Nullable Boolean upsert); +} diff --git a/driver-core/src/main/com/mongodb/client/model/bulk/ClientUpdateOptions.java b/driver-core/src/main/com/mongodb/client/model/bulk/ClientUpdateOptions.java new file mode 100644 index 00000000000..4a74c8846e9 --- /dev/null +++ b/driver-core/src/main/com/mongodb/client/model/bulk/ClientUpdateOptions.java @@ -0,0 +1,83 @@ +/* + * Copyright 2008-present MongoDB, Inc. + * + * 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 com.mongodb.client.model.bulk; + +import com.mongodb.annotations.Sealed; +import com.mongodb.client.model.Collation; +import com.mongodb.client.model.Filters; +import com.mongodb.internal.client.model.bulk.ConcreteClientUpdateOptions; +import com.mongodb.lang.Nullable; +import org.bson.conversions.Bson; + +/** + * The options to apply when updating documents. + * + * @since 5.3 + */ +@Sealed +public interface ClientUpdateOptions { + /** + * Creates the default options. + * + * @return The default options. + */ + static ClientUpdateOptions clientUpdateOptions() { + return new ConcreteClientUpdateOptions(); + } + + /** + * Sets the filters specifying to which array elements an update should apply. + * + * @param arrayFilters The array filters. {@code null} represents the server default. + * @return {@code this}. + * @see Filters + */ + ClientUpdateOptions arrayFilters(@Nullable Iterable arrayFilters); + + /** + * Sets the collation. + * + * @param collation The collation. {@code null} represents the server default. + * @return {@code this}. + */ + ClientUpdateOptions collation(@Nullable Collation collation); + + /** + * Sets the index specification, + * {@code null}-ifies {@linkplain #hintString(String) hint string}. + * + * @param hint The index specification. {@code null} represents the server default. + * @return {@code this}. + */ + ClientUpdateOptions hint(@Nullable Bson hint); + + /** + * Sets the index name, + * {@code null}-ifies {@linkplain #hint(Bson) hint}. + * + * @param hintString The index name. {@code null} represents the server default. + * @return {@code this}. + */ + ClientUpdateOptions hintString(@Nullable String hintString); + + /** + * Enables or disables creation of a document if no documents match the filter. + * + * @param upsert The upsert flag. {@code null} represents the server default. + * @return {@code this}. + */ + ClientUpdateOptions upsert(@Nullable Boolean upsert); +} diff --git a/driver-core/src/main/com/mongodb/client/model/bulk/ClientUpdateResult.java b/driver-core/src/main/com/mongodb/client/model/bulk/ClientUpdateResult.java new file mode 100644 index 00000000000..c667db97c9e --- /dev/null +++ b/driver-core/src/main/com/mongodb/client/model/bulk/ClientUpdateResult.java @@ -0,0 +1,53 @@ +/* + * Copyright 2008-present MongoDB, Inc. + * + * 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 com.mongodb.client.model.bulk; + +import com.mongodb.annotations.Evolving; +import com.mongodb.bulk.WriteConcernError; +import org.bson.BsonValue; + +import java.util.Optional; + +/** + * The result of a successful {@linkplain ClientNamespacedWriteModel individual update or replace operation}. + * Note that {@link WriteConcernError}s are not considered as making individual operations unsuccessful. + * + * @since 5.3 + */ +@Evolving +public interface ClientUpdateResult { + /** + * The number of documents that matched the filter. + * + * @return The number of documents that matched the filter. + */ + long getMatchedCount(); + + /** + * The number of documents that were modified. + * + * @return The number of documents that were modified. + */ + long getModifiedCount(); + + /** + * The {@code "_id"} of the upserted document if and only if an upsert occurred. + * + * @return The {@code "_id"} of the upserted. + * {@linkplain Optional#isPresent() Present} if and only if an upsert occurred. + */ + Optional getUpsertedId(); +} diff --git a/driver-core/src/main/com/mongodb/client/model/bulk/package-info.java b/driver-core/src/main/com/mongodb/client/model/bulk/package-info.java new file mode 100644 index 00000000000..b9cb98f41a7 --- /dev/null +++ b/driver-core/src/main/com/mongodb/client/model/bulk/package-info.java @@ -0,0 +1,23 @@ +/* + * Copyright 2008-present MongoDB, Inc. + * + * 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. + */ + +/** + * Models, options, results for the client-level bulk write operation. + */ +@NonNullApi +package com.mongodb.client.model.bulk; + +import com.mongodb.lang.NonNullApi; diff --git a/driver-core/src/main/com/mongodb/internal/client/model/bulk/AbstractClientDeleteModel.java b/driver-core/src/main/com/mongodb/internal/client/model/bulk/AbstractClientDeleteModel.java new file mode 100644 index 00000000000..3d3829661cf --- /dev/null +++ b/driver-core/src/main/com/mongodb/internal/client/model/bulk/AbstractClientDeleteModel.java @@ -0,0 +1,51 @@ +/* + * Copyright 2008-present MongoDB, Inc. + * + * 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 com.mongodb.internal.client.model.bulk; + +import com.mongodb.client.model.bulk.ClientDeleteOptions; +import com.mongodb.lang.Nullable; +import org.bson.conversions.Bson; + +/** + * This class is not part of the public API and may be removed or changed at any time. + */ +public abstract class AbstractClientDeleteModel implements ClientWriteModel { + private final Bson filter; + private final ConcreteClientDeleteOptions options; + + AbstractClientDeleteModel(final Bson filter, @Nullable final ClientDeleteOptions options) { + this.filter = filter; + this.options = options == null ? ConcreteClientDeleteOptions.MUTABLE_EMPTY : (ConcreteClientDeleteOptions) options; + } + + public final Bson getFilter() { + return filter; + } + + public final ConcreteClientDeleteOptions getOptions() { + return options; + } + + abstract String getToStringDescription(); + + @Override + public final String toString() { + return getToStringDescription() + + "{filter=" + filter + + ", options=" + options + + '}'; + } +} diff --git a/driver-core/src/main/com/mongodb/internal/client/model/bulk/AbstractClientNamespacedWriteModel.java b/driver-core/src/main/com/mongodb/internal/client/model/bulk/AbstractClientNamespacedWriteModel.java new file mode 100644 index 00000000000..25daa0bea15 --- /dev/null +++ b/driver-core/src/main/com/mongodb/internal/client/model/bulk/AbstractClientNamespacedWriteModel.java @@ -0,0 +1,48 @@ +/* + * Copyright 2008-present MongoDB, Inc. + * + * 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 com.mongodb.internal.client.model.bulk; + +import com.mongodb.MongoNamespace; + +/** + * This class is not part of the public API and may be removed or changed at any time. + */ +public abstract class AbstractClientNamespacedWriteModel { + private final MongoNamespace namespace; + private final ClientWriteModel model; + + AbstractClientNamespacedWriteModel(final MongoNamespace namespace, final ClientWriteModel model) { + this.namespace = namespace; + this.model = model; + } + + public final MongoNamespace getNamespace() { + return namespace; + } + + public final ClientWriteModel getModel() { + return model; + } + + @Override + public final String toString() { + return "ClientNamespacedWriteModel{" + + "namespace=" + namespace + + ", model=" + model + + '}'; + } +} diff --git a/driver-core/src/main/com/mongodb/internal/client/model/bulk/AbstractClientUpdateModel.java b/driver-core/src/main/com/mongodb/internal/client/model/bulk/AbstractClientUpdateModel.java new file mode 100644 index 00000000000..2c8cadf3d88 --- /dev/null +++ b/driver-core/src/main/com/mongodb/internal/client/model/bulk/AbstractClientUpdateModel.java @@ -0,0 +1,78 @@ +/* + * Copyright 2008-present MongoDB, Inc. + * + * 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 com.mongodb.internal.client.model.bulk; + +import com.mongodb.client.model.bulk.ClientUpdateOptions; +import com.mongodb.lang.Nullable; +import org.bson.conversions.Bson; + +import java.util.Optional; + +import static com.mongodb.assertions.Assertions.assertTrue; +import static java.util.Optional.ofNullable; + +/** + * This class is not part of the public API and may be removed or changed at any time. + */ +public abstract class AbstractClientUpdateModel { + private final Bson filter; + @Nullable + private final Bson update; + @Nullable + private final Iterable updatePipeline; + private final ConcreteClientUpdateOptions options; + + AbstractClientUpdateModel( + final Bson filter, + @Nullable + final Bson update, + @Nullable + final Iterable updatePipeline, + @Nullable final ClientUpdateOptions options) { + this.filter = filter; + assertTrue(update == null ^ updatePipeline == null); + this.update = update; + this.updatePipeline = updatePipeline; + this.options = options == null ? ConcreteClientUpdateOptions.MUTABLE_EMPTY : (ConcreteClientUpdateOptions) options; + } + + public final Bson getFilter() { + return filter; + } + + public final Optional getUpdate() { + return ofNullable(update); + } + + public final Optional> getUpdatePipeline() { + return ofNullable(updatePipeline); + } + + public final ConcreteClientUpdateOptions getOptions() { + return options; + } + + abstract String getToStringDescription(); + + @Override + public final String toString() { + return getToStringDescription() + + "{filter=" + filter + + ", update=" + (update != null ? update : updatePipeline) + + ", options=" + options + + '}'; + } +} diff --git a/driver-core/src/main/com/mongodb/internal/client/model/bulk/AcknowledgedSummaryClientBulkWriteResult.java b/driver-core/src/main/com/mongodb/internal/client/model/bulk/AcknowledgedSummaryClientBulkWriteResult.java new file mode 100644 index 00000000000..fb088c662ae --- /dev/null +++ b/driver-core/src/main/com/mongodb/internal/client/model/bulk/AcknowledgedSummaryClientBulkWriteResult.java @@ -0,0 +1,114 @@ +/* + * Copyright 2008-present MongoDB, Inc. + * + * 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 com.mongodb.internal.client.model.bulk; + +import com.mongodb.client.model.bulk.ClientBulkWriteResult; + +import java.util.Objects; +import java.util.Optional; + +import static java.util.Optional.empty; + +/** + * This class is not part of the public API and may be removed or changed at any time. + */ +public final class AcknowledgedSummaryClientBulkWriteResult implements ClientBulkWriteResult { + private final long insertedCount; + private final long upsertedCount; + private final long matchedCount; + private final long modifiedCount; + private final long deletedCount; + + public AcknowledgedSummaryClientBulkWriteResult( + final long insertedCount, + final long upsertedCount, + final long matchedCount, + final long modifiedCount, + final long deletedCount) { + this.insertedCount = insertedCount; + this.upsertedCount = upsertedCount; + this.matchedCount = matchedCount; + this.modifiedCount = modifiedCount; + this.deletedCount = deletedCount; + } + + @Override + public boolean isAcknowledged() { + return true; + } + + @Override + public long getInsertedCount() { + return insertedCount; + } + + @Override + public long getUpsertedCount() { + return upsertedCount; + } + + @Override + public long getMatchedCount() { + return matchedCount; + } + + @Override + public long getModifiedCount() { + return modifiedCount; + } + + @Override + public long getDeletedCount() { + return deletedCount; + } + + @Override + public Optional getVerboseResults() { + return empty(); + } + + @Override + public boolean equals(final Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final AcknowledgedSummaryClientBulkWriteResult that = (AcknowledgedSummaryClientBulkWriteResult) o; + return insertedCount == that.insertedCount + && upsertedCount == that.upsertedCount + && matchedCount == that.matchedCount + && modifiedCount == that.modifiedCount + && deletedCount == that.deletedCount; + } + + @Override + public int hashCode() { + return Objects.hash(insertedCount, upsertedCount, matchedCount, modifiedCount, deletedCount); + } + + @Override + public String toString() { + return "AcknowledgedSummaryClientBulkWriteResult{" + + "insertedCount=" + insertedCount + + ", upsertedCount=" + upsertedCount + + ", matchedCount=" + matchedCount + + ", modifiedCount=" + modifiedCount + + ", deletedCount=" + deletedCount + + '}'; + } +} diff --git a/driver-core/src/main/com/mongodb/internal/client/model/bulk/AcknowledgedVerboseClientBulkWriteResult.java b/driver-core/src/main/com/mongodb/internal/client/model/bulk/AcknowledgedVerboseClientBulkWriteResult.java new file mode 100644 index 00000000000..14e9b016d07 --- /dev/null +++ b/driver-core/src/main/com/mongodb/internal/client/model/bulk/AcknowledgedVerboseClientBulkWriteResult.java @@ -0,0 +1,170 @@ +/* + * Copyright 2008-present MongoDB, Inc. + * + * 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 com.mongodb.internal.client.model.bulk; + +import com.mongodb.client.model.bulk.ClientBulkWriteResult; +import com.mongodb.client.model.bulk.ClientDeleteResult; +import com.mongodb.client.model.bulk.ClientInsertOneResult; +import com.mongodb.client.model.bulk.ClientUpdateResult; + +import java.util.Map; +import java.util.Objects; +import java.util.Optional; + +import static java.util.Optional.of; + +/** + * This class is not part of the public API and may be removed or changed at any time. + */ +public final class AcknowledgedVerboseClientBulkWriteResult implements ClientBulkWriteResult { + private final AcknowledgedSummaryClientBulkWriteResult summaryResults; + private final AcknowledgedVerboseClientBulkWriteResult.VerboseResults verboseResults; + + public AcknowledgedVerboseClientBulkWriteResult( + final AcknowledgedSummaryClientBulkWriteResult summaryResults, + final Map insertResults, + final Map updateResults, + final Map deleteResults) { + this.summaryResults = summaryResults; + this.verboseResults = new AcknowledgedVerboseClientBulkWriteResult.VerboseResults(insertResults, updateResults, deleteResults); + } + + @Override + public boolean isAcknowledged() { + return true; + } + + @Override + public long getInsertedCount() { + return summaryResults.getInsertedCount(); + } + + @Override + public long getUpsertedCount() { + return summaryResults.getUpsertedCount(); + } + + @Override + public long getMatchedCount() { + return summaryResults.getMatchedCount(); + } + + @Override + public long getModifiedCount() { + return summaryResults.getModifiedCount(); + } + + @Override + public long getDeletedCount() { + return summaryResults.getDeletedCount(); + } + + @Override + public Optional getVerboseResults() { + return of(verboseResults); + } + + @Override + public boolean equals(final Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final AcknowledgedVerboseClientBulkWriteResult that = (AcknowledgedVerboseClientBulkWriteResult) o; + return Objects.equals(summaryResults, that.summaryResults) + && Objects.equals(verboseResults, that.verboseResults); + } + + @Override + public int hashCode() { + return Objects.hash(summaryResults, verboseResults); + } + + @Override + public String toString() { + return "AcknowledgedVerboseClientBulkWriteResult{" + + "insertedCount=" + summaryResults.getInsertedCount() + + ", upsertedCount=" + summaryResults.getUpsertedCount() + + ", matchedCount=" + summaryResults.getMatchedCount() + + ", modifiedCount=" + summaryResults.getModifiedCount() + + ", deletedCount=" + summaryResults.getDeletedCount() + + ", insertResults=" + verboseResults.insertResults + + ", updateResults=" + verboseResults.updateResults + + ", deleteResults=" + verboseResults.deleteResults + + '}'; + } + + private static final class VerboseResults implements ClientBulkWriteResult.VerboseResults { + private final Map insertResults; + private final Map updateResults; + private final Map deleteResults; + + VerboseResults( + final Map insertResults, + final Map updateResults, + final Map deleteResults) { + this.insertResults = insertResults; + this.updateResults = updateResults; + this.deleteResults = deleteResults; + } + + @Override + public Map getInsertResults() { + return insertResults; + } + + @Override + public Map getUpdateResults() { + return updateResults; + } + + @Override + public Map getDeleteResults() { + return deleteResults; + } + + @Override + public boolean equals(final Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final AcknowledgedVerboseClientBulkWriteResult.VerboseResults verbose = + (AcknowledgedVerboseClientBulkWriteResult.VerboseResults) o; + return Objects.equals(insertResults, verbose.insertResults) + && Objects.equals(updateResults, verbose.updateResults) + && Objects.equals(deleteResults, verbose.deleteResults); + } + + @Override + public int hashCode() { + return Objects.hash(insertResults, updateResults, deleteResults); + } + + @Override + public String toString() { + return "AcknowledgedVerboseClientBulkWriteResult.VerboseResults{" + + "insertResults=" + insertResults + + ", updateResults=" + updateResults + + ", deleteResults=" + deleteResults + + '}'; + } + } +} diff --git a/driver-core/src/main/com/mongodb/internal/client/model/bulk/ClientWriteModel.java b/driver-core/src/main/com/mongodb/internal/client/model/bulk/ClientWriteModel.java new file mode 100644 index 00000000000..56d431ec0e8 --- /dev/null +++ b/driver-core/src/main/com/mongodb/internal/client/model/bulk/ClientWriteModel.java @@ -0,0 +1,24 @@ +/* + * Copyright 2008-present MongoDB, Inc. + * + * 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 com.mongodb.internal.client.model.bulk; + +/** + * An individual write operation to be executed as part of a client-level bulk write operation. + *

+ * This class is not part of the public API and may be removed or changed at any time.

+ */ +public interface ClientWriteModel { +} diff --git a/driver-core/src/main/com/mongodb/internal/client/model/bulk/ConcreteClientBulkWriteOptions.java b/driver-core/src/main/com/mongodb/internal/client/model/bulk/ConcreteClientBulkWriteOptions.java new file mode 100644 index 00000000000..9599e1750bf --- /dev/null +++ b/driver-core/src/main/com/mongodb/internal/client/model/bulk/ConcreteClientBulkWriteOptions.java @@ -0,0 +1,123 @@ +/* + * Copyright 2008-present MongoDB, Inc. + * + * 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 com.mongodb.internal.client.model.bulk; + +import com.mongodb.client.model.bulk.ClientBulkWriteOptions; +import com.mongodb.lang.Nullable; +import org.bson.BsonValue; +import org.bson.conversions.Bson; + +import java.util.Optional; + +import static java.util.Optional.ofNullable; + +/** + * This class is not part of the public API and may be removed or changed at any time. + */ +public final class ConcreteClientBulkWriteOptions implements ClientBulkWriteOptions { + private static final Boolean CLIENT_DEFAULT_ORDERED = true; + private static final Boolean CLIENT_DEFAULT_VERBOSE_RESULTS = false; + + @Nullable + private Boolean ordered; + @Nullable + private Boolean bypassDocumentValidation; + @Nullable + private Bson let; + @Nullable + private BsonValue comment; + @Nullable + private Boolean verboseResults; + + public ConcreteClientBulkWriteOptions() { + } + + @Override + public ClientBulkWriteOptions ordered(@Nullable final Boolean ordered) { + this.ordered = ordered; + return this; + } + + /** + * @see #ordered(Boolean) + */ + public boolean isOrdered() { + return ordered == null ? CLIENT_DEFAULT_ORDERED : ordered; + } + + @Override + public ClientBulkWriteOptions bypassDocumentValidation(@Nullable final Boolean bypassDocumentValidation) { + this.bypassDocumentValidation = bypassDocumentValidation; + return this; + } + + /** + * @see #bypassDocumentValidation(Boolean) + */ + public Optional isBypassDocumentValidation() { + return ofNullable(bypassDocumentValidation); + } + + @Override + public ClientBulkWriteOptions let(@Nullable final Bson let) { + this.let = let; + return this; + } + + /** + * @see #let(Bson) + */ + public Optional getLet() { + return ofNullable(let); + } + + @Override + public ClientBulkWriteOptions comment(@Nullable final BsonValue comment) { + this.comment = comment; + return this; + } + + /** + * @see #comment(BsonValue) + */ + public Optional getComment() { + return ofNullable(comment); + } + + @Override + public ClientBulkWriteOptions verboseResults(@Nullable final Boolean verboseResults) { + this.verboseResults = verboseResults; + return this; + } + + /** + * @see #verboseResults(Boolean) + */ + public boolean isVerboseResults() { + return verboseResults == null ? CLIENT_DEFAULT_VERBOSE_RESULTS : verboseResults; + } + + @Override + public String toString() { + return "ClientBulkWriteOptions{" + + "ordered=" + ordered + + ", bypassDocumentValidation=" + bypassDocumentValidation + + ", let=" + let + + ", comment=" + comment + + ", verboseResults=" + verboseResults + + '}'; + } +} diff --git a/driver-core/src/main/com/mongodb/internal/client/model/bulk/ConcreteClientDeleteManyModel.java b/driver-core/src/main/com/mongodb/internal/client/model/bulk/ConcreteClientDeleteManyModel.java new file mode 100644 index 00000000000..7603c5a7df0 --- /dev/null +++ b/driver-core/src/main/com/mongodb/internal/client/model/bulk/ConcreteClientDeleteManyModel.java @@ -0,0 +1,34 @@ +/* + * Copyright 2008-present MongoDB, Inc. + * + * 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 com.mongodb.internal.client.model.bulk; + +import com.mongodb.client.model.bulk.ClientDeleteOptions; +import com.mongodb.lang.Nullable; +import org.bson.conversions.Bson; + +/** + * This class is not part of the public API and may be removed or changed at any time. + */ +public final class ConcreteClientDeleteManyModel extends AbstractClientDeleteModel implements ClientWriteModel { + public ConcreteClientDeleteManyModel(final Bson filter, @Nullable final ClientDeleteOptions options) { + super(filter, options); + } + + @Override + String getToStringDescription() { + return "ClientDeleteManyModel"; + } +} diff --git a/driver-core/src/main/com/mongodb/internal/client/model/bulk/ConcreteClientDeleteOneModel.java b/driver-core/src/main/com/mongodb/internal/client/model/bulk/ConcreteClientDeleteOneModel.java new file mode 100644 index 00000000000..708f0d3e2ff --- /dev/null +++ b/driver-core/src/main/com/mongodb/internal/client/model/bulk/ConcreteClientDeleteOneModel.java @@ -0,0 +1,34 @@ +/* + * Copyright 2008-present MongoDB, Inc. + * + * 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 com.mongodb.internal.client.model.bulk; + +import com.mongodb.client.model.bulk.ClientDeleteOptions; +import com.mongodb.lang.Nullable; +import org.bson.conversions.Bson; + +/** + * This class is not part of the public API and may be removed or changed at any time. + */ +public final class ConcreteClientDeleteOneModel extends AbstractClientDeleteModel implements ClientWriteModel { + public ConcreteClientDeleteOneModel(final Bson filter, @Nullable final ClientDeleteOptions options) { + super(filter, options); + } + + @Override + String getToStringDescription() { + return "ClientDeleteOneModel"; + } +} diff --git a/driver-core/src/main/com/mongodb/internal/client/model/bulk/ConcreteClientDeleteOptions.java b/driver-core/src/main/com/mongodb/internal/client/model/bulk/ConcreteClientDeleteOptions.java new file mode 100644 index 00000000000..1acef43052b --- /dev/null +++ b/driver-core/src/main/com/mongodb/internal/client/model/bulk/ConcreteClientDeleteOptions.java @@ -0,0 +1,92 @@ +/* + * Copyright 2008-present MongoDB, Inc. + * + * 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 com.mongodb.internal.client.model.bulk; + +import com.mongodb.client.model.Collation; +import com.mongodb.client.model.bulk.ClientDeleteOptions; +import com.mongodb.lang.Nullable; +import org.bson.conversions.Bson; + +import java.util.Optional; + +import static java.util.Optional.ofNullable; + +/** + * This class is not part of the public API and may be removed or changed at any time. + */ +public final class ConcreteClientDeleteOptions implements ClientDeleteOptions { + static final ConcreteClientDeleteOptions MUTABLE_EMPTY = new ConcreteClientDeleteOptions(); + + @Nullable + private Collation collation; + @Nullable + private Bson hint; + @Nullable + private String hintString; + + public ConcreteClientDeleteOptions() { + } + + @Override + public ClientDeleteOptions collation(@Nullable final Collation collation) { + this.collation = collation; + return this; + } + + /** + * @see #collation(Collation) + */ + public Optional getCollation() { + return ofNullable(collation); + } + + @Override + public ClientDeleteOptions hint(@Nullable final Bson hint) { + this.hint = hint; + this.hintString = null; + return this; + } + + /** + * @see #hint(Bson) + */ + public Optional getHint() { + return ofNullable(hint); + } + + @Override + public ClientDeleteOptions hintString(@Nullable final String hintString) { + this.hintString = hintString; + this.hint = null; + return this; + } + + /** + * @see #hintString(String) + */ + public Optional getHintString() { + return ofNullable(hintString); + } + + @Override + public String toString() { + return "ClientDeleteOptions{" + + "collation=" + collation + + ", hint=" + hint + + ", hintString='" + hintString + '\'' + + '}'; + } +} diff --git a/driver-core/src/main/com/mongodb/internal/client/model/bulk/ConcreteClientDeleteResult.java b/driver-core/src/main/com/mongodb/internal/client/model/bulk/ConcreteClientDeleteResult.java new file mode 100644 index 00000000000..a82b8ee8b62 --- /dev/null +++ b/driver-core/src/main/com/mongodb/internal/client/model/bulk/ConcreteClientDeleteResult.java @@ -0,0 +1,58 @@ +/* + * Copyright 2008-present MongoDB, Inc. + * + * 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 com.mongodb.internal.client.model.bulk; + +import com.mongodb.client.model.bulk.ClientDeleteResult; + +/** + * This class is not part of the public API and may be removed or changed at any time. + */ +public final class ConcreteClientDeleteResult implements ClientDeleteResult { + private final long deletedCount; + + public ConcreteClientDeleteResult(final long deletedCount) { + this.deletedCount = deletedCount; + } + + @Override + public long getDeletedCount() { + return deletedCount; + } + + @Override + public boolean equals(final Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final ConcreteClientDeleteResult that = (ConcreteClientDeleteResult) o; + return deletedCount == that.deletedCount; + } + + @Override + public int hashCode() { + return Long.hashCode(deletedCount); + } + + @Override + public String toString() { + return "ClientDeleteResult{" + + "deletedCount=" + deletedCount + + '}'; + } +} diff --git a/driver-core/src/main/com/mongodb/internal/client/model/bulk/ConcreteClientInsertOneModel.java b/driver-core/src/main/com/mongodb/internal/client/model/bulk/ConcreteClientInsertOneModel.java new file mode 100644 index 00000000000..660944fc202 --- /dev/null +++ b/driver-core/src/main/com/mongodb/internal/client/model/bulk/ConcreteClientInsertOneModel.java @@ -0,0 +1,38 @@ +/* + * Copyright 2008-present MongoDB, Inc. + * + * 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 com.mongodb.internal.client.model.bulk; + +/** + * This class is not part of the public API and may be removed or changed at any time. + */ +public final class ConcreteClientInsertOneModel implements ClientWriteModel { + private final Object document; + + public ConcreteClientInsertOneModel(final Object document) { + this.document = document; + } + + public Object getDocument() { + return document; + } + + @Override + public String toString() { + return "ClientInsertOneModel{" + + "document=" + document + + '}'; + } +} diff --git a/driver-core/src/main/com/mongodb/internal/client/model/bulk/ConcreteClientInsertOneResult.java b/driver-core/src/main/com/mongodb/internal/client/model/bulk/ConcreteClientInsertOneResult.java new file mode 100644 index 00000000000..cc755e2c62d --- /dev/null +++ b/driver-core/src/main/com/mongodb/internal/client/model/bulk/ConcreteClientInsertOneResult.java @@ -0,0 +1,66 @@ +/* + * Copyright 2008-present MongoDB, Inc. + * + * 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 com.mongodb.internal.client.model.bulk; + +import com.mongodb.client.model.bulk.ClientInsertOneResult; +import com.mongodb.lang.Nullable; +import org.bson.BsonValue; + +import java.util.Objects; +import java.util.Optional; + +import static java.util.Optional.ofNullable; + +/** + * This class is not part of the public API and may be removed or changed at any time. + */ +public final class ConcreteClientInsertOneResult implements ClientInsertOneResult { + @Nullable + private final BsonValue insertedId; + + public ConcreteClientInsertOneResult(@Nullable final BsonValue insertedId) { + this.insertedId = insertedId; + } + + @Override + public Optional getInsertedId() { + return ofNullable(insertedId); + } + + @Override + public boolean equals(final Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final ConcreteClientInsertOneResult that = (ConcreteClientInsertOneResult) o; + return Objects.equals(insertedId, that.insertedId); + } + + @Override + public int hashCode() { + return Objects.hashCode(insertedId); + } + + @Override + public String toString() { + return "ClientInsertOneResult{" + + "insertedId=" + insertedId + + '}'; + } +} diff --git a/driver-core/src/main/com/mongodb/internal/client/model/bulk/ConcreteClientNamespacedDeleteManyModel.java b/driver-core/src/main/com/mongodb/internal/client/model/bulk/ConcreteClientNamespacedDeleteManyModel.java new file mode 100644 index 00000000000..4deb566cff1 --- /dev/null +++ b/driver-core/src/main/com/mongodb/internal/client/model/bulk/ConcreteClientNamespacedDeleteManyModel.java @@ -0,0 +1,28 @@ +/* + * Copyright 2008-present MongoDB, Inc. + * + * 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 com.mongodb.internal.client.model.bulk; + +import com.mongodb.MongoNamespace; +import com.mongodb.client.model.bulk.ClientNamespacedDeleteManyModel; + +/** + * This class is not part of the public API and may be removed or changed at any time. + */ +public final class ConcreteClientNamespacedDeleteManyModel extends AbstractClientNamespacedWriteModel implements ClientNamespacedDeleteManyModel { + public ConcreteClientNamespacedDeleteManyModel(final MongoNamespace namespace, final ClientWriteModel model) { + super(namespace, model); + } +} diff --git a/driver-core/src/main/com/mongodb/internal/client/model/bulk/ConcreteClientNamespacedDeleteOneModel.java b/driver-core/src/main/com/mongodb/internal/client/model/bulk/ConcreteClientNamespacedDeleteOneModel.java new file mode 100644 index 00000000000..db8a7ad9fde --- /dev/null +++ b/driver-core/src/main/com/mongodb/internal/client/model/bulk/ConcreteClientNamespacedDeleteOneModel.java @@ -0,0 +1,28 @@ +/* + * Copyright 2008-present MongoDB, Inc. + * + * 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 com.mongodb.internal.client.model.bulk; + +import com.mongodb.MongoNamespace; +import com.mongodb.client.model.bulk.ClientNamespacedDeleteOneModel; + +/** + * This class is not part of the public API and may be removed or changed at any time. + */ +public final class ConcreteClientNamespacedDeleteOneModel extends AbstractClientNamespacedWriteModel implements ClientNamespacedDeleteOneModel { + public ConcreteClientNamespacedDeleteOneModel(final MongoNamespace namespace, final ClientWriteModel model) { + super(namespace, model); + } +} diff --git a/driver-core/src/main/com/mongodb/internal/client/model/bulk/ConcreteClientNamespacedInsertOneModel.java b/driver-core/src/main/com/mongodb/internal/client/model/bulk/ConcreteClientNamespacedInsertOneModel.java new file mode 100644 index 00000000000..e80861b947e --- /dev/null +++ b/driver-core/src/main/com/mongodb/internal/client/model/bulk/ConcreteClientNamespacedInsertOneModel.java @@ -0,0 +1,28 @@ +/* + * Copyright 2008-present MongoDB, Inc. + * + * 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 com.mongodb.internal.client.model.bulk; + +import com.mongodb.MongoNamespace; +import com.mongodb.client.model.bulk.ClientNamespacedInsertOneModel; + +/** + * This class is not part of the public API and may be removed or changed at any time. + */ +public final class ConcreteClientNamespacedInsertOneModel extends AbstractClientNamespacedWriteModel implements ClientNamespacedInsertOneModel { + public ConcreteClientNamespacedInsertOneModel(final MongoNamespace namespace, final ClientWriteModel model) { + super(namespace, model); + } +} diff --git a/driver-core/src/main/com/mongodb/internal/client/model/bulk/ConcreteClientNamespacedReplaceOneModel.java b/driver-core/src/main/com/mongodb/internal/client/model/bulk/ConcreteClientNamespacedReplaceOneModel.java new file mode 100644 index 00000000000..96ea786169e --- /dev/null +++ b/driver-core/src/main/com/mongodb/internal/client/model/bulk/ConcreteClientNamespacedReplaceOneModel.java @@ -0,0 +1,28 @@ +/* + * Copyright 2008-present MongoDB, Inc. + * + * 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 com.mongodb.internal.client.model.bulk; + +import com.mongodb.MongoNamespace; +import com.mongodb.client.model.bulk.ClientNamespacedReplaceOneModel; + +/** + * This class is not part of the public API and may be removed or changed at any time. + */ +public final class ConcreteClientNamespacedReplaceOneModel extends AbstractClientNamespacedWriteModel implements ClientNamespacedReplaceOneModel { + public ConcreteClientNamespacedReplaceOneModel(final MongoNamespace namespace, final ClientWriteModel model) { + super(namespace, model); + } +} diff --git a/driver-core/src/main/com/mongodb/internal/client/model/bulk/ConcreteClientNamespacedUpdateManyModel.java b/driver-core/src/main/com/mongodb/internal/client/model/bulk/ConcreteClientNamespacedUpdateManyModel.java new file mode 100644 index 00000000000..28f281287e0 --- /dev/null +++ b/driver-core/src/main/com/mongodb/internal/client/model/bulk/ConcreteClientNamespacedUpdateManyModel.java @@ -0,0 +1,28 @@ +/* + * Copyright 2008-present MongoDB, Inc. + * + * 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 com.mongodb.internal.client.model.bulk; + +import com.mongodb.MongoNamespace; +import com.mongodb.client.model.bulk.ClientNamespacedUpdateManyModel; + +/** + * This class is not part of the public API and may be removed or changed at any time. + */ +public final class ConcreteClientNamespacedUpdateManyModel extends AbstractClientNamespacedWriteModel implements ClientNamespacedUpdateManyModel { + public ConcreteClientNamespacedUpdateManyModel(final MongoNamespace namespace, final ClientWriteModel model) { + super(namespace, model); + } +} diff --git a/driver-core/src/main/com/mongodb/internal/client/model/bulk/ConcreteClientNamespacedUpdateOneModel.java b/driver-core/src/main/com/mongodb/internal/client/model/bulk/ConcreteClientNamespacedUpdateOneModel.java new file mode 100644 index 00000000000..ad3aa0853ab --- /dev/null +++ b/driver-core/src/main/com/mongodb/internal/client/model/bulk/ConcreteClientNamespacedUpdateOneModel.java @@ -0,0 +1,28 @@ +/* + * Copyright 2008-present MongoDB, Inc. + * + * 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 com.mongodb.internal.client.model.bulk; + +import com.mongodb.MongoNamespace; +import com.mongodb.client.model.bulk.ClientNamespacedUpdateOneModel; + +/** + * This class is not part of the public API and may be removed or changed at any time. + */ +public final class ConcreteClientNamespacedUpdateOneModel extends AbstractClientNamespacedWriteModel implements ClientNamespacedUpdateOneModel { + public ConcreteClientNamespacedUpdateOneModel(final MongoNamespace namespace, final ClientWriteModel model) { + super(namespace, model); + } +} diff --git a/driver-core/src/main/com/mongodb/internal/client/model/bulk/ConcreteClientReplaceOneModel.java b/driver-core/src/main/com/mongodb/internal/client/model/bulk/ConcreteClientReplaceOneModel.java new file mode 100644 index 00000000000..3bdf08d424a --- /dev/null +++ b/driver-core/src/main/com/mongodb/internal/client/model/bulk/ConcreteClientReplaceOneModel.java @@ -0,0 +1,56 @@ +/* + * Copyright 2008-present MongoDB, Inc. + * + * 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 com.mongodb.internal.client.model.bulk; + +import com.mongodb.client.model.bulk.ClientReplaceOptions; +import com.mongodb.lang.Nullable; +import org.bson.conversions.Bson; + +/** + * This class is not part of the public API and may be removed or changed at any time. + */ +public final class ConcreteClientReplaceOneModel implements ClientWriteModel { + private final Bson filter; + private final Object replacement; + private final ConcreteClientReplaceOptions options; + + public ConcreteClientReplaceOneModel(final Bson filter, final Object replacement, @Nullable final ClientReplaceOptions options) { + this.filter = filter; + this.replacement = replacement; + this.options = options == null ? ConcreteClientReplaceOptions.MUTABLE_EMPTY : (ConcreteClientReplaceOptions) options; + } + + public Bson getFilter() { + return filter; + } + + public Object getReplacement() { + return replacement; + } + + public ConcreteClientReplaceOptions getOptions() { + return options; + } + + @Override + public String toString() { + return "ClientReplaceOneModel{" + + "filter=" + filter + + ", replacement=" + replacement + + ", options=" + options + + '}'; + } +} diff --git a/driver-core/src/main/com/mongodb/internal/client/model/bulk/ConcreteClientReplaceOptions.java b/driver-core/src/main/com/mongodb/internal/client/model/bulk/ConcreteClientReplaceOptions.java new file mode 100644 index 00000000000..703e6b48df0 --- /dev/null +++ b/driver-core/src/main/com/mongodb/internal/client/model/bulk/ConcreteClientReplaceOptions.java @@ -0,0 +1,108 @@ +/* + * Copyright 2008-present MongoDB, Inc. + * + * 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 com.mongodb.internal.client.model.bulk; + +import com.mongodb.client.model.Collation; +import com.mongodb.client.model.bulk.ClientReplaceOptions; +import com.mongodb.lang.Nullable; +import org.bson.conversions.Bson; + +import java.util.Optional; + +import static java.util.Optional.ofNullable; + +/** + * This class is not part of the public API and may be removed or changed at any time. + */ +public final class ConcreteClientReplaceOptions implements ClientReplaceOptions { + static final ConcreteClientReplaceOptions MUTABLE_EMPTY = new ConcreteClientReplaceOptions(); + + @Nullable + private Collation collation; + @Nullable + private Bson hint; + @Nullable + private String hintString; + @Nullable + private Boolean upsert; + + public ConcreteClientReplaceOptions() { + } + + @Override + public ClientReplaceOptions collation(@Nullable final Collation collation) { + this.collation = collation; + return this; + } + + /** + * @see #collation(Collation) + */ + public Optional getCollation() { + return ofNullable(collation); + } + + @Override + public ClientReplaceOptions hint(@Nullable final Bson hint) { + this.hint = hint; + this.hintString = null; + return this; + } + + /** + * @see #hint(Bson) + */ + public Optional getHint() { + return ofNullable(hint); + } + + @Override + public ClientReplaceOptions hintString(@Nullable final String hintString) { + this.hintString = hintString; + this.hint = null; + return this; + } + + /** + * @see #hintString(String) + */ + public Optional getHintString() { + return ofNullable(hintString); + } + + @Override + public ClientReplaceOptions upsert(@Nullable final Boolean upsert) { + this.upsert = upsert; + return this; + } + + /** + * @see #upsert(Boolean) + */ + public Optional isUpsert() { + return ofNullable(upsert); + } + + @Override + public String toString() { + return "ClientReplaceOptions{" + + "collation=" + collation + + ", hint=" + hint + + ", hintString='" + hintString + '\'' + + ", upsert=" + upsert + + '}'; + } +} diff --git a/driver-core/src/main/com/mongodb/internal/client/model/bulk/ConcreteClientUpdateManyModel.java b/driver-core/src/main/com/mongodb/internal/client/model/bulk/ConcreteClientUpdateManyModel.java new file mode 100644 index 00000000000..a7a0b1ac900 --- /dev/null +++ b/driver-core/src/main/com/mongodb/internal/client/model/bulk/ConcreteClientUpdateManyModel.java @@ -0,0 +1,40 @@ +/* + * Copyright 2008-present MongoDB, Inc. + * + * 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 com.mongodb.internal.client.model.bulk; + +import com.mongodb.client.model.bulk.ClientUpdateOptions; +import com.mongodb.lang.Nullable; +import org.bson.conversions.Bson; + +/** + * This class is not part of the public API and may be removed or changed at any time. + */ +public final class ConcreteClientUpdateManyModel extends AbstractClientUpdateModel implements ClientWriteModel { + public ConcreteClientUpdateManyModel( + final Bson filter, + @Nullable + final Bson update, + @Nullable + final Iterable updatePipeline, + @Nullable final ClientUpdateOptions options) { + super(filter, update, updatePipeline, options); + } + + @Override + String getToStringDescription() { + return "ClientUpdateManyModel"; + } +} diff --git a/driver-core/src/main/com/mongodb/internal/client/model/bulk/ConcreteClientUpdateOneModel.java b/driver-core/src/main/com/mongodb/internal/client/model/bulk/ConcreteClientUpdateOneModel.java new file mode 100644 index 00000000000..aa922a803c6 --- /dev/null +++ b/driver-core/src/main/com/mongodb/internal/client/model/bulk/ConcreteClientUpdateOneModel.java @@ -0,0 +1,40 @@ +/* + * Copyright 2008-present MongoDB, Inc. + * + * 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 com.mongodb.internal.client.model.bulk; + +import com.mongodb.client.model.bulk.ClientUpdateOptions; +import com.mongodb.lang.Nullable; +import org.bson.conversions.Bson; + +/** + * This class is not part of the public API and may be removed or changed at any time. + */ +public final class ConcreteClientUpdateOneModel extends AbstractClientUpdateModel implements ClientWriteModel { + public ConcreteClientUpdateOneModel( + final Bson filter, + @Nullable + final Bson update, + @Nullable + final Iterable updatePipeline, + @Nullable final ClientUpdateOptions options) { + super(filter, update, updatePipeline, options); + } + + @Override + String getToStringDescription() { + return "ClientUpdateOneModel"; + } +} diff --git a/driver-core/src/main/com/mongodb/internal/client/model/bulk/ConcreteClientUpdateOptions.java b/driver-core/src/main/com/mongodb/internal/client/model/bulk/ConcreteClientUpdateOptions.java new file mode 100644 index 00000000000..cdb0d08839b --- /dev/null +++ b/driver-core/src/main/com/mongodb/internal/client/model/bulk/ConcreteClientUpdateOptions.java @@ -0,0 +1,124 @@ +/* + * Copyright 2008-present MongoDB, Inc. + * + * 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 com.mongodb.internal.client.model.bulk; + +import com.mongodb.client.model.Collation; +import com.mongodb.client.model.bulk.ClientUpdateOptions; +import com.mongodb.lang.Nullable; +import org.bson.conversions.Bson; + +import java.util.Optional; + +import static java.util.Optional.ofNullable; + +/** + * This class is not part of the public API and may be removed or changed at any time. + */ +public final class ConcreteClientUpdateOptions implements ClientUpdateOptions { + static final ConcreteClientUpdateOptions MUTABLE_EMPTY = new ConcreteClientUpdateOptions(); + + @Nullable + private Iterable arrayFilters; + @Nullable + private Collation collation; + @Nullable + private Bson hint; + @Nullable + private String hintString; + @Nullable + private Boolean upsert; + + public ConcreteClientUpdateOptions() { + } + + @Override + public ClientUpdateOptions arrayFilters(@Nullable final Iterable arrayFilters) { + this.arrayFilters = arrayFilters; + return this; + } + + /** + * @see #arrayFilters(Iterable) + */ + public Optional> getArrayFilters() { + return ofNullable(arrayFilters); + } + + @Override + public ClientUpdateOptions collation(@Nullable final Collation collation) { + this.collation = collation; + return this; + } + + /** + * @see #collation(Collation) + */ + public Optional getCollation() { + return ofNullable(collation); + } + + @Override + public ClientUpdateOptions hint(@Nullable final Bson hint) { + this.hint = hint; + this.hintString = null; + return this; + } + + /** + * @see #hint(Bson) + */ + public Optional getHint() { + return ofNullable(hint); + } + + @Override + public ClientUpdateOptions hintString(@Nullable final String hintString) { + this.hintString = hintString; + this.hint = null; + return this; + } + + /** + * @see #hintString(String) + */ + public Optional getHintString() { + return ofNullable(hintString); + } + + @Override + public ClientUpdateOptions upsert(@Nullable final Boolean upsert) { + this.upsert = upsert; + return this; + } + + /** + * @see #isUpsert() + */ + public Optional isUpsert() { + return ofNullable(upsert); + } + + @Override + public String toString() { + return "ClientUpdateOptions{" + + "arrayFilters=" + arrayFilters + + ", collation=" + collation + + ", hint=" + hint + + ", hintString='" + hintString + '\'' + + ", upsert=" + upsert + + '}'; + } +} diff --git a/driver-core/src/main/com/mongodb/internal/client/model/bulk/ConcreteClientUpdateResult.java b/driver-core/src/main/com/mongodb/internal/client/model/bulk/ConcreteClientUpdateResult.java new file mode 100644 index 00000000000..54075b792f1 --- /dev/null +++ b/driver-core/src/main/com/mongodb/internal/client/model/bulk/ConcreteClientUpdateResult.java @@ -0,0 +1,87 @@ +/* + * Copyright 2008-present MongoDB, Inc. + * + * 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 com.mongodb.internal.client.model.bulk; + +import com.mongodb.client.model.bulk.ClientUpdateResult; +import com.mongodb.lang.Nullable; +import org.bson.BsonValue; + +import java.util.Objects; +import java.util.Optional; + +import static java.util.Optional.ofNullable; + +/** + * This class is not part of the public API and may be removed or changed at any time. + */ +public final class ConcreteClientUpdateResult implements ClientUpdateResult { + private final long matchedCount; + private final long modifiedCount; + @Nullable + private final BsonValue upsertedId; + + public ConcreteClientUpdateResult( + final long matchedCount, + final long modifiedCount, + @Nullable final BsonValue upsertedId) { + this.matchedCount = matchedCount; + this.modifiedCount = modifiedCount; + this.upsertedId = upsertedId; + } + + @Override + public long getMatchedCount() { + return matchedCount; + } + + @Override + public long getModifiedCount() { + return modifiedCount; + } + + @Override + public Optional getUpsertedId() { + return ofNullable(upsertedId); + } + + @Override + public boolean equals(final Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final ConcreteClientUpdateResult that = (ConcreteClientUpdateResult) o; + return matchedCount == that.matchedCount + && modifiedCount == that.modifiedCount + && Objects.equals(upsertedId, that.upsertedId); + } + + @Override + public int hashCode() { + return Objects.hash(matchedCount, modifiedCount, upsertedId); + } + + @Override + public String toString() { + return "ClientUpdateResult{" + + "matchedCount=" + matchedCount + + ", modifiedCount=" + modifiedCount + + ", upsertedId=" + upsertedId + + '}'; + } +} diff --git a/driver-core/src/main/com/mongodb/internal/client/model/bulk/UnacknowledgedClientBulkWriteResult.java b/driver-core/src/main/com/mongodb/internal/client/model/bulk/UnacknowledgedClientBulkWriteResult.java new file mode 100644 index 00000000000..cdd649b3389 --- /dev/null +++ b/driver-core/src/main/com/mongodb/internal/client/model/bulk/UnacknowledgedClientBulkWriteResult.java @@ -0,0 +1,76 @@ +/* + * Copyright 2008-present MongoDB, Inc. + * + * 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 com.mongodb.internal.client.model.bulk; + +import com.mongodb.annotations.Immutable; +import com.mongodb.client.model.bulk.ClientBulkWriteResult; + +import java.util.Optional; + +/** + * This class is not part of the public API and may be removed or changed at any time. + */ +@Immutable +public final class UnacknowledgedClientBulkWriteResult implements ClientBulkWriteResult { + public static final UnacknowledgedClientBulkWriteResult INSTANCE = new UnacknowledgedClientBulkWriteResult(); + + private UnacknowledgedClientBulkWriteResult() { + } + + @Override + public boolean isAcknowledged() { + return false; + } + + @Override + public long getInsertedCount() throws UnsupportedOperationException { + throw createUnacknowledgedResultsException(); + } + + @Override + public long getUpsertedCount() throws UnsupportedOperationException { + throw createUnacknowledgedResultsException(); + } + + @Override + public long getMatchedCount() throws UnsupportedOperationException { + throw createUnacknowledgedResultsException(); + } + + @Override + public long getModifiedCount() throws UnsupportedOperationException { + throw createUnacknowledgedResultsException(); + } + + @Override + public long getDeletedCount() throws UnsupportedOperationException { + throw createUnacknowledgedResultsException(); + } + + @Override + public Optional getVerboseResults() throws UnsupportedOperationException { + throw createUnacknowledgedResultsException(); + } + + private static UnsupportedOperationException createUnacknowledgedResultsException() { + return new UnsupportedOperationException("Cannot get information about an unacknowledged write"); + } + + @Override + public String toString() { + return "UnacknowledgedClientBulkWriteResult{}"; + } +} diff --git a/driver-core/src/main/com/mongodb/internal/client/model/bulk/package-info.java b/driver-core/src/main/com/mongodb/internal/client/model/bulk/package-info.java new file mode 100644 index 00000000000..2d66f44646b --- /dev/null +++ b/driver-core/src/main/com/mongodb/internal/client/model/bulk/package-info.java @@ -0,0 +1,23 @@ +/* + * Copyright 2008-present MongoDB, Inc. + * + * 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. + */ + +/** + * Internal program elements related to {@link com.mongodb.client.model.bulk}. + */ +@NonNullApi +package com.mongodb.internal.client.model.bulk; + +import com.mongodb.lang.NonNullApi; diff --git a/driver-core/src/main/com/mongodb/internal/operation/OperationHelper.java b/driver-core/src/main/com/mongodb/internal/operation/OperationHelper.java index ac69f8742c7..f65d856451d 100644 --- a/driver-core/src/main/com/mongodb/internal/operation/OperationHelper.java +++ b/driver-core/src/main/com/mongodb/internal/operation/OperationHelper.java @@ -16,7 +16,9 @@ package com.mongodb.internal.operation; +import com.mongodb.ClientBulkWriteException; import com.mongodb.MongoClientException; +import com.mongodb.MongoException; import com.mongodb.WriteConcern; import com.mongodb.client.cursor.TimeoutMode; import com.mongodb.client.model.Collation; @@ -47,7 +49,10 @@ import static com.mongodb.internal.operation.ServerVersionHelper.serverIsLessThanVersionFourDotTwo; import static java.lang.String.format; -final class OperationHelper { +/** + * This class is not part of the public API and may be removed or changed at any time. + */ +public final class OperationHelper { public static final Logger LOGGER = Loggers.getLogger("operation"); static void validateCollationAndWriteConcern(@Nullable final Collation collation, final WriteConcern writeConcern) { @@ -202,6 +207,20 @@ static void setNonTailableCursorMaxTimeSupplier(final TimeoutMode timeoutMode, f } } + /** + * Returns the {@link MongoException} that carries or should carry + * the {@linkplain MongoException#getCode() error code} and {@linkplain MongoException#getErrorLabels() error labels}. + * This method is needed because exceptions like {@link ClientBulkWriteException} do not carry that data themselves. + */ + public static MongoException unwrap(final MongoException exception) { + MongoException result = exception; + if (exception instanceof ClientBulkWriteException) { + result = ((ClientBulkWriteException) exception).getError().orElse(exception); + } + return result; + } + + /** * This internal exception is used to *
    diff --git a/driver-kotlin-coroutine/src/integration/kotlin/com/mongodb/kotlin/client/coroutine/syncadapter/SyncMongoCluster.kt b/driver-kotlin-coroutine/src/integration/kotlin/com/mongodb/kotlin/client/coroutine/syncadapter/SyncMongoCluster.kt index 42313ed2b13..a3f4eada2a0 100644 --- a/driver-kotlin-coroutine/src/integration/kotlin/com/mongodb/kotlin/client/coroutine/syncadapter/SyncMongoCluster.kt +++ b/driver-kotlin-coroutine/src/integration/kotlin/com/mongodb/kotlin/client/coroutine/syncadapter/SyncMongoCluster.kt @@ -25,6 +25,9 @@ import com.mongodb.client.ListDatabasesIterable import com.mongodb.client.MongoCluster as JMongoCluster import com.mongodb.client.MongoDatabase import com.mongodb.client.MongoIterable +import com.mongodb.client.model.bulk.ClientBulkWriteOptions +import com.mongodb.client.model.bulk.ClientBulkWriteResult +import com.mongodb.client.model.bulk.ClientNamespacedWriteModel import com.mongodb.kotlin.client.coroutine.MongoCluster import java.util.concurrent.TimeUnit import kotlinx.coroutines.runBlocking @@ -111,5 +114,31 @@ internal open class SyncMongoCluster(open val wrapped: MongoCluster) : JMongoClu ): ChangeStreamIterable = SyncChangeStreamIterable(wrapped.watch(clientSession.unwrapped(), pipeline, resultClass)) + override fun bulkWrite(models: MutableList): ClientBulkWriteResult { + TODO("BULK-TODO implement") + } + + override fun bulkWrite( + models: MutableList, + options: ClientBulkWriteOptions + ): ClientBulkWriteResult { + TODO("BULK-TODO implement") + } + + override fun bulkWrite( + clientSession: ClientSession, + models: MutableList + ): ClientBulkWriteResult { + TODO("BULK-TODO implement") + } + + override fun bulkWrite( + clientSession: ClientSession, + models: MutableList, + options: ClientBulkWriteOptions + ): ClientBulkWriteResult { + TODO("BULK-TODO implement") + } + private fun ClientSession.unwrapped() = (this as SyncClientSession).wrapped } diff --git a/driver-kotlin-sync/src/integration/kotlin/com/mongodb/kotlin/client/syncadapter/SyncMongoCluster.kt b/driver-kotlin-sync/src/integration/kotlin/com/mongodb/kotlin/client/syncadapter/SyncMongoCluster.kt index 7b948fa6d1d..55cc156d0a3 100644 --- a/driver-kotlin-sync/src/integration/kotlin/com/mongodb/kotlin/client/syncadapter/SyncMongoCluster.kt +++ b/driver-kotlin-sync/src/integration/kotlin/com/mongodb/kotlin/client/syncadapter/SyncMongoCluster.kt @@ -25,6 +25,9 @@ import com.mongodb.client.ListDatabasesIterable import com.mongodb.client.MongoCluster as JMongoCluster import com.mongodb.client.MongoDatabase import com.mongodb.client.MongoIterable +import com.mongodb.client.model.bulk.ClientBulkWriteOptions +import com.mongodb.client.model.bulk.ClientBulkWriteResult +import com.mongodb.client.model.bulk.ClientNamespacedWriteModel import com.mongodb.kotlin.client.MongoCluster import java.util.concurrent.TimeUnit import org.bson.Document @@ -110,5 +113,31 @@ internal open class SyncMongoCluster(open val wrapped: MongoCluster) : JMongoClu ): ChangeStreamIterable = SyncChangeStreamIterable(wrapped.watch(clientSession.unwrapped(), pipeline, resultClass)) + override fun bulkWrite(models: MutableList): ClientBulkWriteResult { + TODO("BULK-TODO implement") + } + + override fun bulkWrite( + models: MutableList, + options: ClientBulkWriteOptions + ): ClientBulkWriteResult { + TODO("BULK-TODO implement") + } + + override fun bulkWrite( + clientSession: ClientSession, + models: MutableList + ): ClientBulkWriteResult { + TODO("BULK-TODO implement") + } + + override fun bulkWrite( + clientSession: ClientSession, + models: MutableList, + options: ClientBulkWriteOptions + ): ClientBulkWriteResult { + TODO("BULK-TODO implement") + } + private fun ClientSession.unwrapped() = (this as SyncClientSession).wrapped } diff --git a/driver-reactive-streams/src/main/com/mongodb/reactivestreams/client/internal/OperationExecutorImpl.java b/driver-reactive-streams/src/main/com/mongodb/reactivestreams/client/internal/OperationExecutorImpl.java index 1c89ab81d34..0a4b0318d1c 100644 --- a/driver-reactive-streams/src/main/com/mongodb/reactivestreams/client/internal/OperationExecutorImpl.java +++ b/driver-reactive-streams/src/main/com/mongodb/reactivestreams/client/internal/OperationExecutorImpl.java @@ -33,6 +33,7 @@ import com.mongodb.internal.connection.ReadConcernAwareNoOpSessionContext; import com.mongodb.internal.operation.AsyncReadOperation; import com.mongodb.internal.operation.AsyncWriteOperation; +import com.mongodb.internal.operation.OperationHelper; import com.mongodb.lang.Nullable; import com.mongodb.reactivestreams.client.ClientSession; import com.mongodb.reactivestreams.client.ReactiveContextProvider; @@ -96,8 +97,9 @@ public Mono execute(final AsyncReadOperation operation, final ReadPref sinkToCallback(sink).onResult(result, t); } })).doOnError((t) -> { - labelException(session, t); - unpinServerAddressOnTransientTransactionError(session, t); + Throwable exceptionToHandle = t instanceof MongoException ? OperationHelper.unwrap((MongoException) t) : t; + labelException(session, exceptionToHandle); + unpinServerAddressOnTransientTransactionError(session, exceptionToHandle); }); } }).subscribe(subscriber) @@ -126,8 +128,9 @@ public Mono execute(final AsyncWriteOperation operation, final ReadCon sinkToCallback(sink).onResult(result, t); } })).doOnError((t) -> { - labelException(session, t); - unpinServerAddressOnTransientTransactionError(session, t); + Throwable exceptionToHandle = t instanceof MongoException ? OperationHelper.unwrap((MongoException) t) : t; + labelException(session, exceptionToHandle); + unpinServerAddressOnTransientTransactionError(session, exceptionToHandle); }) ).subscribe(subscriber) ); diff --git a/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/syncadapter/SyncMongoClient.java b/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/syncadapter/SyncMongoClient.java index ceb5ea72769..3f2265cb795 100644 --- a/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/syncadapter/SyncMongoClient.java +++ b/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/syncadapter/SyncMongoClient.java @@ -16,6 +16,7 @@ package com.mongodb.reactivestreams.client.syncadapter; +import com.mongodb.ClientBulkWriteException; import com.mongodb.ClientSessionOptions; import com.mongodb.ReadConcern; import com.mongodb.ReadPreference; @@ -27,6 +28,9 @@ import com.mongodb.client.MongoCluster; import com.mongodb.client.MongoDatabase; import com.mongodb.client.MongoIterable; +import com.mongodb.client.model.bulk.ClientBulkWriteOptions; +import com.mongodb.client.model.bulk.ClientNamespacedWriteModel; +import com.mongodb.client.model.bulk.ClientBulkWriteResult; import com.mongodb.connection.ClusterDescription; import com.mongodb.reactivestreams.client.internal.BatchCursor; import org.bson.Document; @@ -274,6 +278,34 @@ public void close() { } + @Override + public ClientBulkWriteResult bulkWrite( + final List clientWriteModels) throws ClientBulkWriteException { + return delegate.bulkWrite(clientWriteModels); + } + + @Override + public ClientBulkWriteResult bulkWrite( + final List clientWriteModels, + final ClientBulkWriteOptions options) throws ClientBulkWriteException { + return delegate.bulkWrite(clientWriteModels, options); + } + + @Override + public ClientBulkWriteResult bulkWrite( + final ClientSession clientSession, + final List clientWriteModels) throws ClientBulkWriteException { + return delegate.bulkWrite(clientSession, clientWriteModels); + } + + @Override + public ClientBulkWriteResult bulkWrite( + final ClientSession clientSession, + final List clientWriteModels, + final ClientBulkWriteOptions options) throws ClientBulkWriteException { + return delegate.bulkWrite(clientSession, clientWriteModels, options); + } + @Override public ClusterDescription getClusterDescription() { return wrapped.getClusterDescription(); diff --git a/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/syncadapter/SyncMongoCluster.java b/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/syncadapter/SyncMongoCluster.java index 780f7260eb4..19e58f829b0 100644 --- a/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/syncadapter/SyncMongoCluster.java +++ b/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/syncadapter/SyncMongoCluster.java @@ -16,16 +16,21 @@ package com.mongodb.reactivestreams.client.syncadapter; +import com.mongodb.ClientBulkWriteException; import com.mongodb.ClientSessionOptions; import com.mongodb.ReadConcern; import com.mongodb.ReadPreference; import com.mongodb.WriteConcern; +import com.mongodb.assertions.Assertions; import com.mongodb.client.ChangeStreamIterable; import com.mongodb.client.ClientSession; import com.mongodb.client.ListDatabasesIterable; import com.mongodb.client.MongoCluster; import com.mongodb.client.MongoDatabase; import com.mongodb.client.MongoIterable; +import com.mongodb.client.model.bulk.ClientBulkWriteOptions; +import com.mongodb.client.model.bulk.ClientNamespacedWriteModel; +import com.mongodb.client.model.bulk.ClientBulkWriteResult; import org.bson.BsonDocument; import org.bson.Document; import org.bson.codecs.configuration.CodecRegistry; @@ -278,6 +283,34 @@ public ChangeStreamIterable watch(final ClientSession clientS return new SyncChangeStreamIterable<>(wrapped.watch(unwrap(clientSession), pipeline, resultClass)); } + @Override + public ClientBulkWriteResult bulkWrite( + final List clientWriteModels) throws ClientBulkWriteException { + throw Assertions.fail("BULK-TODO implement"); + } + + @Override + public ClientBulkWriteResult bulkWrite( + final List clientWriteModels, + final ClientBulkWriteOptions options) throws ClientBulkWriteException { + throw Assertions.fail("BULK-TODO implement"); + } + + @Override + public ClientBulkWriteResult bulkWrite( + final ClientSession clientSession, + final List clientWriteModels) throws ClientBulkWriteException { + throw Assertions.fail("BULK-TODO implement"); + } + + @Override + public ClientBulkWriteResult bulkWrite( + final ClientSession clientSession, + final List clientWriteModels, + final ClientBulkWriteOptions options) throws ClientBulkWriteException { + throw Assertions.fail("BULK-TODO implement"); + } + private com.mongodb.reactivestreams.client.ClientSession unwrap(final ClientSession clientSession) { return ((SyncClientSession) clientSession).getWrapped(); } diff --git a/driver-scala/src/integration/scala/org/mongodb/scala/syncadapter/SyncMongoCluster.scala b/driver-scala/src/integration/scala/org/mongodb/scala/syncadapter/SyncMongoCluster.scala index 3871aded144..15f4be00d0d 100644 --- a/driver-scala/src/integration/scala/org/mongodb/scala/syncadapter/SyncMongoCluster.scala +++ b/driver-scala/src/integration/scala/org/mongodb/scala/syncadapter/SyncMongoCluster.scala @@ -1,5 +1,7 @@ package org.mongodb.scala.syncadapter +import com.mongodb.assertions.Assertions +import com.mongodb.client.model.bulk.{ ClientBulkWriteOptions, ClientBulkWriteResult, ClientNamespacedWriteModel } import com.mongodb.{ ClientSessionOptions, ReadConcern, ReadPreference, WriteConcern } import com.mongodb.client.{ ClientSession, MongoCluster => JMongoCluster, MongoDatabase => JMongoDatabase } import org.bson.Document @@ -8,6 +10,7 @@ import org.bson.conversions.Bson import org.mongodb.scala.MongoCluster import org.mongodb.scala.bson.DefaultHelper.DefaultsTo +import java.util import java.util.concurrent.TimeUnit import scala.collection.JavaConverters._ import scala.concurrent.Await @@ -123,4 +126,28 @@ class SyncMongoCluster(wrapped: MongoCluster) extends JMongoCluster { private def unwrap(clientSession: ClientSession): org.mongodb.scala.ClientSession = clientSession.asInstanceOf[SyncClientSession].wrapped + + override def bulkWrite( + models: util.List[_ <: ClientNamespacedWriteModel] + ): ClientBulkWriteResult = + throw Assertions.fail("BULK-TODO implement") + + override def bulkWrite( + models: util.List[_ <: ClientNamespacedWriteModel], + options: ClientBulkWriteOptions + ): ClientBulkWriteResult = + throw Assertions.fail("BULK-TODO implement") + + override def bulkWrite( + clientSession: ClientSession, + models: util.List[_ <: ClientNamespacedWriteModel] + ): ClientBulkWriteResult = + throw Assertions.fail("BULK-TODO implement") + + override def bulkWrite( + clientSession: ClientSession, + models: util.List[_ <: ClientNamespacedWriteModel], + options: ClientBulkWriteOptions + ): ClientBulkWriteResult = + throw Assertions.fail("BULK-TODO implement") } diff --git a/driver-sync/src/main/com/mongodb/client/MongoCluster.java b/driver-sync/src/main/com/mongodb/client/MongoCluster.java index f901845333b..f097f71288f 100644 --- a/driver-sync/src/main/com/mongodb/client/MongoCluster.java +++ b/driver-sync/src/main/com/mongodb/client/MongoCluster.java @@ -16,7 +16,10 @@ package com.mongodb.client; +import com.mongodb.ClientBulkWriteException; import com.mongodb.ClientSessionOptions; +import com.mongodb.MongoClientSettings; +import com.mongodb.MongoException; import com.mongodb.MongoNamespace; import com.mongodb.ReadConcern; import com.mongodb.ReadPreference; @@ -24,6 +27,11 @@ import com.mongodb.annotations.Alpha; import com.mongodb.annotations.Immutable; import com.mongodb.annotations.Reason; +import com.mongodb.client.model.bulk.ClientBulkWriteOptions; +import com.mongodb.client.model.bulk.ClientNamespacedDeleteManyModel; +import com.mongodb.client.model.bulk.ClientNamespacedUpdateManyModel; +import com.mongodb.client.model.bulk.ClientNamespacedWriteModel; +import com.mongodb.client.model.bulk.ClientBulkWriteResult; import com.mongodb.lang.Nullable; import org.bson.Document; import org.bson.codecs.configuration.CodecRegistry; @@ -352,4 +360,115 @@ public interface MongoCluster { * @mongodb.driver.dochub core/changestreams Change Streams */ ChangeStreamIterable watch(ClientSession clientSession, List pipeline, Class resultClass); + + /** + * Executes a client-level bulk write operation. + * This method is functionally equivalent to {@link #bulkWrite(List, ClientBulkWriteOptions)} + * with the {@linkplain ClientBulkWriteOptions#clientBulkWriteOptions() default options}. + *

    + * This operation supports {@linkplain MongoClientSettings#getRetryWrites() retryable writes}. + * Depending on the number of {@code models}, encoded size of {@code models}, and the size limits in effect, + * executing this operation may require multiple {@code bulkWrite} commands. + * The eligibility for retries is determined per each {@code bulkWrite} command: + * {@link ClientNamespacedUpdateManyModel}, {@link ClientNamespacedDeleteManyModel} in a command render it non-retryable.

    + *

    + * This operation is not supported by MongoDB Atlas Serverless instances.

    + * + * @param models The {@linkplain ClientNamespacedWriteModel individual write operations}. + * @return The {@link ClientBulkWriteResult} if the operation is successful. + * @throws ClientBulkWriteException If and only if the operation is unsuccessful or partially unsuccessful, + * and there is at least one of the following pieces of information to report: + * {@link ClientBulkWriteException#getWriteConcernErrors()}, {@link ClientBulkWriteException#getWriteErrors()}, + * {@link ClientBulkWriteException#getPartialResult()}. + * @throws MongoException Only if the operation is unsuccessful. + * @since 5.3 + * @mongodb.server.release 8.0 + * @mongodb.driver.manual reference/command/bulkWrite/ bulkWrite + */ + ClientBulkWriteResult bulkWrite(List models) throws ClientBulkWriteException; + + /** + * Executes a client-level bulk write operation. + *

    + * This operation supports {@linkplain MongoClientSettings#getRetryWrites() retryable writes}. + * Depending on the number of {@code models}, encoded size of {@code models}, and the size limits in effect, + * executing this operation may require multiple {@code bulkWrite} commands. + * The eligibility for retries is determined per each {@code bulkWrite} command: + * {@link ClientNamespacedUpdateManyModel}, {@link ClientNamespacedDeleteManyModel} in a command render it non-retryable.

    + *

    + * This operation is not supported by MongoDB Atlas Serverless instances.

    + * + * @param models The {@linkplain ClientNamespacedWriteModel individual write operations}. + * @param options The options. + * @return The {@link ClientBulkWriteResult} if the operation is successful. + * @throws ClientBulkWriteException If and only if the operation is unsuccessful or partially unsuccessful, + * and there is at least one of the following pieces of information to report: + * {@link ClientBulkWriteException#getWriteConcernErrors()}, {@link ClientBulkWriteException#getWriteErrors()}, + * {@link ClientBulkWriteException#getPartialResult()}. + * @throws MongoException Only if the operation is unsuccessful. + * @since 5.3 + * @mongodb.server.release 8.0 + * @mongodb.driver.manual reference/command/bulkWrite/ bulkWrite + */ + ClientBulkWriteResult bulkWrite( + List models, + ClientBulkWriteOptions options) throws ClientBulkWriteException; + + /** + * Executes a client-level bulk write operation. + * This method is functionally equivalent to {@link #bulkWrite(ClientSession, List, ClientBulkWriteOptions)} + * with the {@linkplain ClientBulkWriteOptions#clientBulkWriteOptions() default options}. + *

    + * This operation supports {@linkplain MongoClientSettings#getRetryWrites() retryable writes}. + * Depending on the number of {@code models}, encoded size of {@code models}, and the size limits in effect, + * executing this operation may require multiple {@code bulkWrite} commands. + * The eligibility for retries is determined per each {@code bulkWrite} command: + * {@link ClientNamespacedUpdateManyModel}, {@link ClientNamespacedDeleteManyModel} in a command render it non-retryable.

    + *

    + * This operation is not supported by MongoDB Atlas Serverless instances.

    + * + * @param clientSession The {@linkplain ClientSession client session} with which to associate this operation. + * @param models The {@linkplain ClientNamespacedWriteModel individual write operations}. + * @return The {@link ClientBulkWriteResult} if the operation is successful. + * @throws ClientBulkWriteException If and only if the operation is unsuccessful or partially unsuccessful, + * and there is at least one of the following pieces of information to report: + * {@link ClientBulkWriteException#getWriteConcernErrors()}, {@link ClientBulkWriteException#getWriteErrors()}, + * {@link ClientBulkWriteException#getPartialResult()}. + * @throws MongoException Only if the operation is unsuccessful. + * @since 5.3 + * @mongodb.server.release 8.0 + * @mongodb.driver.manual reference/command/bulkWrite/ bulkWrite + */ + ClientBulkWriteResult bulkWrite( + ClientSession clientSession, + List models) throws ClientBulkWriteException; + + /** + * Executes a client-level bulk write operation. + *

    + * This operation supports {@linkplain MongoClientSettings#getRetryWrites() retryable writes}. + * Depending on the number of {@code models}, encoded size of {@code models}, and the size limits in effect, + * executing this operation may require multiple {@code bulkWrite} commands. + * The eligibility for retries is determined per each {@code bulkWrite} command: + * {@link ClientNamespacedUpdateManyModel}, {@link ClientNamespacedDeleteManyModel} in a command render it non-retryable.

    + *

    + * This operation is not supported by MongoDB Atlas Serverless instances.

    + * + * @param clientSession The {@linkplain ClientSession client session} with which to associate this operation. + * @param models The {@linkplain ClientNamespacedWriteModel individual write operations}. + * @param options The options. + * @return The {@link ClientBulkWriteResult} if the operation is successful. + * @throws ClientBulkWriteException If and only if the operation is unsuccessful or partially unsuccessful, + * and there is at least one of the following pieces of information to report: + * {@link ClientBulkWriteException#getWriteConcernErrors()}, {@link ClientBulkWriteException#getWriteErrors()}, + * {@link ClientBulkWriteException#getPartialResult()}. + * @throws MongoException Only if the operation is unsuccessful. + * @since 5.3 + * @mongodb.server.release 8.0 + * @mongodb.driver.manual reference/command/bulkWrite/ bulkWrite + */ + ClientBulkWriteResult bulkWrite( + ClientSession clientSession, + List models, + ClientBulkWriteOptions options) throws ClientBulkWriteException; } diff --git a/driver-sync/src/main/com/mongodb/client/internal/ClientSessionImpl.java b/driver-sync/src/main/com/mongodb/client/internal/ClientSessionImpl.java index d3bbd850ae0..b60fc90316a 100644 --- a/driver-sync/src/main/com/mongodb/client/internal/ClientSessionImpl.java +++ b/driver-sync/src/main/com/mongodb/client/internal/ClientSessionImpl.java @@ -30,6 +30,7 @@ import com.mongodb.internal.TimeoutContext; import com.mongodb.internal.operation.AbortTransactionOperation; import com.mongodb.internal.operation.CommitTransactionOperation; +import com.mongodb.internal.operation.OperationHelper; import com.mongodb.internal.operation.ReadOperation; import com.mongodb.internal.operation.WriteConcernHelper; import com.mongodb.internal.operation.WriteOperation; @@ -241,7 +242,8 @@ public T withTransaction(final TransactionBody transactionBody, final Tra abortTransaction(); } if (e instanceof MongoException && !(e instanceof MongoOperationTimeoutException)) { - if (((MongoException) e).hasErrorLabel(TRANSIENT_TRANSACTION_ERROR_LABEL) + MongoException exceptionToHandle = OperationHelper.unwrap((MongoException) e); + if (exceptionToHandle.hasErrorLabel(TRANSIENT_TRANSACTION_ERROR_LABEL) && ClientSessionClock.INSTANCE.now() - startTime < MAX_RETRY_TIME_LIMIT_MS) { continue; } diff --git a/driver-sync/src/main/com/mongodb/client/internal/MongoClientImpl.java b/driver-sync/src/main/com/mongodb/client/internal/MongoClientImpl.java index 473d8ec4e8e..e15ecbb406a 100644 --- a/driver-sync/src/main/com/mongodb/client/internal/MongoClientImpl.java +++ b/driver-sync/src/main/com/mongodb/client/internal/MongoClientImpl.java @@ -17,6 +17,7 @@ package com.mongodb.client.internal; import com.mongodb.AutoEncryptionSettings; +import com.mongodb.ClientBulkWriteException; import com.mongodb.ClientSessionOptions; import com.mongodb.MongoClientSettings; import com.mongodb.MongoDriverInformation; @@ -31,6 +32,9 @@ import com.mongodb.client.MongoDatabase; import com.mongodb.client.MongoIterable; import com.mongodb.client.SynchronousContextProvider; +import com.mongodb.client.model.bulk.ClientBulkWriteOptions; +import com.mongodb.client.model.bulk.ClientNamespacedWriteModel; +import com.mongodb.client.model.bulk.ClientBulkWriteResult; import com.mongodb.connection.ClusterDescription; import com.mongodb.connection.SocketSettings; import com.mongodb.connection.TransportSettings; @@ -256,6 +260,34 @@ public ChangeStreamIterable watch( return delegate.watch(clientSession, pipeline, resultClass); } + @Override + public ClientBulkWriteResult bulkWrite( + final List clientWriteModels) throws ClientBulkWriteException { + return delegate.bulkWrite(clientWriteModels); + } + + @Override + public ClientBulkWriteResult bulkWrite( + final List clientWriteModels, + final ClientBulkWriteOptions options) throws ClientBulkWriteException { + return delegate.bulkWrite(clientWriteModels, options); + } + + @Override + public ClientBulkWriteResult bulkWrite( + final ClientSession clientSession, + final List clientWriteModels) throws ClientBulkWriteException { + return delegate.bulkWrite(clientSession, clientWriteModels); + } + + @Override + public ClientBulkWriteResult bulkWrite( + final ClientSession clientSession, + final List clientWriteModels, + final ClientBulkWriteOptions options) throws ClientBulkWriteException { + return delegate.bulkWrite(clientSession, clientWriteModels, options); + } + private static Cluster createCluster(final MongoClientSettings settings, @Nullable final MongoDriverInformation mongoDriverInformation) { notNull("settings", settings); diff --git a/driver-sync/src/main/com/mongodb/client/internal/MongoClusterImpl.java b/driver-sync/src/main/com/mongodb/client/internal/MongoClusterImpl.java index b3d03095070..d6eded9cda6 100644 --- a/driver-sync/src/main/com/mongodb/client/internal/MongoClusterImpl.java +++ b/driver-sync/src/main/com/mongodb/client/internal/MongoClusterImpl.java @@ -17,6 +17,7 @@ package com.mongodb.client.internal; import com.mongodb.AutoEncryptionSettings; +import com.mongodb.ClientBulkWriteException; import com.mongodb.ClientSessionOptions; import com.mongodb.MongoClientException; import com.mongodb.MongoException; @@ -30,6 +31,7 @@ import com.mongodb.ServerApi; import com.mongodb.TransactionOptions; import com.mongodb.WriteConcern; +import com.mongodb.assertions.Assertions; import com.mongodb.client.ChangeStreamIterable; import com.mongodb.client.ClientSession; import com.mongodb.client.ListDatabasesIterable; @@ -37,6 +39,9 @@ import com.mongodb.client.MongoDatabase; import com.mongodb.client.MongoIterable; import com.mongodb.client.SynchronousContextProvider; +import com.mongodb.client.model.bulk.ClientBulkWriteOptions; +import com.mongodb.client.model.bulk.ClientNamespacedWriteModel; +import com.mongodb.client.model.bulk.ClientBulkWriteResult; import com.mongodb.internal.IgnorableRequestContext; import com.mongodb.internal.TimeoutSettings; import com.mongodb.internal.binding.ClusterAwareReadWriteBinding; @@ -48,6 +53,7 @@ import com.mongodb.internal.connection.Cluster; import com.mongodb.internal.connection.OperationContext; import com.mongodb.internal.connection.ReadConcernAwareNoOpSessionContext; +import com.mongodb.internal.operation.OperationHelper; import com.mongodb.internal.operation.ReadOperation; import com.mongodb.internal.operation.WriteOperation; import com.mongodb.internal.session.ServerSessionPool; @@ -307,6 +313,42 @@ public ChangeStreamIterable watch(final ClientSession clientS return createChangeStreamIterable(clientSession, pipeline, clazz); } + @Override + public ClientBulkWriteResult bulkWrite( + final List clientWriteModels) throws ClientBulkWriteException { + notNull("clientWriteModels", clientWriteModels); + throw Assertions.fail("BULK-TODO implement"); + } + + @Override + public ClientBulkWriteResult bulkWrite( + final List clientWriteModels, + final ClientBulkWriteOptions options) throws ClientBulkWriteException { + notNull("clientWriteModels", clientWriteModels); + notNull("options", options); + throw Assertions.fail("BULK-TODO implement"); + } + + @Override + public ClientBulkWriteResult bulkWrite( + final ClientSession clientSession, + final List clientWriteModels) throws ClientBulkWriteException { + notNull("clientSession", clientSession); + notNull("clientWriteModels", clientWriteModels); + throw Assertions.fail("BULK-TODO implement"); + } + + @Override + public ClientBulkWriteResult bulkWrite( + final ClientSession clientSession, + final List clientWriteModels, + final ClientBulkWriteOptions options) throws ClientBulkWriteException { + notNull("clientSession", clientSession); + notNull("clientWriteModels", clientWriteModels); + notNull("options", options); + throw Assertions.fail("BULK-TODO implement"); + } + private ListDatabasesIterable createListDatabasesIterable(@Nullable final ClientSession clientSession, final Class clazz) { return new ListDatabasesIterableImpl<>(clientSession, clazz, codecRegistry, ReadPreference.primary(), operationExecutor, retryReads, timeoutSettings); } @@ -357,8 +399,9 @@ public T execute(final ReadOperation operation, final ReadPreference read } return operation.execute(binding); } catch (MongoException e) { - labelException(actualClientSession, e); - clearTransactionContextOnTransientTransactionError(session, e); + MongoException exceptionToHandle = OperationHelper.unwrap(e); + labelException(actualClientSession, exceptionToHandle); + clearTransactionContextOnTransientTransactionError(session, exceptionToHandle); throw e; } finally { binding.release(); @@ -378,8 +421,9 @@ public T execute(final WriteOperation operation, final ReadConcern readCo try { return operation.execute(binding); } catch (MongoException e) { - labelException(actualClientSession, e); - clearTransactionContextOnTransientTransactionError(session, e); + MongoException exceptionToHandle = OperationHelper.unwrap(e); + labelException(actualClientSession, exceptionToHandle); + clearTransactionContextOnTransientTransactionError(session, exceptionToHandle); throw e; } finally { binding.release();