Search in sources :

Example 66 with RecordMetaData

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());
    }
}
Also used : RecordMetaData(com.apple.foundationdb.record.RecordMetaData) MetaDataException(com.apple.foundationdb.record.metadata.MetaDataException) Test(org.junit.jupiter.api.Test) MetaDataProtoTest(com.apple.foundationdb.record.metadata.MetaDataProtoTest) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Example 67 with RecordMetaData

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();
    }
}
Also used : RecordMetaData(com.apple.foundationdb.record.RecordMetaData) RecordMetaDataBuilder(com.apple.foundationdb.record.RecordMetaDataBuilder) Test(org.junit.jupiter.api.Test) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Example 68 with RecordMetaData

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);
    }
}
Also used : TestRecords1Proto(com.apple.foundationdb.record.TestRecords1Proto) RecordMetaData(com.apple.foundationdb.record.RecordMetaData) RecordCoreException(com.apple.foundationdb.record.RecordCoreException) DynamicMessage(com.google.protobuf.DynamicMessage) Message(com.google.protobuf.Message) RecordSerializationException(com.apple.foundationdb.record.provider.common.RecordSerializationException) Test(org.junit.jupiter.api.Test) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Example 69 with RecordMetaData

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();
    }
}
Also used : RecordMetaData(com.apple.foundationdb.record.RecordMetaData) DescriptorProtos(com.google.protobuf.DescriptorProtos) MetaDataException(com.apple.foundationdb.record.metadata.MetaDataException) Test(org.junit.jupiter.api.Test) MetaDataProtoTest(com.apple.foundationdb.record.metadata.MetaDataProtoTest) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Example 70 with RecordMetaData

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());
    }
}
Also used : RecordMetaData(com.apple.foundationdb.record.RecordMetaData) MetaDataException(com.apple.foundationdb.record.metadata.MetaDataException) Test(org.junit.jupiter.api.Test) MetaDataProtoTest(com.apple.foundationdb.record.metadata.MetaDataProtoTest) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Aggregations

RecordMetaData (com.apple.foundationdb.record.RecordMetaData)168 Test (org.junit.jupiter.api.Test)130 RecordMetaDataBuilder (com.apple.foundationdb.record.RecordMetaDataBuilder)81 ParameterizedTest (org.junit.jupiter.params.ParameterizedTest)66 Nonnull (javax.annotation.Nonnull)47 Descriptors (com.google.protobuf.Descriptors)44 RecordMetaDataProto (com.apple.foundationdb.record.RecordMetaDataProto)39 MetaDataException (com.apple.foundationdb.record.metadata.MetaDataException)39 MetaDataProtoTest (com.apple.foundationdb.record.metadata.MetaDataProtoTest)38 Tuple (com.apple.foundationdb.tuple.Tuple)36 List (java.util.List)33 ArrayList (java.util.ArrayList)31 TestRecords1Proto (com.apple.foundationdb.record.TestRecords1Proto)30 Index (com.apple.foundationdb.record.metadata.Index)30 DescriptorProtos (com.google.protobuf.DescriptorProtos)30 Collectors (java.util.stream.Collectors)30 RecordCoreException (com.apple.foundationdb.record.RecordCoreException)27 ByteString (com.google.protobuf.ByteString)27 Assertions.assertNotNull (org.junit.jupiter.api.Assertions.assertNotNull)27 RecordMetaDataOptionsProto (com.apple.foundationdb.record.RecordMetaDataOptionsProto)26