| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with this |
| * work for additional information regarding copyright ownership. The ASF |
| * licenses this file to You under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| * License for the specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| package org.apache.hugegraph.backend.store.postgresql; |
| |
| import static org.apache.hugegraph.backend.store.mysql.MysqlTables.BOOLEAN; |
| import static org.apache.hugegraph.backend.store.mysql.MysqlTables.HUGE_TEXT; |
| import static org.apache.hugegraph.backend.store.mysql.MysqlTables.INT; |
| import static org.apache.hugegraph.backend.store.mysql.MysqlTables.LARGE_TEXT; |
| import static org.apache.hugegraph.backend.store.mysql.MysqlTables.MID_TEXT; |
| import static org.apache.hugegraph.backend.store.mysql.MysqlTables.NUMERIC; |
| import static org.apache.hugegraph.backend.store.mysql.MysqlTables.SMALL_TEXT; |
| import static org.apache.hugegraph.backend.store.mysql.MysqlTables.TINYINT; |
| |
| import java.sql.SQLException; |
| import java.util.List; |
| import java.util.Map; |
| |
| import org.apache.hugegraph.backend.BackendException; |
| import org.apache.hugegraph.backend.id.Id; |
| import org.apache.hugegraph.backend.store.BackendEntry; |
| import org.apache.hugegraph.backend.store.TableDefine; |
| import org.apache.hugegraph.backend.store.mysql.MysqlBackendEntry; |
| import org.apache.hugegraph.backend.store.mysql.MysqlSessions.Session; |
| import org.apache.hugegraph.backend.store.mysql.MysqlTables; |
| import org.apache.hugegraph.backend.store.mysql.MysqlTables.MysqlTableTemplate; |
| import org.apache.hugegraph.type.HugeType; |
| import org.apache.hugegraph.type.define.Directions; |
| import org.apache.hugegraph.type.define.HugeKeys; |
| |
| import com.google.common.collect.ImmutableMap; |
| |
| public class PostgresqlTables { |
| |
| private static final Map<String, String> TYPES_MAPPING = |
| ImmutableMap.<String, String>builder() |
| .put(BOOLEAN, "BOOL") |
| .put(TINYINT, "INT") |
| .put(INT, "INT") |
| .put(NUMERIC, "DECIMAL") |
| .put(SMALL_TEXT, "VARCHAR(255)") |
| .put(MID_TEXT, "VARCHAR(1024)") |
| .put(LARGE_TEXT, "VARCHAR(65533)") |
| .put(HUGE_TEXT, "TEXT") |
| .build(); |
| |
| public static class PostgresqlTableTemplate extends PostgresqlTable { |
| |
| protected MysqlTableTemplate template; |
| |
| public PostgresqlTableTemplate(MysqlTableTemplate template) { |
| super(template.table()); |
| this.template = template; |
| } |
| |
| @Override |
| public TableDefine tableDefine() { |
| return this.template.tableDefine(); |
| } |
| } |
| |
| public static class Meta extends PostgresqlTableTemplate { |
| |
| public Meta() { |
| super(new MysqlTables.Meta(TYPES_MAPPING)); |
| } |
| |
| public void writeVersion(Session session, String version) { |
| String versionColumn = formatKey(HugeKeys.VERSION); |
| String insert = String.format("INSERT INTO %s VALUES ('%s', '%s') " + |
| "ON CONFLICT(name) DO NOTHING;", |
| this.table(), versionColumn, version); |
| try { |
| session.execute(insert); |
| } catch (SQLException e) { |
| throw new BackendException("Failed to insert driver version " + |
| "with '%s'", e, insert); |
| } |
| } |
| |
| public String readVersion(Session session) { |
| MysqlTables.Meta table = (MysqlTables.Meta) this.template; |
| return table.readVersion(session); |
| } |
| } |
| |
| public static class Counters extends PostgresqlTableTemplate { |
| |
| public Counters() { |
| super(new MysqlTables.Counters(TYPES_MAPPING)); |
| } |
| |
| public long getCounter(Session session, HugeType 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;", |
| 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) { |
| throw new BackendException( |
| "Failed to update counters with type '%s'", e, type); |
| } |
| } |
| } |
| |
| public static class VertexLabel extends PostgresqlTableTemplate { |
| |
| public VertexLabel() { |
| super(new MysqlTables.VertexLabel(TYPES_MAPPING)); |
| } |
| } |
| |
| public static class EdgeLabel extends PostgresqlTableTemplate { |
| |
| public EdgeLabel() { |
| super(new MysqlTables.EdgeLabel(TYPES_MAPPING)); |
| } |
| } |
| |
| public static class PropertyKey extends PostgresqlTableTemplate { |
| |
| public PropertyKey() { |
| super(new MysqlTables.PropertyKey(TYPES_MAPPING)); |
| } |
| } |
| |
| public static class IndexLabel extends PostgresqlTableTemplate { |
| |
| public IndexLabel() { |
| super(new MysqlTables.IndexLabel(TYPES_MAPPING)); |
| } |
| } |
| |
| public static class Vertex extends PostgresqlTableTemplate { |
| |
| public static final String TABLE = HugeType.VERTEX.string(); |
| |
| public Vertex(String store) { |
| super(new MysqlTables.Vertex(store, TYPES_MAPPING)); |
| } |
| } |
| |
| public static class Edge extends PostgresqlTableTemplate { |
| |
| public Edge(String store, Directions direction) { |
| super(new MysqlTables.Edge(store, direction, TYPES_MAPPING)); |
| } |
| |
| @Override |
| protected List<Object> idColumnValue(Id id) { |
| MysqlTables.Edge table = (MysqlTables.Edge) this.template; |
| return table.idColumnValue(id); |
| } |
| |
| @Override |
| public void delete(Session session, MysqlBackendEntry.Row entry) { |
| MysqlTables.Edge table = (MysqlTables.Edge) this.template; |
| table.delete(session, entry); |
| } |
| |
| @Override |
| protected BackendEntry mergeEntries(BackendEntry e1, BackendEntry e2) { |
| MysqlTables.Edge table = (MysqlTables.Edge) this.template; |
| return table.mergeEntries(e1, e2); |
| } |
| } |
| |
| public static class SecondaryIndex extends PostgresqlTableTemplate { |
| |
| public static final String TABLE = MysqlTables.SecondaryIndex.TABLE; |
| |
| public SecondaryIndex(String store) { |
| super(new MysqlTables.SecondaryIndex(store, TABLE, TYPES_MAPPING)); |
| } |
| |
| public SecondaryIndex(String store, String table) { |
| super(new MysqlTables.SecondaryIndex(store, table, TYPES_MAPPING)); |
| } |
| |
| protected final String entryId(MysqlBackendEntry entry) { |
| return ((MysqlTables.SecondaryIndex) this.template).entryId(entry); |
| } |
| } |
| |
| public static class SearchIndex extends SecondaryIndex { |
| |
| public static final String TABLE = MysqlTables.SearchIndex.TABLE; |
| |
| public SearchIndex(String store) { |
| super(store, TABLE); |
| } |
| } |
| |
| public static class UniqueIndex extends SecondaryIndex { |
| |
| public static final String TABLE = MysqlTables.UniqueIndex.TABLE; |
| |
| public UniqueIndex(String store) { |
| super(store, TABLE); |
| } |
| } |
| |
| public static class RangeIntIndex extends PostgresqlTableTemplate { |
| |
| public static final String TABLE = HugeType.RANGE_INT_INDEX.string(); |
| |
| public RangeIntIndex(String store) { |
| super(new MysqlTables.RangeIntIndex(store, TABLE, TYPES_MAPPING)); |
| } |
| |
| protected final String entryId(MysqlBackendEntry entry) { |
| return ((MysqlTables.RangeIntIndex) this.template).entryId(entry); |
| } |
| } |
| |
| public static class RangeFloatIndex extends PostgresqlTableTemplate { |
| |
| public static final String TABLE = HugeType.RANGE_FLOAT_INDEX.string(); |
| |
| public RangeFloatIndex(String store) { |
| super(new MysqlTables.RangeFloatIndex(store, TABLE, TYPES_MAPPING)); |
| } |
| |
| protected final String entryId(MysqlBackendEntry entry) { |
| return ((MysqlTables.RangeFloatIndex) this.template).entryId(entry); |
| } |
| } |
| |
| public static class RangeLongIndex extends PostgresqlTableTemplate { |
| |
| public static final String TABLE = HugeType.RANGE_LONG_INDEX.string(); |
| |
| public RangeLongIndex(String store) { |
| super(new MysqlTables.RangeLongIndex(store, TABLE, TYPES_MAPPING)); |
| } |
| |
| protected final String entryId(MysqlBackendEntry entry) { |
| return ((MysqlTables.RangeLongIndex) this.template).entryId(entry); |
| } |
| } |
| |
| public static class RangeDoubleIndex extends PostgresqlTableTemplate { |
| |
| public static final String TABLE = HugeType.RANGE_DOUBLE_INDEX.string(); |
| |
| public RangeDoubleIndex(String store) { |
| super(new MysqlTables.RangeDoubleIndex(store, TABLE, |
| TYPES_MAPPING)); |
| } |
| |
| protected final String entryId(MysqlBackendEntry entry) { |
| return ((MysqlTables.RangeDoubleIndex) this.template) |
| .entryId(entry); |
| } |
| } |
| |
| public static class ShardIndex extends PostgresqlTableTemplate { |
| |
| public ShardIndex(String store) { |
| super(new MysqlTables.ShardIndex(store, TYPES_MAPPING)); |
| } |
| |
| protected final String entryId(MysqlBackendEntry entry) { |
| return ((MysqlTables.ShardIndex) this.template).entryId(entry); |
| } |
| } |
| } |