Skip to content

Commit

Permalink
Add collection exists precondition
Browse files Browse the repository at this point in the history
  • Loading branch information
Nemanja Vasic authored and alexandru-slobodcicov committed Nov 5, 2021
1 parent 48dc184 commit f85f571
Show file tree
Hide file tree
Showing 5 changed files with 142 additions and 24 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package liquibase.ext.mongodb.precondition;

import liquibase.changelog.ChangeSet;
import liquibase.changelog.DatabaseChangeLog;
import liquibase.changelog.visitor.ChangeExecListener;
import liquibase.database.Database;
import liquibase.exception.PreconditionErrorException;
import liquibase.exception.PreconditionFailedException;
import liquibase.exception.ValidationErrors;
import liquibase.exception.Warnings;
import liquibase.ext.mongodb.database.MongoLiquibaseDatabase;
import liquibase.ext.mongodb.statement.CountCollectionByNameStatement;
import liquibase.precondition.AbstractPrecondition;
import lombok.Getter;
import lombok.Setter;

import static java.lang.String.format;

public class CollectionExistsPrecondition extends AbstractPrecondition {

@Getter
@Setter
private String collectionName;

@Override
public String getName() {
return "collectionExists";
}

@Override
public Warnings warn(final Database database) {
return new Warnings();
}

@Override
public ValidationErrors validate(final Database database) {
return new ValidationErrors();
}

@Override
public void check(final Database database, final DatabaseChangeLog changeLog, final ChangeSet changeSet,
final ChangeExecListener changeExecListener)
throws PreconditionFailedException, PreconditionErrorException {

try {
final CountCollectionByNameStatement countCollectionByNameStatement
= new CountCollectionByNameStatement(collectionName);

if (countCollectionByNameStatement.queryForLong((MongoLiquibaseDatabase) database) == 0L) {
throw new PreconditionFailedException(format("Collection %s does not exist", collectionName), changeLog,
this);

}
} catch (final PreconditionFailedException e) {
throw e;
} catch (final Exception e) {
throw new PreconditionErrorException(e, changeLog, this);
}
}

@Override
public String getSerializedObjectNamespace() {
return GENERIC_CHANGELOG_EXTENSION_NAMESPACE;
}
}
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
liquibase.ext.mongodb.precondition.DocumentExistsPrecondition
liquibase.ext.mongodb.precondition.ExpectedDocumentCountPrecondition
liquibase.ext.mongodb.precondition.ExpectedDocumentCountPrecondition
liquibase.ext.mongodb.precondition.CollectionExistsPrecondition
11 changes: 8 additions & 3 deletions src/main/resources/liquibase.parser.core.xml/dbchangelog-ext.xsd
Original file line number Diff line number Diff line change
Expand Up @@ -123,17 +123,22 @@

</xsd:complexType>
</xsd:element>

<xsd:element name="expectedDocumentCount">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="filter" type="xsd:string" minOccurs="0" maxOccurs="1"/>
</xsd:sequence>

<xsd:attribute name="collectionName" type="xsd:string" use="required"/>
<xsd:attribute name="expectedCount" type="xsd:nonNegativeInteger" use="required"/>
<xsd:attribute name="expectedCount" type="xsd:nonNegativeInteger" use="required"/>
</xsd:complexType>
</xsd:element>


<xsd:element name="collectionExists">
<xsd:complexType>
<xsd:attribute name="collectionName" type="xsd:string" use="required"/>
</xsd:complexType>
</xsd:element>

