This is an automated email from the ASF dual-hosted git repository. amashenkov pushed a commit to branch ignite-13748 in repository https://gitbox.apache.org/repos/asf/ignite-3.git
commit c1ee0b3f5e7e22962bf5948de4f19140dc96f96f Author: Andrew Mashenkov <andrey.mashen...@gmail.com> AuthorDate: Thu Nov 26 21:47:31 2020 +0300 Add schema builder prototype. --- .../commons/schema/ColumnConfigurationBuilder.java | 58 ++++++++++++ .../apache/ignite/commons/schema/ColumnType.java | 100 +++++++++++++++++++++ .../schema/IndexColumnConfigurationBuilder.java | 41 +++++++++ .../commons/schema/IndexConfigurationBuilder.java | 53 +++++++++++ .../schema/KeyColumnConfigurationBuilder.java | 49 ++++++++++ .../commons/schema/SchemaConfigurationBuilder.java | 78 ++++++++++++++++ .../commons/schema/SchemaConfigurationTest.java | 30 +++++++ 7 files changed, 409 insertions(+) diff --git a/modules/commons/src/main/java/org/apache/ignite/commons/schema/ColumnConfigurationBuilder.java b/modules/commons/src/main/java/org/apache/ignite/commons/schema/ColumnConfigurationBuilder.java new file mode 100644 index 0000000..1c4350a --- /dev/null +++ b/modules/commons/src/main/java/org/apache/ignite/commons/schema/ColumnConfigurationBuilder.java @@ -0,0 +1,58 @@ +package org.apache.ignite.commons.schema; + +public class ColumnConfigurationBuilder { + private final SchemaConfigurationBuilder schemaBuilder; + + private String colName; + private ColumnType columnType; + private boolean nullable; + private Object defValue; + + public ColumnConfigurationBuilder(SchemaConfigurationBuilder schemaBuilder) { + this.schemaBuilder = schemaBuilder; + } + + public ColumnConfigurationBuilder withType(ColumnType columnType) { + this.columnType = columnType; + + return this; + } + + public ColumnConfigurationBuilder nullable() { + nullable = true; + + return this; + } + + public ColumnConfigurationBuilder notNull() { + nullable = false; + + return this; + } + + ColumnConfigurationBuilder withName(String colName) { + this.colName = colName; + + return this; + } + + public String name() { + return colName; + } + + public boolean isNullable() { + return nullable; + } + + public ColumnConfigurationBuilder defaultValue(Object defValue) { + this.defValue = defValue; + + return this; + } + + public SchemaConfigurationBuilder done() { + schemaBuilder.addColumn(this); + + return schemaBuilder; + } +} diff --git a/modules/commons/src/main/java/org/apache/ignite/commons/schema/ColumnType.java b/modules/commons/src/main/java/org/apache/ignite/commons/schema/ColumnType.java new file mode 100644 index 0000000..c25606a --- /dev/null +++ b/modules/commons/src/main/java/org/apache/ignite/commons/schema/ColumnType.java @@ -0,0 +1,100 @@ +package org.apache.ignite.commons.schema; + +public class ColumnType { + // Syntax sugar. + public static final ColumnType INT8 = new ColumnType(ColumnTypeSpec.INT8); + public static final ColumnType INT16 = new ColumnType(ColumnTypeSpec.INT16); + public static final ColumnType INT32 = new ColumnType(ColumnTypeSpec.INT32); + public static final ColumnType INT64 = new ColumnType(ColumnTypeSpec.INT64); + + public static final ColumnType UINT8 = new ColumnType(ColumnTypeSpec.UINT8); + public static final ColumnType UINT16 = new ColumnType(ColumnTypeSpec.UINT16); + public static final ColumnType UINT32 = new ColumnType(ColumnTypeSpec.UINT32); + public static final ColumnType UINT64 = new ColumnType(ColumnTypeSpec.UINT64); + + public static final ColumnType FLOAT = new ColumnType(ColumnTypeSpec.FLOAT); + public static final ColumnType DOUBLE = new ColumnType(ColumnTypeSpec.DOUBLE); + + public static final ColumnType UUID = new ColumnType(ColumnTypeSpec.UUID); + + public static VarLenType bitmaskOf(int bits) { + return new VarLenType(ColumnTypeSpec.BITMASK).lengthOf(bits); + } + + public static VarLenType string() { + return new VarLenType(ColumnTypeSpec.STRING); + } + + public static VarLenType blob() { + return new VarLenType(ColumnTypeSpec.STRING); + } + + public static NumericType number(int precision, int scale) { + return new NumericType(ColumnTypeSpec.STRING).withPrecision(precision).withScale(scale); + } + + public static class VarLenType extends ColumnType { + private int length; + + VarLenType(ColumnTypeSpec baseType) { + super(baseType); + } + + public VarLenType lengthOf(int length) { + this.length = length; + + return this; + } + } + + private final ColumnTypeSpec typeSpec; + + private ColumnType(ColumnTypeSpec typeSpec) { + this.typeSpec = typeSpec; + } + + static class NumericType extends ColumnType { + int precision; + int scale; + + public NumericType(ColumnTypeSpec typeSpec) { + super(typeSpec); + } + + public NumericType withPrecision(int precision) { + this.precision = precision; + + return this; + } + + public NumericType withScale(int scale) { + this.scale = scale; + + return this; + } + } + + enum ColumnTypeSpec { + INT8, // Convert to numeric. + INT16, + INT32, + INT64, + + UINT8, + UINT16, + UINT32, + UINT64, + + FLOAT, // Convert to decimal??? + DOUBLE, + + //NUMERIC, + //DECIMAL, + + UUID, + + BITMASK, + STRING, + BLOB, + } +} diff --git a/modules/commons/src/main/java/org/apache/ignite/commons/schema/IndexColumnConfigurationBuilder.java b/modules/commons/src/main/java/org/apache/ignite/commons/schema/IndexColumnConfigurationBuilder.java new file mode 100644 index 0000000..c97b996 --- /dev/null +++ b/modules/commons/src/main/java/org/apache/ignite/commons/schema/IndexColumnConfigurationBuilder.java @@ -0,0 +1,41 @@ +package org.apache.ignite.commons.schema; + +public class IndexColumnConfigurationBuilder { + private final IndexConfigurationBuilder indexBuilder; + + private String name; + private boolean desc; + + public IndexColumnConfigurationBuilder(IndexConfigurationBuilder indexBuilder) { + this.indexBuilder = indexBuilder; + } + + + public IndexColumnConfigurationBuilder desc() { + desc = true; + + return this; + } + + public IndexColumnConfigurationBuilder asc() { + desc = false; + + return this; + } + + IndexColumnConfigurationBuilder withName(String name) { + this.name = name; + + return this; + } + + public String name() { + return name; + } + + public IndexConfigurationBuilder done() { + indexBuilder.addIndexColumn(this); + + return indexBuilder; + } +} diff --git a/modules/commons/src/main/java/org/apache/ignite/commons/schema/IndexConfigurationBuilder.java b/modules/commons/src/main/java/org/apache/ignite/commons/schema/IndexConfigurationBuilder.java new file mode 100644 index 0000000..36f53e1 --- /dev/null +++ b/modules/commons/src/main/java/org/apache/ignite/commons/schema/IndexConfigurationBuilder.java @@ -0,0 +1,53 @@ +package org.apache.ignite.commons.schema; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +public class IndexConfigurationBuilder { + private final SchemaConfigurationBuilder schemaBuilder; + + private final Map<String, IndexColumnConfigurationBuilder> cols = new HashMap<>(); + + protected String name; + private int inlineSize; + + public IndexConfigurationBuilder(SchemaConfigurationBuilder schemaBuilder) { + this.schemaBuilder = schemaBuilder; + } + + public IndexConfigurationBuilder withName(String name) { + this.name = name; + + return this; + } + + public IndexConfigurationBuilder inlineSize(int inlineSize) { + this.inlineSize = inlineSize; + + return this; + } + + String name() { + return name; + } + + public IndexColumnConfigurationBuilder addIndexColumn(String name) { + return new IndexColumnConfigurationBuilder(this).withName(name); + } + + void addIndexColumn(IndexColumnConfigurationBuilder bld) { + if (cols.put(bld.name(), bld) != null) + throw new IllegalArgumentException("Index with same name already exists: " + bld.name()); + } + + Collection<IndexColumnConfigurationBuilder> columns() { + return cols.values(); + } + + public SchemaConfigurationBuilder done() { + schemaBuilder.addIndex(this); + + return schemaBuilder; + } +} diff --git a/modules/commons/src/main/java/org/apache/ignite/commons/schema/KeyColumnConfigurationBuilder.java b/modules/commons/src/main/java/org/apache/ignite/commons/schema/KeyColumnConfigurationBuilder.java new file mode 100644 index 0000000..011a43f --- /dev/null +++ b/modules/commons/src/main/java/org/apache/ignite/commons/schema/KeyColumnConfigurationBuilder.java @@ -0,0 +1,49 @@ +package org.apache.ignite.commons.schema; + +public class KeyColumnConfigurationBuilder extends ColumnConfigurationBuilder { + private boolean isAffinityColumn = false; + + public KeyColumnConfigurationBuilder(SchemaConfigurationBuilder schemaBuilder) { + super(schemaBuilder); + } + + public KeyColumnConfigurationBuilder affinityColumn() { + isAffinityColumn = true; + + return this; + } + + public boolean isAffinityColumn() { + return isAffinityColumn; + } + + @Override public KeyColumnConfigurationBuilder withName(String colName) { + super.withName(colName); + + return this; + } + + @Override public KeyColumnConfigurationBuilder withType(ColumnType columnType) { + super.withType(columnType); + + return this; + } + + @Override public KeyColumnConfigurationBuilder nullable() { + super.nullable(); + + return this; + } + + @Override public KeyColumnConfigurationBuilder notNull() { + super.notNull(); + + return this; + } + + @Override public KeyColumnConfigurationBuilder defaultValue(Object defValue) { + super.defaultValue(defValue); + + return this; + } +} diff --git a/modules/commons/src/main/java/org/apache/ignite/commons/schema/SchemaConfigurationBuilder.java b/modules/commons/src/main/java/org/apache/ignite/commons/schema/SchemaConfigurationBuilder.java new file mode 100644 index 0000000..1862fdf --- /dev/null +++ b/modules/commons/src/main/java/org/apache/ignite/commons/schema/SchemaConfigurationBuilder.java @@ -0,0 +1,78 @@ +package org.apache.ignite.commons.schema; + +import java.util.HashMap; +import java.util.Map; + +public class SchemaConfigurationBuilder { + public static SchemaConfigurationBuilder create() { + return new SchemaConfigurationBuilder(); + } + + public static SchemaConfigurationBuilder create(Class keyClass, Class valueClass) { + // TODO: implement. + + return new SchemaConfigurationBuilder(); + } + + private final Map<String, ColumnConfigurationBuilder> columns = new HashMap<>(); + private final Map<String, IndexConfigurationBuilder> indices = new HashMap<>(); + private final Map<String, String> aliasMap = new HashMap<>(); + + private String tableName; + + SchemaConfigurationBuilder withName(String tableName) { + this.tableName = tableName; + + return this; + } + + public String name() { + return tableName; + } + + public KeyColumnConfigurationBuilder addKeyColumn(String name) { + return new KeyColumnConfigurationBuilder(this).withName(name).notNull(); + } + + public ColumnConfigurationBuilder addValueColumn(String name) { + return new ColumnConfigurationBuilder(this).withName(name); + } + + public IndexConfigurationBuilder addIndex(String name) { + return new IndexConfigurationBuilder(this).withName(name); + } + + void addColumn(ColumnConfigurationBuilder bld) { + if (columns.put(bld.name(), bld) != null) + throw new IllegalArgumentException("Column with same name already exists: " + bld.name()); + + } + + public SchemaConfigurationBuilder addAlias(String alias, String columnName) { + if (aliasMap.put(alias, columnName) != null) + throw new IllegalArgumentException("Alias with same name already exists: " + alias); + + return this; + } + + public void build() { + assert tableName != null :"Table name was not specified."; + assert !columns.isEmpty() : "No columns was defined."; + assert columns.values().stream().anyMatch(c -> c instanceof KeyColumnConfigurationBuilder && !c.isNullable()) : "At least one non-null key column must exists."; + assert columns.values().stream().allMatch(c -> + !(c instanceof KeyColumnConfigurationBuilder) + || !((KeyColumnConfigurationBuilder)c).isAffinityColumn() + || !c.isNullable()) : "Nullable affinity column is not allowed."; + + assert indices.values().stream().flatMap(idx -> idx.columns().stream()).allMatch(idxCol -> columns.containsKey(idxCol.name())) : "Unknown index column."; + + assert aliasMap.keySet().stream().noneMatch(columns::containsKey) : "Alias hides existed column."; + assert aliasMap.values().stream().allMatch(columns::containsKey) : "Alias for unknown column."; + + } + + public void addIndex(IndexConfigurationBuilder bld) { + if (indices.put(bld.name(), bld) != null) + throw new IllegalArgumentException("Index with same name already exists: " + bld.name()); + } +} diff --git a/modules/commons/src/test/java/org/apache/ignite/commons/schema/SchemaConfigurationTest.java b/modules/commons/src/test/java/org/apache/ignite/commons/schema/SchemaConfigurationTest.java new file mode 100644 index 0000000..08f8c79 --- /dev/null +++ b/modules/commons/src/test/java/org/apache/ignite/commons/schema/SchemaConfigurationTest.java @@ -0,0 +1,30 @@ +package org.apache.ignite.commons.schema; + +import org.junit.jupiter.api.Test; + +public class SchemaConfigurationTest { + + @Test + public void testBasicSchema() { + final SchemaConfigurationBuilder builder = SchemaConfigurationBuilder.create(); + + builder.withName("TestTabke") + .addKeyColumn("id").withType(ColumnType.INT64).done() + .addKeyColumn("affId").withType(ColumnType.INT32).affinityColumn().done() + .addKeyColumn("labal").withType(ColumnType.string().lengthOf(2)).defaultValue("GG").done() + + .addValueColumn("name").withType(ColumnType.string()).notNull().done() + .addValueColumn("data").withType(ColumnType.blob().lengthOf(255)).nullable().done() + + .addIndex("idx_1") + .addIndexColumn("id").desc().done() + .addIndexColumn("name").asc().done() + .inlineSize(42) + .done() + + .addAlias("colAlias", "name") + .build(); + + } + +}