| /* |
| * 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.phoenix.query; |
| |
| import com.google.common.base.Joiner; |
| import com.google.common.collect.Lists; |
| import org.apache.phoenix.jdbc.PhoenixConnection; |
| import org.apache.phoenix.schema.PTable; |
| import org.apache.phoenix.schema.PTableKey; |
| import org.apache.phoenix.util.PropertiesUtil; |
| import org.apache.phoenix.util.SchemaUtil; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| import java.sql.Connection; |
| import java.sql.DriverManager; |
| import java.sql.PreparedStatement; |
| import java.sql.SQLException; |
| import java.util.List; |
| import java.util.Properties; |
| import java.util.concurrent.atomic.AtomicInteger; |
| |
| import static java.util.Arrays.asList; |
| import static org.apache.phoenix.util.PhoenixRuntime.TENANT_ID_ATTRIB; |
| |
| /** |
| * PhoenixTestBuilder is a utility class using a Builder pattern. |
| * Facilitates the following creation patterns |
| * 1. Simple tables. |
| * 2. Global Views on tables. |
| * 3. Tenant Views on tables or global views. |
| * 4. Indexes global or local on all of the above. |
| * 5. Create multiple tenants |
| * 6. Multiple views for a tenant. |
| * Typical usage pattern when using this class is - |
| * 1. Create schema for the test. |
| * 2. Provide a DataSupplier for the above schema. |
| * 3. Write validations for your tests. |
| * PhoenixTestBuilder facilitates steps 1 and 2. |
| */ |
| public class PhoenixTestBuilder { |
| |
| private static final Logger LOGGER = LoggerFactory.getLogger(PhoenixTestBuilder.class); |
| private static final int MAX_SUFFIX_VALUE = 1000000; |
| private static AtomicInteger NAME_SUFFIX = new AtomicInteger(0); |
| |
| private static String generateUniqueName() { |
| int nextName = NAME_SUFFIX.incrementAndGet(); |
| if (nextName >= MAX_SUFFIX_VALUE) { |
| throw new IllegalStateException("Used up all unique names"); |
| } |
| return "T" + Integer.toString(MAX_SUFFIX_VALUE + nextName).substring(1); |
| } |
| |
| /** |
| * @return a formatted string with nullable info |
| * for e.g "COL1 VARCHAR (NOT NULL), COL2 VARCHAR (NOT NULL), COL3 VARCHAR (NOT NULL)" |
| */ |
| private static String getColumnsAsString(List<String> columns, List<String> types, |
| boolean isPK) { |
| assert (columns.size() == types.size()); |
| |
| Joiner columnJoiner = Joiner.on(","); |
| Joiner typeJoiner = Joiner.on(" "); |
| List<String> columnDefinitions = Lists.newArrayList(); |
| for (int colIndex = 0; colIndex < columns.size(); colIndex++) { |
| String column = columns.get(colIndex); |
| String datatype = types.get(colIndex); |
| if ((column != null) && (!column.isEmpty())) { |
| String |
| columnWithType = |
| isPK ? |
| typeJoiner.join(column, datatype, "NOT NULL") : |
| typeJoiner.join(column, datatype); |
| columnDefinitions.add(columnWithType); |
| } |
| } |
| return columnJoiner.join(columnDefinitions); |
| } |
| |
| /** |
| * @return a formatted string with sort info |
| * for e.g "PK_COL1, PK_COL2 , PK_COL3 DESC" |
| */ |
| private static String getPKColumnsWithSort(List<String> pkColumns, List<String> sortTypes) { |
| assert (sortTypes == null || sortTypes.size() == pkColumns.size()); |
| |
| Joiner pkColumnJoiner = Joiner.on(","); |
| Joiner sortTypeJoiner = Joiner.on(" "); |
| List<String> pkColumnDefinitions = Lists.newArrayList(); |
| for (int colIndex = 0; colIndex < pkColumns.size(); colIndex++) { |
| String column = pkColumns.get(colIndex); |
| String sorttype = sortTypes == null ? null : sortTypes.get(colIndex); |
| if ((column != null) && (!column.isEmpty())) { |
| String |
| columnWithSortType = |
| sorttype == null || sorttype.isEmpty() ? |
| column : |
| sortTypeJoiner.join(column, sorttype); |
| pkColumnDefinitions.add(columnWithSortType); |
| } |
| } |
| return pkColumnJoiner.join(pkColumnDefinitions); |
| } |
| |
| /** |
| * @return a formatted string with CFs |
| * for e.g "A.COL1, B.COL2, C.COl3" |
| */ |
| private static String getFQColumnsAsString(List<String> columns, List<String> families) { |
| Joiner columnJoiner = Joiner.on(","); |
| return columnJoiner.join(getFQColumnsAsList(columns, families)); |
| } |
| |
| private static List<String> getFQColumnsAsList(List<String> columns, List<String> families) { |
| assert (columns.size() == families.size()); |
| |
| Joiner familyJoiner = Joiner.on("."); |
| List<String> columnDefinitions = Lists.newArrayList(); |
| int colIndex = 0; |
| for (String family : families) { |
| String column = columns.get(colIndex++); |
| if ((column != null) && (!column.isEmpty())) { |
| columnDefinitions.add(((family != null) && (!family.isEmpty())) ? |
| familyJoiner.join(family, column) : |
| column); |
| } |
| } |
| return columnDefinitions; |
| } |
| |
| /** |
| * @return a formatted string with data types |
| * for e.g => A.COL1 VARCHAR, A.COL2 VARCHAR, B.COL3 VARCHAR |
| */ |
| private static String getFQColumnsAsString(List<String> columns, List<String> families, |
| List<String> types) { |
| Joiner columnJoiner = Joiner.on(","); |
| return columnJoiner.join(getFQColumnsAsList(columns, families, types)); |
| } |
| |
| /* |
| * ----------------- |
| * Helper methods |
| * ----------------- |
| */ |
| |
| private static List<String> getFQColumnsAsList(List<String> columns, List<String> families, |
| List<String> types) { |
| assert (columns.size() == families.size()); |
| |
| Joiner familyJoiner = Joiner.on("."); |
| Joiner typeJoiner = Joiner.on(" "); |
| List<String> columnDefinitions = Lists.newArrayList(); |
| int colIndex = 0; |
| for (String family : families) { |
| String column = columns.get(colIndex); |
| String datatype = types.get(colIndex); |
| colIndex++; |
| if ((column != null) && (!column.isEmpty())) { |
| String columnWithType = typeJoiner.join(column, datatype); |
| columnDefinitions.add(((family != null) && (!family.isEmpty())) ? |
| familyJoiner.join(family, columnWithType) : |
| columnWithType); |
| } |
| } |
| return columnDefinitions; |
| } |
| |
| // Test Data supplier interface for test writers to provide custom data. |
| public interface DataSupplier { |
| // return the values to be used for upserting data into the underlying entity. |
| List<Object> getValues(int rowIndex); |
| } |
| |
| // A Data Writer to be used in tests to upsert sample data (@see TestDataSupplier) into the sample schema. |
| public interface DataWriter { |
| // returns the columns that need to be upserted, |
| // should match the #columns in TestDataSupplier::getValues(). |
| List<String> getUpsertColumns(); |
| |
| void setUpsertColumns(List<String> upsertColumns); |
| |
| // returns the partial/overridden set of columns to be used for upserts. |
| List<Integer> getColumnPositionsToUpdate(); |
| |
| void setColumnPositionsToUpdate(List<Integer> columnPositionsToUpdate); |
| |
| // returns the connection to be used for upserting rows. |
| Connection getConnection(); |
| |
| void setConnection(Connection connection); |
| |
| // returns the target entity - whether to use the table, global-view or the tenant-view. |
| String getTargetEntity(); |
| |
| void setTargetEntity(String targetEntity); |
| |
| // return the data provider for this writer |
| DataSupplier getTestDataSupplier(); |
| |
| // template method to upsert rows using the above info. |
| void upsertRow(int rowIndex) throws SQLException; |
| |
| void setDataSupplier(DataSupplier dataSupplier); |
| } |
| |
| /** |
| * Test SchemaBuilder defaults. |
| */ |
| public static class DDLDefaults { |
| public static final int MAX_ROWS = 10000; |
| public static List<String> TABLE_PK_TYPES = asList("CHAR(15)", "CHAR(3)"); |
| public static List<String> GLOBAL_VIEW_PK_TYPES = asList("CHAR(15)"); |
| public static List<String> TENANT_VIEW_PK_TYPES = asList("CHAR(15)"); |
| |
| public static List<String> COLUMN_TYPES = asList("VARCHAR", "VARCHAR", "VARCHAR"); |
| public static List<String> TABLE_COLUMNS = asList("COL1", "COL2", "COL3"); |
| public static List<String> GLOBAL_VIEW_COLUMNS = asList("COL4", "COL5", "COL6"); |
| public static List<String> TENANT_VIEW_COLUMNS = asList("COL7", "COL8", "COL9"); |
| |
| public static List<String> TABLE_COLUMN_FAMILIES = asList(null, null, null); |
| public static List<String> GLOBAL_VIEW_COLUMN_FAMILIES = asList(null, null, null); |
| public static List<String> TENANT_VIEW_COLUMN_FAMILIES = asList(null, null, null); |
| |
| public static List<String> TABLE_PK_COLUMNS = asList("OID", "KP"); |
| public static List<String> GLOBAL_VIEW_PK_COLUMNS = asList("ID"); |
| public static List<String> TENANT_VIEW_PK_COLUMNS = asList("ZID"); |
| |
| public static List<String> TABLE_INDEX_COLUMNS = asList("COL1"); |
| public static List<String> TABLE_INCLUDE_COLUMNS = asList("COL3"); |
| |
| public static List<String> GLOBAL_VIEW_INDEX_COLUMNS = asList("COL4"); |
| public static List<String> GLOBAL_VIEW_INCLUDE_COLUMNS = asList("COL6"); |
| |
| public static List<String> TENANT_VIEW_INDEX_COLUMNS = asList("COL9"); |
| public static List<String> TENANT_VIEW_INCLUDE_COLUMNS = asList("COL7"); |
| |
| public static String |
| DEFAULT_TABLE_PROPS = |
| "COLUMN_ENCODED_BYTES=0, MULTI_TENANT=true,DEFAULT_COLUMN_FAMILY='Z'"; |
| public static String DEFAULT_TABLE_INDEX_PROPS = ""; |
| public static String DEFAULT_GLOBAL_VIEW_PROPS = ""; |
| public static String DEFAULT_GLOBAL_VIEW_INDEX_PROPS = ""; |
| public static String DEFAULT_TENANT_VIEW_PROPS = ""; |
| public static String DEFAULT_TENANT_VIEW_INDEX_PROPS = ""; |
| public static String DEFAULT_KP = "0EC"; |
| public static String DEFAULT_SCHEMA_NAME = "TEST_ENTITY"; |
| public static String DEFAULT_TENANT_ID_FMT = "00D0t%03d%s"; |
| |
| public static String DEFAULT_CONNECT_URL = "jdbc:phoenix:localhost"; |
| |
| } |
| |
| // Provides template method for upserting rows |
| public static abstract class AbstractDataWriter implements DataWriter { |
| |
| public void upsertRow(int rowIndex) throws SQLException { |
| List<String> upsertColumns = Lists.newArrayList(); |
| List<Object> upsertValues = Lists.newArrayList(); |
| |
| if (getColumnPositionsToUpdate().isEmpty()) { |
| upsertColumns.addAll(getUpsertColumns()); |
| upsertValues.addAll(getTestDataSupplier().getValues(rowIndex)); |
| } else { |
| List<String> tmpColumns = getUpsertColumns(); |
| List<Object> tmpValues = getTestDataSupplier().getValues(rowIndex); |
| for (int i : getColumnPositionsToUpdate()) { |
| upsertColumns.add(tmpColumns.get(i)); |
| upsertValues.add(tmpValues.get(i)); |
| } |
| } |
| StringBuilder buf = new StringBuilder("UPSERT INTO "); |
| buf.append(getTargetEntity()); |
| buf.append(" (").append(Joiner.on(",").join(upsertColumns)).append(") VALUES("); |
| |
| for (int i = 0; i < upsertValues.size(); i++) { |
| buf.append("?,"); |
| } |
| buf.setCharAt(buf.length() - 1, ')'); |
| |
| LOGGER.info(buf.toString()); |
| |
| Connection connection = getConnection(); |
| try (PreparedStatement stmt = connection.prepareStatement(buf.toString())) { |
| for (int i = 0; i < upsertValues.size(); i++) { |
| stmt.setObject(i + 1, upsertValues.get(i)); |
| } |
| stmt.execute(); |
| connection.commit(); |
| } |
| } |
| } |
| |
| // An implementation of the TestDataWriter. |
| public static class BasicDataWriter extends AbstractDataWriter { |
| List<String> upsertColumns = Lists.newArrayList(); |
| List<Integer> columnPositionsToUpdate = Lists.newArrayList(); |
| DataSupplier dataSupplier; |
| Connection connection; |
| String targetEntity; |
| |
| @Override public List<String> getUpsertColumns() { |
| return upsertColumns; |
| } |
| |
| @Override public void setUpsertColumns(List<String> upsertColumns) { |
| this.upsertColumns = upsertColumns; |
| } |
| |
| @Override public List<Integer> getColumnPositionsToUpdate() { |
| return columnPositionsToUpdate; |
| } |
| |
| @Override public void setColumnPositionsToUpdate(List<Integer> columnPositionsToUpdate) { |
| this.columnPositionsToUpdate = columnPositionsToUpdate; |
| } |
| |
| @Override public Connection getConnection() { |
| return connection; |
| } |
| |
| @Override public void setConnection(Connection connection) { |
| this.connection = connection; |
| } |
| |
| @Override public String getTargetEntity() { |
| return targetEntity; |
| } |
| |
| @Override public void setTargetEntity(String targetEntity) { |
| this.targetEntity = targetEntity; |
| } |
| |
| @Override public DataSupplier getTestDataSupplier() { |
| return dataSupplier; |
| } |
| |
| @Override public void setDataSupplier(DataSupplier dataSupplier) { |
| this.dataSupplier = dataSupplier; |
| } |
| } |
| |
| /** |
| * Schema builder for test writers to prepare various test scenarios. |
| * It can be used to define the following type of schemas - |
| * 1. Simple Table. |
| * 2. Table with Global and Tenant Views. |
| * 3. Table with Tenant Views |
| * The above entities can be supplemented with indexes (global or local) |
| * The builder also provides some reasonable defaults, but can be customized/overridden |
| * for specific test requirements. |
| */ |
| public static class SchemaBuilder { |
| private static final AtomicInteger TENANT_COUNTER = new AtomicInteger(0); |
| // variables holding the various options. |
| boolean tableEnabled = false; |
| boolean globalViewEnabled = false; |
| boolean tenantViewEnabled = false; |
| boolean tableIndexEnabled = false; |
| boolean globalViewIndexEnabled = false; |
| boolean tenantViewIndexEnabled = false; |
| boolean tableCreated = false; |
| boolean globalViewCreated = false; |
| boolean tenantViewCreated = false; |
| boolean tableIndexCreated = false; |
| boolean globalViewIndexCreated = false; |
| boolean tenantViewIndexCreated = false; |
| String url; |
| String entityKeyPrefix; |
| String entityTableName; |
| String entityGlobalViewName; |
| String entityTenantViewName; |
| PTable baseTable; |
| ConnectOptions connectOptions; |
| TableOptions tableOptions; |
| GlobalViewOptions globalViewOptions; |
| TenantViewOptions tenantViewOptions; |
| TableIndexOptions tableIndexOptions; |
| GlobalViewIndexOptions globalViewIndexOptions; |
| TenantViewIndexOptions tenantViewIndexOptions; |
| OtherOptions otherOptions; |
| DataOptions dataOptions; |
| |
| public SchemaBuilder(String url) { |
| this.url = url; |
| } |
| |
| public PTable getBaseTable() { |
| return baseTable; |
| } |
| |
| void setBaseTable(PTable baseTable) { |
| this.baseTable = baseTable; |
| } |
| |
| public String getUrl() { |
| return this.url; |
| } |
| |
| public boolean isTableEnabled() { |
| return tableEnabled; |
| } |
| |
| public boolean isGlobalViewEnabled() { |
| return globalViewEnabled; |
| } |
| |
| public boolean isTenantViewEnabled() { |
| return tenantViewEnabled; |
| } |
| |
| public boolean isTableIndexEnabled() { |
| return tableIndexEnabled; |
| } |
| |
| public boolean isGlobalViewIndexEnabled() { |
| return globalViewIndexEnabled; |
| } |
| |
| public boolean isTenantViewIndexEnabled() { |
| return tenantViewIndexEnabled; |
| } |
| |
| /* |
| ***************************** |
| * Setters and Getters |
| ***************************** |
| */ |
| |
| public boolean isTableCreated() { |
| return tableCreated; |
| } |
| |
| public boolean isGlobalViewCreated() { |
| return globalViewCreated; |
| } |
| |
| public boolean isTenantViewCreated() { |
| return tenantViewCreated; |
| } |
| |
| public boolean isTableIndexCreated() { |
| return tableIndexCreated; |
| } |
| |
| public boolean isGlobalViewIndexCreated() { |
| return globalViewIndexCreated; |
| } |
| |
| public boolean isTenantViewIndexCreated() { |
| return tenantViewIndexCreated; |
| } |
| |
| public String getEntityKeyPrefix() { |
| return entityKeyPrefix; |
| } |
| |
| public String getEntityTableName() { |
| return entityTableName; |
| } |
| |
| public String getEntityGlobalViewName() { |
| return entityGlobalViewName; |
| } |
| |
| public String getEntityTenantViewName() { |
| return entityTenantViewName; |
| } |
| |
| public ConnectOptions getConnectOptions() { |
| return connectOptions; |
| } |
| |
| public TableOptions getTableOptions() { |
| return tableOptions; |
| } |
| |
| public GlobalViewOptions getGlobalViewOptions() { |
| return globalViewOptions; |
| } |
| |
| public TenantViewOptions getTenantViewOptions() { |
| return tenantViewOptions; |
| } |
| |
| public TableIndexOptions getTableIndexOptions() { |
| return tableIndexOptions; |
| } |
| |
| public GlobalViewIndexOptions getGlobalViewIndexOptions() { |
| return globalViewIndexOptions; |
| } |
| |
| public TenantViewIndexOptions getTenantViewIndexOptions() { |
| return tenantViewIndexOptions; |
| } |
| |
| public OtherOptions getOtherOptions() { |
| return otherOptions; |
| } |
| |
| public DataOptions getDataOptions() { |
| return dataOptions; |
| } |
| |
| // "CREATE TABLE IF NOT EXISTS " + |
| // tableName + |
| // "(" + |
| // dataColumns + |
| // " CONSTRAINT pk PRIMARY KEY (" + pk + ") |
| // ) " + |
| // (dataProps.isEmpty() ? "" : dataProps; |
| public SchemaBuilder withTableDefaults() { |
| tableEnabled = true; |
| tableCreated = false; |
| tableOptions = TableOptions.withDefaults(); |
| return this; |
| } |
| |
| // "CREATE TABLE IF NOT EXISTS " + |
| // tableName + |
| // "(" + |
| // dataColumns + " CONSTRAINT pk PRIMARY KEY (" + pk + ") |
| // ) " + |
| // (dataProps.isEmpty() ? "" : dataProps; |
| public SchemaBuilder withTableOptions(TableOptions options) { |
| tableEnabled = true; |
| tableCreated = false; |
| tableOptions = options; |
| return this; |
| } |
| |
| // "CREATE VIEW IF NOT EXISTS " + |
| // globalViewName + |
| // AS SELECT * FROM " + tableName + " WHERE " + globalViewCondition; |
| public SchemaBuilder withSimpleGlobalView() { |
| globalViewEnabled = true; |
| globalViewCreated = false; |
| globalViewOptions = new GlobalViewOptions(); |
| return this; |
| } |
| |
| // "CREATE VIEW IF NOT EXISTS " + |
| // globalViewName + |
| // "(" + |
| // globalViewColumns + " CONSTRAINT pk PRIMARY KEY (" + globalViewPK + ") |
| // ) AS SELECT * FROM " + tableName + " WHERE " + globalViewCondition; |
| public SchemaBuilder withGlobalViewDefaults() { |
| globalViewEnabled = true; |
| globalViewCreated = false; |
| globalViewOptions = GlobalViewOptions.withDefaults(); |
| return this; |
| } |
| |
| // "CREATE VIEW IF NOT EXISTS " + |
| // globalViewName + |
| // "(" + |
| // globalViewColumns + " CONSTRAINT pk PRIMARY KEY (" + globalViewPK + ") |
| // ) AS SELECT * FROM " + tableName + " WHERE " + globalViewCondition; |
| public SchemaBuilder withGlobalViewOptions(GlobalViewOptions options) { |
| globalViewEnabled = true; |
| globalViewCreated = false; |
| globalViewOptions = options; |
| return this; |
| } |
| |
| // "CREATE VIEW IF NOT EXISTS " + tenantViewName + AS SELECT * FROM " + globalViewName; |
| public SchemaBuilder withSimpleTenantView() { |
| tenantViewEnabled = true; |
| tenantViewCreated = false; |
| tenantViewOptions = new TenantViewOptions(); |
| return this; |
| } |
| |
| // "CREATE VIEW IF NOT EXISTS " + |
| // tenantViewName + |
| // "(" + |
| // tenantViewColumns + " CONSTRAINT pk PRIMARY KEY (" + tenantViewPK + ") |
| // ) AS SELECT * FROM " + globalViewName; |
| public SchemaBuilder withTenantViewDefaults() { |
| tenantViewEnabled = true; |
| tenantViewCreated = false; |
| tenantViewOptions = TenantViewOptions.withDefaults(); |
| return this; |
| } |
| |
| // "CREATE VIEW IF NOT EXISTS " + |
| // tenantViewName + |
| // "(" + |
| // tenantViewColumns + " CONSTRAINT pk PRIMARY KEY (" + tenantViewPK + ") |
| // ) AS SELECT * FROM " + globalViewName; |
| public SchemaBuilder withTenantViewOptions(TenantViewOptions options) { |
| tenantViewEnabled = true; |
| tenantViewCreated = false; |
| tenantViewOptions = options; |
| return this; |
| } |
| |
| // "CREATE INDEX IF NOT EXISTS |
| // "IDX_T_T000001" |
| // ON "TEST_ENTITY"."T_T000001"(COL1) INCLUDE (COL3)" |
| public SchemaBuilder withTableIndexDefaults() { |
| tableIndexEnabled = true; |
| tableIndexCreated = false; |
| tableIndexOptions = TableIndexOptions.withDefaults(); |
| return this; |
| } |
| |
| public SchemaBuilder withTableIndexOptions(TableIndexOptions options) { |
| tableIndexEnabled = true; |
| tableIndexCreated = false; |
| tableIndexOptions = options; |
| return this; |
| } |
| |
| public SchemaBuilder withGlobalViewIndexDefaults() { |
| globalViewIndexEnabled = true; |
| globalViewIndexCreated = false; |
| globalViewIndexOptions = GlobalViewIndexOptions.withDefaults(); |
| return this; |
| } |
| |
| public SchemaBuilder withGlobalViewIndexOptions(GlobalViewIndexOptions options) { |
| globalViewIndexEnabled = true; |
| globalViewIndexCreated = false; |
| globalViewIndexOptions = options; |
| return this; |
| } |
| |
| public SchemaBuilder withTenantViewIndexDefaults() { |
| tenantViewIndexEnabled = true; |
| tenantViewIndexCreated = false; |
| tenantViewIndexOptions = TenantViewIndexOptions.withDefaults(); |
| return this; |
| } |
| |
| public SchemaBuilder withTenantViewIndexOptions(TenantViewIndexOptions options) { |
| tenantViewIndexEnabled = true; |
| tenantViewIndexCreated = false; |
| tenantViewIndexOptions = options; |
| return this; |
| } |
| |
| public SchemaBuilder withOtherDefaults() { |
| this.otherOptions = OtherOptions.withDefaults(); |
| return this; |
| } |
| |
| public SchemaBuilder withOtherOptions(OtherOptions otherOptions) { |
| this.otherOptions = otherOptions; |
| return this; |
| } |
| |
| public SchemaBuilder withDataOptionsDefaults() { |
| this.dataOptions = DataOptions.withDefaults(); |
| return this; |
| } |
| |
| public SchemaBuilder withDataOptions(DataOptions dataOptions) { |
| this.dataOptions = dataOptions; |
| return this; |
| } |
| |
| public SchemaBuilder withConnectOptions(ConnectOptions connectOptions) { |
| this.connectOptions = connectOptions; |
| return this; |
| } |
| |
| public SchemaBuilder withConnectDefaults() { |
| this.connectOptions = new ConnectOptions(); |
| return this; |
| } |
| |
| // Build method for creating new tenants with existing table, |
| // global and tenant view definitions. |
| // If the tenant view definition is not changed then |
| // the same view is created with different names for different tenants. |
| public void buildWithNewTenant() throws Exception { |
| tenantViewCreated = false; |
| tenantViewIndexCreated = false; |
| if (this.dataOptions == null) { |
| this.dataOptions = DataOptions.withDefaults(); |
| } |
| this.dataOptions.tenantId = |
| String.format(dataOptions.tenantIdFormat, TENANT_COUNTER.incrementAndGet(), |
| dataOptions.uniqueName); |
| |
| build(); |
| } |
| |
| // Build method for creating new tenant views with existing table, |
| // global and tenant view definitions. |
| // If the tenant view definition is not changed then |
| // the same view is created with different names. |
| public void buildNewView() throws Exception { |
| tenantViewCreated = false; |
| tenantViewIndexCreated = false; |
| if (this.dataOptions == null) { |
| this.dataOptions = DataOptions.withDefaults(); |
| } |
| dataOptions.viewNumber = this.getDataOptions().getNextViewNumber(); |
| build(); |
| } |
| |
| // The main build method for the builder. |
| public void build() throws Exception { |
| |
| // Set defaults if not specified |
| if (this.otherOptions == null) { |
| this.otherOptions = OtherOptions.withDefaults(); |
| } |
| |
| if (this.dataOptions == null) { |
| this.dataOptions = DataOptions.withDefaults(); |
| } |
| |
| if (this.connectOptions == null) { |
| this.connectOptions = new ConnectOptions(); |
| } |
| |
| if (connectOptions.useGlobalConnectionOnly |
| && connectOptions.useTenantConnectionForGlobalView) { |
| throw new IllegalArgumentException( |
| "useTenantConnectionForGlobalView and useGlobalConnectionOnly both cannot be true"); |
| } |
| |
| String tableName = SchemaUtil.getEscapedArgument("T_" + dataOptions.uniqueName); |
| String globalViewName = SchemaUtil.getEscapedArgument("V_" + dataOptions.uniqueName); |
| String |
| tableSchemaName = |
| tableEnabled ? SchemaUtil.getEscapedArgument(tableOptions.schemaName) : ""; |
| String |
| globalViewSchemaName = |
| globalViewEnabled ? |
| SchemaUtil.getEscapedArgument(globalViewOptions.schemaName) : |
| ""; |
| String |
| tenantViewSchemaName = |
| tenantViewEnabled ? |
| SchemaUtil.getEscapedArgument(tenantViewOptions.schemaName) : |
| ""; |
| entityTableName = SchemaUtil.getTableName(tableSchemaName, tableName); |
| entityGlobalViewName = SchemaUtil.getTableName(globalViewSchemaName, globalViewName); |
| |
| // Derive the keyPrefix to use. |
| entityKeyPrefix = |
| connectOptions.useGlobalConnectionOnly ? |
| (String.format("Z%02d", dataOptions.getViewNumber())) : |
| (tenantViewEnabled && !globalViewEnabled ? |
| (String.format("Z%02d", dataOptions.getViewNumber())) : |
| DDLDefaults.DEFAULT_KP); |
| |
| String tenantViewName = SchemaUtil.getEscapedArgument(entityKeyPrefix); |
| entityTenantViewName = SchemaUtil.getTableName(tenantViewSchemaName, tenantViewName); |
| String globalViewCondition = String.format("KP = '%s'", entityKeyPrefix); |
| |
| // Table and Table Index creation. |
| try (Connection globalConnection = getGlobalConnection()) { |
| if (tableEnabled && !tableCreated) { |
| globalConnection.createStatement() |
| .execute(buildCreateTableStmt(entityTableName)); |
| tableCreated = true; |
| PTableKey |
| tableKey = |
| new PTableKey(null, SchemaUtil.normalizeFullTableName(entityTableName)); |
| setBaseTable( |
| globalConnection.unwrap(PhoenixConnection.class).getTable(tableKey)); |
| } |
| // Index on Table |
| if (tableIndexEnabled && !tableIndexCreated) { |
| String |
| indexOnTableName = |
| SchemaUtil.getEscapedArgument(String.format("IDX_%s", |
| SchemaUtil.normalizeIdentifier(tableName))); |
| globalConnection.createStatement().execute( |
| buildCreateIndexStmt(indexOnTableName, entityTableName, |
| tableIndexOptions.isLocal, tableIndexOptions.tableIndexColumns, |
| tableIndexOptions.tableIncludeColumns, |
| tableIndexOptions.indexProps)); |
| tableIndexCreated = true; |
| } |
| } |
| |
| // Global View and View Index creation. |
| try (Connection globalViewConnection = getGlobalViewConnection()) { |
| if (globalViewEnabled && !globalViewCreated) { |
| globalViewConnection.createStatement().execute( |
| buildCreateGlobalViewStmt(entityGlobalViewName, entityTableName, |
| globalViewCondition)); |
| globalViewCreated = true; |
| } |
| // Index on GlobalView |
| if (globalViewIndexEnabled && !globalViewIndexCreated) { |
| String |
| indexOnGlobalViewName = |
| String.format("IDX_%s", SchemaUtil.normalizeIdentifier(globalViewName)); |
| globalViewConnection.createStatement().execute( |
| buildCreateIndexStmt(indexOnGlobalViewName, entityGlobalViewName, |
| globalViewIndexOptions.isLocal, |
| globalViewIndexOptions.globalViewIndexColumns, |
| globalViewIndexOptions.globalViewIncludeColumns, |
| globalViewIndexOptions.indexProps)); |
| globalViewIndexCreated = true; |
| } |
| } |
| |
| // Tenant View and View Index creation. |
| try (Connection tenantConnection = getTenantConnection()) { |
| // Build tenant related views if any |
| if (tenantViewEnabled && !tenantViewCreated) { |
| String tenantViewCondition; |
| if (globalViewEnabled) { |
| tenantViewCondition = |
| String.format("SELECT * FROM %s", entityGlobalViewName); |
| } else if (tableEnabled) { |
| tenantViewCondition = |
| String.format("SELECT * FROM %s WHERE KP = '%s'", entityTableName, |
| entityKeyPrefix); |
| } else { |
| throw new IllegalStateException( |
| "Tenant View must be based on tables or global view"); |
| } |
| tenantConnection.createStatement().execute( |
| buildCreateTenantViewStmt(entityTenantViewName, tenantViewCondition)); |
| tenantViewCreated = true; |
| } |
| // Index on TenantView |
| if (tenantViewIndexEnabled && !tenantViewIndexCreated) { |
| String indexOnTenantViewName = String.format("IDX_%s", entityKeyPrefix); |
| tenantConnection.createStatement().execute( |
| buildCreateIndexStmt(indexOnTenantViewName, entityTenantViewName, |
| tenantViewIndexOptions.isLocal, |
| tenantViewIndexOptions.tenantViewIndexColumns, |
| tenantViewIndexOptions.tenantViewIncludeColumns, |
| tenantViewIndexOptions.indexProps)); |
| tenantViewIndexCreated = true; |
| } |
| } |
| } |
| |
| // Helper method for CREATE INDEX stmt builder. |
| private String buildCreateIndexStmt(String indexName, String onEntityName, boolean isLocal, |
| List<String> indexColumns, List<String> includeColumns, String indexProps) { |
| StringBuilder statement = new StringBuilder(); |
| statement.append(isLocal ? |
| "CREATE LOCAL INDEX IF NOT EXISTS " : |
| "CREATE INDEX IF NOT EXISTS ") |
| .append(indexName) |
| .append(" ON ") |
| .append(onEntityName) |
| .append("(") |
| .append(Joiner.on(",").join(indexColumns)) |
| .append(") ") |
| .append(includeColumns.isEmpty() ? |
| "" : |
| "INCLUDE (" + Joiner.on(",").join(includeColumns) + ") ") |
| .append((indexProps.isEmpty() ? "" : indexProps)); |
| |
| LOGGER.info(statement.toString()); |
| return statement.toString(); |
| |
| } |
| |
| // Helper method for CREATE TABLE stmt builder. |
| private String buildCreateTableStmt(String fullTableName) { |
| StringBuilder statement = new StringBuilder(); |
| StringBuilder tableDefinition = new StringBuilder(); |
| |
| if (!tableOptions.tablePKColumns.isEmpty() || !tableOptions.tableColumns.isEmpty()) { |
| tableDefinition.append(("(")); |
| if (!tableOptions.tablePKColumns.isEmpty()) { |
| tableDefinition.append(getColumnsAsString(tableOptions.tablePKColumns, |
| tableOptions.tablePKColumnTypes, true)); |
| } |
| if (!tableOptions.tableColumns.isEmpty()) { |
| tableDefinition.append(tableOptions.tablePKColumns.isEmpty() ? "" : ",") |
| .append(getFQColumnsAsString(tableOptions.tableColumns, |
| otherOptions.tableCFs, tableOptions.tableColumnTypes)); |
| } |
| |
| if (!tableOptions.tablePKColumns.isEmpty()) { |
| tableDefinition.append(" CONSTRAINT pk PRIMARY KEY ").append("(") |
| .append(getPKColumnsWithSort(tableOptions.tablePKColumns, |
| tableOptions.tablePKColumnSort)).append(")"); |
| } |
| tableDefinition.append((")")); |
| } |
| |
| statement.append("CREATE TABLE IF NOT EXISTS ").append(fullTableName) |
| .append(tableDefinition.toString()).append(" ") |
| .append((tableOptions.tableProps.isEmpty() ? "" : tableOptions.tableProps)); |
| LOGGER.info(statement.toString()); |
| return statement.toString(); |
| } |
| |
| // Helper method for CREATE VIEW (GLOBAL) stmt builder. |
| private String buildCreateGlobalViewStmt(String fullGlobalViewName, String fullTableName, |
| String globalViewCondition) { |
| StringBuilder statement = new StringBuilder(); |
| StringBuilder viewDefinition = new StringBuilder(); |
| |
| if (!globalViewOptions.globalViewPKColumns.isEmpty() |
| || !globalViewOptions.globalViewColumns.isEmpty()) { |
| viewDefinition.append(("(")); |
| if (!globalViewOptions.globalViewPKColumns.isEmpty()) { |
| viewDefinition.append(getColumnsAsString(globalViewOptions.globalViewPKColumns, |
| globalViewOptions.globalViewPKColumnTypes, true)); |
| } |
| if (!globalViewOptions.globalViewColumns.isEmpty()) { |
| viewDefinition |
| .append(globalViewOptions.globalViewPKColumns.isEmpty() ? "" : ",") |
| .append(getFQColumnsAsString(globalViewOptions.globalViewColumns, |
| otherOptions.globalViewCFs, |
| globalViewOptions.globalViewColumnTypes)); |
| } |
| |
| if (!globalViewOptions.globalViewPKColumns.isEmpty()) { |
| viewDefinition.append(" CONSTRAINT pk PRIMARY KEY ").append("(") |
| .append(getPKColumnsWithSort(globalViewOptions.globalViewPKColumns, |
| globalViewOptions.globalViewPKColumnSort)).append(")"); |
| } |
| viewDefinition.append((")")); |
| } |
| |
| statement.append("CREATE VIEW IF NOT EXISTS ").append(fullGlobalViewName) |
| .append(viewDefinition.toString()).append(" AS SELECT * FROM ") |
| .append(fullTableName).append(" WHERE ").append(globalViewCondition).append(" ") |
| .append((globalViewOptions.tableProps.isEmpty() ? |
| "" : |
| globalViewOptions.tableProps)); |
| LOGGER.info(statement.toString()); |
| return statement.toString(); |
| } |
| |
| // Helper method for CREATE VIEW (TENANT) stmt builder. |
| private String buildCreateTenantViewStmt(String fullTenantViewName, |
| String tenantViewCondition) { |
| StringBuilder statement = new StringBuilder(); |
| StringBuilder viewDefinition = new StringBuilder(); |
| |
| if (!tenantViewOptions.tenantViewPKColumns.isEmpty() |
| || !tenantViewOptions.tenantViewColumns.isEmpty()) { |
| viewDefinition.append(("(")); |
| if (!tenantViewOptions.tenantViewPKColumns.isEmpty()) { |
| viewDefinition.append(getColumnsAsString(tenantViewOptions.tenantViewPKColumns, |
| tenantViewOptions.tenantViewPKColumnTypes, true)); |
| } |
| if (!tenantViewOptions.tenantViewColumns.isEmpty()) { |
| viewDefinition |
| .append(tenantViewOptions.tenantViewPKColumns.isEmpty() ? "" : ",") |
| .append(getFQColumnsAsString(tenantViewOptions.tenantViewColumns, |
| otherOptions.tenantViewCFs, |
| tenantViewOptions.tenantViewColumnTypes)); |
| } |
| |
| if (!tenantViewOptions.tenantViewPKColumns.isEmpty()) { |
| viewDefinition.append(" CONSTRAINT pk PRIMARY KEY ").append("(") |
| .append(getPKColumnsWithSort(tenantViewOptions.tenantViewPKColumns, |
| tenantViewOptions.tenantViewPKColumnSort)).append(")"); |
| } |
| viewDefinition.append((")")); |
| } |
| |
| statement.append("CREATE VIEW IF NOT EXISTS ").append(fullTenantViewName) |
| .append(viewDefinition.toString()).append(" AS ").append(tenantViewCondition) |
| .append(" ").append((tenantViewOptions.tableProps.isEmpty() ? |
| "" : |
| tenantViewOptions.tableProps)); |
| LOGGER.info(statement.toString()); |
| return statement.toString(); |
| } |
| |
| Connection getGlobalConnection() throws SQLException { |
| return getPhoenixConnection(getUrl()); |
| } |
| |
| Connection getGlobalViewConnection() throws SQLException { |
| return getPhoenixConnection(connectOptions.useTenantConnectionForGlobalView ? |
| getUrl() + ';' + TENANT_ID_ATTRIB + '=' + dataOptions.tenantId : |
| getUrl()); |
| } |
| |
| Connection getTenantConnection() throws SQLException { |
| return getPhoenixConnection(connectOptions.useGlobalConnectionOnly ? |
| getUrl() : |
| getUrl() + ';' + TENANT_ID_ATTRIB + '=' + dataOptions.tenantId); |
| } |
| |
| Connection getPhoenixConnection(String url) throws SQLException { |
| return getPhoenixConnection(url, connectOptions.connectProps); |
| } |
| |
| Connection getPhoenixConnection(String url, Properties props) throws SQLException { |
| Connection phoenixConnection; |
| if (props == null) { |
| Properties connProps = PropertiesUtil.deepCopy(connectOptions.connectProps); |
| phoenixConnection = DriverManager.getConnection(url, connProps); |
| } else { |
| phoenixConnection = DriverManager.getConnection(url, props); |
| } |
| phoenixConnection.setAutoCommit(true); |
| return phoenixConnection; |
| } |
| |
| /** |
| * Option holders for various statement generation. |
| */ |
| |
| // Connect options. |
| public static class ConnectOptions { |
| Properties connectProps = new Properties(); |
| boolean useGlobalConnectionOnly = false; |
| boolean useTenantConnectionForGlobalView = false; |
| |
| /* |
| ***************************** |
| * Setters and Getters |
| ***************************** |
| */ |
| |
| public Properties getConnectProps() { |
| return connectProps; |
| } |
| |
| public void setConnectProps(Properties connectProps) { |
| this.connectProps = connectProps; |
| } |
| |
| public boolean isUseGlobalConnectionOnly() { |
| return useGlobalConnectionOnly; |
| } |
| |
| public void setUseGlobalConnectionOnly(boolean useGlobalConnectionOnly) { |
| this.useGlobalConnectionOnly = useGlobalConnectionOnly; |
| } |
| |
| public boolean isUseTenantConnectionForGlobalView() { |
| return useTenantConnectionForGlobalView; |
| } |
| |
| public void setUseTenantConnectionForGlobalView( |
| boolean useTenantConnectionForGlobalView) { |
| this.useTenantConnectionForGlobalView = useTenantConnectionForGlobalView; |
| } |
| |
| } |
| |
| // Table statement generation. |
| public static class TableOptions { |
| String schemaName = DDLDefaults.DEFAULT_SCHEMA_NAME; |
| List<String> tableColumns = Lists.newArrayList(); |
| List<String> tableColumnTypes = Lists.newArrayList(); |
| List<String> tablePKColumns = Lists.newArrayList(); |
| List<String> tablePKColumnTypes = Lists.newArrayList(); |
| List<String> tablePKColumnSort; |
| String tableProps = DDLDefaults.DEFAULT_TABLE_PROPS; |
| |
| /* |
| ***************************** |
| * Setters and Getters |
| ***************************** |
| */ |
| |
| public static TableOptions withDefaults() { |
| TableOptions options = new TableOptions(); |
| options.schemaName = DDLDefaults.DEFAULT_SCHEMA_NAME; |
| options.tableColumns = Lists.newArrayList(DDLDefaults.TABLE_COLUMNS); |
| options.tableColumnTypes = Lists.newArrayList(DDLDefaults.COLUMN_TYPES); |
| options.tablePKColumns = Lists.newArrayList(DDLDefaults.TABLE_PK_COLUMNS); |
| options.tablePKColumnTypes = Lists.newArrayList(DDLDefaults.TABLE_PK_TYPES); |
| options.tableProps = DDLDefaults.DEFAULT_TABLE_PROPS; |
| return options; |
| } |
| |
| public String getSchemaName() { |
| return schemaName; |
| } |
| |
| public void setSchemaName(String schemaName) { |
| this.schemaName = schemaName; |
| } |
| |
| public List<String> getTableColumns() { |
| return tableColumns; |
| } |
| |
| public void setTableColumns(List<String> tableColumns) { |
| this.tableColumns = tableColumns; |
| } |
| |
| public List<String> getTableColumnTypes() { |
| return tableColumnTypes; |
| } |
| |
| public void setTableColumnTypes(List<String> tableColumnTypes) { |
| this.tableColumnTypes = tableColumnTypes; |
| } |
| |
| public List<String> getTablePKColumns() { |
| return tablePKColumns; |
| } |
| |
| public void setTablePKColumns(List<String> tablePKColumns) { |
| this.tablePKColumns = tablePKColumns; |
| } |
| |
| public List<String> getTablePKColumnTypes() { |
| return tablePKColumnTypes; |
| } |
| |
| public void setTablePKColumnTypes(List<String> tablePKColumnTypes) { |
| this.tablePKColumnTypes = tablePKColumnTypes; |
| } |
| |
| public List<String> getTablePKColumnSort() { |
| return tablePKColumnSort; |
| } |
| |
| public void setTablePKColumnSort(List<String> tablePKColumnSort) { |
| this.tablePKColumnSort = tablePKColumnSort; |
| } |
| |
| public String getTableProps() { |
| return tableProps; |
| } |
| |
| public void setTableProps(String tableProps) { |
| this.tableProps = tableProps; |
| } |
| } |
| |
| // Global View statement generation. |
| public static class GlobalViewOptions { |
| String schemaName = DDLDefaults.DEFAULT_SCHEMA_NAME; |
| List<String> globalViewColumns = Lists.newArrayList(); |
| List<String> globalViewColumnTypes = Lists.newArrayList(); |
| List<String> globalViewPKColumns = Lists.newArrayList(); |
| List<String> globalViewPKColumnTypes = Lists.newArrayList(); |
| List<String> globalViewPKColumnSort; |
| String tableProps = DDLDefaults.DEFAULT_TENANT_VIEW_PROPS; |
| String globalViewCondition; |
| |
| /* |
| ***************************** |
| * Setters and Getters |
| ***************************** |
| */ |
| |
| public static GlobalViewOptions withDefaults() { |
| GlobalViewOptions options = new GlobalViewOptions(); |
| options.schemaName = DDLDefaults.DEFAULT_SCHEMA_NAME; |
| options.globalViewColumns = Lists.newArrayList(DDLDefaults.GLOBAL_VIEW_COLUMNS); |
| options.globalViewColumnTypes = Lists.newArrayList(DDLDefaults.COLUMN_TYPES); |
| options.globalViewPKColumns = |
| Lists.newArrayList(DDLDefaults.GLOBAL_VIEW_PK_COLUMNS); |
| options.globalViewPKColumnTypes = |
| Lists.newArrayList(DDLDefaults.GLOBAL_VIEW_PK_TYPES); |
| options.tableProps = DDLDefaults.DEFAULT_GLOBAL_VIEW_PROPS; |
| options.globalViewCondition = ""; |
| return options; |
| } |
| |
| public String getSchemaName() { |
| return schemaName; |
| } |
| |
| public void setSchemaName(String schemaName) { |
| this.schemaName = schemaName; |
| } |
| |
| public List<String> getGlobalViewColumns() { |
| return globalViewColumns; |
| } |
| |
| public void setGlobalViewColumns(List<String> globalViewColumns) { |
| this.globalViewColumns = globalViewColumns; |
| } |
| |
| public List<String> getGlobalViewColumnTypes() { |
| return globalViewColumnTypes; |
| } |
| |
| public void setGlobalViewColumnTypes(List<String> globalViewColumnTypes) { |
| this.globalViewColumnTypes = globalViewColumnTypes; |
| } |
| |
| public List<String> getGlobalViewPKColumns() { |
| return globalViewPKColumns; |
| } |
| |
| public void setGlobalViewPKColumns(List<String> globalViewPKColumns) { |
| this.globalViewPKColumns = globalViewPKColumns; |
| } |
| |
| public List<String> getGlobalViewPKColumnTypes() { |
| return globalViewPKColumnTypes; |
| } |
| |
| public void setGlobalViewPKColumnTypes(List<String> globalViewPKColumnTypes) { |
| this.globalViewPKColumnTypes = globalViewPKColumnTypes; |
| } |
| |
| public List<String> getGlobalViewPKColumnSort() { |
| return globalViewPKColumnSort; |
| } |
| |
| public void setGlobalViewPKColumnSort(List<String> globalViewPKColumnSort) { |
| this.globalViewPKColumnSort = globalViewPKColumnSort; |
| } |
| |
| public String getTableProps() { |
| return tableProps; |
| } |
| |
| public void setTableProps(String tableProps) { |
| this.tableProps = tableProps; |
| } |
| |
| public String getGlobalViewCondition() { |
| return globalViewCondition; |
| } |
| |
| public void setGlobalViewCondition(String globalViewCondition) { |
| this.globalViewCondition = globalViewCondition; |
| } |
| } |
| |
| // Tenant View statement generation. |
| public static class TenantViewOptions { |
| String schemaName = DDLDefaults.DEFAULT_SCHEMA_NAME; |
| List<String> tenantViewColumns = Lists.newArrayList(); |
| List<String> tenantViewColumnTypes = Lists.newArrayList(); |
| List<String> tenantViewPKColumns = Lists.newArrayList(); |
| List<String> tenantViewPKColumnTypes = Lists.newArrayList(); |
| List<String> tenantViewPKColumnSort; |
| String tableProps = DDLDefaults.DEFAULT_TENANT_VIEW_PROPS; |
| |
| /* |
| ***************************** |
| * Setters and Getters |
| ***************************** |
| */ |
| |
| public static TenantViewOptions withDefaults() { |
| TenantViewOptions options = new TenantViewOptions(); |
| options.schemaName = DDLDefaults.DEFAULT_SCHEMA_NAME; |
| options.tenantViewColumns = Lists.newArrayList(DDLDefaults.TENANT_VIEW_COLUMNS); |
| options.tenantViewColumnTypes = Lists.newArrayList(DDLDefaults.COLUMN_TYPES); |
| options.tenantViewPKColumns = |
| Lists.newArrayList(DDLDefaults.TENANT_VIEW_PK_COLUMNS); |
| options.tenantViewPKColumnTypes = |
| Lists.newArrayList(DDLDefaults.TENANT_VIEW_PK_TYPES); |
| options.tableProps = DDLDefaults.DEFAULT_TENANT_VIEW_PROPS; |
| return options; |
| } |
| |
| public String getSchemaName() { |
| return schemaName; |
| } |
| |
| public void setSchemaName(String schemaName) { |
| this.schemaName = schemaName; |
| } |
| |
| public List<String> getTenantViewColumns() { |
| return tenantViewColumns; |
| } |
| |
| public void setTenantViewColumns(List<String> tenantViewColumns) { |
| this.tenantViewColumns = tenantViewColumns; |
| } |
| |
| public List<String> getTenantViewColumnTypes() { |
| return tenantViewColumnTypes; |
| } |
| |
| public void setTenantViewColumnTypes(List<String> tenantViewColumnTypes) { |
| this.tenantViewColumnTypes = tenantViewColumnTypes; |
| } |
| |
| public List<String> getTenantViewPKColumns() { |
| return tenantViewPKColumns; |
| } |
| |
| public void setTenantViewPKColumns(List<String> tenantViewPKColumns) { |
| this.tenantViewPKColumns = tenantViewPKColumns; |
| } |
| |
| public List<String> getTenantViewPKColumnTypes() { |
| return tenantViewPKColumnTypes; |
| } |
| |
| public void setTenantViewPKColumnTypes(List<String> tenantViewPKColumnTypes) { |
| this.tenantViewPKColumnTypes = tenantViewPKColumnTypes; |
| } |
| |
| public List<String> getTenantViewPKColumnSort() { |
| return tenantViewPKColumnSort; |
| } |
| |
| public void setTenantViewPKColumnSort(List<String> tenantViewPKColumnSort) { |
| this.tenantViewPKColumnSort = tenantViewPKColumnSort; |
| } |
| |
| public String getTableProps() { |
| return tableProps; |
| } |
| |
| public void setTableProps(String tableProps) { |
| this.tableProps = tableProps; |
| } |
| } |
| |
| // Table Index statement generation. |
| public static class TableIndexOptions { |
| List<String> tableIndexColumns = Lists.newArrayList(); |
| List<String> tableIncludeColumns = Lists.newArrayList(); |
| boolean isLocal = false; |
| String indexProps = ""; |
| |
| /* |
| ***************************** |
| * Setters and Getters |
| ***************************** |
| */ |
| |
| public static TableIndexOptions withDefaults() { |
| TableIndexOptions options = new TableIndexOptions(); |
| options.tableIndexColumns = Lists.newArrayList(DDLDefaults.TABLE_INDEX_COLUMNS); |
| options.tableIncludeColumns = Lists.newArrayList(DDLDefaults.TABLE_INCLUDE_COLUMNS); |
| options.indexProps = DDLDefaults.DEFAULT_TABLE_INDEX_PROPS; |
| return options; |
| } |
| |
| public List<String> getTableIndexColumns() { |
| return tableIndexColumns; |
| } |
| |
| public void setTableIndexColumns(List<String> tableIndexColumns) { |
| this.tableIndexColumns = tableIndexColumns; |
| } |
| |
| public List<String> getTableIncludeColumns() { |
| return tableIncludeColumns; |
| } |
| |
| public void setTableIncludeColumns(List<String> tableIncludeColumns) { |
| this.tableIncludeColumns = tableIncludeColumns; |
| } |
| |
| public boolean isLocal() { |
| return isLocal; |
| } |
| |
| public void setLocal(boolean local) { |
| isLocal = local; |
| } |
| |
| public String getIndexProps() { |
| return indexProps; |
| } |
| |
| public void setIndexProps(String indexProps) { |
| this.indexProps = indexProps; |
| } |
| } |
| |
| // Global View Index statement generation. |
| public static class GlobalViewIndexOptions { |
| List<String> globalViewIndexColumns = Lists.newArrayList(); |
| List<String> globalViewIncludeColumns = Lists.newArrayList(); |
| boolean isLocal = false; |
| String indexProps = ""; |
| |
| /* |
| ***************************** |
| * Setters and Getters |
| ***************************** |
| */ |
| |
| public static GlobalViewIndexOptions withDefaults() { |
| GlobalViewIndexOptions options = new GlobalViewIndexOptions(); |
| options.globalViewIndexColumns = |
| Lists.newArrayList(DDLDefaults.GLOBAL_VIEW_INDEX_COLUMNS); |
| options.globalViewIncludeColumns = |
| Lists.newArrayList(DDLDefaults.GLOBAL_VIEW_INCLUDE_COLUMNS); |
| options.indexProps = DDLDefaults.DEFAULT_GLOBAL_VIEW_INDEX_PROPS; |
| return options; |
| } |
| |
| public List<String> getGlobalViewIndexColumns() { |
| return globalViewIndexColumns; |
| } |
| |
| public void setGlobalViewIndexColumns(List<String> globalViewIndexColumns) { |
| this.globalViewIndexColumns = globalViewIndexColumns; |
| } |
| |
| public List<String> getGlobalViewIncludeColumns() { |
| return globalViewIncludeColumns; |
| } |
| |
| public void setGlobalViewIncludeColumns(List<String> globalViewIncludeColumns) { |
| this.globalViewIncludeColumns = globalViewIncludeColumns; |
| } |
| |
| public boolean isLocal() { |
| return isLocal; |
| } |
| |
| public void setLocal(boolean local) { |
| isLocal = local; |
| } |
| |
| public String getIndexProps() { |
| return indexProps; |
| } |
| |
| public void setIndexProps(String indexProps) { |
| this.indexProps = indexProps; |
| } |
| } |
| |
| // Tenant View Index statement generation. |
| public static class TenantViewIndexOptions { |
| List<String> tenantViewIndexColumns = Lists.newArrayList(); |
| List<String> tenantViewIncludeColumns = Lists.newArrayList(); |
| boolean isLocal = false; |
| String indexProps = ""; |
| |
| /* |
| ***************************** |
| * Setters and Getters |
| ***************************** |
| */ |
| |
| public static TenantViewIndexOptions withDefaults() { |
| TenantViewIndexOptions options = new TenantViewIndexOptions(); |
| options.tenantViewIndexColumns = |
| Lists.newArrayList(DDLDefaults.TENANT_VIEW_INDEX_COLUMNS); |
| options.tenantViewIncludeColumns = |
| Lists.newArrayList(DDLDefaults.TENANT_VIEW_INCLUDE_COLUMNS); |
| options.indexProps = DDLDefaults.DEFAULT_TENANT_VIEW_INDEX_PROPS; |
| return options; |
| } |
| |
| public List<String> getTenantViewIndexColumns() { |
| return tenantViewIndexColumns; |
| } |
| |
| public void setTenantViewIndexColumns(List<String> tenantViewIndexColumns) { |
| this.tenantViewIndexColumns = tenantViewIndexColumns; |
| } |
| |
| public List<String> getTenantViewIncludeColumns() { |
| return tenantViewIncludeColumns; |
| } |
| |
| public void setTenantViewIncludeColumns(List<String> tenantViewIncludeColumns) { |
| this.tenantViewIncludeColumns = tenantViewIncludeColumns; |
| } |
| |
| public boolean isLocal() { |
| return isLocal; |
| } |
| |
| public void setLocal(boolean local) { |
| isLocal = local; |
| } |
| |
| public String getIndexProps() { |
| return indexProps; |
| } |
| |
| public void setIndexProps(String indexProps) { |
| this.indexProps = indexProps; |
| } |
| } |
| |
| public static class OtherOptions { |
| String testName; |
| List<String> tableCFs = Lists.newArrayList(); |
| List<String> globalViewCFs = Lists.newArrayList(); |
| List<String> tenantViewCFs = Lists.newArrayList(); |
| |
| /* |
| ***************************** |
| * Setters and Getters |
| ***************************** |
| */ |
| |
| public static OtherOptions withDefaults() { |
| OtherOptions options = new OtherOptions(); |
| options.tableCFs = Lists.newArrayList(DDLDefaults.TABLE_COLUMN_FAMILIES); |
| options.globalViewCFs = Lists.newArrayList(DDLDefaults.GLOBAL_VIEW_COLUMN_FAMILIES); |
| options.tenantViewCFs = Lists.newArrayList(DDLDefaults.TENANT_VIEW_COLUMN_FAMILIES); |
| return options; |
| } |
| |
| public String getTestName() { |
| return testName; |
| } |
| |
| public void setTestName(String testName) { |
| this.testName = testName; |
| } |
| |
| public List<String> getTableCFs() { |
| return tableCFs; |
| } |
| |
| public void setTableCFs(List<String> tableCFs) { |
| this.tableCFs = tableCFs; |
| } |
| |
| public List<String> getGlobalViewCFs() { |
| return globalViewCFs; |
| } |
| |
| public void setGlobalViewCFs(List<String> globalViewCFs) { |
| this.globalViewCFs = globalViewCFs; |
| } |
| |
| public List<String> getTenantViewCFs() { |
| return tenantViewCFs; |
| } |
| |
| public void setTenantViewCFs(List<String> tenantViewCFs) { |
| this.tenantViewCFs = tenantViewCFs; |
| } |
| } |
| |
| public static class DataOptions { |
| String uniqueName = ""; |
| String tenantIdFormat = DDLDefaults.DEFAULT_TENANT_ID_FMT; |
| int viewNumber = 0; |
| AtomicInteger viewCounter = new AtomicInteger(0); |
| String tenantId = ""; |
| |
| /* |
| ***************************** |
| * Setters and Getters |
| ***************************** |
| */ |
| |
| public static DataOptions withDefaults() { |
| DataOptions options = new DataOptions(); |
| options.uniqueName = generateUniqueName(); |
| options.viewCounter = new AtomicInteger(0); |
| options.tenantId = |
| String.format(options.tenantIdFormat, TENANT_COUNTER.get(), |
| options.uniqueName); |
| return options; |
| } |
| |
| public int getNextViewNumber() { |
| return viewNumber = viewCounter.incrementAndGet(); |
| } |
| |
| public int getViewNumber() { |
| return viewNumber; |
| } |
| |
| public String getTenantIdFormat() { |
| return tenantIdFormat; |
| } |
| |
| public void setTenantIdFormat(String tenantIdFormat) { |
| this.tenantIdFormat = tenantIdFormat; |
| } |
| |
| public String getUniqueName() { |
| return uniqueName; |
| } |
| |
| public void setUniqueName(String uniqueName) { |
| this.uniqueName = uniqueName; |
| } |
| |
| public String getTenantId() { |
| return tenantId; |
| } |
| |
| public void setTenantId(String tenantId) { |
| this.tenantId = tenantId; |
| } |
| } |
| } |
| |
| } |