</xsd:schema>
36 changes: 22 additions & 14 deletions src/test/java/liquibase/ext/MongoLiquibaseIT.java
Original file line number Diff line number Diff line change
Expand Up @@ -250,17 +250,19 @@ void testPreconditions() {
liquibase.update("");

List<MongoRanChangeSet> changeSets = findAllRanChangeSets.queryForList(database).stream().map(converter::fromDocument).collect(Collectors.toList());
assertThat(changeSets).hasSize(8)
.extracting(MongoRanChangeSet::getId, MongoRanChangeSet::getOrderExecuted, MongoRanChangeSet::getExecType)
assertThat(changeSets).hasSize(10)
.extracting(MongoRanChangeSet::getId, MongoRanChangeSet::getOrderExecuted, MongoRanChangeSet::getExecType, MongoRanChangeSet::getLastCheckSum)
.containsExactly(
tuple("1", 1, SKIPPED),
tuple("2", 2, EXECUTED),
tuple("3", 3, EXECUTED),
tuple("4", 4, SKIPPED),
tuple("5", 5, EXECUTED),
tuple("6", 6, EXECUTED),
tuple("7", 7, SKIPPED),
tuple("8", 8, EXECUTED)
tuple("1", 1, SKIPPED, CheckSum.parse("8:025f868444aa99ff8238b3aeb8348fe0")),
tuple("2", 2, EXECUTED, CheckSum.parse("8:517a149b6d344ba6859c016767c0b8d1")),
tuple("3", 3, EXECUTED, CheckSum.parse("8:02aeacdd13ced7e88bd8a6373832e69c")),
tuple("4", 4, SKIPPED, CheckSum.parse("8:54a251bbf203b3523eef2abf23a8f78d")),
tuple("5", 5, EXECUTED, CheckSum.parse("8:d3c5dd6de42b559b7b1086012b5b38b9")),
tuple("6", 6, EXECUTED, CheckSum.parse("8:5fe0e992687d479011653c2bc8d3d10f")),
tuple("7", 7, SKIPPED, CheckSum.parse("8:c5876904ee5ebcc255f25d6ae100b3f5")),
tuple("8", 8, EXECUTED, CheckSum.parse("8:253b4eb9514ddca767da8da818992fb1")),
tuple("9", 9, EXECUTED, CheckSum.parse("8:7814f3ccf6a3132bd0473e1fe29394a3")),
tuple("10", 10, SKIPPED, CheckSum.parse("8:6e91149e36cdaecf7e919312556e0e6b"))
);

assertThat(getCollections(connection))
Expand All @@ -269,8 +271,14 @@ void testPreconditions() {

final FindAllStatement findAllResults = new FindAllStatement("results");
assertThat(findAllResults.queryForList(database))
.hasSize(4).extracting(d -> d.get("info"))
.containsExactlyInAnyOrder("existsAnyDocumentInCollection1", "filterMatchedInCollection1", "changeSetExecutedMatch", "expectedDocumentCountfilterMatchedInCollection1");
.hasSize(5).extracting(d -> d.get("info"))
.containsExactlyInAnyOrder(
"existsAnyDocumentInCollection1",
"filterMatchedInCollection1",
"changeSetExecutedMatch",
"expectedDocumentCountFilterMatchedInCollection1",
"expectedCollectionResultsExists"
);

}

Expand All @@ -286,7 +294,7 @@ void testTags() {
assertThat(changeSets).hasSize(1)
.extracting(MongoRanChangeSet::getOrderExecuted, MongoRanChangeSet::getExecType, MongoRanChangeSet::getTag)
.containsExactly(
tuple( 1, EXECUTED, "tag0")
tuple(1, EXECUTED, "tag0")
);

final FindAllStatement findAllResults = new FindAllStatement("results");
Expand Down Expand Up @@ -366,7 +374,7 @@ void testTags() {
.containsExactlyInAnyOrder("DATABASECHANGELOG", "DATABASECHANGELOGLOCK", "results");

// rollback to not existing
assertThatExceptionOfType(RollbackFailedException.class).isThrownBy(()-> liquibase.rollback("notExisting", ""))
assertThatExceptionOfType(RollbackFailedException.class).isThrownBy(() -> liquibase.rollback("notExisting", ""))
.withMessageContaining("Could not find tag 'notExisting' in the database");

// rollback to tagged state. Tagged ChangeSet remains
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@

<changeSet id="7" author="alex">
<preConditions onFail="CONTINUE" onError="HALT">
<ext:expectedDocumentCount collectionName="collection1">
<ext:expectedDocumentCount collectionName="collection1" expectedCount="0">
<ext:filter>
<!--@formatter:off-->
{
Expand All @@ -179,7 +179,6 @@
}
<!--@formatter:on-->
</ext:filter>
<ext:expectedCount>0</ext:expectedCount>
</ext:expectedDocumentCount>
</preConditions>
<comment>Will not be inserted as filter not matches</comment>
Expand All @@ -189,7 +188,7 @@
<ext:document>
<!--@formatter:off-->
{
info: "expectedDocumentCountfilterNotMatchedInCollection1"
info: "expectedDocumentCountFilterNotMatchedInCollection1"
}
<!--@formatter:on-->
</ext:document>
Expand All @@ -200,7 +199,7 @@

<changeSet id="8" author="alex">
<preConditions onFail="CONTINUE" onError="HALT">
<ext:expectedDocumentCount collectionName="collection1">
<ext:expectedDocumentCount collectionName="collection1" expectedCount="1">
<ext:filter>
<!--@formatter:off-->
{
Expand All @@ -211,7 +210,6 @@
}
<!--@formatter:on-->
</ext:filter>
<ext:expectedCount>1</ext:expectedCount>
</ext:expectedDocumentCount>
</preConditions>
<comment>Will be inserted as filter matches</comment>
Expand All @@ -221,12 +219,53 @@
<ext:document>
<!--@formatter:off-->
{
info: "expectedDocumentCountfilterMatchedInCollection1"
info: "expectedDocumentCountFilterMatchedInCollection1"
}
<!--@formatter:on-->
</ext:document>

</ext:insertOne>

</changeSet>

<changeSet id="9" author="alex">
<preConditions onFail="CONTINUE" onError="HALT">
<ext:collectionExists collectionName="results"/>
</preConditions>
<comment>Will be inserted as collection exists</comment>

<ext:insertOne collectionName="results">

<ext:document>
<!--@formatter:off-->
{
info: "expectedCollectionResultsExists"
}
<!--@formatter:on-->
</ext:document>

</ext:insertOne>

</changeSet>

<changeSet id="10" author="alex">
<preConditions onFail="CONTINUE" onError="HALT">
<ext:collectionExists collectionName="results1"/>
</preConditions>
<comment>Will be inserted as collection exists</comment>

<ext:insertOne collectionName="results">

<ext:document>
<!--@formatter:off-->
{
info: "expectedCollectionResults1NotExists"
}
<!--@formatter:on-->
</ext:document>

</ext:insertOne>

</changeSet>

</databaseChangeLog>

0 comments on commit f85f571

Please sign in to comment.