use of herddb.utils.Bytes in project herddb by diennea.
the class Table method deserialize.
@SuppressFBWarnings("OS_OPEN_STREAM")
public static Table deserialize(byte[] data) {
try {
SimpleByteArrayInputStream ii = new SimpleByteArrayInputStream(data);
ExtendedDataInputStream dii = new ExtendedDataInputStream(ii);
// version
long tversion = dii.readVLong();
// flags for future implementations
long tflags = dii.readVLong();
if (tversion != 1 || tflags != 0) {
throw new IOException("corrupted table file");
}
String tablespace = dii.readUTF();
String name = dii.readUTF();
String uuid = dii.readUTF();
boolean auto_increment = dii.readByte() > 0;
int maxSerialPosition = dii.readVInt();
byte pkcols = dii.readByte();
String[] primaryKey = new String[pkcols];
for (int i = 0; i < pkcols; i++) {
primaryKey[i] = dii.readUTF();
}
// for future implementations
int flags = dii.readVInt();
int ncols = dii.readVInt();
Column[] columns = new Column[ncols];
for (int i = 0; i < ncols; i++) {
// version
long cversion = dii.readVLong();
// flags for future implementations
long cflags = dii.readVLong();
if (cversion != COLUMNVERSION_1 || (cflags != COLUMNFLAGS_NO_FLAGS && cflags != COLUMNFLAGS_HAS_DEFAULT_VALUE)) {
throw new IOException("corrupted table file");
}
String cname = dii.readUTF();
int type = dii.readVInt();
int serialPosition = dii.readVInt();
Bytes defaultValue = null;
if ((cflags & COLUMNFLAGS_HAS_DEFAULT_VALUE) == COLUMNFLAGS_HAS_DEFAULT_VALUE) {
defaultValue = dii.readBytes();
}
columns[i] = Column.column(cname, type, serialPosition, defaultValue);
}
ForeignKeyDef[] foreignKeys = null;
if ((flags & TABLEFLAGS_HAS_FOREIGN_KEYS) == TABLEFLAGS_HAS_FOREIGN_KEYS) {
int numForeignKeys = dii.readVInt();
if (numForeignKeys > 0) {
foreignKeys = new ForeignKeyDef[numForeignKeys];
for (int i = 0; i < numForeignKeys; i++) {
ForeignKeyDef.Builder builder = ForeignKeyDef.builder();
String fkName = dii.readUTF();
String parentTableId = dii.readUTF();
builder.parentTableId(parentTableId);
builder.name(fkName);
int numColumns = dii.readVInt();
for (int k = 0; k < numColumns; k++) {
String col = dii.readUTF();
builder.column(col);
}
for (int k = 0; k < numColumns; k++) {
String col = dii.readUTF();
builder.parentTableColumn(col);
}
builder.onUpdateAction(dii.readVInt());
builder.onDeleteAction(dii.readVInt());
foreignKeys[i] = builder.build();
}
}
}
return new Table(uuid, name, columns, primaryKey, tablespace, auto_increment, maxSerialPosition, foreignKeys);
} catch (IOException err) {
throw new IllegalArgumentException(err);
}
}
use of herddb.utils.Bytes in project herddb by diennea.
the class RecordSerializerTest method testSerializeIndexKey.
private void testSerializeIndexKey(DataAccessor record, Bytes expectedResult, Column... indexedColumns) {
ColumnsList index = new ColumnsListImpl(indexedColumns);
Bytes result = RecordSerializer.serializeIndexKey(record, index, index.getPrimaryKey());
assertEquals(expectedResult, result);
}
use of herddb.utils.Bytes in project herddb by diennea.
the class AutoTransactionTest method testAutoTransactionOnGetWithError.
@Test
public void testAutoTransactionOnGetWithError() throws Exception {
int i = 1;
Map<String, Object> data = new HashMap<>();
Bytes key = Bytes.from_string("key_" + i);
data.put("id", "key_" + i);
data.put("number", i);
Record record = RecordSerializer.toRecord(data, table);
InsertStatement st = new InsertStatement(tableSpace, tableName, record);
manager.executeUpdate(st, StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.NO_TRANSACTION);
try {
GetResult get = manager.get(new GetStatement(tableSpace, "no_table_exists", key, null, false), StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.AUTOTRANSACTION_TRANSACTION);
fail();
} catch (TableDoesNotExistException ok) {
}
assertTrue(manager.getTableSpaceManager(tableSpace).getOpenTransactions().isEmpty());
}
use of herddb.utils.Bytes in project herddb by diennea.
the class AutoTransactionTest method testAutoTransactionOnErrorScan.
@Test
public void testAutoTransactionOnErrorScan() throws Exception {
int i = 1;
Map<String, Object> data = new HashMap<>();
Bytes key = Bytes.from_string("key_" + i);
data.put("id", "key_" + i);
data.put("number", i);
Record record = RecordSerializer.toRecord(data, table);
InsertStatement st = new InsertStatement(tableSpace, tableName, record);
DMLStatementExecutionResult executeUpdate = manager.executeUpdate(st, StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.NO_TRANSACTION);
long tx;
try (DataScanner scan = manager.scan(new ScanStatement(tableSpace, "no_table", Projection.IDENTITY(table.columnNames, table.getColumns()), null, null, null), StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.AUTOTRANSACTION_TRANSACTION)) {
fail();
} catch (TableDoesNotExistException ok) {
}
assertTrue(manager.getTableSpaceManager(tableSpace).getOpenTransactions().isEmpty());
}
use of herddb.utils.Bytes in project herddb by diennea.
the class TableManager method apply.
@Override
public void apply(CommitLogResult writeResult, LogEntry entry, boolean recovery) throws DataStorageManagerException, LogNotAvailableException {
if (recovery) {
if (writeResult.deferred) {
throw new DataStorageManagerException("impossibile to have a deferred CommitLogResult during recovery");
}
LogSequenceNumber position = writeResult.getLogSequenceNumber();
if (dumpLogSequenceNumber != null && !position.after(dumpLogSequenceNumber)) {
// in "restore mode" the 'position" parameter is from the 'old' transaction log
Transaction transaction = null;
if (entry.transactionId > 0) {
transaction = tableSpaceManager.getTransaction(entry.transactionId);
}
if (transaction != null) {
transaction.touch();
LOGGER.log(Level.FINER, "{0}.{1} keep {2} at {3}, table restored from position {4}, it belongs to transaction {5} which was in progress during the dump of the table", new Object[] { table.tablespace, table.name, entry, position, dumpLogSequenceNumber, entry.transactionId });
} else {
LOGGER.log(Level.FINER, "{0}.{1} skip {2} at {3}, table restored from position {4}", new Object[] { table.tablespace, table.name, entry, position, dumpLogSequenceNumber });
return;
}
} else if (!position.after(bootSequenceNumber)) {
// recovery mode
Transaction transaction = null;
if (entry.transactionId > 0) {
transaction = tableSpaceManager.getTransaction(entry.transactionId);
}
if (transaction != null) {
transaction.touch();
LOGGER.log(Level.FINER, "{0}.{1} keep {2} at {3}, table booted at {4}, it belongs to transaction {5} which was in progress during the flush of the table", new Object[] { table.tablespace, table.name, entry, position, bootSequenceNumber, entry.transactionId });
} else {
LOGGER.log(Level.FINER, "{0}.{1} skip {2} at {3}, table booted at {4}", new Object[] { table.tablespace, table.name, entry, position, bootSequenceNumber });
return;
}
}
}
if (writeResult.sync) {
// wait for data to be stored to log
writeResult.getLogSequenceNumber();
}
switch(entry.type) {
case LogEntryType.DELETE:
{
// remove the record from the set of existing records
Bytes key = entry.key;
if (entry.transactionId > 0) {
Transaction transaction = tableSpaceManager.getTransaction(entry.transactionId);
if (transaction == null) {
/* Ignore missing transaction only if during recovery and ignore property is active */
if (recovery && ignoreMissingTransactionsOnRecovery) {
LOGGER.log(Level.WARNING, "Ignoring delete of {0} due to missing transaction {1}", new Object[] { entry.key, entry.transactionId });
} else {
throw new DataStorageManagerException("no such transaction " + entry.transactionId);
}
} else {
transaction.registerDeleteOnTable(this.table.name, key, writeResult);
}
} else {
applyDelete(key);
}
break;
}
case LogEntryType.UPDATE:
{
Bytes key = entry.key;
Bytes value = entry.value;
if (entry.transactionId > 0) {
Transaction transaction = tableSpaceManager.getTransaction(entry.transactionId);
if (transaction == null) {
/* Ignore missing transaction only if during recovery and ignore property is active */
if (recovery && ignoreMissingTransactionsOnRecovery) {
LOGGER.log(Level.WARNING, "Ignoring update of {0} due to missing transaction {1}", new Object[] { entry.key, entry.transactionId });
} else {
throw new DataStorageManagerException("no such transaction " + entry.transactionId);
}
} else {
transaction.registerRecordUpdate(this.table.name, key, value, writeResult);
}
} else {
applyUpdate(key, value);
}
break;
}
case LogEntryType.INSERT:
{
Bytes key = entry.key;
Bytes value = entry.value;
if (entry.transactionId > 0) {
Transaction transaction = tableSpaceManager.getTransaction(entry.transactionId);
if (transaction == null) {
/* Ignore missing transaction only if during recovery and ignore property is active */
if (recovery && ignoreMissingTransactionsOnRecovery) {
LOGGER.log(Level.WARNING, "Ignoring insert of {0} due to missing transaction {1}", new Object[] { entry.key, entry.transactionId });
} else {
throw new DataStorageManagerException("no such transaction " + entry.transactionId);
}
} else {
transaction.registerInsertOnTable(table.name, key, value, writeResult);
}
} else {
applyInsert(key, value, false);
}
break;
}
case LogEntryType.TRUNCATE_TABLE:
{
applyTruncate();
}
break;
default:
throw new IllegalArgumentException("unhandled entry type " + entry.type);
}
}
Aggregations