@Test public void testDeserializeValidSerializedSchemaAndIndexName() { final IndexSchema actualSchema = IndexSchema.deserialize(TEST_INDEX_SCHEMA.serialize(), TEST_INDEX_SCHEMA.getIndexName()); assertEquals(TEST_INDEX_SCHEMA.getIndexName(), actualSchema.getIndexName()); assertEquals(TEST_INDEX_SCHEMA, actualSchema); }
/** * Deserialize a byte array into an index schema. * * @param serializedIndexSchema Byte array of the index schema [Not null] * @param indexName Name of the index [Not null, Not empty] * @return An index schema for the byte array. */ public static IndexSchema deserialize(byte[] serializedIndexSchema, String indexName) { checkNotNull(serializedIndexSchema); Verify.isNotNullOrEmpty(indexName); return new IndexSchema(indexName, Util.deserializeAvroObject(serializedIndexSchema, reader)); }
/** * Verifies that the index schema only index columns for columns that are available * @param indices A mapping of the index details, not null * @param columns A mapping of column details, not null * @throws NullPointerException Thrown if the indices or columns container is null * @throws IllegalArgumentException Thrown if a {@link IndexSchema} indexes * a column that is not an available column */ public static void isValidIndexSchema(final Collection<IndexSchema> indices, final Collection<ColumnSchema> columns) { checkNotNull(indices); checkNotNull(columns); Set<String> columnNames = Sets.newHashSet(); for (ColumnSchema column : columns) { columnNames.add(column.getColumnName()); } for (final IndexSchema index : indices) { for (final String column : index.getColumns()) { if (!columnNames.contains(column)) { throw new IllegalArgumentException("Only columns in the table may be indexed."); } } } } }
/** * Add an index schema to the table schema * * @param indices New index schemas [Not null] */ public void addIndices(Collection<IndexSchema> indices) { checkNotNull(indices); for (IndexSchema entry : indices) { this.indices.add(entry); avroTableSchema.getIndices().put(entry.getIndexName(), entry.getAvroValue()); if (entry.getIsUnique()) { uniqueIndexCount++; } } }
@Test(expected = NullPointerException.class) public void testDeserializeInvalidIndexName() { IndexSchema.deserialize(TEST_INDEX_SCHEMA.serialize(), null); }
private Put putIndices(long tableId, Collection<IndexSchema> indices) { checkState(!indices.isEmpty(), "putIndices requires 1 or more indices."); long indexId = getNextIndexId(tableId, indices.size()); Put put = new Put(new IndicesRowKey(tableId).encode()); for (IndexSchema columnEntry : indices) { put.add(columnFamily, serializeName(columnEntry.getIndexName()), serializeId(indexId--)); } return put; }
/** * Add the provided index information to the table. The table must be open * before this operation can be performed. * * @param indexName The name of the index to add, not null or empty * @param serializedSchema The byte representation of the {@link IndexSchema} for this index, not null */ public void addIndex(String indexName, byte[] serializedSchema) { Verify.isNotNullOrEmpty(indexName, "The index name is invalid"); checkNotNull(serializedSchema, "Schema cannot be null"); checkTableOpen(); IndexSchema schema = IndexSchema.deserialize(serializedSchema, indexName); checkArgument(!schema.getIsUnique(), "Honeycomb does not support adding unique indices without a table rebuild."); store.addIndex(tableName, schema); table.insertTableIndex(schema); table.flush(); }
@Test(expected = IllegalArgumentException.class) public void testAddUniqueIndex() { when(storeFactory.createStore(anyString())).thenReturn(storageMock); when(storageMock.openTable(anyString())).thenReturn(tableMock); proxy.openTable(TEST_TABLE_NAME); verify(storeFactory, times(1)).createStore(eq(TEST_TABLE_NAME)); verify(storageMock, times(1)).openTable(eq(TEST_TABLE_NAME)); final IndexSchema uniqueIndex = new IndexSchema("uniqueIdx", ImmutableList.<String>of(TEST_COLUMN), true); proxy.addIndex(TEST_INDEX, uniqueIndex.serialize()); verify(storageMock, never()).addIndex(eq(TEST_TABLE_NAME), eq(INDEX_SCHEMA)); verify(tableMock, never()).insertTableIndex(eq(INDEX_SCHEMA)); verify(tableMock, never()).flush(); }
@Test(expected = NullPointerException.class) public void testDeserializeNullSerializedSchema() { IndexSchema.deserialize(null, INDEX_A); }
@Test(expected = IllegalStateException.class) public void testAddIndexTableNotOpen() { when(storeFactory.createStore(anyString())).thenReturn(storageMock); when(storageMock.openTable(anyString())).thenReturn(tableMock); proxy.addIndex(TEST_INDEX, INDEX_SCHEMA.serialize()); verify(storageMock, never()).addIndex(eq(TEST_TABLE_NAME), eq(INDEX_SCHEMA)); verify(tableMock, never()).insertTableIndex(eq(INDEX_SCHEMA)); verify(tableMock, never()).flush(); }
/** * Remove an index schema from the table schema * * @param indexName Name of index schema [Not null, Not empty] */ public void removeIndex(String indexName) { Verify.isNotNullOrEmpty(indexName); IndexSchema schema = getIndexSchema(indexName); checkNotNull(schema); indices.remove(schema); avroTableSchema.getIndices().remove(indexName); if (schema.getIsUnique()) { uniqueIndexCount--; } }
/** * Construct a table schema from a map of column schemas and index schemas. * * @param columns Column schemas map [Not null] * @param indices Index schema map [Not null] */ public TableSchema(Collection<ColumnSchema> columns, Collection<IndexSchema> indices) { checkArgument(columns.size() > 0, "Table must have at least one column."); checkNotNull(indices); Map<String, AvroColumnSchema> columnSchemaMap = Maps.newHashMap(); for (ColumnSchema columnSchema : columns) { columnSchemaMap.put(columnSchema.getColumnName(), columnSchema.getAvroValue()); } Map<String, AvroIndexSchema> indexSchemaMap = Maps.newHashMap(); for (IndexSchema indexSchema : indices) { indexSchemaMap.put(indexSchema.getIndexName(), indexSchema.getAvroValue()); if (indexSchema.getIsUnique()) { uniqueIndexCount++; } } avroTableSchema = AvroTableSchema.newBuilder() .setColumns(columnSchemaMap) .setIndices(indexSchemaMap) .build(); this.columns = new LinkedList<ColumnSchema>(columns); this.indices = new LinkedList<IndexSchema>(indices); }
private void doToIndices(long tableId, final Row row, final Collection<IndexSchema> indices, final IndexAction action) { for (IndexSchema index : indices) { long indexId = store.getIndexId(tableId, index.getIndexName()); TableSchema schema = store.getSchema(tableId); IndexRowKeyBuilder builder = IndexRowKeyBuilder .newBuilder(tableId, indexId) .withUUID(row.getUUID()) .withRow(row, index.getIndexName(), schema); action.execute(builder); } }
@Test(expected = IllegalArgumentException.class) public void testDeserializeEmptyIndexName() { IndexSchema.deserialize(TEST_INDEX_SCHEMA.serialize(), ""); }
@Test public void testAddIndex() { when(storeFactory.createStore(anyString())).thenReturn(storageMock); when(storageMock.openTable(anyString())).thenReturn(tableMock); proxy.openTable(TEST_TABLE_NAME); verify(storeFactory, times(1)).createStore(eq(TEST_TABLE_NAME)); verify(storageMock, times(1)).openTable(eq(TEST_TABLE_NAME)); proxy.addIndex(TEST_INDEX, INDEX_SCHEMA.serialize()); verify(storageMock, times(1)).addIndex(eq(TEST_TABLE_NAME), eq(INDEX_SCHEMA)); verify(tableMock, times(1)).insertTableIndex(eq(INDEX_SCHEMA)); verify(tableMock, times(1)).flush(); }
public QueryKeyGenerator(TableSchema schema) { super(); this.rows = new RowGenerator(schema); ImmutableList.Builder<String> indices = ImmutableList.builder(); for (IndexSchema indexSchema : schema.getIndices()) { indices.add(indexSchema.getIndexName()); } this.indices = PrimitiveGenerators.fixedValues(indices.build()); }
/** * Retrieve an index schema by name. * * @param indexName Name of index schema [Not null, Not empty] * @return Index schema by name indexName */ public IndexSchema getIndexSchema(String indexName) { Verify.isNotNullOrEmpty(indexName); AvroIndexSchema indexSchema = avroTableSchema.getIndices().get(indexName); return new IndexSchema(indexName, indexSchema); }
/** * Retrieve from a list of indices which ones have been changed. * * @param indices Table indices * @param oldRecords Old MySQL row * @param newRecords New MySQL row * @return List of changed indices */ public static ImmutableList<IndexSchema> getChangedIndices(Collection<IndexSchema> indices, Map<String, ByteBuffer> oldRecords, Map<String, ByteBuffer> newRecords) { if (indices.isEmpty()) { return ImmutableList.of(); } MapDifference<String, ByteBuffer> diff = Maps.difference(oldRecords, newRecords); Set<String> changedColumns = Sets.difference( Sets.union(newRecords.keySet(), oldRecords.keySet()), diff.entriesInCommon().keySet()); ImmutableList.Builder<IndexSchema> changedIndices = ImmutableList.builder(); for (IndexSchema index : indices) { Set<String> indexColumns = ImmutableSet.copyOf(index.getColumns()); if (!Sets.intersection(changedColumns, indexColumns).isEmpty()) { changedIndices.add(index); } } return changedIndices.build(); }
@Test(expected = NullPointerException.class) public void testAddIndexInvalidIndexName() { proxy.addIndex(null, INDEX_SCHEMA.serialize()); }
@Test public void testRemoveIndexValidIndexName() { final TableSchema schema = new TableSchema(COLUMNS, INDICES); assertEquals(INDICES.size(), schema.getIndices().size()); // Remove all of the indexes from the schema for(final IndexSchema indexSchema : INDICES ) { schema.removeIndex(indexSchema.getIndexName()); } assertEquals(0, schema.getIndices().size()); }