Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue 90: Convert DropCollection to execute as a runCommand #99

Merged
merged 2 commits into from
Feb 16, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 10 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ Liquibase turned to be the most feasible tool to extend as it allows to define c
<a name="release-notes"></a>
## 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)
Expand Down Expand Up @@ -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) -
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ public class CreateCollectionStatement extends AbstractRunCommandStatement {

public static final String RUN_COMMAND_NAME = "create";

public CreateCollectionStatement(final String collectionName) {
this(collectionName, (String) null);
}

public CreateCollectionStatement(final String collectionName, final String options) {
this(collectionName, BsonUtils.orEmptyDocument(options));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,10 @@
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 <a href="https://docs.mongodb.com/manual/reference/command/createIndexes//">createIndexes</a>
*
* @see <a href="https://docs.mongodb.com/manual/reference/command/createIndexes/">createIndexes</a>
*/
@Getter
@EqualsAndHashCode(callSuper = true)
Expand All @@ -45,11 +46,6 @@ public class CreateIndexStatement extends AbstractRunCommandStatement
private static final String KEY = "key";
private static final String INDEXES = "indexes";

@Override
public String getRunCommandName() {
return RUN_COMMAND_NAME;
}

public CreateIndexStatement(final String collectionName, final Document keys, final Document options) {
super(toCommand(RUN_COMMAND_NAME, collectionName, combine(keys, options)));
}
Expand All @@ -58,6 +54,11 @@ public CreateIndexStatement(final String collectionName, final String keys, fina
this(collectionName, orEmptyDocument(keys), orEmptyDocument(options));
}

@Override
public String getRunCommandName() {
return RUN_COMMAND_NAME;
}

private static Document combine(final Document key, final Document options) {

final Document indexDocument = new Document(KEY, key);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,11 @@
* #L%
*/

import com.mongodb.client.MongoCollection;
import liquibase.ext.mongodb.database.MongoLiquibaseDatabase;
import liquibase.nosql.statement.NoSqlExecuteStatement;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import org.bson.Document;

import java.util.function.Consumer;

Expand All @@ -45,8 +43,8 @@ public String getCommandName() {
@Override
public void execute(final MongoLiquibaseDatabase database) {
getMongoDatabase(database).listCollectionNames()
.map(getMongoDatabase(database)::getCollection)
.forEach((Consumer<? super MongoCollection<Document>>) MongoCollection::drop);
.map(DropCollectionStatement::new)
.forEach((Consumer<? super DropCollectionStatement>) s -> s.execute(database));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -20,46 +20,32 @@
* #L%
*/

import com.mongodb.client.MongoCollection;
import liquibase.ext.mongodb.database.MongoLiquibaseDatabase;
import liquibase.nosql.statement.NoSqlExecuteStatement;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import org.bson.Document;

import static liquibase.ext.mongodb.statement.AbstractRunCommandStatement.SHELL_DB_PREFIX;
import static liquibase.ext.mongodb.statement.BsonUtils.toCommand;

/**
* Drops a collection via the database runCommand method
* For a list of supported options see the reference page:
*
* @see <a href="https://docs.mongodb.com/manual/reference/command/drop/">drop</a>
*/
@Getter
@EqualsAndHashCode(callSuper = true)
public class DropCollectionStatement extends AbstractCollectionStatement
public class DropCollectionStatement extends AbstractRunCommandStatement
implements NoSqlExecuteStatement<MongoLiquibaseDatabase> {

public static final String COMMAND_NAME = "drop";
public static final String RUN_COMMAND_NAME = "drop";

public DropCollectionStatement(final String collectionName) {
super(collectionName);
}

@Override
public String getCommandName() {
return COMMAND_NAME;
super(toCommand(RUN_COMMAND_NAME, collectionName, null));
}

@Override
public String toJs() {
return
SHELL_DB_PREFIX +
getCollectionName() +
"." +
getCommandName() +
"(" +
");";
public String getRunCommandName() {
return RUN_COMMAND_NAME;
}

@Override
public void execute(final MongoLiquibaseDatabase database) {
final MongoCollection<Document> collection = getMongoDatabase(database).getCollection(getCollectionName());
collection.drop();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -26,48 +26,38 @@
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 <a href="https://docs.mongodb.com/manual/reference/command/dropIndexes/">dropIndexes</a>
*/
@Getter
@EqualsAndHashCode(callSuper = true)
public class DropIndexStatement extends AbstractCollectionStatement
public class DropIndexStatement extends AbstractRunCommandStatement
implements NoSqlExecuteStatement<MongoLiquibaseDatabase> {

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) {
this(collectionName, orEmptyDocument(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);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@

<xsd:sequence>
<xsd:element name="keys" type="xsd:string" minOccurs="1" maxOccurs="1"/>
<xsd:element name="options" type="xsd:string" minOccurs="1" maxOccurs="1"/>
<xsd:element name="options" type="xsd:string" minOccurs="0" maxOccurs="1"/>
</xsd:sequence>

<xsd:attribute name="collectionName" type="xsd:string" use="required"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ void getConfirmationMessage() {
.hasSize(1)
.first()
.isInstanceOf(DropCollectionStatement.class)
.returns("collection1", s -> ((DropCollectionStatement) s).getCollectionName());
.returns("drop", s -> ((DropCollectionStatement) s).getRunCommandName())
.returns("collection1", s -> ((DropCollectionStatement) s).getCommand().get("drop"));
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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
Expand All @@ -56,20 +78,60 @@ void generateStatements() {
final List<ChangeSet> 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<Change> 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());
}
}
Loading