-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement support for node constraints
- Loading branch information
Showing
7 changed files
with
371 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
112 changes: 112 additions & 0 deletions
112
src/main/java/liquibase/ext/neo4j/snapshot/NodeConstraintSnapshotGeneratorNeo4j.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
package liquibase.ext.neo4j.snapshot; | ||
|
||
import liquibase.Scope; | ||
import liquibase.database.Database; | ||
import liquibase.exception.DatabaseException; | ||
import liquibase.exception.LiquibaseException; | ||
import liquibase.ext.neo4j.database.KernelVersion; | ||
import liquibase.ext.neo4j.database.Neo4jDatabase; | ||
import liquibase.ext.neo4j.structure.EntityType; | ||
import liquibase.ext.neo4j.structure.Label; | ||
import liquibase.ext.neo4j.structure.NodeConstraint; | ||
import liquibase.logging.Logger; | ||
import liquibase.snapshot.DatabaseSnapshot; | ||
import liquibase.snapshot.InvalidExampleException; | ||
import liquibase.snapshot.SnapshotGenerator; | ||
import liquibase.snapshot.SnapshotGeneratorChain; | ||
import liquibase.statement.core.RawParameterizedSqlStatement; | ||
import liquibase.structure.DatabaseObject; | ||
|
||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.stream.Collectors; | ||
|
||
public class NodeConstraintSnapshotGeneratorNeo4j implements SnapshotGenerator { | ||
|
||
@Override | ||
public int getPriority(Class<? extends DatabaseObject> objectType, Database database) { | ||
if (!(database instanceof Neo4jDatabase)) { | ||
return PRIORITY_NONE; | ||
} | ||
if (Label.class.isAssignableFrom(objectType)) { | ||
return PRIORITY_ADDITIONAL; | ||
} | ||
if (NodeConstraint.class.isAssignableFrom(objectType)) { | ||
return PRIORITY_DEFAULT; | ||
} | ||
return PRIORITY_NONE; | ||
} | ||
|
||
@Override | ||
public <T extends DatabaseObject> T snapshot(T example, DatabaseSnapshot snapshot, SnapshotGeneratorChain chain) throws DatabaseException, InvalidExampleException { | ||
Database database = snapshot.getDatabase(); | ||
if (!(database instanceof Neo4jDatabase)) { | ||
return chain.snapshot(example, snapshot); | ||
} | ||
if (!snapshot.getSnapshotControl().shouldInclude(NodeConstraint.class)) { | ||
return chain.snapshot(example, snapshot); | ||
} | ||
if (example instanceof NodeConstraint) { | ||
return example; | ||
} | ||
if (!(example instanceof Label)) { | ||
return chain.snapshot(example, snapshot); | ||
} | ||
Neo4jDatabase neo4j = (Neo4jDatabase) database; | ||
KernelVersion version = neo4j.getKernelVersion(); | ||
if (version.compareTo(KernelVersion.V4_4_0) < 0) { | ||
Logger log = Scope.getCurrentScope().getLog(getClass()); | ||
log.warning(String.format("Ignoring snapshot request as Neo4j version is too old (%s): expected at least 4.4", | ||
version)); | ||
return chain.snapshot(example, snapshot); | ||
} | ||
|
||
Label label = (Label) example; | ||
List<NodeConstraint> indices = retrieveConstraints(neo4j, label); | ||
indices.forEach(label::addConstraint); | ||
return example; | ||
} | ||
|
||
@Override | ||
@SuppressWarnings("unchecked") | ||
public Class<? extends DatabaseObject>[] addsTo() { | ||
return new Class[]{Label.class}; | ||
} | ||
|
||
@Override | ||
public Class<? extends SnapshotGenerator>[] replaces() { | ||
return null; | ||
} | ||
|
||
private static List<NodeConstraint> retrieveConstraints(Neo4jDatabase neo4j, Label label) throws DatabaseException { | ||
String cypher = "SHOW CONSTRAINTS YIELD name, type, entityType, labelsOrTypes, properties, options " + | ||
"WHERE entityType = $1 AND $2 IN labelsOrTypes " + | ||
"RETURN type, name, labelsOrTypes AS labels, properties, options " + | ||
"ORDER BY type, name ASC"; | ||
try { | ||
return neo4j.run(new RawParameterizedSqlStatement(cypher, | ||
EntityType.NODE.name(), | ||
label.getName() | ||
)) | ||
.stream() | ||
.map(row -> mapConstraint(label, row)) | ||
.collect(Collectors.toList()); | ||
} catch (LiquibaseException e) { | ||
throw new DatabaseException("Could not retrieve BTREE node indexes", e); | ||
} | ||
} | ||
|
||
@SuppressWarnings("unchecked") | ||
private static NodeConstraint mapConstraint(Label label, Map<String, ?> row) { | ||
Map<String, Object> options = (Map<String, Object>) row.get("options"); | ||
return new NodeConstraint( | ||
label, | ||
(String) row.get("type"), | ||
(String) row.get("name"), | ||
((List<String>) row.get("labels")), | ||
(List<String>) row.get("properties"), | ||
(String) (options == null ? null : options.get("indexProvider")), | ||
(Map<String, Object>) (options == null ? null : options.get("indexConfig"))); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
55 changes: 55 additions & 0 deletions
55
src/main/java/liquibase/ext/neo4j/structure/NodeConstraint.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
package liquibase.ext.neo4j.structure; | ||
|
||
import liquibase.structure.AbstractDatabaseObject; | ||
import liquibase.structure.CatalogLevelObject; | ||
import liquibase.structure.DatabaseObject; | ||
import liquibase.structure.core.Catalog; | ||
import liquibase.structure.core.Schema; | ||
|
||
import java.util.List; | ||
import java.util.Map; | ||
|
||
public class NodeConstraint extends AbstractDatabaseObject implements CatalogLevelObject { | ||
|
||
private Label label; | ||
private String name; | ||
|
||
public NodeConstraint() { | ||
} | ||
|
||
public NodeConstraint(Label label, String type, String name, List<String> labels, List<String> properties, String indexProvider, Map<String, Object> indexConfig) { | ||
this.label = label; | ||
this.name = name; | ||
this.setAttribute("type", type); | ||
this.setAttribute("labels", labels); | ||
this.setAttribute("properties", properties); | ||
this.setAttribute("indexProvider", indexProvider); | ||
this.setAttribute("indexConfig", indexConfig); | ||
} | ||
|
||
@Override | ||
public DatabaseObject[] getContainingObjects() { | ||
return null; | ||
} | ||
|
||
@Override | ||
public DatabaseObject setName(String name) { | ||
this.name = name; | ||
return this; | ||
} | ||
|
||
@Override | ||
public String getName() { | ||
return name; | ||
} | ||
|
||
@Override | ||
public Catalog getCatalog() { | ||
return label.getCatalog(); | ||
} | ||
|
||
@Override | ||
public Schema getSchema() { | ||
return null; | ||
} | ||
} |
3 changes: 2 additions & 1 deletion
3
src/main/resources/META-INF/services/liquibase.snapshot.SnapshotGenerator
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
liquibase.ext.neo4j.snapshot.LabelSnapshotGeneratorNeo4j | ||
liquibase.ext.neo4j.snapshot.TypeSnapshotGeneratorNeo4j | ||
liquibase.ext.neo4j.snapshot.NodeIndexSnapshotGeneratorNeo4j | ||
liquibase.ext.neo4j.snapshot.NodeConstraintSnapshotGeneratorNeo4j | ||
liquibase.ext.neo4j.snapshot.TypeSnapshotGeneratorNeo4j |
1 change: 1 addition & 0 deletions
1
src/main/resources/META-INF/services/liquibase.structure.DatabaseObject
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
liquibase.ext.neo4j.structure.Label | ||
liquibase.ext.neo4j.structure.NodeIndex | ||
liquibase.ext.neo4j.structure.NodeConstraint | ||
liquibase.ext.neo4j.structure.Type |
Oops, something went wrong.