/** * Deserialize the provided serialized row buffer to a new {@link Row} instance * * @param serializedRow byte buffer containing serialized Row * @return new Row instance from serializedRow */ public static Row deserialize(byte[] serializedRow) { checkNotNull(serializedRow); checkArgument(serializedRow.length > 0); SchemaVersionUtils.processSchemaVersion(serializedRow[0], RowSchemaInfo.VER_CURRENT); return new Row(Util.deserializeAvroObject(serializedRow, reader)); }
public void updateRow(byte[] oldRowBytes, byte[] rowBytes) { checkTableOpen(); checkNotNull(rowBytes); Row updatedRow = Row.deserialize(rowBytes); TableSchema schema = store.getSchema(tableName); Row oldRow = Row.deserialize(oldRowBytes); oldRow.setUUID(updatedRow.getUUID()); ImmutableList<IndexSchema> changedIndices = Util.getChangedIndices(schema.getIndices(), oldRow.getRecords(), updatedRow.getRecords()); table.updateRow(oldRow, updatedRow, changedIndices); if (schema.hasUniqueIndices()) { table.flush(); } }
public static byte[] updateSerializedSchema(byte[] row) { byte version = row[0]; if (isMostRecentVersion(version)) { return row; } // Bring the row up to most recent version return Row.deserialize(row).serialize(); }
@Override public String toString() { final ToStringHelper toString = Objects.toStringHelper(this.getClass()); toString.add("Version", row.getVersion()) .add("UUID", getUUID()); for (final Map.Entry<String, ByteBuffer> entry : getRecords().entrySet()) { toString.add("Record", format("%s: %s", entry.getKey(), entry.getValue())); } return toString.toString(); } }
checkNotNull(serializedRow); Row row = Row.deserialize(serializedRow); IndexSchema indexSchema = schema.getIndexSchema(indexName); QueryKey key = new QueryKey(indexName, QueryType.EXACT_KEY, row.getRecords()); Scanner scanner = t.indexScanExact(key); Row next = Row.deserialize(scanner.next()); if (!next.getUUID().equals(row.getUUID())) { boolean isNullInRecord = !row.getRecords().containsKey(column); if (isNullInRecord) { return false;
/** * Insert row into table. * * @param rowBytes Serialized row to be written */ public void insertRow(byte[] rowBytes) { checkTableOpen(); checkNotNull(rowBytes); TableSchema schema = store.getSchema(tableName); Row row = Row.deserialize(rowBytes); row.setRandomUUID(); String auto_inc_col = schema.getAutoIncrementColumn(); if (auto_inc_col != null) { ByteBuffer bb = row.getRecords().get(auto_inc_col); if (bb != null) { long auto_inc = bb.getLong(); long next_auto_inc = auto_inc + 1; if (auto_inc > next_auto_inc) { // The autoincrement will wrap around. MySQL says don't wrap. next_auto_inc = auto_inc; } bb.rewind(); store.setAutoInc(tableName, next_auto_inc); } } table.insertRow(row); if (schema.hasUniqueIndices()) { table.flush(); } }
/** * Test that row serialization and deserialization is isomorphic in the * serialization direction. * * @throws Exception */ @Test public void testSerDe() throws Exception { TableSchema schema = new TableSchemaGenerator().next(); for (Row row : Iterables.toIterable(new RowGenerator(schema))) { Assert.assertEquals(row, Row.deserialize(row.serialize())); } } }
/** * Build put list for a row insert with specified indices * * @param tableId * @param row * @param indices * @return The list of put mutations */ public List<Put> insert(long tableId, final Row row, final Collection<IndexSchema> indices) { checkNotNull(row); // tableId, indices checked by called methods final byte[] serializedRow = row.serialize(); final UUID uuid = row.getUUID(); final ImmutableList.Builder<Put> puts = ImmutableList.builder(); puts.add(emptyQualifierPut(new DataRowKey(tableId, uuid), serializedRow)); puts.addAll(insertIndices(tableId, row, indices)); return puts.build(); }
public void deleteRow(byte[] rowBytes) { checkTableOpen(); Row row = Row.deserialize(rowBytes); table.deleteRow(row); }
/** * Build put list for inserting only the specified indices of the row * * @param tableId * @param row * @param indices * @return The list of put mutations */ public List<Put> insertIndices(long tableId, final Row row, final Collection<IndexSchema> indices) { checkNotNull(row); final byte[] serializedRow = row.serialize(); final ImmutableList.Builder<Put> puts = ImmutableList.builder(); doToIndices(tableId, row, indices, new IndexAction() { @Override public void execute(IndexRowKeyBuilder builder) { puts.add(emptyQualifierPut(builder.withSortOrder(SortOrder.Ascending).build(), serializedRow)); puts.add(emptyQualifierPut(builder.withSortOrder(SortOrder.Descending).build(), serializedRow)); } }); return puts.build(); }
/** * Set the values of the index row based on a sql row. If an index column is * missing from the sql row it is replaced with an explicit null. (This * method is intended for insert) * * @param row SQL row * @param indexName Columns in the index * @param tableSchema Table schema * @return The current builder instance */ public IndexRowKeyBuilder withRow(Row row, String indexName, TableSchema tableSchema) { checkNotNull(row, "row must not be null."); Map<String, ByteBuffer> recordCopy = Maps.newHashMap(row.getRecords()); for (String column : tableSchema.getIndexSchema(indexName).getColumns()) { if (!recordCopy.containsKey(column)) { recordCopy.put(column, null); } } this.fields = recordCopy; this.indexName = indexName; this.tableSchema = tableSchema; return this; }
/** * Build delete list for the data and indices belonging to the row * * @param tableId * @param row * @return The list of delete mutations */ public List<Delete> delete(long tableId, final Row row) { List<Delete> deletes = deleteIndices(tableId, row); deletes.add(new Delete(new DataRowKey(tableId, row.getUUID()).encode())); return deletes; }
public byte[] getNextRow() { checkNotNull(currentScanner, "Scanner cannot be null to get next row."); byte[] next = currentScanner.next(); if (next == null) { return null; } return Row.updateSerializedSchema(next); }
@Override public Row getRow(UUID uuid) { DataRowKey dataRow = new DataRowKey(tableId, uuid); Get get = new Get(dataRow.encode()); Result result = HBaseOperations.performGet(hTable, get); if (result.isEmpty()) { throw new RowNotFoundException(uuid); } return Row.deserialize(result.getValue(columnFamily.getBytes(), new byte[0])); }
public byte[] getRow(byte[] uuid) { checkTableOpen(); checkNotNull(uuid, "Get row cannot have a null UUID."); return table.getRow(Util.bytesToUUID(uuid)).serialize(); }
@Override public QueryKey next() { return new QueryKey(indices.next(), queryTypes.next(), rows.next().getRecords()); } }
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); } }
/** * Parse a line of a CSV into a Honeycomb {@link Row} * * @param line CSV line * @return Honeycomb {@link Row} * @throws IOException The CSV line was improperly formed * @throws ParseException The CSV line contained invalid data. */ public Row parseRow(String line) throws IOException, ParseException { checkNotNull(line); String[] unparsedFields = csvParser.parseLine(line); checkArgument((schema.getColumns().size() == unparsedFields.length), "Line contains wrong number of columns."); ImmutableMap.Builder<String, ByteBuffer> fields = ImmutableMap.builder(); for (int i = 0; i < columns.length; i++) { fields.put(columns[i], FieldParser.parse(unparsedFields[i], schema.getColumnSchema(columns[i]))); } return new Row(fields.build(), UUID.randomUUID()); } }
@Override public void insertTableIndex(final IndexSchema indexSchema) { checkNotNull(indexSchema, "The index schema is invalid"); final Collection<IndexSchema> indices = ImmutableList.of(indexSchema); final Scanner scanner = tableScan(); while (scanner.hasNext()) { HBaseOperations.performPut(hTable, mutationFactory.insertIndices(tableId, Row.deserialize(scanner.next()), indices)); } Util.closeQuietly(scanner); }
@Override public Row next() { ImmutableMap.Builder<String, ByteBuffer> records = ImmutableMap.builder(); for (Map.Entry<String, Generator<ByteBuffer>> record : recordGenerators.entrySet()) { ByteBuffer nextValue = record.getValue().next(); if (nextValue != null) { records.put(record.getKey(), nextValue); } } return new Row(records.build(), uuids.next()); } }