diff --git a/README.md b/README.md
index 9a835a95..5dc520d2 100644
--- a/README.md
+++ b/README.md
@@ -28,6 +28,10 @@ Liquibase turned to be the most feasible tool to extend as it allows to define c
## Release Notes
+#### 4.3.1
+* Support for Liquibase 4.3.1
+* Fixed [Issue-90: Convert all statements to runCommand so it is compatible with majority JavaDriver versions](https://github.com/liquibase/liquibase-mongodb/issues/90)
+
#### 4.2.2.1
* Fixed [Issue-64:Support for DNS Seed List Connection Format or Atlas Cluster](https://github.com/liquibase/liquibase-mongodb/issues/66)
* Fixed [Issue-69: Does it support preconditions](https://github.com/liquibase/liquibase-mongodb/issues/69)
@@ -89,17 +93,17 @@ Previous releases used by default : `databaseChangeLogLock, databaseChangeLog`
A couple of Changes were implemented until identified that majority of the operations can be achieved using `db.runCommand()` and `db.adminCommand()`
* [createCollection](https://docs.mongodb.com/manual/reference/method/db.createCollection/#db.createCollection) -
-Creates a collection with validator
+Creates a collection with validator [create](https://docs.mongodb.com/manual/reference/command/create/)
* [dropCollection](https://docs.mongodb.com/manual/reference/method/db.collection.drop/#db-collection-drop) -
-Removes a collection or view from the database
+Removes a collection or view from the database [drop](https://docs.mongodb.com/manual/reference/command/drop/)
* [createIndex](https://docs.mongodb.com/manual/reference/method/db.collection.createIndex/#db.collection.createIndex) -
-Creates an index for a collection
+Creates an index for a collection [createIndexes](https://docs.mongodb.com/manual/reference/command/createIndexes/)
* [dropIndex](https://docs.mongodb.com/manual/reference/method/db.collection.dropIndex/#db.collection.dropIndex) -
-Drops index for a collection by keys
+Drops index for a collection by keys [dropIndexes](https://docs.mongodb.com/manual/reference/command/dropIndexes/)
* [insertMany](https://docs.mongodb.com/manual/reference/method/db.collection.insertMany/#db.collection.insertMany) -
-Inserts multiple documents into a collection
+Inserts multiple documents into a collection [insert](https://docs.mongodb.com/manual/reference/command/insert/)
* [insertOne](https://docs.mongodb.com/manual/tutorial/insert-documents/#insert-a-single-document) -
-Inserts a Single Document into a collection
+Inserts a Single Document into a collection [insert](https://docs.mongodb.com/manual/reference/command/insert/)
* [__runCommand__](https://docs.mongodb.com/manual/reference/method/db.runCommand/#db-runcommand) -
Provides a helper to run specified database commands. This is the preferred method to issue database commands, as it provides a consistent interface between the shell and drivers
* [__adminCommand__](https://docs.mongodb.com/manual/reference/method/db.adminCommand/#db.adminCommand) -
diff --git a/src/main/java/liquibase/ext/mongodb/statement/CreateIndexStatement.java b/src/main/java/liquibase/ext/mongodb/statement/CreateIndexStatement.java
index e32b571d..89c53ccd 100644
--- a/src/main/java/liquibase/ext/mongodb/statement/CreateIndexStatement.java
+++ b/src/main/java/liquibase/ext/mongodb/statement/CreateIndexStatement.java
@@ -32,7 +32,7 @@
import static liquibase.ext.mongodb.statement.BsonUtils.toCommand;
/**
- * Creates a index via the database runCommand method
+ * Creates an index via the database runCommand method
* For a list of supported options see the reference page:
*
* @see createIndexes
diff --git a/src/main/java/liquibase/ext/mongodb/statement/DropIndexStatement.java b/src/main/java/liquibase/ext/mongodb/statement/DropIndexStatement.java
index 17c28672..28cfd2d9 100644
--- a/src/main/java/liquibase/ext/mongodb/statement/DropIndexStatement.java
+++ b/src/main/java/liquibase/ext/mongodb/statement/DropIndexStatement.java
@@ -26,22 +26,25 @@
import lombok.Getter;
import org.bson.Document;
-import static java.util.Optional.ofNullable;
-import static liquibase.ext.mongodb.statement.AbstractRunCommandStatement.SHELL_DB_PREFIX;
import static liquibase.ext.mongodb.statement.BsonUtils.orEmptyDocument;
+import static liquibase.ext.mongodb.statement.BsonUtils.toCommand;
+/**
+ * Drops an index via the database runCommand method
+ * For a list of supported options see the reference page:
+ *
+ * @see dropIndexes
+ */
@Getter
@EqualsAndHashCode(callSuper = true)
-public class DropIndexStatement extends AbstractCollectionStatement
+public class DropIndexStatement extends AbstractRunCommandStatement
implements NoSqlExecuteStatement {
- public static final String COMMAND_NAME = "dropIndex";
-
- private final Document keys;
+ public static final String RUN_COMMAND_NAME = "dropIndexes";
+ private static final String INDEX = "index";
public DropIndexStatement(final String collectionName, final Document keys) {
- super(collectionName);
- this.keys = keys;
+ super(toCommand(RUN_COMMAND_NAME, collectionName, combine(keys)));
}
public DropIndexStatement(final String collectionName, final String keys) {
@@ -49,25 +52,12 @@ public DropIndexStatement(final String collectionName, final String keys) {
}
@Override
- public String getCommandName() {
- return COMMAND_NAME;
+ public String getRunCommandName() {
+ return RUN_COMMAND_NAME;
}
- @Override
- public String toJs() {
- return
- SHELL_DB_PREFIX
- + getCollectionName()
- + ". "
- + getCommandName()
- + "("
- + ofNullable(keys).map(Document::toJson).orElse(null)
- + ");";
- }
-
- @Override
- public void execute(final MongoLiquibaseDatabase database) {
- getMongoDatabase(database).getCollection(collectionName).dropIndex(keys);
+ private static Document combine(final Document keys) {
+ return new Document(INDEX, keys);
}
}
diff --git a/src/main/resources/liquibase.parser.core.xml/dbchangelog-ext.xsd b/src/main/resources/liquibase.parser.core.xml/dbchangelog-ext.xsd
index c52dd6ec..cddf4330 100644
--- a/src/main/resources/liquibase.parser.core.xml/dbchangelog-ext.xsd
+++ b/src/main/resources/liquibase.parser.core.xml/dbchangelog-ext.xsd
@@ -65,7 +65,7 @@
-
+
diff --git a/src/test/java/liquibase/ext/mongodb/change/CreateIndexChangeTest.java b/src/test/java/liquibase/ext/mongodb/change/CreateIndexChangeTest.java
index de1b16e8..79abe4dc 100644
--- a/src/test/java/liquibase/ext/mongodb/change/CreateIndexChangeTest.java
+++ b/src/test/java/liquibase/ext/mongodb/change/CreateIndexChangeTest.java
@@ -21,9 +21,13 @@
*/
import liquibase.change.Change;
+import liquibase.change.CheckSum;
import liquibase.changelog.ChangeSet;
+import liquibase.ext.mongodb.statement.AbstractRunCommandStatement;
+import liquibase.ext.mongodb.statement.CreateIndexStatement;
import liquibase.ext.mongodb.statement.DropIndexStatement;
import lombok.SneakyThrows;
+import org.bson.Document;
import org.junit.jupiter.api.Test;
import java.util.Arrays;
@@ -40,14 +44,32 @@ void getConfirmationMessage() {
final CreateIndexChange createIndexChange = new CreateIndexChange();
createIndexChange.setCollectionName("collection1");
createIndexChange.setKeys("{ clientId: 1, type: 1}");
- assertThat(createIndexChange.getConfirmationMessage()).isEqualTo("Index created for collection collection1");
-
- assertThat(Arrays.asList(createIndexChange.generateRollbackStatements(database)))
- .hasSize(1)
- .first()
- .isInstanceOf(DropIndexStatement.class)
- .returns("collection1", s -> ((DropIndexStatement)s).getCollectionName())
- .returns("{\"clientId\": 1, \"type\": 1}", s -> ((DropIndexStatement)s).getKeys().toJson());
+
+ assertThat(createIndexChange)
+ .hasFieldOrPropertyWithValue("CollectionName", "collection1")
+ .hasFieldOrPropertyWithValue("keys", "{ clientId: 1, type: 1}")
+ .hasFieldOrPropertyWithValue("options", null)
+ .returns(CheckSum.parse("8:e6b1630ad2b20ef41a69eee853528099"), Change::generateCheckSum)
+ .returns("Index created for collection collection1", Change::getConfirmationMessage)
+ .returns(true, c -> c.supportsRollback(database));
+
+ assertThat(Arrays.asList(createIndexChange.generateStatements(database))).hasSize(1)
+ .hasOnlyElementsOfType(CreateIndexStatement.class).first().extracting(s -> (CreateIndexStatement) s)
+ .returns("createIndexes", CreateIndexStatement::getRunCommandName)
+ .returns("runCommand", AbstractRunCommandStatement::getCommandName)
+ .returns("collection1", s -> s.getCommand().get("createIndexes"))
+ .returns(null, s -> s.getCommand().getList("indexes", Document.class).get(0).get("name"))
+ .returns(null, s -> s.getCommand().getList("indexes", Document.class).get(0).get("unique"))
+ .returns("{\"clientId\": 1, \"type\": 1}",
+ s -> s.getCommand().getList("indexes", Document.class).get(0).get("key", Document.class).toJson());
+
+ assertThat(Arrays.asList(createIndexChange.generateRollbackStatements(database))).hasSize(1)
+ .hasOnlyElementsOfType(DropIndexStatement.class).first().extracting(s -> (DropIndexStatement) s)
+ .returns("dropIndexes", DropIndexStatement::getRunCommandName)
+ .returns("runCommand", AbstractRunCommandStatement::getCommandName)
+ .returns("collection1", s -> s.getCommand().get("dropIndexes"))
+ .returns("{\"clientId\": 1, \"type\": 1}",
+ s -> s.getCommand().get("index", Document.class).toJson());
}
@Test
@@ -56,20 +78,60 @@ void generateStatements() {
final List changeSets = getChangesets("liquibase/ext/changelog.create-index.test.xml", database);
assertThat(changeSets).hasSize(1).first()
- .returns("8:c2b981901db6061d2e034a4f31501ec5", s -> s.generateCheckSum().toString());
+ .returns("8:c2b981901db6061d2e034a4f31501ec5", s -> s.generateCheckSum().toString());
final List changes1 = changeSets.get(0).getChanges();
assertThat(changes1).hasSize(2);
assertThat(changes1).hasOnlyElementsOfType(CreateIndexChange.class);
assertThat(changes1.get(0))
- .hasFieldOrPropertyWithValue("CollectionName", "createIndexTest")
- .hasFieldOrPropertyWithValue("keys", "{ clientId: 1, type: 1}")
- .hasFieldOrPropertyWithValue("options", "{unique: true, name: \"ui_tppClientId\"}");
+ .hasFieldOrPropertyWithValue("CollectionName", "createIndexTest")
+ .hasFieldOrPropertyWithValue("keys", "{ clientId: 1, type: 1}")
+ .hasFieldOrPropertyWithValue("options", "{unique: true, name: \"ui_tppClientId\"}")
+ .returns(CheckSum.parse("8:2ea778164e5507ea6678158bee3f8959"), Change::generateCheckSum)
+ .returns(true, c -> c.supportsRollback(database));
+
+ assertThat(Arrays.asList(changes1.get(0).generateStatements(database))).hasSize(1)
+ .hasOnlyElementsOfType(CreateIndexStatement.class).first().extracting(s -> (CreateIndexStatement) s)
+ .returns("createIndexes", CreateIndexStatement::getRunCommandName)
+ .returns("runCommand", AbstractRunCommandStatement::getCommandName)
+ .returns("createIndexTest", s -> s.getCommand().get("createIndexes"))
+ .returns("ui_tppClientId", s -> s.getCommand().getList("indexes", Document.class).get(0).get("name"))
+ .returns(true, s -> s.getCommand().getList("indexes", Document.class).get(0).get("unique"))
+ .returns("{\"clientId\": 1, \"type\": 1}",
+ s -> s.getCommand().getList("indexes", Document.class).get(0).get("key", Document.class).toJson());
+
+ assertThat(Arrays.asList(changes1.get(0).generateRollbackStatements(database))).hasSize(1)
+ .hasOnlyElementsOfType(DropIndexStatement.class).first().extracting(s -> (DropIndexStatement) s)
+ .returns("dropIndexes", DropIndexStatement::getRunCommandName)
+ .returns("runCommand", AbstractRunCommandStatement::getCommandName)
+ .returns("createIndexTest", s -> s.getCommand().get("dropIndexes"))
+ .returns("{\"clientId\": 1, \"type\": 1}",
+ s -> s.getCommand().get("index", Document.class).toJson());
assertThat(changes1.get(1))
- .hasFieldOrPropertyWithValue("CollectionName", "createIndexNoOptionsTest")
- .hasFieldOrPropertyWithValue("keys", "{ clientId: 1, type: 1}")
- .hasFieldOrPropertyWithValue("options", null);
+ .hasFieldOrPropertyWithValue("CollectionName", "createIndexNoOptionsTest")
+ .hasFieldOrPropertyWithValue("keys", "{ clientId: 1, type: 1}")
+ .hasFieldOrPropertyWithValue("options", null)
+ .returns(CheckSum.parse("8:4499e67ade10db858b5eafa32665623f"), Change::generateCheckSum)
+ .returns(true, c -> c.supportsRollback(database));
+
+ assertThat(Arrays.asList(changes1.get(1).generateStatements(database))).hasSize(1)
+ .hasOnlyElementsOfType(CreateIndexStatement.class).first().extracting(s -> (CreateIndexStatement) s)
+ .returns("createIndexes", CreateIndexStatement::getRunCommandName)
+ .returns("runCommand", AbstractRunCommandStatement::getCommandName)
+ .returns("createIndexNoOptionsTest", s -> s.getCommand().get("createIndexes"))
+ .returns(null, s -> s.getCommand().getList("indexes", Document.class).get(0).get("name"))
+ .returns(null, s -> s.getCommand().getList("indexes", Document.class).get(0).get("unique"))
+ .returns("{\"clientId\": 1, \"type\": 1}",
+ s -> s.getCommand().getList("indexes", Document.class).get(0).get("key", Document.class).toJson());
+
+ assertThat(Arrays.asList(changes1.get(1).generateRollbackStatements(database))).hasSize(1)
+ .hasOnlyElementsOfType(DropIndexStatement.class).first().extracting(s -> (DropIndexStatement) s)
+ .returns("dropIndexes", DropIndexStatement::getRunCommandName)
+ .returns("runCommand", AbstractRunCommandStatement::getCommandName)
+ .returns("createIndexNoOptionsTest", s -> s.getCommand().get("dropIndexes"))
+ .returns("{\"clientId\": 1, \"type\": 1}",
+ s -> s.getCommand().get("index", Document.class).toJson());
}
}
diff --git a/src/test/java/liquibase/ext/mongodb/change/DropIndexChangeTest.java b/src/test/java/liquibase/ext/mongodb/change/DropIndexChangeTest.java
new file mode 100644
index 00000000..df78673e
--- /dev/null
+++ b/src/test/java/liquibase/ext/mongodb/change/DropIndexChangeTest.java
@@ -0,0 +1,60 @@
+package liquibase.ext.mongodb.change;
+
+/*-
+ * #%L
+ * Liquibase MongoDB Extension
+ * %%
+ * Copyright (C) 2021 Mastercard
+ * %%
+ * 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.
+ * #L%
+ */
+
+import liquibase.change.Change;
+import liquibase.change.CheckSum;
+import liquibase.ext.mongodb.statement.AbstractRunCommandStatement;
+import liquibase.ext.mongodb.statement.DropIndexStatement;
+import lombok.SneakyThrows;
+import org.bson.Document;
+import org.junit.jupiter.api.Test;
+
+import java.util.Arrays;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class DropIndexChangeTest extends AbstractMongoChangeTest {
+
+ @SneakyThrows
+ @Test
+ void getConfirmationMessage() {
+ final DropIndexChange dropIndexChange = new DropIndexChange();
+ dropIndexChange.setCollectionName("collection1");
+ dropIndexChange.setKeys("{ clientId: 1, type: 1}");
+
+ assertThat(dropIndexChange)
+ .hasFieldOrPropertyWithValue("CollectionName", "collection1")
+ .hasFieldOrPropertyWithValue("keys", "{ clientId: 1, type: 1}")
+ .returns(CheckSum.parse("8:016c274fba45cb1313dccf7866797235"), Change::generateCheckSum)
+ .returns("Index dropped for collection collection1", Change::getConfirmationMessage)
+ .returns(false, c -> c.supportsRollback(database));
+
+ assertThat(Arrays.asList(dropIndexChange.generateStatements(database))).hasSize(1)
+ .hasOnlyElementsOfType(DropIndexStatement.class).first().extracting(s -> (DropIndexStatement) s)
+ .returns("dropIndexes", DropIndexStatement::getRunCommandName)
+ .returns("runCommand", AbstractRunCommandStatement::getCommandName)
+ .returns("collection1", s -> s.getCommand().get("dropIndexes"))
+ .returns("{\"clientId\": 1, \"type\": 1}",
+ s -> s.getCommand().get("index", Document.class).toJson());
+ }
+
+}
diff --git a/src/test/java/liquibase/ext/mongodb/statement/DropIndexStatementIT.java b/src/test/java/liquibase/ext/mongodb/statement/DropIndexStatementIT.java
new file mode 100644
index 00000000..a872f68d
--- /dev/null
+++ b/src/test/java/liquibase/ext/mongodb/statement/DropIndexStatementIT.java
@@ -0,0 +1,69 @@
+package liquibase.ext.mongodb.statement;
+
+/*-
+ * #%L
+ * Liquibase MongoDB Extension
+ * %%
+ * Copyright (C) 2021 Mastercard
+ * %%
+ * 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.
+ * #L%
+ */
+
+import com.mongodb.MongoCommandException;
+import liquibase.ext.AbstractMongoIntegrationTest;
+import org.junit.jupiter.api.Test;
+
+import static java.util.stream.StreamSupport.stream;
+import static liquibase.ext.mongodb.TestUtils.COLLECTION_NAME_1;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
+
+class DropIndexStatementIT extends AbstractMongoIntegrationTest {
+
+ @Test
+ void toStringJs() {
+ final DropIndexStatement dropIndexStatement = new DropIndexStatement(COLLECTION_NAME_1, "{ locale: 1 }");
+ assertThat(dropIndexStatement.toString())
+ .isEqualTo(dropIndexStatement.toJs())
+ .isEqualTo("db.runCommand({\"dropIndexes\": \"collectionName\", \"index\": {\"locale\": 1}});");
+ }
+
+ @Test
+ void execute() {
+ final String indexName = "locale_indx";
+ mongoDatabase.createCollection(COLLECTION_NAME_1);
+ new CreateIndexStatement(COLLECTION_NAME_1, "{ locale: -1 }",
+ "{ name: \"" + indexName + "0" + "\", unique: true, expireAfterSeconds: NumberLong(\"30\") }").execute(database);
+
+ new CreateIndexStatement(COLLECTION_NAME_1, "{ locale: 1 }",
+ "{ name: \"" + indexName + "1" + "\", unique: true, expireAfterSeconds: NumberLong(\"30\") }").execute(database);
+
+ assertThat(stream(mongoDatabase.getCollection(COLLECTION_NAME_1).listIndexes().spliterator(), false)
+ .filter(doc -> doc.getString("name").startsWith(indexName)).count()).isEqualTo(2);
+
+ new DropIndexStatement(COLLECTION_NAME_1, "{ locale: 1 }").execute(database);
+
+ assertThat(stream(mongoDatabase.getCollection(COLLECTION_NAME_1).listIndexes().spliterator(), false)
+ .filter(doc -> doc.getString("name").startsWith(indexName)).count()).isEqualTo(1);
+
+ assertThat(stream(mongoDatabase.getCollection(COLLECTION_NAME_1).listIndexes().spliterator(), false)
+ .filter(doc -> doc.get("name").equals(indexName + "1")).count()).isEqualTo(0);
+
+ // repeatedly attempt to delete same index or not existing
+ assertThatExceptionOfType(MongoCommandException.class)
+ .isThrownBy(() -> new DropIndexStatement(COLLECTION_NAME_1, "{ locale: 1 }").execute(database))
+ .withMessageStartingWith("Command failed with error")
+ .withMessageContaining("can't find index with key");
+ }
+}