use of com.apple.foundationdb.record.RecordMetaData in project fdb-record-layer by FoundationDB.
the class FDBMetaDataStoreTest method nestedRecordDefinition.
/**
* Validate that a message type cannot be specified using "." syntax.
*/
@Test
public void nestedRecordDefinition() {
try (FDBRecordContext context = fdb.openContext()) {
openMetaDataStore(context);
RecordMetaData metaData = RecordMetaData.build(TestRecordsDoubleNestedProto.getDescriptor());
metaDataStore.saveRecordMetaData(metaData);
context.commit();
}
try (FDBRecordContext context = fdb.openContext()) {
openMetaDataStore(context);
MetaDataException e = assertThrows(MetaDataException.class, () -> renameRecordType("OuterRecord.MiddleRecord", "OuterRecord.MiddlingRecord"));
assertEquals("No record type found with name OuterRecord.MiddleRecord", e.getMessage());
}
}
use of com.apple.foundationdb.record.RecordMetaData in project fdb-record-layer by FoundationDB.
the class FDBRecordStoreTest method testUserVersionDeterminesMetaData.
@Test
public void testUserVersionDeterminesMetaData() {
final RecordMetaDataBuilder builder = RecordMetaData.newBuilder().setRecords(TestRecords1Proto.getDescriptor());
builder.setVersion(101);
final RecordMetaData metaData1 = builder.getRecordMetaData();
builder.setVersion(102);
final RecordMetaData metaData2 = builder.getRecordMetaData();
final SwitchingProvider oldProvider = new SwitchingProvider(101, metaData1, metaData1);
final SwitchingProvider newProvider = new SwitchingProvider(102, metaData1, metaData2);
try (FDBRecordContext context = openContext()) {
recordStore = FDBRecordStore.newBuilder().setContext(context).setKeySpacePath(path).setMetaDataProvider(oldProvider).setUserVersionChecker(oldProvider).create();
assertEquals(101, recordStore.getUserVersion());
assertEquals(metaData1, recordStore.getRecordMetaData());
assertEquals(metaData1.getVersion(), recordStore.getRecordStoreState().getStoreHeader().getMetaDataversion());
context.commit();
}
try (FDBRecordContext context = openContext()) {
recordStore = FDBRecordStore.newBuilder().setContext(context).setKeySpacePath(path).setMetaDataProvider(newProvider).setUserVersionChecker(newProvider).open();
assertEquals(101, recordStore.getUserVersion());
assertEquals(metaData1, recordStore.getRecordMetaData());
assertEquals(metaData1.getVersion(), recordStore.getRecordStoreState().getStoreHeader().getMetaDataversion());
context.commit();
}
final SwitchingProvider newProvider2 = new SwitchingProvider(102, metaData1, metaData2);
try (FDBRecordContext context = openContext()) {
FDBRecordStore.deleteStore(context, path);
recordStore = FDBRecordStore.newBuilder().setContext(context).setKeySpacePath(path).setMetaDataProvider(newProvider2).setUserVersionChecker(newProvider2).create();
assertEquals(102, recordStore.getUserVersion());
assertEquals(metaData2, recordStore.getRecordMetaData());
assertEquals(metaData2.getVersion(), recordStore.getRecordStoreState().getStoreHeader().getMetaDataversion());
context.commit();
}
}
use of com.apple.foundationdb.record.RecordMetaData in project fdb-record-layer by FoundationDB.
the class FDBRecordStoreTest method unionFieldUpdateCompatibility.
@Test
public void unionFieldUpdateCompatibility() throws Exception {
final TestRecords1Proto.MySimpleRecord record1 = TestRecords1Proto.MySimpleRecord.newBuilder().setRecNo(1066L).setNumValue2(42).build();
final TestRecords1Proto.MySimpleRecord record2 = TestRecords1Proto.MySimpleRecord.newBuilder().setRecNo(1415L).setStrValueIndexed("second_record").build();
final TestRecords1Proto.MySimpleRecord record3 = TestRecords1Proto.MySimpleRecord.newBuilder().setRecNo(800L).setNumValue2(14).build();
try (FDBRecordContext context = openContext()) {
openSimpleRecordStore(context);
RecordMetaData metaData = recordStore.getRecordMetaData();
assertSame(TestRecords1Proto.RecordTypeUnion.getDescriptor().findFieldByName("_MySimpleRecord"), metaData.getUnionFieldForRecordType(metaData.getRecordType("MySimpleRecord")));
// Save a record using the field using the old meta-data
recordStore.saveRecord(record1);
// Save a record using the new union descriptor but in the old location
context.ensureActive().set(recordStore.recordsSubspace().pack(Tuple.from(record2.getRecNo(), SplitHelper.UNSPLIT_RECORD)), TestRecordsDuplicateUnionFields.RecordTypeUnion.newBuilder().setMySimpleRecordOld(record2).build().toByteArray());
// Save a record using the new union descriptor in the new location
context.ensureActive().set(recordStore.recordsSubspace().pack(Tuple.from(record3.getRecNo(), SplitHelper.UNSPLIT_RECORD)), TestRecordsDuplicateUnionFields.RecordTypeUnion.newBuilder().setMySimpleRecordNew(record3).build().toByteArray());
assertEquals(record1, recordStore.loadRecord(Tuple.from(record1.getRecNo())).getRecord());
assertEquals(record2, recordStore.loadRecord(Tuple.from(record2.getRecNo())).getRecord());
RecordCoreException e = assertThrows(RecordCoreException.class, () -> recordStore.loadRecord(Tuple.from(record3.getRecNo())).getRecord());
assertNotNull(e.getCause());
assertThat(e.getCause(), instanceOf(RecordSerializationException.class));
assertThat(e.getCause().getMessage(), containsString("because there are unknown fields"));
commit(context);
}
try (FDBRecordContext context = openContext()) {
openSimpleRecordStore(context, metaDataBuilder -> metaDataBuilder.updateRecords(TestRecordsDuplicateUnionFields.getDescriptor()));
RecordMetaData metaData = recordStore.getRecordMetaData();
assertSame(TestRecordsDuplicateUnionFields.RecordTypeUnion.getDescriptor().findFieldByName("_MySimpleRecord_new"), metaData.getUnionFieldForRecordType(metaData.getRecordType("MySimpleRecord")));
// All three records should be readable even though written by the previous store
for (TestRecords1Proto.MySimpleRecord record : Arrays.asList(record1, record2, record3)) {
FDBStoredRecord<Message> storedRecord = recordStore.loadRecord(Tuple.from(record.getRecNo()));
assertNotNull(storedRecord);
assertSame(metaData.getRecordType("MySimpleRecord"), storedRecord.getRecordType());
assertEquals(record, storedRecord.getRecord());
}
commit(context);
}
}
use of com.apple.foundationdb.record.RecordMetaData in project fdb-record-layer by FoundationDB.
the class FDBMetaDataStoreTest method nestedRecordTypes.
@Test
public void nestedRecordTypes() {
int version;
try (FDBRecordContext context = fdb.openContext()) {
openMetaDataStore(context);
RecordMetaData metaData = RecordMetaData.build(TestRecords1Proto.getDescriptor());
version = metaData.getVersion();
metaDataStore.saveRecordMetaData(metaData);
context.commit();
assertNotNull(metaDataStore.getRecordMetaData().getRecordType("MySimpleRecord"));
}
// Adding an existing record type should fail
try (FDBRecordContext context = fdb.openContext()) {
openMetaDataStore(context);
assertNotNull(metaDataStore.getRecordMetaData().getRecordType("MySimpleRecord"));
assertEquals(version, metaDataStore.getRecordMetaData().getVersion());
DescriptorProtos.MessageOptions.Builder nestedMessageOptions = DescriptorProtos.MessageOptions.newBuilder().setExtension(RecordMetaDataOptionsProto.record, RecordMetaDataOptionsProto.RecordTypeOptions.newBuilder().setUsage(RecordMetaDataOptionsProto.RecordTypeOptions.Usage.NESTED).build());
DescriptorProtos.DescriptorProto newRecordType = DescriptorProtos.DescriptorProto.newBuilder().setName("MySimpleRecord").addField(DescriptorProtos.FieldDescriptorProto.newBuilder().setLabel(DescriptorProtos.FieldDescriptorProto.Label.LABEL_OPTIONAL).setType(DescriptorProtos.FieldDescriptorProto.Type.TYPE_INT32).setName("rec_no").setNumber(1)).setOptions(nestedMessageOptions).build();
MetaDataException e = assertThrows(MetaDataException.class, () -> addNestedRecordType(newRecordType));
assertEquals(e.getMessage(), "Record type MySimpleRecord already exists");
assertNotNull(metaDataStore.getRecordMetaData().getRecordType("MySimpleRecord"));
// version should not change
assertEquals(version, metaDataStore.getRecordMetaData().getVersion());
context.commit();
}
// Add a nested record type.
try (FDBRecordContext context = fdb.openContext()) {
openMetaDataStore(context);
assertNotNull(metaDataStore.getRecordMetaData().getRecordType("MySimpleRecord"));
assertEquals(version, metaDataStore.getRecordMetaData().getVersion());
DescriptorProtos.MessageOptions.Builder nestedMessageOptions = DescriptorProtos.MessageOptions.newBuilder().setExtension(RecordMetaDataOptionsProto.record, RecordMetaDataOptionsProto.RecordTypeOptions.newBuilder().setUsage(RecordMetaDataOptionsProto.RecordTypeOptions.Usage.NESTED).build());
DescriptorProtos.DescriptorProto newRecordType = DescriptorProtos.DescriptorProto.newBuilder().setName("MyNewNestedRecord").addField(DescriptorProtos.FieldDescriptorProto.newBuilder().setLabel(DescriptorProtos.FieldDescriptorProto.Label.LABEL_OPTIONAL).setType(DescriptorProtos.FieldDescriptorProto.Type.TYPE_INT32).setName("rec_no").setNumber(1)).setOptions(nestedMessageOptions).build();
// Use addRecordType should fail
MetaDataException e = assertThrows(MetaDataException.class, () -> addRecordType(newRecordType, Key.Expressions.field("rec_no")));
assertEquals(e.getMessage(), "Use addNestedRecordType for adding NESTED record types");
// Use addNestedRecordType should succeed
addNestedRecordType(newRecordType);
assertNotNull(metaDataStore.getRecordMetaData().getRecordType("MySimpleRecord"));
e = assertThrows(MetaDataException.class, () -> metaDataStore.getRecordMetaData().getRecordType("MyNewNestedRecord"));
assertEquals(e.getMessage(), "Unknown record type MyNewNestedRecord");
assertNotNull(metaDataStore.getRecordMetaData().getRecordsDescriptor().findMessageTypeByName("MyNewNestedRecord"));
assertNull(metaDataStore.getRecordMetaData().getRecordsDescriptor().findMessageTypeByName(RecordMetaDataBuilder.DEFAULT_UNION_NAME).findFieldByName("_MyNewNestedRecord"));
assertEquals(version + 1, metaDataStore.getRecordMetaData().getVersion());
// addNestedRecordType is not idempotent!
e = assertThrows(MetaDataException.class, () -> addNestedRecordType(newRecordType));
assertEquals(e.getMessage(), "Record type MyNewNestedRecord already exists");
assertEquals(version + 1, metaDataStore.getRecordMetaData().getVersion());
context.commit();
}
// Add nested type as a field
try (FDBRecordContext context = fdb.openContext()) {
openMetaDataStore(context);
assertNotNull(metaDataStore.getRecordMetaData().getRecordType("MySimpleRecord"));
assertNotNull(metaDataStore.getRecordMetaData().getRecordsDescriptor().findMessageTypeByName("MyNewNestedRecord"));
assertEquals(version + 1, metaDataStore.getRecordMetaData().getVersion());
DescriptorProtos.FieldDescriptorProto field = DescriptorProtos.FieldDescriptorProto.newBuilder().setName("newField").setType(DescriptorProtos.FieldDescriptorProto.Type.TYPE_MESSAGE).setTypeName("MyNewNestedRecord").setLabel(DescriptorProtos.FieldDescriptorProto.Label.LABEL_OPTIONAL).setNumber(10).build();
addField("MySimpleRecord", field);
assertNotNull(metaDataStore.getRecordMetaData().getRecordType("MySimpleRecord"));
assertNotNull(metaDataStore.getRecordMetaData().getRecordsDescriptor().findMessageTypeByName("MySimpleRecord").findFieldByName("newField"));
assertEquals(metaDataStore.getRecordMetaData().getRecordsDescriptor().findMessageTypeByName("MyNewNestedRecord"), metaDataStore.getRecordMetaData().getRecordsDescriptor().findMessageTypeByName("MySimpleRecord").findFieldByName("newField").getMessageType());
assertEquals(version + 2, metaDataStore.getRecordMetaData().getVersion());
context.commit();
}
// Deprecate a nested record type.
try (FDBRecordContext context = fdb.openContext()) {
openMetaDataStore(context);
assertEquals(version + 2, metaDataStore.getRecordMetaData().getVersion());
assertNotNull(metaDataStore.getRecordMetaData().getRecordType("MySimpleRecord"));
assertNotNull(metaDataStore.getRecordMetaData().getRecordsDescriptor().findMessageTypeByName("MyNewNestedRecord"));
deprecateField("MySimpleRecord", "newField");
assertNotNull(metaDataStore.getRecordMetaData().getRecordType("MySimpleRecord"));
assertTrue(metaDataStore.getRecordMetaData().getRecordsDescriptor().findMessageTypeByName("MySimpleRecord").findFieldByName("newField").getOptions().getDeprecated());
assertEquals(version + 3, metaDataStore.getRecordMetaData().getVersion());
context.commit();
}
}
use of com.apple.foundationdb.record.RecordMetaData in project fdb-record-layer by FoundationDB.
the class FDBMetaDataStoreTest method dontRenameRecordTypeWhenClashingWithImported.
/**
* Validate that if a {@code NESTED} record with the same name as an imported record type has its
* name changed, then the record type in the record type list does not change.
*/
@Test
public void dontRenameRecordTypeWhenClashingWithImported() {
try (FDBRecordContext context = fdb.openContext()) {
openMetaDataStore(context);
RecordMetaData metaData = RecordMetaData.build(TestRecordsImportedAndNewProto.getDescriptor());
metaDataStore.saveRecordMetaData(metaData);
// rename the nested record
renameRecordType("MySimpleRecord", "MyLocalSimpleRecord");
assertEquals(ImmutableSet.of("MySimpleRecord", "MyOtherRecord"), metaData.getRecordTypes().keySet());
context.commit();
}
try (FDBRecordContext context = fdb.openContext()) {
openMetaDataStore(context);
MetaDataException e = assertThrows(MetaDataException.class, () -> renameRecordType("MyOtherRecord", "MySimpleRecord"));
assertEquals("Cannot rename record type to MySimpleRecord as an imported record type of that name already exists", e.getMessage());
}
}
Aggregations