use of org.umlg.sqlg.structure.PropertyType in project sqlg by pietermartin.
the class PostgresDialect method flushRemovedGlobalUniqueIndexVertices.
@Override
public void flushRemovedGlobalUniqueIndexVertices(SqlgGraph sqlgGraph, Map<SchemaTable, List<SqlgVertex>> removeVertexCache) {
if (!removeVertexCache.isEmpty()) {
Map<String, PropertyType> tmpColumns = new HashMap<>();
tmpColumns.put("recordId", PropertyType.STRING);
tmpColumns.put("property", PropertyType.STRING);
// split the list of vertices, postgres existVertexLabel a 2 byte limit in the in clause
for (Map.Entry<SchemaTable, List<SqlgVertex>> schemaVertices : removeVertexCache.entrySet()) {
SchemaTable schemaTable = schemaVertices.getKey();
Map<String, PropertyColumn> propertyColumns = sqlgGraph.getTopology().getPropertiesWithGlobalUniqueIndexFor(schemaTable.withPrefix(VERTEX_PREFIX));
for (PropertyColumn propertyColumn : propertyColumns.values()) {
for (GlobalUniqueIndex globalUniqueIndex : propertyColumn.getGlobalUniqueIndices()) {
List<SqlgVertex> vertices = schemaVertices.getValue();
if (!vertices.isEmpty()) {
SecureRandom random = new SecureRandom();
byte[] bytes = new byte[6];
random.nextBytes(bytes);
String tmpTableIdentified = Base64.getEncoder().encodeToString(bytes);
sqlgGraph.getTopology().getPublicSchema().createTempTable(VERTEX_PREFIX + tmpTableIdentified, tmpColumns);
String copySql = ((SqlBulkDialect) sqlgGraph.getSqlDialect()).temporaryTableCopyCommandSqlVertex(sqlgGraph, SchemaTable.of("public", tmpTableIdentified), tmpColumns.keySet());
Writer writer = ((SqlBulkDialect) sqlgGraph.getSqlDialect()).streamSql(sqlgGraph, copySql);
for (SqlgVertex sqlgVertex : vertices) {
Map<String, Object> tmpMap = new HashMap<>();
tmpMap.put("recordId", sqlgVertex.id().toString());
tmpMap.put("property", propertyColumn.getName());
((SqlBulkDialect) sqlgGraph.getSqlDialect()).writeStreamingVertex(writer, tmpMap);
}
try {
writer.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
StringBuilder sql = new StringBuilder("WITH tmp as (SELECT * FROM " + sqlgGraph.getSqlDialect().maybeWrapInQoutes(VERTEX_PREFIX + tmpTableIdentified) + ")\n");
sql.append("DELETE FROM ");
sql.append(sqlgGraph.getSqlDialect().maybeWrapInQoutes(Schema.GLOBAL_UNIQUE_INDEX_SCHEMA));
sql.append(".");
sql.append(sqlgGraph.getSqlDialect().maybeWrapInQoutes(VERTEX_PREFIX + globalUniqueIndex.getName()));
sql.append("as gui \nUSING tmp WHERE ");
sql.append("tmp.\"recordId\" = gui.\"recordId\" AND tmp.property = gui.property");
if (sqlgGraph.getSqlDialect().needsSemicolon()) {
sql.append(";");
}
if (logger.isDebugEnabled()) {
logger.debug(sql.toString());
}
Connection conn = sqlgGraph.tx().getConnection();
try (PreparedStatement preparedStatement = conn.prepareStatement(sql.toString())) {
preparedStatement.executeUpdate();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
}
}
}
}
use of org.umlg.sqlg.structure.PropertyType in project sqlg by pietermartin.
the class PostgresDialect method internalConstructCompleteCopyCommandSqlVertex.
private String internalConstructCompleteCopyCommandSqlVertex(SqlgGraph sqlgGraph, boolean isTemp, String schema, String table, Set<String> keys) {
Map<String, PropertyType> propertyTypeMap;
if (isTemp) {
propertyTypeMap = sqlgGraph.getTopology().getPublicSchema().getTemporaryTable(VERTEX_PREFIX + table);
} else {
propertyTypeMap = sqlgGraph.getTopology().getTableFor(SchemaTable.of(schema, VERTEX_PREFIX + table));
}
StringBuilder sql = new StringBuilder();
sql.append("COPY ");
if (!isTemp) {
sql.append(maybeWrapInQoutes(schema));
sql.append(".");
}
sql.append(maybeWrapInQoutes(VERTEX_PREFIX + table));
sql.append(" (");
if (keys.isEmpty()) {
// copy command needs at least one field.
// check if the dummy field exist, if not createVertexLabel it
Map<String, PropertyType> columns = new HashMap<>();
columns.put(COPY_DUMMY, PropertyType.from(0));
sqlgGraph.getTopology().ensureVertexLabelPropertiesExist(schema, table, columns);
sql.append(maybeWrapInQoutes(COPY_DUMMY));
} else {
int count = 1;
for (String key : keys) {
if (count > 1 && count <= keys.size()) {
sql.append(", ");
}
count++;
appendKeyForStream(propertyTypeMap.get(key), sql, key);
}
}
sql.append(")");
sql.append(" FROM stdin CSV DELIMITER '");
sql.append(COPY_COMMAND_DELIMITER);
sql.append("' ");
sql.append("QUOTE ");
sql.append(COPY_COMMAND_QUOTE);
sql.append(" ESCAPE '");
sql.append(ESCAPE);
sql.append("'");
sql.append(" NULL'");
sql.append(BATCH_NULL);
sql.append("';");
if (logger.isDebugEnabled()) {
logger.debug(sql.toString());
}
return sql.toString();
}
use of org.umlg.sqlg.structure.PropertyType in project sqlg by pietermartin.
the class PostgresDialect method flushElementPropertyCache.
private <T extends SqlgElement> void flushElementPropertyCache(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>>> vertexKeysPropertyCache = schemaVertexPropertyCache.get(schemaTable);
SortedSet<String> keys = vertexKeysPropertyCache.getLeft();
Map<? extends SqlgElement, Map<String, Object>> vertexPropertyCache = vertexKeysPropertyCache.getRight();
StringBuilder sql = new StringBuilder();
sql.append("UPDATE ");
sql.append(maybeWrapInQoutes(schemaTable.getSchema()));
sql.append(".");
sql.append(maybeWrapInQoutes((forVertices ? VERTEX_PREFIX : EDGE_PREFIX) + schemaTable.getTable()));
sql.append(" a \nSET\n\t");
if (keys.size() > 1) {
sql.append("(");
}
int count = 1;
// this map is for optimizations reason to not look up the property via all tables within the loop
Map<String, PropertyType> keyPropertyTypeMap = new HashMap<>();
for (String key : keys) {
PropertyType propertyType = sqlgGraph.getTopology().getTableFor(schemaTable.withPrefix(forVertices ? VERTEX_PREFIX : EDGE_PREFIX)).get(key);
if (keys.size() == 1 && propertyType.getPostFixes().length > 0) {
sql.append("(");
}
keyPropertyTypeMap.put(key, propertyType);
appendKeyForBatchUpdate(propertyType, sql, key, false);
if (count++ < keys.size()) {
sql.append(", ");
}
if (keys.size() == 1 && propertyType.getPostFixes().length > 0) {
sql.append(")");
}
}
if (keys.size() > 1) {
sql.append(")");
}
sql.append(" = \n\t(");
count = 1;
for (String key : keys) {
sql.append("v.");
PropertyType propertyType = keyPropertyTypeMap.get(key);
appendKeyForBatchUpdate(propertyType, sql, key, true);
sqlCastArray(sql, propertyType);
if (count++ < keys.size()) {
sql.append(", ");
}
}
sql.append(")\nFROM (\nVALUES\n\t");
count = 1;
for (SqlgElement sqlgElement : vertexPropertyCache.keySet()) {
Map<String, Object> properties = vertexPropertyCache.get(sqlgElement);
sql.append("(");
sql.append(((RecordId) sqlgElement.id()).getId());
sql.append(", ");
int countProperties = 1;
for (String key : keys) {
Object value = properties.get(key);
if (value == null) {
if (sqlgElement.property(key).isPresent()) {
value = sqlgElement.value(key);
} else {
value = null;
}
}
PropertyType propertyType = keyPropertyTypeMap.get(key);
appendSqlValue(sql, value, propertyType);
if (countProperties++ < keys.size()) {
sql.append(", ");
}
}
sql.append(")");
if (count++ < vertexPropertyCache.size()) {
sql.append(",\n\t");
}
}
sql.append("\n) AS v(id, ");
count = 1;
for (String key : keys) {
PropertyType propertyType = keyPropertyTypeMap.get(key);
appendKeyForBatchUpdate(propertyType, sql, key, false);
if (count++ < keys.size()) {
sql.append(", ");
}
}
sql.append(")");
sql.append("\nWHERE a.\"ID\" = v.id");
if (logger.isDebugEnabled()) {
logger.debug(sql.toString());
}
try (Statement statement = conn.createStatement()) {
statement.execute(sql.toString());
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
use of org.umlg.sqlg.structure.PropertyType in project sqlg by pietermartin.
the class TestBatchStreamTemporaryVertex method testStreamTemporaryVertexMultipleThreads.
// Testing issue #226
@Test
public void testStreamTemporaryVertexMultipleThreads() throws InterruptedException {
VertexLabel haloVertexLabel = this.sqlgGraph.getTopology().ensureVertexLabelExist("halo");
haloVertexLabel.ensurePropertiesExist(new HashMap<String, PropertyType>() {
{
put("this", PropertyType.STRING);
}
});
this.sqlgGraph.getTopology().ensureVertexLabelExist("A");
this.sqlgGraph.tx().commit();
final CountDownLatch countDownLatch1 = new CountDownLatch(1);
final CountDownLatch countDownLatch2 = new CountDownLatch(1);
final Thread thread1 = new Thread("thread1") {
@Override
public void run() {
TestBatchStreamTemporaryVertex.this.sqlgGraph.tx().streamingBatchModeOn();
TestBatchStreamTemporaryVertex.this.sqlgGraph.streamTemporaryVertex("halo", new LinkedHashMap<String, Object>() {
{
put("this", "that");
}
});
countDownLatch1.countDown();
System.out.println("countDownLatch1 countDown");
TestBatchStreamTemporaryVertex.this.sqlgGraph.streamTemporaryVertex("halo", new LinkedHashMap<String, Object>() {
{
put("this", "that");
}
});
try {
countDownLatch2.await();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
// If Topology.temporaryTable has been cleared then the next line will block.
// It will block because it will try to create the temp table but the copy command is already in progress.
// The copy command needs to finish before the driver will allow any other command to execute.
TestBatchStreamTemporaryVertex.this.sqlgGraph.streamTemporaryVertex("halo", new LinkedHashMap<String, Object>() {
{
put("this", "that");
}
});
TestBatchStreamTemporaryVertex.this.sqlgGraph.tx().commit();
}
};
thread1.start();
final Thread thread2 = new Thread("thread2") {
@Override
public void run() {
try {
countDownLatch1.await();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("thread2 countDownLatch ");
TestBatchStreamTemporaryVertex.this.sqlgGraph.addVertex(T.label, "A");
TestBatchStreamTemporaryVertex.this.sqlgGraph.tx().commit();
countDownLatch2.countDown();
}
};
thread2.start();
thread1.join();
thread2.join();
}
use of org.umlg.sqlg.structure.PropertyType in project sqlg by pietermartin.
the class H2Dialect method putJsonObject.
@Override
public void putJsonObject(ObjectNode obj, String columnName, int sqlType, Object o) {
switch(sqlType) {
case Types.ARRAY:
try {
ArrayNode arrayNode = obj.putArray(columnName);
java.sql.Array sqlA = (java.sql.Array) o;
Object a = sqlA.getArray();
int len = Array.getLength(a);
if (len > 0) {
PropertyType pt = PropertyType.from(Array.get(a, 0));
for (int i = 0; i < len; ++i) {
Object v = Array.get(a, i);
switch(pt) {
case BOOLEAN:
arrayNode.add((Boolean) v);
break;
case BYTE:
arrayNode.add((Byte) v);
break;
case DOUBLE:
arrayNode.add((Double) v);
break;
case FLOAT:
arrayNode.add((Float) v);
break;
case INTEGER:
arrayNode.add((Integer) v);
break;
case LONG:
arrayNode.add((Long) v);
break;
case SHORT:
arrayNode.add((Short) v);
break;
case STRING:
arrayNode.add((String) v);
break;
}
}
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
break;
default:
super.putJsonObject(obj, columnName, sqlType, o);
}
}
Aggregations