use of org.umlg.sqlg.structure.topology.GlobalUniqueIndex in project sqlg by pietermartin.
the class BaseSqlDialect method flushElementGlobalUniqueIndexPropertyCache.
private <T extends SqlgElement> void flushElementGlobalUniqueIndexPropertyCache(SqlgGraph sqlgGraph, boolean forVertices, Map<SchemaTable, Pair<SortedSet<String>, Map<T, Map<String, Object>>>> schemaVertexPropertyCache) {
Connection conn = sqlgGraph.tx().getConnection();
for (SchemaTable schemaTable : schemaVertexPropertyCache.keySet()) {
Pair<SortedSet<String>, Map<T, Map<String, Object>>> vertexPropertyCache = schemaVertexPropertyCache.get(schemaTable);
SortedSet<String> propertyNames = vertexPropertyCache.getKey();
Map<String, PropertyColumn> globalUniqueIndexPropertyMap = sqlgGraph.getTopology().getPropertiesWithGlobalUniqueIndexFor(schemaTable.withPrefix(VERTEX_PREFIX));
for (Map.Entry<String, PropertyColumn> propertyColumnEntry : globalUniqueIndexPropertyMap.entrySet()) {
PropertyColumn propertyColumn = propertyColumnEntry.getValue();
if (propertyNames.contains(propertyColumn.getName())) {
for (GlobalUniqueIndex globalUniqueIndex : propertyColumn.getGlobalUniqueIndices()) {
StringBuilder sql = new StringBuilder();
sql.append("UPDATE ");
sql.append(maybeWrapInQoutes(Schema.GLOBAL_UNIQUE_INDEX_SCHEMA));
sql.append(".");
sql.append(maybeWrapInQoutes((forVertices ? VERTEX_PREFIX : EDGE_PREFIX) + globalUniqueIndex.getName()));
sql.append(" \nSET\n\t");
sql.append(maybeWrapInQoutes("value"));
sql.append(" = ?\nWHERE\n\t");
sql.append(maybeWrapInQoutes("recordId"));
sql.append(" = ? AND ");
sql.append(maybeWrapInQoutes("property"));
sql.append(" = ?");
if (needsSemicolon()) {
sql.append(";");
}
if (logger.isDebugEnabled()) {
logger.debug(sql.toString());
}
try (PreparedStatement preparedStatement = conn.prepareStatement(sql.toString())) {
boolean foundSomething = false;
for (T t : vertexPropertyCache.getRight().keySet()) {
Object value = vertexPropertyCache.getRight().get(t).get(propertyColumn.getName());
if (value != null) {
foundSomething = true;
SqlgUtil.setKeyValuesAsParameterUsingPropertyColumn(sqlgGraph, true, 1, preparedStatement, Collections.singleton(Pair.of(propertyColumn.getPropertyType(), value)));
preparedStatement.setString(2, t.id().toString());
preparedStatement.setString(3, propertyColumn.getName());
preparedStatement.addBatch();
}
}
if (foundSomething) {
preparedStatement.executeBatch();
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
}
}
}
use of org.umlg.sqlg.structure.topology.GlobalUniqueIndex 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.GlobalUniqueIndex in project sqlg by pietermartin.
the class TestBatchGlobalUniqueIndexes method testGlobalUniqueIndexOnEdgeNormalBatchMode.
@SuppressWarnings("OptionalGetWithoutIsPresent")
@Test
public void testGlobalUniqueIndexOnEdgeNormalBatchMode() throws InterruptedException {
Assume.assumeTrue(this.sqlgGraph.getSqlDialect().supportsBatchMode());
Map<String, PropertyType> properties = new HashMap<>();
properties.put("name", PropertyType.STRING);
VertexLabel vertexLabelA = this.sqlgGraph.getTopology().ensureVertexLabelExist("A", properties);
VertexLabel vertexLabelB = this.sqlgGraph.getTopology().ensureVertexLabelExist("B", properties);
properties.clear();
properties.put("namea", PropertyType.STRING);
properties.put("nameb", PropertyType.STRING);
properties.put("namec", PropertyType.STRING);
vertexLabelA.ensureEdgeLabelExist("ab", vertexLabelB, properties);
@SuppressWarnings("OptionalGetWithoutIsPresent") Collection<PropertyColumn> propertyColumns = this.sqlgGraph.getTopology().getPublicSchema().getEdgeLabel("ab").get().getProperties().values();
this.sqlgGraph.getTopology().ensureGlobalUniqueIndexExist(new HashSet<>(propertyColumns));
this.sqlgGraph.tx().commit();
Schema globalUniqueIndexSchema = this.sqlgGraph.getTopology().getGlobalUniqueIndexSchema();
Optional<GlobalUniqueIndex> globalUniqueIndexOptional = globalUniqueIndexSchema.getGlobalUniqueIndex("ab_namea_ab_nameb_ab_namec");
Assert.assertTrue(globalUniqueIndexOptional.isPresent());
Optional<PropertyColumn> nameaPropertyColumnOptional = this.sqlgGraph.getTopology().getPublicSchema().getEdgeLabel("ab").get().getProperty("namea");
Assert.assertTrue(nameaPropertyColumnOptional.isPresent());
@SuppressWarnings("OptionalGetWithoutIsPresent") Set<GlobalUniqueIndex> globalUniqueIndices = nameaPropertyColumnOptional.get().getGlobalUniqueIndices();
Assert.assertEquals(1, globalUniqueIndices.size());
GlobalUniqueIndex globalUniqueIndex = globalUniqueIndices.iterator().next();
Assert.assertEquals("ab_namea_ab_nameb_ab_namec", globalUniqueIndex.getName());
this.sqlgGraph.tx().normalBatchModeOn();
Vertex a1 = this.sqlgGraph.addVertex(T.label, "A", "name", "a");
Vertex b1 = this.sqlgGraph.addVertex(T.label, "B", "name", "b");
Edge edge = a1.addEdge("ab", b1, "namea", "a", "nameb", "b", "namec", "c");
this.sqlgGraph.tx().commit();
this.sqlgGraph.tx().normalBatchModeOn();
try {
a1 = this.sqlgGraph.addVertex(T.label, "A", "name", "a");
b1 = this.sqlgGraph.addVertex(T.label, "B", "name", "b");
a1.addEdge("ab", b1, "namea", "a", "nameb", "b", "namec", "c");
this.sqlgGraph.tx().commit();
Assert.fail("GlobalUniqueIndex should prevent this from executing");
} catch (Exception e) {
// swallow
}
this.sqlgGraph.tx().rollback();
this.sqlgGraph.tx().normalBatchModeOn();
this.sqlgGraph.addVertex(T.label, "A", "namea", "aa");
this.sqlgGraph.tx().commit();
testGlobalUniqueIndexOnEdgeNormalBatchMode_assert(this.sqlgGraph, globalUniqueIndex, edge);
if (this.sqlgGraph1 != null) {
Thread.sleep(1000);
testGlobalUniqueIndexOnEdgeNormalBatchMode_assert(this.sqlgGraph1, globalUniqueIndex, edge);
}
}
use of org.umlg.sqlg.structure.topology.GlobalUniqueIndex in project sqlg by pietermartin.
the class SqlgElement method removeGlobalUniqueIndex.
private void removeGlobalUniqueIndex() {
Map<String, PropertyColumn> properties = this.sqlgGraph.getTopology().getPropertiesWithGlobalUniqueIndexFor(this.getSchemaTablePrefixed());
for (PropertyColumn propertyColumn : properties.values()) {
for (GlobalUniqueIndex globalUniqueIndex : propertyColumn.getGlobalUniqueIndices()) {
StringBuilder sql = new StringBuilder("DELETE FROM ");
sql.append(this.sqlgGraph.getSqlDialect().maybeWrapInQoutes(Schema.GLOBAL_UNIQUE_INDEX_SCHEMA));
sql.append(".");
sql.append(this.sqlgGraph.getSqlDialect().maybeWrapInQoutes(VERTEX_PREFIX + globalUniqueIndex.getName()));
sql.append(" WHERE ");
sql.append(this.sqlgGraph.getSqlDialect().maybeWrapInQoutes("recordId"));
sql.append(" = ? AND ");
sql.append(this.sqlgGraph.getSqlDialect().maybeWrapInQoutes("property"));
sql.append(" = ?");
if (this.sqlgGraph.getSqlDialect().needsSemicolon()) {
sql.append(";");
}
if (logger.isDebugEnabled()) {
logger.debug(sql.toString());
}
Connection conn = this.sqlgGraph.tx().getConnection();
try (PreparedStatement preparedStatement = conn.prepareStatement(sql.toString())) {
preparedStatement.setString(1, this.id().toString());
preparedStatement.setString(2, propertyColumn.getName());
preparedStatement.executeUpdate();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
}
use of org.umlg.sqlg.structure.topology.GlobalUniqueIndex in project sqlg by pietermartin.
the class SqlgElement method updateRow.
private void updateRow(String key, Object value) {
boolean elementInInsertedCache = false;
if (this.sqlgGraph.getSqlDialect().supportsBatchMode() && this.sqlgGraph.tx().isInBatchMode()) {
elementInInsertedCache = this.sqlgGraph.tx().getBatchManager().updateProperty(this, key, value);
}
if (!elementInInsertedCache) {
Object oldValue = this.property(key).orElse(null);
if (oldValue != null && oldValue.equals(value)) {
return;
}
// TODO needs optimizing, firing this all the time when there probably are no GlobalUniqueIndexes is a tad dum.
// GlobalUniqueIndex
Map<String, PropertyColumn> properties;
if (this instanceof Vertex) {
properties = this.sqlgGraph.getTopology().getSchema(this.schema).orElseThrow(() -> new IllegalStateException(String.format("Schema %s not found", this.schema))).getVertexLabel(this.table).orElseThrow(() -> new IllegalStateException(String.format("VertexLabel %s not found", this.table))).getProperties();
} else {
properties = this.sqlgGraph.getTopology().getSchema(this.schema).orElseThrow(() -> new IllegalStateException(String.format("Schema %s not found", this.schema))).getEdgeLabel(this.table).orElseThrow(() -> new IllegalStateException(String.format("EdgeLabel %s not found", this.table))).getProperties();
}
// sync up the keyValueMap with its PropertyColumn
PropertyColumn propertyColumn = properties.get(key);
Pair<PropertyColumn, Object> propertyColumnObjectPair = Pair.of(propertyColumn, value);
for (GlobalUniqueIndex globalUniqueIndex : propertyColumn.getGlobalUniqueIndices()) {
SqlgElement.updateGlobalUniqueIndex(this.sqlgGraph, globalUniqueIndex, this.recordId, propertyColumnObjectPair);
}
String tableName = (this instanceof Vertex ? VERTEX_PREFIX : EDGE_PREFIX) + this.table;
StringBuilder sql = new StringBuilder("UPDATE ");
sql.append(this.sqlgGraph.getSqlDialect().maybeWrapInQoutes(this.schema));
sql.append(".");
sql.append(this.sqlgGraph.getSqlDialect().maybeWrapInQoutes(tableName));
sql.append(" SET ");
sql.append(this.sqlgGraph.getSqlDialect().maybeWrapInQoutes(key));
sql.append(" = ?");
// some data types require several columns in the db, make sure to update them all
PropertyType pt = PropertyType.from(value);
String[] postfixes = this.sqlgGraph.getSqlDialect().propertyTypeToSqlDefinition(pt);
if (postfixes != null && postfixes.length > 1) {
for (int i = 1; i < postfixes.length; i++) {
sql.append(",");
sql.append(this.sqlgGraph.getSqlDialect().maybeWrapInQoutes(key + pt.getPostFixes()[i - 1]));
sql.append(" = ?");
}
}
sql.append(" WHERE ");
sql.append(this.sqlgGraph.getSqlDialect().maybeWrapInQoutes("ID"));
sql.append(" = ?");
if (this.sqlgGraph.getSqlDialect().needsSemicolon()) {
sql.append(";");
}
if (logger.isDebugEnabled()) {
logger.debug(sql.toString());
}
Connection conn = this.sqlgGraph.tx().getConnection();
try (PreparedStatement preparedStatement = conn.prepareStatement(sql.toString())) {
Map<String, Object> keyValue = new HashMap<>();
keyValue.put(key, value);
// the index of the id column in the statement depend on how many columns we had to use to store that data type
int idx = setKeyValuesAsParameter(this.sqlgGraph, 1, preparedStatement, keyValue);
preparedStatement.setLong(idx, ((RecordId) this.id()).getId());
preparedStatement.executeUpdate();
preparedStatement.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
// Cache the properties
this.properties.put(key, value);
}
Aggregations