From b63f05245b94ef17ee91ce68c90d914abf1193bb Mon Sep 17 00:00:00 2001 From: zhangyi51 Date: Mon, 29 Apr 2019 17:32:34 +0800 Subject: [PATCH] adjust table define Change-Id: I155d9f121dc47309c0aab3181cb82916bf62d91f --- .travis.yml | 3 - .../hugegraph/backend/store/TableDefine.java | 17 +- .../assembly/static/conf/hugegraph.properties | 2 +- .../src/assembly/travis/install-postgresql.sh | 5 +- .../backend/store/mysql/MysqlOptions.java | 10 +- .../backend/store/mysql/MysqlTable.java | 41 ++- .../backend/store/mysql/MysqlTables.java | 124 +++++-- .../store/postgresql/PostgresqlOptions.java | 24 +- .../postgresql/PostgresqlSerializer.java | 33 +- .../store/postgresql/PostgresqlTable.java | 223 +----------- .../store/postgresql/PostgresqlTables.java | 334 ++++-------------- .../baidu/hugegraph/core/EdgeCoreTest.java | 2 +- .../baidu/hugegraph/core/VertexCoreTest.java | 2 +- 13 files changed, 258 insertions(+), 562 deletions(-) diff --git a/.travis.yml b/.travis.yml index b6dd5ac5ca..a2c687549b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,9 +5,6 @@ jdk: sudo: required -addons: - postgresql: "9.5" - cache: directories: - $HOME/.m2 diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/store/TableDefine.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/store/TableDefine.java index 3dd4358e22..9bc6af4f89 100644 --- a/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/store/TableDefine.java +++ b/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/store/TableDefine.java @@ -29,20 +29,35 @@ import com.baidu.hugegraph.type.define.HugeKeys; import com.baidu.hugegraph.util.InsertionOrderUtil; +import jersey.repackaged.com.google.common.collect.ImmutableMap; + public class TableDefine { private final Map columns; private final List keys; + private final Map typesMapping; public TableDefine() { this.columns = InsertionOrderUtil.newMap(); this.keys = InsertionOrderUtil.newList(); + this.typesMapping = ImmutableMap.of(); + } + + public TableDefine(Map typesMapping) { + this.columns = InsertionOrderUtil.newMap(); + this.keys = InsertionOrderUtil.newList(); + this.typesMapping = typesMapping; } public TableDefine column(HugeKeys key, String... desc) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < desc.length; i++) { - sb.append(desc[i]); + String type = desc[i]; + if (i == 0 && this.typesMapping.containsKey(type)) { + type = this.typesMapping.get(type); + } + assert type != null; + sb.append(type); if (i != desc.length - 1) { sb.append(" "); } diff --git a/hugegraph-dist/src/assembly/static/conf/hugegraph.properties b/hugegraph-dist/src/assembly/static/conf/hugegraph.properties index 2973ffd51d..5a83ffd30b 100644 --- a/hugegraph-dist/src/assembly/static/conf/hugegraph.properties +++ b/hugegraph-dist/src/assembly/static/conf/hugegraph.properties @@ -39,7 +39,7 @@ cassandra.password= #jdbc.password= #jdbc.reconnect_max_times=3 #jdbc.reconnect_interval=3 - +#jdbc.sslmode=disable # palo backend config #palo.host=127.0.0.1 diff --git a/hugegraph-dist/src/assembly/travis/install-postgresql.sh b/hugegraph-dist/src/assembly/travis/install-postgresql.sh index 191cff1d6d..73f318e97a 100755 --- a/hugegraph-dist/src/assembly/travis/install-postgresql.sh +++ b/hugegraph-dist/src/assembly/travis/install-postgresql.sh @@ -3,7 +3,7 @@ set -ev TRAVIS_DIR=`dirname $0` -CONF=$TRAVIS_DIR/../../../../hugegraph-test/src/main/resources/hugegraph.properties +CONF=hugegraph-test/src/main/resources/hugegraph.properties POSTGRESQL_DRIVER=org.postgresql.Driver POSTGRESQL_URL=jdbc:postgresql://localhost:5432/ @@ -14,4 +14,5 @@ sed -i "s/jdbc.driver=.*/jdbc.driver=$POSTGRESQL_DRIVER/" $CONF sed -i "s?jdbc.url=.*?jdbc.url=$POSTGRESQL_URL?" $CONF sed -i "s/jdbc.username=.*/jdbc.username=$POSTGRESQL_USERNAME/" $CONF -sudo service postgresql restart +sudo service postgresql stop 9.2 +sudo service postgresql start 9.5 diff --git a/hugegraph-mysql/src/main/java/com/baidu/hugegraph/backend/store/mysql/MysqlOptions.java b/hugegraph-mysql/src/main/java/com/baidu/hugegraph/backend/store/mysql/MysqlOptions.java index c6bd854864..db9fc53a43 100644 --- a/hugegraph-mysql/src/main/java/com/baidu/hugegraph/backend/store/mysql/MysqlOptions.java +++ b/hugegraph-mysql/src/main/java/com/baidu/hugegraph/backend/store/mysql/MysqlOptions.java @@ -27,7 +27,7 @@ public class MysqlOptions extends OptionHolder { - private MysqlOptions() { + protected MysqlOptions() { super(); } @@ -89,4 +89,12 @@ public static synchronized MysqlOptions instance() { rangeInt(1, 10), 3 ); + + public static final ConfigOption SSL_MODE = + new ConfigOption<>( + "jdbc.ssl_mode", + "The url of database in JDBC format.", + disallowEmpty(), + "disable" + ); } diff --git a/hugegraph-mysql/src/main/java/com/baidu/hugegraph/backend/store/mysql/MysqlTable.java b/hugegraph-mysql/src/main/java/com/baidu/hugegraph/backend/store/mysql/MysqlTable.java index f675bc9c4d..6df2e7a39b 100644 --- a/hugegraph-mysql/src/main/java/com/baidu/hugegraph/backend/store/mysql/MysqlTable.java +++ b/hugegraph-mysql/src/main/java/com/baidu/hugegraph/backend/store/mysql/MysqlTable.java @@ -28,6 +28,7 @@ import java.util.Map; import java.util.Set; +import org.apache.logging.log4j.util.Strings; import org.slf4j.Logger; import com.baidu.hugegraph.backend.BackendException; @@ -50,6 +51,8 @@ public abstract class MysqlTable private static final Logger LOG = Log.logger(MysqlStore.class); + protected String dropTableTemplate = "DROP TABLE IF EXISTS %s;"; + protected String truncateTableTemplate = "TRUNCATE TABLE %s;"; // The template for insert and delete statements private String insertTemplate; private String deleteTemplate; @@ -91,14 +94,16 @@ protected void createTable(Session session, TableDefine tableDefine) { // Specified primary keys sql.append(" PRIMARY KEY ("); int i = 0; + int size = tableDefine.keys().size(); for (HugeKeys key : tableDefine.keys()) { - sql.append(key); - if (++i != tableDefine.keys().size()) { + sql.append(formatKey(key)); + if (++i != size) { sql.append(", "); } } - - sql.append(")) ENGINE=InnoDB;"); + sql.append("))"); + sql.append(this.engine()); + sql.append(";"); LOG.debug("Create table: {}", sql); try { @@ -109,9 +114,13 @@ protected void createTable(Session session, TableDefine tableDefine) { } } + protected String engine() { + return " ENGINE=InnoDB"; + } + protected void dropTable(Session session) { LOG.debug("Drop table: {}", this.table()); - String sql = String.format("DROP TABLE IF EXISTS %s;", this.table()); + String sql = String.format(this.dropTableTemplate, this.table()); try { session.execute(sql); } catch (SQLException e) { @@ -122,7 +131,7 @@ protected void dropTable(Session session) { protected void truncateTable(Session session) { LOG.debug("Truncate table: {}", this.table()); - String sql = String.format("TRUNCATE TABLE %s;", this.table()); + String sql = String.format(this.truncateTableTemplate, this.table()); try { session.execute(sql); } catch (SQLException e) { @@ -202,7 +211,7 @@ public void insert(Session session, MysqlBackendEntry.Row entry) { // Create or get insert prepare statement insertStmt = session.prepareStatement(template); int i = 1; - for (Object object : entry.columns().values()) { + for (Object object : this.insertTemplateObjects(entry)) { insertStmt.setObject(i++, object); } } catch (SQLException e) { @@ -413,7 +422,7 @@ protected StringBuilder relation2Sql(Condition.Relation relation) { Object value = relation.serialValue(); // Serialize value (TODO: should move to Serializer) - value = serializeValue(value); + value = this.serializeValue(value); StringBuilder sql = new StringBuilder(32); sql.append(key); @@ -503,6 +512,8 @@ protected void wrapPage(StringBuilder select, Query query) { select.append(where.build()); } + select.append(this.orderByKeys()); + assert query.limit() != Query.NO_LIMIT; // Fetch `limit + 1` records for judging whether reached the last page select.append(" limit "); @@ -510,6 +521,10 @@ protected void wrapPage(StringBuilder select, Query query) { select.append(";"); } + protected String orderByKeys() { + return Strings.EMPTY; + } + protected void wrapOffset(StringBuilder select, Query query) { assert query.limit() >= 0; assert query.offset() >= 0; @@ -521,7 +536,7 @@ protected void wrapOffset(StringBuilder select, Query query) { select.append(";"); } - protected static Object serializeValue(Object value) { + protected Object serializeValue(Object value) { if (value instanceof Id) { value = ((Id) value).asObject(); } @@ -545,6 +560,14 @@ protected void appendPartition(StringBuilder delete) { // pass } + protected List insertTemplateObjects(MysqlBackendEntry.Row entry) { + List objects = new ArrayList<>(); + for (Object key : entry.columns().keySet()) { + objects.add(entry.columns().get(key)); + } + return objects; + } + public static String formatKey(HugeKeys key) { return key.name(); } diff --git a/hugegraph-mysql/src/main/java/com/baidu/hugegraph/backend/store/mysql/MysqlTables.java b/hugegraph-mysql/src/main/java/com/baidu/hugegraph/backend/store/mysql/MysqlTables.java index 594aae3803..faf083a0c4 100644 --- a/hugegraph-mysql/src/main/java/com/baidu/hugegraph/backend/store/mysql/MysqlTables.java +++ b/hugegraph-mysql/src/main/java/com/baidu/hugegraph/backend/store/mysql/MysqlTables.java @@ -25,6 +25,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Map; import com.baidu.hugegraph.backend.BackendException; import com.baidu.hugegraph.backend.id.EdgeId; @@ -40,20 +41,30 @@ import com.baidu.hugegraph.type.define.HugeKeys; import com.baidu.hugegraph.util.E; +import jersey.repackaged.com.google.common.collect.ImmutableMap; + public class MysqlTables { - private static final String INT = "INT"; + public static final String BOOLEAN = "BOOLEAN"; + public static final String TINYINT = "TINYINT"; + public static final String INT = "INT"; + public static final String DOUBLE = "DOUBLE"; + public static final String SMALL_TEXT = "SMALL_TEXT"; + public static final String MID_TEXT = "MID_TEXT"; + public static final String LARGE_TEXT = "LARGE_TEXT"; + + private static final String DATATYPE_PK = INT; + private static final String DATATYPE_SL = INT; // VL/EL + private static final String DATATYPE_IL = INT; - private static final String DATATYPE_PK = "INT"; - private static final String DATATYPE_SL = "INT"; // VL/EL - private static final String DATATYPE_IL = "INT"; + private static final String SMALL_JSON = MID_TEXT; + private static final String LARGE_JSON = LARGE_TEXT; - private static final String BOOLEAN = "BOOLEAN"; - private static final String TINYINT = "TINYINT"; - private static final String DOUBLE = "DOUBLE"; - private static final String VARCHAR = "VARCHAR(255)"; - private static final String SMALL_JSON = "VARCHAR(1024)"; - private static final String LARGE_JSON = "TEXT"; + private static final Map TYPES_MAPPING = ImmutableMap.of( + SMALL_TEXT, "VARCHAR(255)", + MID_TEXT, "VARCHAR(1024)", + LARGE_TEXT, "TEXT" + ); public static class MysqlTableTemplate extends MysqlTable { @@ -74,10 +85,14 @@ public static class Counters extends MysqlTableTemplate { public static final String TABLE = "counters"; public Counters() { + this(TYPES_MAPPING); + } + + public Counters(Map typesMapping) { super(TABLE); - this.define = new TableDefine(); - this.define.column(HugeKeys.SCHEMA_TYPE, VARCHAR); + this.define = new TableDefine(typesMapping); + this.define.column(HugeKeys.SCHEMA_TYPE, SMALL_TEXT); this.define.column(HugeKeys.ID, INT); this.define.keys(HugeKeys.SCHEMA_TYPE); } @@ -122,11 +137,15 @@ public static class VertexLabel extends MysqlTableTemplate { public static final String TABLE = "vertex_labels"; public VertexLabel() { + this(TYPES_MAPPING); + } + + public VertexLabel(Map typesMapping) { super(TABLE); - this.define = new TableDefine(); + this.define = new TableDefine(typesMapping); this.define.column(HugeKeys.ID, DATATYPE_SL); - this.define.column(HugeKeys.NAME, VARCHAR); + this.define.column(HugeKeys.NAME, SMALL_TEXT); this.define.column(HugeKeys.ID_STRATEGY, TINYINT); this.define.column(HugeKeys.PRIMARY_KEYS, SMALL_JSON); this.define.column(HugeKeys.PROPERTIES, SMALL_JSON); @@ -144,11 +163,15 @@ public static class EdgeLabel extends MysqlTableTemplate { public static final String TABLE = "edge_labels"; public EdgeLabel() { + this(TYPES_MAPPING); + } + + public EdgeLabel(Map typesMapping) { super(TABLE); - this.define = new TableDefine(); + this.define = new TableDefine(typesMapping); this.define.column(HugeKeys.ID, DATATYPE_SL); - this.define.column(HugeKeys.NAME, VARCHAR); + this.define.column(HugeKeys.NAME, SMALL_TEXT); this.define.column(HugeKeys.FREQUENCY, TINYINT); this.define.column(HugeKeys.SOURCE_LABEL, DATATYPE_SL); this.define.column(HugeKeys.TARGET_LABEL, DATATYPE_SL); @@ -168,11 +191,15 @@ public static class PropertyKey extends MysqlTableTemplate { public static final String TABLE = "property_keys"; public PropertyKey() { + this(TYPES_MAPPING); + } + + public PropertyKey(Map typesMapping) { super(TABLE); - this.define = new TableDefine(); + this.define = new TableDefine(typesMapping); this.define.column(HugeKeys.ID, DATATYPE_PK); - this.define.column(HugeKeys.NAME, VARCHAR); + this.define.column(HugeKeys.NAME, SMALL_TEXT); this.define.column(HugeKeys.DATA_TYPE, TINYINT); this.define.column(HugeKeys.CARDINALITY, TINYINT); this.define.column(HugeKeys.PROPERTIES, SMALL_JSON); @@ -187,11 +214,15 @@ public static class IndexLabel extends MysqlTableTemplate { public static final String TABLE = "index_labels"; public IndexLabel() { + this(TYPES_MAPPING); + } + + public IndexLabel(Map typesMapping) { super(TABLE); - this.define = new TableDefine(); + this.define = new TableDefine(typesMapping); this.define.column(HugeKeys.ID, DATATYPE_IL); - this.define.column(HugeKeys.NAME, VARCHAR); + this.define.column(HugeKeys.NAME, SMALL_TEXT); this.define.column(HugeKeys.BASE_TYPE, TINYINT); this.define.column(HugeKeys.BASE_VALUE, DATATYPE_SL); this.define.column(HugeKeys.INDEX_TYPE, TINYINT); @@ -206,10 +237,14 @@ public static class Vertex extends MysqlTableTemplate { public static final String TABLE = "vertices"; public Vertex(String store) { + this(store, TYPES_MAPPING); + } + + public Vertex(String store, Map typesMapping) { super(joinTableName(store, TABLE)); - this.define = new TableDefine(); - this.define.column(HugeKeys.ID, VARCHAR); + this.define = new TableDefine(typesMapping); + this.define.column(HugeKeys.ID, SMALL_TEXT); this.define.column(HugeKeys.LABEL, DATATYPE_SL); this.define.column(HugeKeys.PROPERTIES, LARGE_JSON); this.define.keys(HugeKeys.ID); @@ -223,7 +258,12 @@ public static class Edge extends MysqlTableTemplate { private final Directions direction; private final String delByLabelTemplate; - protected Edge(String store, Directions direction) { + public Edge(String store, Directions direction) { + this(store, direction, TYPES_MAPPING); + } + + public Edge(String store, Directions direction, + Map typesMapping) { super(joinTableName(store, table(direction))); this.direction = direction; @@ -231,12 +271,12 @@ protected Edge(String store, Directions direction) { "DELETE FROM %s WHERE %s = ?;", this.table(), formatKey(HugeKeys.LABEL)); - this.define = new TableDefine(); - this.define.column(HugeKeys.OWNER_VERTEX, VARCHAR); + this.define = new TableDefine(typesMapping); + this.define.column(HugeKeys.OWNER_VERTEX, SMALL_TEXT); this.define.column(HugeKeys.DIRECTION, TINYINT); this.define.column(HugeKeys.LABEL, DATATYPE_SL); - this.define.column(HugeKeys.SORT_VALUES, VARCHAR); - this.define.column(HugeKeys.OTHER_VERTEX, VARCHAR); + this.define.column(HugeKeys.SORT_VALUES, SMALL_TEXT); + this.define.column(HugeKeys.OTHER_VERTEX, SMALL_TEXT); this.define.column(HugeKeys.PROPERTIES, LARGE_JSON); this.define.keys(HugeKeys.OWNER_VERTEX, HugeKeys.DIRECTION, HugeKeys.LABEL, HugeKeys.SORT_VALUES, @@ -244,7 +284,7 @@ protected Edge(String store, Directions direction) { } @Override - protected List idColumnValue(Id id) { + public List idColumnValue(Id id) { EdgeId edgeId; if (!(id instanceof EdgeId)) { String[] idParts = EdgeId.split(id); @@ -299,7 +339,7 @@ private void deleteEdgesByLabel(Session session, Id label) { } @Override - protected BackendEntry mergeEntries(BackendEntry e1, BackendEntry e2) { + public BackendEntry mergeEntries(BackendEntry e1, BackendEntry e2) { // Merge edges into vertex // TODO: merge rows before calling row2Entry() @@ -366,22 +406,24 @@ public static class SecondaryIndex extends Index { public static final String TABLE = "secondary_indexes"; public SecondaryIndex(String store) { - this(store, TABLE); + this(store, TABLE, TYPES_MAPPING); } - public SecondaryIndex(String store, String table) { + + public SecondaryIndex(String store, String table, + Map typesMapping) { super(joinTableName(store, table)); - this.define = new TableDefine(); - this.define.column(HugeKeys.FIELD_VALUES, VARCHAR); + this.define = new TableDefine(typesMapping); + this.define.column(HugeKeys.FIELD_VALUES, SMALL_TEXT); this.define.column(HugeKeys.INDEX_LABEL_ID, DATATYPE_IL); - this.define.column(HugeKeys.ELEMENT_IDS, VARCHAR); + this.define.column(HugeKeys.ELEMENT_IDS, SMALL_TEXT); this.define.keys(HugeKeys.FIELD_VALUES, HugeKeys.INDEX_LABEL_ID, HugeKeys.ELEMENT_IDS); } @Override - protected final String entryId(MysqlBackendEntry entry) { + public final String entryId(MysqlBackendEntry entry) { String fieldValues = entry.column(HugeKeys.FIELD_VALUES); Integer labelId = entry.column(HugeKeys.INDEX_LABEL_ID); return SplicingIdGenerator.concat(fieldValues, labelId.toString()); @@ -393,7 +435,7 @@ public static class SearchIndex extends SecondaryIndex { public static final String TABLE = "search_indexes"; public SearchIndex(String store) { - super(store, TABLE); + super(store, TABLE, TYPES_MAPPING); } } @@ -402,19 +444,23 @@ public static class RangeIndex extends Index { public static final String TABLE = "range_indexes"; public RangeIndex(String store) { + this(store, TYPES_MAPPING); + } + + public RangeIndex(String store, Map typesMapping) { super(joinTableName(store, TABLE)); - this.define = new TableDefine(); + this.define = new TableDefine(typesMapping); this.define.column(HugeKeys.INDEX_LABEL_ID, DATATYPE_IL); this.define.column(HugeKeys.FIELD_VALUES, DOUBLE); - this.define.column(HugeKeys.ELEMENT_IDS, VARCHAR); + this.define.column(HugeKeys.ELEMENT_IDS, SMALL_TEXT); this.define.keys(HugeKeys.INDEX_LABEL_ID, HugeKeys.FIELD_VALUES, HugeKeys.ELEMENT_IDS); } @Override - protected final String entryId(MysqlBackendEntry entry) { + public final String entryId(MysqlBackendEntry entry) { Double fieldValue = entry.column(HugeKeys.FIELD_VALUES); Integer labelId = entry.column(HugeKeys.INDEX_LABEL_ID); return SplicingIdGenerator.concat(labelId.toString(), diff --git a/hugegraph-postgresql/src/main/java/com/baidu/hugegraph/backend/store/postgresql/PostgresqlOptions.java b/hugegraph-postgresql/src/main/java/com/baidu/hugegraph/backend/store/postgresql/PostgresqlOptions.java index bd68cf4889..75ccc843cd 100644 --- a/hugegraph-postgresql/src/main/java/com/baidu/hugegraph/backend/store/postgresql/PostgresqlOptions.java +++ b/hugegraph-postgresql/src/main/java/com/baidu/hugegraph/backend/store/postgresql/PostgresqlOptions.java @@ -19,12 +19,12 @@ package com.baidu.hugegraph.backend.store.postgresql; +import com.baidu.hugegraph.backend.store.mysql.MysqlOptions; import com.baidu.hugegraph.config.ConfigOption; -import com.baidu.hugegraph.config.OptionHolder; -import static com.baidu.hugegraph.config.OptionChecker.*; +import static com.baidu.hugegraph.config.OptionChecker.disallowEmpty; -public class PostgresqlOptions extends OptionHolder { +public class PostgresqlOptions extends MysqlOptions { private PostgresqlOptions() { super(); @@ -56,27 +56,11 @@ public static synchronized PostgresqlOptions instance() { "jdbc:postgresql://127.0.0.1:5432" ); - public static final ConfigOption SSL_MODE = - new ConfigOption<>( - "jdbc.ssl_mode", - "The url of database in JDBC format.", - disallowEmpty(), - "disable" - ); - public static final ConfigOption JDBC_USERNAME = new ConfigOption<>( "jdbc.username", "The username to login database.", disallowEmpty(), - "root" - ); - - public static final ConfigOption JDBC_PASSWORD = - new ConfigOption<>( - "jdbc.password", - "The password corresponding to jdbc.username.", - null, - "" + "postgres" ); } diff --git a/hugegraph-postgresql/src/main/java/com/baidu/hugegraph/backend/store/postgresql/PostgresqlSerializer.java b/hugegraph-postgresql/src/main/java/com/baidu/hugegraph/backend/store/postgresql/PostgresqlSerializer.java index adb465743a..edd276c4ef 100644 --- a/hugegraph-postgresql/src/main/java/com/baidu/hugegraph/backend/store/postgresql/PostgresqlSerializer.java +++ b/hugegraph-postgresql/src/main/java/com/baidu/hugegraph/backend/store/postgresql/PostgresqlSerializer.java @@ -19,6 +19,37 @@ package com.baidu.hugegraph.backend.store.postgresql; +import org.apache.logging.log4j.util.Strings; + +import com.baidu.hugegraph.backend.id.IdUtil; +import com.baidu.hugegraph.backend.serializer.TableBackendEntry; +import com.baidu.hugegraph.backend.store.BackendEntry; import com.baidu.hugegraph.backend.store.mysql.MysqlSerializer; +import com.baidu.hugegraph.structure.HugeIndex; +import com.baidu.hugegraph.type.define.HugeKeys; + +public class PostgresqlSerializer extends MysqlSerializer { -public class PostgresqlSerializer extends MysqlSerializer {} + @Override + public BackendEntry writeIndex(HugeIndex index) { + TableBackendEntry entry = newBackendEntry(index); + /* + * When field-values is null and elementIds size is 0, it is + * meaningful for deletion of index data in secondary/range index. + */ + if (index.fieldValues() == null && index.elementIds().size() == 0) { + entry.column(HugeKeys.INDEX_LABEL_ID, index.indexLabel().asLong()); + } else { + Object value = index.fieldValues(); + if (value != null && value.equals("\u0000")) { + value = Strings.EMPTY; + } + entry.column(HugeKeys.FIELD_VALUES, value); + entry.column(HugeKeys.INDEX_LABEL_ID, index.indexLabel().asLong()); + entry.column(HugeKeys.ELEMENT_IDS, + IdUtil.writeString(index.elementId())); + entry.subId(index.elementId()); + } + return entry; + } +} diff --git a/hugegraph-postgresql/src/main/java/com/baidu/hugegraph/backend/store/postgresql/PostgresqlTable.java b/hugegraph-postgresql/src/main/java/com/baidu/hugegraph/backend/store/postgresql/PostgresqlTable.java index c222ca3766..abc54de0ea 100644 --- a/hugegraph-postgresql/src/main/java/com/baidu/hugegraph/backend/store/postgresql/PostgresqlTable.java +++ b/hugegraph-postgresql/src/main/java/com/baidu/hugegraph/backend/store/postgresql/PostgresqlTable.java @@ -19,161 +19,44 @@ package com.baidu.hugegraph.backend.store.postgresql; -import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; -import java.util.Map; +import org.apache.logging.log4j.util.Strings; import org.postgresql.core.Utils; -import org.slf4j.Logger; import com.baidu.hugegraph.HugeException; -import com.baidu.hugegraph.backend.BackendException; import com.baidu.hugegraph.backend.id.Id; -import com.baidu.hugegraph.backend.query.Condition; -import com.baidu.hugegraph.backend.query.Query; -import com.baidu.hugegraph.backend.store.TableDefine; import com.baidu.hugegraph.backend.store.mysql.MysqlBackendEntry; -import com.baidu.hugegraph.backend.store.mysql.MysqlEntryIterator; -import com.baidu.hugegraph.backend.store.mysql.MysqlSessions.Session; import com.baidu.hugegraph.backend.store.mysql.MysqlTable; -import com.baidu.hugegraph.backend.store.mysql.WhereBuilder; import com.baidu.hugegraph.type.define.HugeKeys; -import com.baidu.hugegraph.util.Log; public abstract class PostgresqlTable extends MysqlTable { - private static final Logger LOG = Log.logger(PostgresqlStore.class); - private String insertTemplate; public PostgresqlTable(String table) { super(table); + this.dropTableTemplate = "DROP TABLE IF EXISTS %s CASCADE;"; + this.truncateTableTemplate = "TRUNCATE TABLE %s CASCADE;"; } @Override - protected void createTable(Session session, TableDefine tableDefine) { - StringBuilder sql = new StringBuilder(); - sql.append("CREATE TABLE IF NOT EXISTS "); - sql.append(this.table()).append(" ("); - // Add columns - for (Map.Entry entry : - tableDefine.columns().entrySet()) { - sql.append(formatKey(entry.getKey())); - sql.append(" "); - sql.append(entry.getValue()); - sql.append(", "); - } - // Specified primary keys - sql.append(" PRIMARY KEY ("); - int i = 0; - int size = tableDefine.keys().size(); - for (HugeKeys key : tableDefine.keys()) { - sql.append(formatKey(key)); - if (++i != size) { - sql.append(", "); - } - } - sql.append("))"); - - LOG.debug("Create table: {}", sql); - try { - session.execute(sql.toString()); - } catch (SQLException e) { - throw new BackendException("Failed to create table with '%s'", - e, sql); - } - } - - @Override - protected void dropTable(Session session) { - LOG.debug("Drop table: {}", this.table()); - String sql = String.format("DROP TABLE IF EXISTS %s CASCADE;", - this.table()); - try { - session.execute(sql); - } catch (SQLException e) { - throw new BackendException("Failed to drop table with '%s'", - e, sql); - } + protected String engine() { + return Strings.EMPTY; } - @Override - protected void truncateTable(Session session) { - LOG.debug("Truncate table: {}", this.table()); - String sql = String.format("TRUNCATE TABLE %s CASCADE;", this.table()); - try { - session.execute(sql); - } catch (SQLException e) { - throw new BackendException("Failed to truncate table with '%s'", - e, sql); - } - } - /** - * Insert an entire row - */ @Override - public void insert(Session session, MysqlBackendEntry.Row entry) { - String template = this.buildInsertTemplate(entry); - - PreparedStatement insertStmt; - try { - // Create or get insert prepare statement - insertStmt = session.prepareStatement(template); - int i = 1; - int size = entry.columns().size(); - for (Object object : entry.columns().values()) { - if (object.equals("\u0000")) { - object = ""; - } - insertStmt.setObject(i, object); - insertStmt.setObject(size + i++, object); - } - } catch (SQLException e) { - throw new BackendException("Failed to prepare statement '%s'" + - "for entry: %s", template, entry); - } - session.add(insertStmt); + protected List insertTemplateObjects(MysqlBackendEntry.Row entry) { + List objects = new ArrayList<>(); + objects.addAll(super.insertTemplateObjects(entry)); + objects.addAll(super.insertTemplateObjects(entry)); + return objects; } @Override - public void delete(Session session, MysqlBackendEntry.Row entry) { - List idNames = this.idColumnName(); - String template = this.buildDeleteTemplate(idNames); - - PreparedStatement deleteStmt; - try { - deleteStmt = session.prepareStatement(template); - if (entry.columns().isEmpty()) { - // Delete just by id - List idValues = this.idColumnValue(entry); - assert idNames.size() == idValues.size(); - - for (int i = 0, n = idNames.size(); i < n; i++) { - deleteStmt.setObject(i + 1, idValues.get(i)); - } - } else { - // Delete just by column keys(must be id columns) - for (int i = 0, n = idNames.size(); i < n; i++) { - HugeKeys key = idNames.get(i); - Object value = entry.column(key); - if (value != null && value.equals("\u0000")) { - value = "\'\'"; - } - - deleteStmt.setObject(i + 1, value); - } - } - } catch (SQLException e) { - throw new BackendException("Failed to prepare statement '%s'" + - "with entry columns %s", - template, entry.columns().values()); - } - session.add(deleteStmt); - } - protected String buildInsertTemplate(MysqlBackendEntry.Row entry) { if (this.insertTemplate != null) { return this.insertTemplate; @@ -225,34 +108,11 @@ protected String buildInsertTemplate(MysqlBackendEntry.Row entry) { return this.insertTemplate; } - protected void wrapPage(StringBuilder select, Query query) { - String page = query.page(); - // It's the first time if page is empty - if (!page.isEmpty()) { - MysqlEntryIterator.PageState - pageState = MysqlEntryIterator.PageState.fromString(page); - Map columns = pageState.columns(); - - List idColumnNames = this.idColumnName(); - List values = new ArrayList<>(idColumnNames.size()); - for (HugeKeys key : idColumnNames) { - values.add(columns.get(key)); - } - - // Need add `where` to `select` when query is IdQuery - boolean startWithWhere = query.conditions().isEmpty(); - WhereBuilder where = new WhereBuilder(startWithWhere); - where.gte(formatKeys(idColumnNames), values); - if (!startWithWhere) { - select.append(" AND"); - } - select.append(where.build()); - } - + // Set order-by to keep results order consistence for PostgreSQL result + protected String orderByKeys() { int i = 0; int size = this.tableDefine().keys().size(); - - // Set order-by to keep results order consistence for result + StringBuilder select = new StringBuilder(); select.append(" ORDER BY "); for (HugeKeys hugeKey : this.tableDefine().keys()) { String key = formatKey(hugeKey); @@ -262,63 +122,10 @@ protected void wrapPage(StringBuilder select, Query query) { select.append(", "); } } - - assert query.limit() != Query.NO_LIMIT; - // Fetch `limit + 1` records for judging whether reached the last page - select.append(" limit "); - select.append(query.limit() + 1); - select.append(";"); - } - - @Override - protected StringBuilder relation2Sql(Condition.Relation relation) { - String key = relation.serialKey().toString(); - Object value = relation.serialValue(); - - value = serializeValue(value); - - StringBuilder sql = new StringBuilder(32); - sql.append(key); - switch (relation.relation()) { - case EQ: - sql.append(" = ").append(value); - break; - case NEQ: - sql.append(" != ").append(value); - break; - case GT: - sql.append(" > ").append(value); - break; - case GTE: - sql.append(" >= ").append(value); - break; - case LT: - sql.append(" < ").append(value); - break; - case LTE: - sql.append(" <= ").append(value); - break; - case IN: - sql.append(" IN ("); - List values = (List) value; - for (int i = 0, n = values.size(); i < n; i++) { - sql.append(serializeValue(values.get(i))); - if (i != n - 1) { - sql.append(", "); - } - } - sql.append(")"); - break; - case CONTAINS: - case CONTAINS_KEY: - case SCAN: - default: - throw new AssertionError("Unsupported relation: " + relation); - } - return sql; + return select.toString(); } - protected static Object serializeValue(Object value) { + protected Object serializeValue(Object value) { if (value instanceof Id) { value = ((Id) value).asObject(); } diff --git a/hugegraph-postgresql/src/main/java/com/baidu/hugegraph/backend/store/postgresql/PostgresqlTables.java b/hugegraph-postgresql/src/main/java/com/baidu/hugegraph/backend/store/postgresql/PostgresqlTables.java index 794c3e9182..a48d8b7525 100644 --- a/hugegraph-postgresql/src/main/java/com/baidu/hugegraph/backend/store/postgresql/PostgresqlTables.java +++ b/hugegraph-postgresql/src/main/java/com/baidu/hugegraph/backend/store/postgresql/PostgresqlTables.java @@ -19,102 +19,79 @@ package com.baidu.hugegraph.backend.store.postgresql; -import java.sql.PreparedStatement; -import java.sql.ResultSet; import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Arrays; import java.util.List; +import java.util.Map; import com.baidu.hugegraph.backend.BackendException; -import com.baidu.hugegraph.backend.id.EdgeId; import com.baidu.hugegraph.backend.id.Id; -import com.baidu.hugegraph.backend.id.IdGenerator; -import com.baidu.hugegraph.backend.id.IdUtil; -import com.baidu.hugegraph.backend.id.SplicingIdGenerator; import com.baidu.hugegraph.backend.store.BackendEntry; import com.baidu.hugegraph.backend.store.TableDefine; import com.baidu.hugegraph.backend.store.mysql.MysqlBackendEntry; import com.baidu.hugegraph.backend.store.mysql.MysqlSessions.Session; import com.baidu.hugegraph.backend.store.mysql.MysqlTables; +import com.baidu.hugegraph.backend.store.mysql.MysqlTables.MysqlTableTemplate; import com.baidu.hugegraph.type.HugeType; import com.baidu.hugegraph.type.define.Directions; import com.baidu.hugegraph.type.define.HugeKeys; -import com.baidu.hugegraph.util.E; -public class PostgresqlTables { +import jersey.repackaged.com.google.common.collect.ImmutableMap; - private static final String NOT_NULL = "NOT NULL"; - private static final String DEFAULT_EMPTY = "DEFAULT ''"; +import static com.baidu.hugegraph.backend.store.mysql.MysqlTables.BOOLEAN; +import static com.baidu.hugegraph.backend.store.mysql.MysqlTables.DOUBLE; +import static com.baidu.hugegraph.backend.store.mysql.MysqlTables.INT; +import static com.baidu.hugegraph.backend.store.mysql.MysqlTables.LARGE_TEXT; +import static com.baidu.hugegraph.backend.store.mysql.MysqlTables.MID_TEXT; +import static com.baidu.hugegraph.backend.store.mysql.MysqlTables.SMALL_TEXT; +import static com.baidu.hugegraph.backend.store.mysql.MysqlTables.TINYINT; - private static final String DATATYPE_PK = "INT"; - private static final String DATATYPE_SL = "INT"; // VL/EL - private static final String DATATYPE_IL = "INT"; +public class PostgresqlTables { - private static final String INT = "INT"; - private static final String FLOAT = "FLOAT"; - private static final String VARCHAR = "VARCHAR(255)"; - private static final String TEXT = "VARCHAR(65533)"; - private static final String BOOL = "BOOL"; + private static final Map TYPES_MAPPING = + ImmutableMap.builder() + .put(BOOLEAN, "BOOL") + .put(TINYINT, INT) + .put(DOUBLE, "FLOAT") + .put(SMALL_TEXT, "VARCHAR(255)") + .put(MID_TEXT, "VARCHAR(1024)") + .put(LARGE_TEXT, "VARCHAR(65533)") + .build(); public static class PostgresqlTableTemplate extends PostgresqlTable { - protected TableDefine define; + protected MysqlTableTemplate template; - public PostgresqlTableTemplate(String table) { - super(table); + public PostgresqlTableTemplate(MysqlTableTemplate template) { + super(template.table()); + this.template = template; } @Override public TableDefine tableDefine() { - return this.define; + return this.template.tableDefine(); } } public static class Counters extends PostgresqlTableTemplate { - public static final String TABLE = "counters"; - public Counters() { - super(TABLE); - - this.define = new TableDefine(); - this.define.column(HugeKeys.SCHEMA_TYPE, VARCHAR); - this.define.column(HugeKeys.ID, INT); - this.define.keys(HugeKeys.SCHEMA_TYPE); + super(new MysqlTables.Counters(TYPES_MAPPING)); } public long getCounter(Session session, HugeType type) { - String schemaCol = formatKey(HugeKeys.SCHEMA_TYPE); - String idCol = formatKey(HugeKeys.ID); - - String select = String.format("SELECT ID FROM %s WHERE %s = '%s';", - TABLE, schemaCol, type.name()); - try { - ResultSet resultSet = session.select(select); - if (resultSet.next()) { - return resultSet.getLong(idCol); - } else { - return 0L; - } - } catch (SQLException e) { - throw new BackendException( - "Failed to get id from counters with type '%s'", - e, type); - } + MysqlTables.Counters table = (MysqlTables.Counters) this.template; + return table.getCounter(session, type); } public void increaseCounter(Session session, HugeType type, long increment) { - String update = String.format("INSERT INTO %s (%s, %s) VALUES " + - "('%s', %s) ON CONFLICT (%s) " + - "DO UPDATE SET ID = %s.ID + %s;", - TABLE, - formatKey(HugeKeys.SCHEMA_TYPE), - formatKey(HugeKeys.ID), - type.name(), increment, - formatKey(HugeKeys.SCHEMA_TYPE), - TABLE, increment); + String update = String.format( + "INSERT INTO %s (%s, %s) VALUES ('%s', %s) " + + "ON CONFLICT (%s) DO UPDATE SET ID = %s.ID + %s;", + this.table(), formatKey(HugeKeys.SCHEMA_TYPE), + formatKey(HugeKeys.ID), type.name(), increment, + formatKey(HugeKeys.SCHEMA_TYPE), + this.table(), increment); try { session.execute(update); } catch (SQLException e) { @@ -126,85 +103,29 @@ public void increaseCounter(Session session, HugeType type, public static class VertexLabel extends PostgresqlTableTemplate { - public static final String TABLE = "vertex_labels"; - public VertexLabel() { - super(TABLE); - this.define = new TableDefine(); - this.define.column(HugeKeys.ID, DATATYPE_SL, NOT_NULL); - this.define.column(HugeKeys.NAME, VARCHAR, NOT_NULL); - this.define.column(HugeKeys.ID_STRATEGY, INT, NOT_NULL); - this.define.column(HugeKeys.PRIMARY_KEYS, VARCHAR, DEFAULT_EMPTY); - this.define.column(HugeKeys.PROPERTIES, VARCHAR, DEFAULT_EMPTY); - this.define.column(HugeKeys.NULLABLE_KEYS, VARCHAR, DEFAULT_EMPTY); - this.define.column(HugeKeys.INDEX_LABELS, VARCHAR, DEFAULT_EMPTY); - this.define.column(HugeKeys.ENABLE_LABEL_INDEX, BOOL, NOT_NULL); - this.define.column(HugeKeys.USER_DATA, VARCHAR, DEFAULT_EMPTY); - this.define.column(HugeKeys.STATUS, INT, NOT_NULL); - // Unique keys/hash keys - this.define.keys(HugeKeys.ID); + super(new MysqlTables.VertexLabel(TYPES_MAPPING)); } } public static class EdgeLabel extends PostgresqlTableTemplate { - public static final String TABLE = "edge_labels"; - public EdgeLabel() { - super(TABLE); - this.define = new TableDefine(); - this.define.column(HugeKeys.ID, DATATYPE_SL, NOT_NULL); - this.define.column(HugeKeys.NAME, VARCHAR, NOT_NULL); - this.define.column(HugeKeys.FREQUENCY, INT, NOT_NULL); - this.define.column(HugeKeys.SOURCE_LABEL, INT, NOT_NULL); - this.define.column(HugeKeys.TARGET_LABEL, INT, NOT_NULL); - this.define.column(HugeKeys.SORT_KEYS, VARCHAR, DEFAULT_EMPTY); - this.define.column(HugeKeys.PROPERTIES, VARCHAR, DEFAULT_EMPTY); - this.define.column(HugeKeys.NULLABLE_KEYS, VARCHAR, DEFAULT_EMPTY); - this.define.column(HugeKeys.INDEX_LABELS, VARCHAR, DEFAULT_EMPTY); - this.define.column(HugeKeys.ENABLE_LABEL_INDEX, BOOL, NOT_NULL); - this.define.column(HugeKeys.USER_DATA, VARCHAR, DEFAULT_EMPTY); - this.define.column(HugeKeys.STATUS, INT, NOT_NULL); - // Unique keys/hash keys - this.define.keys(HugeKeys.ID); + super(new MysqlTables.EdgeLabel(TYPES_MAPPING)); } } public static class PropertyKey extends PostgresqlTableTemplate { - public static final String TABLE = "property_keys"; - public PropertyKey() { - super(TABLE); - this.define = new TableDefine(); - this.define.column(HugeKeys.ID, DATATYPE_PK, NOT_NULL); - this.define.column(HugeKeys.NAME, VARCHAR, NOT_NULL); - this.define.column(HugeKeys.DATA_TYPE, INT, NOT_NULL); - this.define.column(HugeKeys.CARDINALITY, INT, NOT_NULL); - this.define.column(HugeKeys.PROPERTIES, VARCHAR, DEFAULT_EMPTY); - this.define.column(HugeKeys.USER_DATA, VARCHAR, DEFAULT_EMPTY); - this.define.column(HugeKeys.STATUS, INT, NOT_NULL); - // Unique keys/hash keys - this.define.keys(HugeKeys.ID); + super(new MysqlTables.PropertyKey(TYPES_MAPPING)); } } public static class IndexLabel extends PostgresqlTableTemplate { - public static final String TABLE = "index_labels"; - public IndexLabel() { - super(TABLE); - this.define = new TableDefine(); - this.define.column(HugeKeys.ID, DATATYPE_IL, NOT_NULL); - this.define.column(HugeKeys.NAME, VARCHAR, NOT_NULL); - this.define.column(HugeKeys.BASE_TYPE, INT, NOT_NULL); - this.define.column(HugeKeys.BASE_VALUE, INT, NOT_NULL); - this.define.column(HugeKeys.INDEX_TYPE, INT, NOT_NULL); - this.define.column(HugeKeys.FIELDS, VARCHAR, NOT_NULL); - this.define.column(HugeKeys.STATUS, INT, NOT_NULL); - // Unique keys/hash keys - this.define.keys(HugeKeys.ID); + super(new MysqlTables.IndexLabel(TYPES_MAPPING)); } } @@ -213,175 +134,51 @@ public static class Vertex extends PostgresqlTableTemplate { public static final String TABLE = "vertices"; public Vertex(String store) { - super(joinTableName(store, TABLE)); - - this.define = new TableDefine(); - this.define.column(HugeKeys.ID, VARCHAR, NOT_NULL); - this.define.column(HugeKeys.LABEL, INT, NOT_NULL); - this.define.column(HugeKeys.PROPERTIES, TEXT, DEFAULT_EMPTY); - // Unique keys/hash keys - this.define.keys(HugeKeys.ID); + super(new MysqlTables.Vertex(store, TYPES_MAPPING)); } } public static class Edge extends PostgresqlTableTemplate { - private final Directions direction; - private final String delByLabelTemplate; - public Edge(String store, Directions direction) { - super(joinTableName(store, MysqlTables.Edge.table(direction))); - - this.direction = direction; - this.delByLabelTemplate = String.format( - "DELETE FROM %s WHERE %s = ?;", - this.table(), formatKey(HugeKeys.LABEL)); - - this.define = new TableDefine(); - this.define.column(HugeKeys.OWNER_VERTEX, VARCHAR, NOT_NULL); - this.define.column(HugeKeys.DIRECTION, INT, NOT_NULL); - this.define.column(HugeKeys.LABEL, INT, NOT_NULL); - this.define.column(HugeKeys.SORT_VALUES, VARCHAR, NOT_NULL, - DEFAULT_EMPTY); - this.define.column(HugeKeys.OTHER_VERTEX, VARCHAR, NOT_NULL); - this.define.column(HugeKeys.PROPERTIES, TEXT, DEFAULT_EMPTY); - // Unique keys/hash keys - this.define.keys(HugeKeys.OWNER_VERTEX, HugeKeys.DIRECTION, - HugeKeys.LABEL, HugeKeys.SORT_VALUES, - HugeKeys.OTHER_VERTEX); + super(new MysqlTables.Edge(store, direction, TYPES_MAPPING)); } @Override protected List idColumnValue(Id id) { - EdgeId edgeId; - if (!(id instanceof EdgeId)) { - String[] idParts = EdgeId.split(id); - if (idParts.length == 1) { - // Delete edge by label - return Arrays.asList((Object[]) idParts); - } - id = IdUtil.readString(id.asString()); - edgeId = EdgeId.parse(id.asString()); - } else { - edgeId = (EdgeId) id; - } - - E.checkState(edgeId.direction() == this.direction, - "Can't query %s edges from %s edges table", - edgeId.direction(), this.direction); - - List list = new ArrayList<>(5); - list.add(IdUtil.writeString(edgeId.ownerVertexId())); - list.add(edgeId.direction().code()); - list.add(edgeId.edgeLabelId().asLong()); - list.add(edgeId.sortValues()); - list.add(IdUtil.writeString(edgeId.otherVertexId())); - return list; + MysqlTables.Edge table = (MysqlTables.Edge) this.template; + return table.idColumnValue(id); } @Override public void delete(Session session, MysqlBackendEntry.Row entry) { - // Let super class do delete if not deleting edge by label - List idParts = this.idColumnValue(entry.id()); - if (idParts.size() > 1 || entry.columns().size() > 0) { - super.delete(session, entry); - return; - } - - // The only element is label - this.deleteEdgesByLabel(session, entry.id()); - } - - private void deleteEdgesByLabel(Session session, Id label) { - PreparedStatement deleteStmt; - try { - // Create or get delete prepare statement - deleteStmt = session.prepareStatement(this.delByLabelTemplate); - // Delete edges - deleteStmt.setObject(1, label.asLong()); - } catch (SQLException e) { - throw new BackendException("Failed to prepare statement '%s'", - this.delByLabelTemplate); - } - session.add(deleteStmt); + MysqlTables.Edge table = (MysqlTables.Edge) this.template; + table.delete(session, entry); } @Override protected BackendEntry mergeEntries(BackendEntry e1, BackendEntry e2) { - // Merge edges into vertex - // TODO: merge rows before calling row2Entry() - - MysqlBackendEntry current = (MysqlBackendEntry) e1; - MysqlBackendEntry next = (MysqlBackendEntry) e2; - - E.checkState(current == null || current.type().isVertex(), - "The current entry must be null or VERTEX"); - E.checkState(next != null && next.type().isEdge(), - "The next entry must be EDGE"); - - if (current != null) { - Id nextVertexId = IdGenerator.of( - next.column(HugeKeys.OWNER_VERTEX)); - if (current.id().equals(nextVertexId)) { - current.subRow(next.row()); - return current; - } - } - - return this.wrapByVertex(next); - } - - private MysqlBackendEntry wrapByVertex(MysqlBackendEntry edge) { - assert edge.type().isEdge(); - String ownerVertex = edge.column(HugeKeys.OWNER_VERTEX); - E.checkState(ownerVertex != null, "Invalid backend entry"); - Id vertexId = IdGenerator.of(ownerVertex); - MysqlBackendEntry vertex = new MysqlBackendEntry(HugeType.VERTEX, - vertexId); - - vertex.column(HugeKeys.ID, ownerVertex); - vertex.column(HugeKeys.PROPERTIES, ""); - - vertex.subRow(edge.row()); - return vertex; + MysqlTables.Edge table = (MysqlTables.Edge) this.template; + return table.mergeEntries(e1, e2); } } - public abstract static class Index extends PostgresqlTableTemplate { - - public Index(String table) { - super(table); - } - - protected abstract String entryId(MysqlBackendEntry entry); - } - - public static class SecondaryIndex extends Index { + public static class SecondaryIndex extends PostgresqlTableTemplate { public static final String TABLE = "secondary_indexes"; public SecondaryIndex(String store) { - this(store, TABLE); + super(new MysqlTables.SecondaryIndex(store, TABLE, TYPES_MAPPING)); } - protected SecondaryIndex(String store, String table) { - super(joinTableName(store, table)); - - this.define = new TableDefine(); - this.define.column(HugeKeys.FIELD_VALUES, VARCHAR, NOT_NULL); - this.define.column(HugeKeys.INDEX_LABEL_ID, INT, NOT_NULL); - this.define.column(HugeKeys.ELEMENT_IDS, VARCHAR, NOT_NULL); - // Unique keys/hash keys - this.define.keys(HugeKeys.FIELD_VALUES, - HugeKeys.INDEX_LABEL_ID, - HugeKeys.ELEMENT_IDS); + public SecondaryIndex(String store, String table) { + super(new MysqlTables.SecondaryIndex(store, table, TYPES_MAPPING)); } - @Override protected final String entryId(MysqlBackendEntry entry) { - String fieldValues = entry.column(HugeKeys.FIELD_VALUES); - Long labelId = entry.column(HugeKeys.INDEX_LABEL_ID); - return SplicingIdGenerator.concat(fieldValues, labelId.toString()); + MysqlTables.SecondaryIndex table = + (MysqlTables.SecondaryIndex) this.template; + return table.entryId(entry); } } @@ -394,29 +191,16 @@ public SearchIndex(String store) { } } - public static class RangeIndex extends Index { - - public static final String TABLE = "range_indexes"; + public static class RangeIndex extends PostgresqlTableTemplate { public RangeIndex(String store) { - super(joinTableName(store, TABLE)); - - this.define = new TableDefine(); - this.define.column(HugeKeys.INDEX_LABEL_ID, INT, NOT_NULL); - this.define.column(HugeKeys.FIELD_VALUES, FLOAT, NOT_NULL); - this.define.column(HugeKeys.ELEMENT_IDS, VARCHAR, NOT_NULL); - // Unique keys/hash keys - this.define.keys(HugeKeys.INDEX_LABEL_ID, - HugeKeys.FIELD_VALUES, - HugeKeys.ELEMENT_IDS); + super(new MysqlTables.RangeIndex(store, TYPES_MAPPING)); } - @Override protected final String entryId(MysqlBackendEntry entry) { - Double fieldValue = entry.column(HugeKeys.FIELD_VALUES); - Long labelId = entry.column(HugeKeys.INDEX_LABEL_ID); - return SplicingIdGenerator.concat(labelId.toString(), - fieldValue.toString()); + MysqlTables.RangeIndex table = + (MysqlTables.RangeIndex) this.template; + return table.entryId(entry); } } } diff --git a/hugegraph-test/src/main/java/com/baidu/hugegraph/core/EdgeCoreTest.java b/hugegraph-test/src/main/java/com/baidu/hugegraph/core/EdgeCoreTest.java index f855ad10a8..95fbd270d2 100644 --- a/hugegraph-test/src/main/java/com/baidu/hugegraph/core/EdgeCoreTest.java +++ b/hugegraph-test/src/main/java/com/baidu/hugegraph/core/EdgeCoreTest.java @@ -2578,7 +2578,6 @@ public void testQueryEdgeByPage() { Assert.assertEquals(90, edges.size()); } - @SuppressWarnings("unchecked") @Test public void testQueryEdgeByPageResultsMatched() { Assume.assumeTrue("Not support paging", @@ -2598,6 +2597,7 @@ public void testQueryEdgeByPageResultsMatched() { for (int i = 0; i < 100 / size; i++) { iter = graph.traversal().E() .has("~page", page).limit(size); + @SuppressWarnings("unchecked") List edges = IteratorUtils.asList(iter); Assert.assertEquals(size, edges.size()); diff --git a/hugegraph-test/src/main/java/com/baidu/hugegraph/core/VertexCoreTest.java b/hugegraph-test/src/main/java/com/baidu/hugegraph/core/VertexCoreTest.java index 8dbf46d3ff..4d06ad20f3 100644 --- a/hugegraph-test/src/main/java/com/baidu/hugegraph/core/VertexCoreTest.java +++ b/hugegraph-test/src/main/java/com/baidu/hugegraph/core/VertexCoreTest.java @@ -3265,7 +3265,6 @@ public void testQueryByPage() { Assert.assertEquals(90, vertexes.size()); } - @SuppressWarnings("unchecked") @Test public void testQueryByPageResultsMatched() { Assume.assumeTrue("Not support paging", @@ -3285,6 +3284,7 @@ public void testQueryByPageResultsMatched() { for (int i = 0; i < 100 / size; i++) { iter = graph.traversal().V() .has("~page", page).limit(size); + @SuppressWarnings("unchecked") List vertexes = IteratorUtils.asList(iter); Assert.assertEquals(size, vertexes.size());