use of org.umlg.sqlg.structure.topology.EdgeLabel in project sqlg by pietermartin.
the class SchemaTableTree method hasNoEdgeLabels.
private boolean hasNoEdgeLabels(SchemaTable schemaTable) {
Optional<Schema> schemaOptional = sqlgGraph.getTopology().getSchema(schemaTable.getSchema());
Preconditions.checkState(schemaOptional.isPresent(), "BUG: %s not found in the topology.", schemaTable.getSchema());
Schema schema = schemaOptional.get();
boolean result = true;
if (schemaTable.isVertexTable()) {
// Need to delete any in/out edges.
Optional<VertexLabel> vertexLabelOptional = schema.getVertexLabel(schemaTable.withOutPrefix().getTable());
Preconditions.checkState(vertexLabelOptional.isPresent(), "BUG: %s not found in the topology.", schemaTable.withOutPrefix().getTable());
VertexLabel vertexLabel = vertexLabelOptional.get();
Collection<EdgeLabel> outEdgeLabels = vertexLabel.getOutEdgeLabels().values();
Collection<EdgeLabel> inEdgeLabels = vertexLabel.getInEdgeLabels().values();
result = outEdgeLabels.isEmpty() && inEdgeLabels.isEmpty();
}
return result;
}
use of org.umlg.sqlg.structure.topology.EdgeLabel in project sqlg by pietermartin.
the class SqlgDropStepBarrier method processNextStart.
@Override
protected Traverser.Admin<S> processNextStart() {
if (this.first) {
this.first = false;
EventStrategy eventStrategy = null;
if (!this.callbackRegistry.getCallbacks().isEmpty()) {
eventStrategy = getTraversal().getStrategies().getStrategy(EventStrategy.class).get();
}
while (this.starts.hasNext()) {
Traverser.Admin<S> start = this.starts.next();
Object object = start.get();
if (object instanceof SqlgElement) {
SqlgElement sqlgElement = (SqlgElement) object;
RecordId recordId = (RecordId) sqlgElement.id();
SchemaTable schemaTable = recordId.getSchemaTable();
Long id = recordId.getId();
if (sqlgElement instanceof SqlgVertex) {
Optional<VertexLabel> vertexLabelOptional = this.sqlgGraph.getTopology().getVertexLabel(schemaTable.getSchema(), schemaTable.getTable());
Preconditions.checkState(vertexLabelOptional.isPresent());
SqlgVertex sqlgVertex = (SqlgVertex) sqlgElement;
boolean added = this.verticesToDelete.put(vertexLabelOptional.get(), id);
if (added && eventStrategy != null) {
final Event removeEvent = new Event.VertexRemovedEvent(eventStrategy.detach(sqlgVertex));
this.callbackRegistry.getCallbacks().forEach(c -> c.accept(removeEvent));
}
for (EdgeLabel outEdgeLabel : vertexLabelOptional.get().getOutEdgeLabels().values()) {
// Get all the edges, register to the callBack and delete.
if (eventStrategy != null) {
Iterator<Edge> edges = sqlgVertex.edges(Direction.OUT);
while (edges.hasNext()) {
Edge edge = edges.next();
SchemaTable schemaTableEdge = ((SqlgEdge) edge).getSchemaTablePrefixed().withOutPrefix();
Optional<EdgeLabel> edgeLabelOptional = this.sqlgGraph.getTopology().getEdgeLabel(schemaTableEdge.getSchema(), schemaTableEdge.getTable());
Preconditions.checkState(edgeLabelOptional.isPresent());
added = this.edgesToDelete.put(edgeLabelOptional.get(), ((RecordId) edge.id()).getId());
if (added) {
final Event removeEvent = new Event.EdgeRemovedEvent(eventStrategy.detach(edge));
this.callbackRegistry.getCallbacks().forEach(c -> c.accept(removeEvent));
}
}
} else {
this.foreignKeyOutEdgesToDelete.put(Pair.of(outEdgeLabel, vertexLabelOptional.get()), id);
}
}
for (EdgeLabel inEdgeLabel : vertexLabelOptional.get().getInEdgeLabels().values()) {
// Get all the edges, register to the callBack and delete.
if (!this.callbackRegistry.getCallbacks().isEmpty()) {
Iterator<Edge> edges = sqlgVertex.edges(Direction.IN);
while (edges.hasNext()) {
Edge edge = edges.next();
SchemaTable schemaTableEdge = ((SqlgEdge) edge).getSchemaTablePrefixed().withOutPrefix();
Optional<EdgeLabel> edgeLabelOptional = this.sqlgGraph.getTopology().getEdgeLabel(schemaTableEdge.getSchema(), schemaTableEdge.getTable());
Preconditions.checkState(edgeLabelOptional.isPresent());
added = this.edgesToDelete.put(edgeLabelOptional.get(), ((RecordId) edge.id()).getId());
if (added) {
final Event removeEvent = new Event.EdgeRemovedEvent(eventStrategy.detach(edge));
this.callbackRegistry.getCallbacks().forEach(c -> c.accept(removeEvent));
}
}
} else {
this.foreignKeyInEdgesToDelete.put(Pair.of(inEdgeLabel, vertexLabelOptional.get()), id);
}
}
} else if (sqlgElement instanceof SqlgEdge) {
Optional<EdgeLabel> edgeLabelOptional = this.sqlgGraph.getTopology().getEdgeLabel(schemaTable.getSchema(), schemaTable.getTable());
Preconditions.checkState(edgeLabelOptional.isPresent());
boolean added = this.edgesToDelete.put(edgeLabelOptional.get(), id);
if (added && eventStrategy != null) {
final Event removeEvent = new Event.EdgeRemovedEvent(eventStrategy.detach((SqlgEdge) sqlgElement));
this.callbackRegistry.getCallbacks().forEach(c -> c.accept(removeEvent));
}
}
} else if (object instanceof SqlgProperty) {
SqlgProperty sqlgProperty = (SqlgProperty) object;
if (eventStrategy != null) {
final Event removeEvent;
if (sqlgProperty.element() instanceof Edge) {
removeEvent = new Event.EdgePropertyRemovedEvent(eventStrategy.detach((Edge) sqlgProperty.element()), eventStrategy.detach(sqlgProperty));
} else if (sqlgProperty instanceof VertexProperty)
removeEvent = new Event.VertexPropertyRemovedEvent(eventStrategy.detach((VertexProperty) sqlgProperty));
else
throw new IllegalStateException("The incoming object is not removable: " + object);
this.callbackRegistry.getCallbacks().forEach(c -> c.accept(removeEvent));
}
sqlgProperty.remove();
} else {
throw new IllegalStateException("Expected SqlgElement or SqlgProperty. Found " + object.getClass().getSimpleName());
}
}
}
for (Pair<EdgeLabel, VertexLabel> edgeLabelVertexLabelPair : this.foreignKeyOutEdgesToDelete.keySet()) {
EdgeLabel outEdgeLabel = edgeLabelVertexLabelPair.getKey();
VertexLabel vertexLabel = edgeLabelVertexLabelPair.getValue();
Collection<Long> ids = this.foreignKeyOutEdgesToDelete.get(edgeLabelVertexLabelPair);
String sql = this.sqlgGraph.getSqlDialect().dropWithForeignKey(true, outEdgeLabel, vertexLabel, ids, !this.callbackRegistry.getCallbacks().isEmpty());
SqlgSqlExecutor.executeDropEdges(this.sqlgGraph, outEdgeLabel, sql, this.callbackRegistry.getCallbacks());
}
for (Pair<EdgeLabel, VertexLabel> edgeLabelVertexLabelPair : this.foreignKeyInEdgesToDelete.keySet()) {
EdgeLabel inEdgeLabel = edgeLabelVertexLabelPair.getKey();
VertexLabel vertexLabel = edgeLabelVertexLabelPair.getValue();
Collection<Long> ids = this.foreignKeyInEdgesToDelete.get(edgeLabelVertexLabelPair);
String sql = this.sqlgGraph.getSqlDialect().dropWithForeignKey(false, inEdgeLabel, vertexLabel, ids, !this.callbackRegistry.getCallbacks().isEmpty());
SqlgSqlExecutor.executeDropEdges(this.sqlgGraph, inEdgeLabel, sql, this.callbackRegistry.getCallbacks());
}
for (EdgeLabel edgeLabel : this.edgesToDelete.keySet()) {
Collection<Long> ids = this.edgesToDelete.get(edgeLabel);
String sql = this.sqlgGraph.getSqlDialect().drop(edgeLabel, ids);
SqlgSqlExecutor.executeDrop(this.sqlgGraph, sql);
}
for (VertexLabel vertexLabel : this.verticesToDelete.keySet()) {
Collection<Long> ids = this.verticesToDelete.get(vertexLabel);
String sql = this.sqlgGraph.getSqlDialect().drop(vertexLabel, ids);
SqlgSqlExecutor.executeDrop(this.sqlgGraph, sql);
}
// The standard TraversalFilterStep.filter calls TraversalUtil.test which normally resets the traversal for every incoming start.
reset();
throw FastNoSuchElementException.instance();
}
use of org.umlg.sqlg.structure.topology.EdgeLabel in project sqlg by pietermartin.
the class SqlDialect method drop.
/**
* if the query traverses edges then the deletion logic is non trivial.
* The edges can not be deleted upfront as then we will not be able to travers to the leaf vertices anymore
* because the edges are no longer there to travers. In this case we need to drop foreign key constraint checking.
* Delete the vertices and then the edges using the same query.
* The edge query is the same as the vertex query with the last SchemaTableTree removed from the distinctQueryStack;
*
* @param sqlgGraph The graph.
* @param leafElementsToDelete The leaf elements of the query. eg. g.V().out().out() The last vertices returned by the gremlin query.
* @param edgesToDelete
* @param distinctQueryStack The query's SchemaTableTree stack as constructed by parsing.
* @return
*/
default List<Triple<SqlgSqlExecutor.DROP_QUERY, String, SchemaTable>> drop(SqlgGraph sqlgGraph, String leafElementsToDelete, Optional<String> edgesToDelete, LinkedList<SchemaTableTree> distinctQueryStack) {
List<Triple<SqlgSqlExecutor.DROP_QUERY, String, SchemaTable>> sqls = new ArrayList<>();
SchemaTableTree last = distinctQueryStack.getLast();
SchemaTableTree lastEdge = null;
// if the leaf elements are vertices then we need to delete its in and out edges.
boolean isVertex = last.getSchemaTable().isVertexTable();
VertexLabel lastVertexLabel = null;
if (isVertex) {
Optional<Schema> schemaOptional = sqlgGraph.getTopology().getSchema(last.getSchemaTable().getSchema());
Preconditions.checkState(schemaOptional.isPresent(), "BUG: %s not found in the topology.", last.getSchemaTable().getSchema());
Schema schema = schemaOptional.get();
Optional<VertexLabel> vertexLabelOptional = schema.getVertexLabel(last.getSchemaTable().withOutPrefix().getTable());
Preconditions.checkState(vertexLabelOptional.isPresent(), "BUG: %s not found in the topology.", last.getSchemaTable().withOutPrefix().getTable());
lastVertexLabel = vertexLabelOptional.get();
}
boolean queryTraversesEdge = isVertex && (distinctQueryStack.size() > 1);
EdgeLabel lastEdgeLabel = null;
if (queryTraversesEdge) {
lastEdge = distinctQueryStack.get(distinctQueryStack.size() - 2);
Optional<Schema> edgeSchema = sqlgGraph.getTopology().getSchema(lastEdge.getSchemaTable().getSchema());
Preconditions.checkState(edgeSchema.isPresent(), "BUG: %s not found in the topology.", lastEdge.getSchemaTable().getSchema());
Optional<EdgeLabel> edgeLabelOptional = edgeSchema.get().getEdgeLabel(lastEdge.getSchemaTable().withOutPrefix().getTable());
Preconditions.checkState(edgeLabelOptional.isPresent(), "BUG: %s not found in the topology.", lastEdge.getSchemaTable().getTable());
lastEdgeLabel = edgeLabelOptional.get();
}
if (isVertex) {
// First delete all edges except for this edge traversed to get to the vertices.
StringBuilder sb;
for (Map.Entry<String, EdgeLabel> edgeLabelEntry : lastVertexLabel.getOutEdgeLabels().entrySet()) {
EdgeLabel edgeLabel = edgeLabelEntry.getValue();
if (lastEdgeLabel == null || !edgeLabel.equals(lastEdgeLabel)) {
// Delete
sb = new StringBuilder();
sb.append("DELETE FROM ");
sb.append(maybeWrapInQoutes(edgeLabel.getSchema().getName()));
sb.append(".");
sb.append(maybeWrapInQoutes(Topology.EDGE_PREFIX + edgeLabel.getName()));
sb.append("\nWHERE ");
sb.append(maybeWrapInQoutes(lastVertexLabel.getSchema().getName() + "." + lastVertexLabel.getName() + Topology.OUT_VERTEX_COLUMN_END));
sb.append(" IN\n\t(");
sb.append(leafElementsToDelete);
sb.append(")");
sqls.add(Triple.of(SqlgSqlExecutor.DROP_QUERY.NORMAL, sb.toString(), SchemaTable.of(edgeLabel.getSchema().getName(), Topology.EDGE_PREFIX + edgeLabel.getName())));
}
}
for (Map.Entry<String, EdgeLabel> edgeLabelEntry : lastVertexLabel.getInEdgeLabels().entrySet()) {
EdgeLabel edgeLabel = edgeLabelEntry.getValue();
if (lastEdgeLabel == null || !edgeLabel.equals(lastEdgeLabel)) {
// Delete
sb = new StringBuilder();
sb.append("DELETE FROM ");
sb.append(maybeWrapInQoutes(edgeLabel.getSchema().getName()));
sb.append(".");
sb.append(maybeWrapInQoutes(Topology.EDGE_PREFIX + edgeLabel.getName()));
sb.append("\nWHERE ");
sb.append(maybeWrapInQoutes(lastVertexLabel.getSchema().getName() + "." + lastVertexLabel.getName() + Topology.IN_VERTEX_COLUMN_END));
sb.append(" IN\n\t(");
sb.append(leafElementsToDelete);
sb.append(")");
sqls.add(Triple.of(SqlgSqlExecutor.DROP_QUERY.NORMAL, sb.toString(), SchemaTable.of(edgeLabel.getSchema().getName(), Topology.EDGE_PREFIX + edgeLabel.getName())));
}
}
}
// Need to defer foreign key constraint checks.
if (queryTraversesEdge) {
String edgeTableName = (maybeWrapInQoutes(lastEdge.getSchemaTable().getSchema())) + "." + maybeWrapInQoutes(lastEdge.getSchemaTable().getTable());
sqls.add(Triple.of(SqlgSqlExecutor.DROP_QUERY.ALTER, this.sqlToTurnOffReferentialConstraintCheck(edgeTableName), lastEdge.getSchemaTable()));
}
// Delete the leaf vertices, if there are foreign keys then its been deferred.
StringBuilder sb = new StringBuilder();
sb.append("DELETE FROM ");
sb.append(maybeWrapInQoutes(last.getSchemaTable().getSchema()));
sb.append(".");
sb.append(maybeWrapInQoutes(last.getSchemaTable().getTable()));
sb.append("\nWHERE \"ID\" IN (\n\t");
sb.append(leafElementsToDelete);
sb.append(")");
sqls.add(Triple.of(SqlgSqlExecutor.DROP_QUERY.NORMAL, sb.toString(), null));
if (queryTraversesEdge) {
sb = new StringBuilder();
sb.append("DELETE FROM ");
sb.append(maybeWrapInQoutes(lastEdge.getSchemaTable().getSchema()));
sb.append(".");
sb.append(maybeWrapInQoutes(lastEdge.getSchemaTable().getTable()));
sb.append("\nWHERE \"ID\" IN (\n\t");
sb.append(edgesToDelete.get());
sb.append(")");
sqls.add(Triple.of(SqlgSqlExecutor.DROP_QUERY.EDGE, sb.toString(), lastEdge.getSchemaTable()));
}
// Enable the foreign key constraint
if (queryTraversesEdge) {
String edgeTableName = (maybeWrapInQoutes(lastEdge.getSchemaTable().getSchema())) + "." + maybeWrapInQoutes(lastEdge.getSchemaTable().getTable());
sqls.add(Triple.of(SqlgSqlExecutor.DROP_QUERY.ALTER, this.sqlToTurnOnReferentialConstraintCheck(edgeTableName), null));
}
return sqls;
}
use of org.umlg.sqlg.structure.topology.EdgeLabel in project sqlg by pietermartin.
the class TestLoadSchema method testLoadGlobalUniqueIndexes.
@Test
public void testLoadGlobalUniqueIndexes() throws Exception {
Map<String, PropertyType> properties = new HashMap<>();
properties.put("name1", PropertyType.STRING);
properties.put("name2", PropertyType.STRING);
VertexLabel aVertexLabel = this.sqlgGraph.getTopology().getPublicSchema().ensureVertexLabelExist("A", properties);
Assert.assertTrue(aVertexLabel.isUncommitted());
properties.clear();
properties.put("name3", PropertyType.STRING);
properties.put("name4", PropertyType.STRING);
VertexLabel bVertexLabel = this.sqlgGraph.getTopology().getPublicSchema().ensureVertexLabelExist("B", properties);
Assert.assertTrue(bVertexLabel.isUncommitted());
properties.clear();
properties.put("name5", PropertyType.STRING);
properties.put("name6", PropertyType.STRING);
EdgeLabel edgeLabel = aVertexLabel.ensureEdgeLabelExist("ab", bVertexLabel, properties);
Assert.assertTrue(edgeLabel.isUncommitted());
Set<PropertyColumn> globalUniqueIndexPropertyColumns = new HashSet<>();
globalUniqueIndexPropertyColumns.addAll(new HashSet<>(aVertexLabel.getProperties().values()));
globalUniqueIndexPropertyColumns.addAll(new HashSet<>(bVertexLabel.getProperties().values()));
globalUniqueIndexPropertyColumns.addAll(new HashSet<>(edgeLabel.getProperties().values()));
this.sqlgGraph.getTopology().ensureGlobalUniqueIndexExist(globalUniqueIndexPropertyColumns);
this.sqlgGraph.tx().commit();
this.sqlgGraph.close();
try (SqlgGraph sqlgGraph = SqlgGraph.open(configuration)) {
assertEquals(1, sqlgGraph.getTopology().getGlobalUniqueIndexes().size());
GlobalUniqueIndex globalUniqueIndex = sqlgGraph.getTopology().getGlobalUniqueIndexes().iterator().next();
Assert.assertTrue(globalUniqueIndex.getProperties().containsAll(globalUniqueIndexPropertyColumns));
for (PropertyColumn globalUniqueIndexPropertyColumn : globalUniqueIndexPropertyColumns) {
assertEquals(1, globalUniqueIndexPropertyColumn.getGlobalUniqueIndices().size());
}
}
}
use of org.umlg.sqlg.structure.topology.EdgeLabel in project sqlg by pietermartin.
the class SqlgEdge method load.
// TODO this needs optimizing, an edge created in the transaction need not go to the db to load itself again
@Override
protected void load() {
// recordId can be null when in batchMode
if (this.recordId != null && this.properties.isEmpty()) {
this.sqlgGraph.tx().readWrite();
if (this.sqlgGraph.getSqlDialect().supportsBatchMode() && this.sqlgGraph.tx().getBatchManager().isStreaming()) {
throw new IllegalStateException("streaming is in progress, first flush or commit before querying.");
}
// Generate the columns to prevent 'ERROR: cached plan must not change result type" error'
// This happens when the schema changes after the statement is prepared.
@SuppressWarnings("OptionalGetWithoutIsPresent") EdgeLabel edgeLabel = this.sqlgGraph.getTopology().getSchema(this.schema).get().getEdgeLabel(this.table).get();
StringBuilder sql = new StringBuilder("SELECT\n\t");
sql.append(this.sqlgGraph.getSqlDialect().maybeWrapInQoutes("ID"));
for (PropertyColumn propertyColumn : edgeLabel.getProperties().values()) {
sql.append(", ");
sql.append(this.sqlgGraph.getSqlDialect().maybeWrapInQoutes(propertyColumn.getName()));
// additional columns for time zone, etc.
String[] ps = propertyColumn.getPropertyType().getPostFixes();
if (ps != null) {
for (String p : propertyColumn.getPropertyType().getPostFixes()) {
sql.append(", ");
sql.append(this.sqlgGraph.getSqlDialect().maybeWrapInQoutes(propertyColumn.getName() + p));
}
}
}
for (VertexLabel vertexLabel : edgeLabel.getOutVertexLabels()) {
sql.append(", ");
sql.append(this.sqlgGraph.getSqlDialect().maybeWrapInQoutes(vertexLabel.getSchema().getName() + "." + vertexLabel.getName() + Topology.OUT_VERTEX_COLUMN_END));
}
for (VertexLabel vertexLabel : edgeLabel.getInVertexLabels()) {
sql.append(", ");
sql.append(this.sqlgGraph.getSqlDialect().maybeWrapInQoutes(vertexLabel.getSchema().getName() + "." + vertexLabel.getName() + Topology.IN_VERTEX_COLUMN_END));
}
sql.append("\nFROM\n\t");
sql.append(this.sqlgGraph.getSqlDialect().maybeWrapInQoutes(this.schema));
sql.append(".");
sql.append(this.sqlgGraph.getSqlDialect().maybeWrapInQoutes(EDGE_PREFIX + this.table));
sql.append(" WHERE ");
sql.append(this.sqlgGraph.getSqlDialect().maybeWrapInQoutes("ID"));
sql.append(" = ?");
if (this.sqlgGraph.getSqlDialect().needsSemicolon()) {
sql.append(";");
}
Connection conn = this.sqlgGraph.tx().getConnection();
if (logger.isDebugEnabled()) {
logger.debug(sql.toString());
}
try (PreparedStatement preparedStatement = conn.prepareStatement(sql.toString())) {
preparedStatement.setLong(1, this.recordId.getId());
ResultSet resultSet = preparedStatement.executeQuery();
if (resultSet.next()) {
loadResultSet(resultSet);
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
Aggregations