Search in sources :

Example 6 with RecordMetaDataBuilder

use of com.apple.foundationdb.record.RecordMetaDataBuilder in project fdb-record-layer by FoundationDB.

the class MetaDataEvolutionValidatorTest method indexRecordTypeRemoved.

@Test
public void indexRecordTypeRemoved() {
    final String indexName = "simple&other$num_value_2";
    RecordMetaDataBuilder metaDataBuilder = RecordMetaData.newBuilder().setRecords(TestRecords1Proto.getDescriptor());
    metaDataBuilder.addMultiTypeIndex(Arrays.asList(metaDataBuilder.getRecordType("MySimpleRecord"), metaDataBuilder.getRecordType("MyOtherRecord")), new Index(indexName, "num_value_2"));
    RecordMetaData metaData1 = metaDataBuilder.getRecordMetaData();
    validateIndexMutation("new index removes record type", metaData1, indexName, indexProto -> indexProto.toBuilder().clearRecordType().addRecordType("MySimpleRecord").build());
}
Also used : RecordMetaData(com.apple.foundationdb.record.RecordMetaData) RecordMetaDataBuilder(com.apple.foundationdb.record.RecordMetaDataBuilder) ByteString(com.google.protobuf.ByteString) Matchers.containsString(org.hamcrest.Matchers.containsString) Test(org.junit.jupiter.api.Test)

Example 7 with RecordMetaDataBuilder

use of com.apple.foundationdb.record.RecordMetaDataBuilder in project fdb-record-layer by FoundationDB.

the class MetaDataEvolutionValidatorTest method textOptionsChanged.

@Test
public void textOptionsChanged() {
    final String indexName = "MySimpleRecord$text(str_value_indexed)";
    RecordMetaDataBuilder metaDataBuilder = RecordMetaData.newBuilder().setRecords(TestRecords1Proto.getDescriptor());
    metaDataBuilder.addIndex("MySimpleRecord", new Index(indexName, Key.Expressions.field("str_value_indexed"), IndexTypes.TEXT));
    RecordMetaData metaData1 = metaDataBuilder.getRecordMetaData();
    validateIndexMutation("text tokenizer changed", metaData1, indexName, indexProto -> changeOption(indexProto, IndexOptions.TEXT_TOKENIZER_NAME_OPTION, AllSuffixesTextTokenizer.NAME));
    // Setting the default explicitly is fine
    RecordMetaData metaData2 = replaceIndex(metaData1, indexName, indexProto -> changeOption(indexProto, IndexOptions.TEXT_TOKENIZER_NAME_OPTION, DefaultTextTokenizer.NAME));
    validator.validate(metaData1, metaData2);
    RecordMetaData metaData3 = replaceIndex(metaData2, indexName, this::clearOptions);
    validator.validate(metaData2, metaData3);
    // Increasing the tokenizer version is fine, but decreasing it is not
    RecordMetaData metaData4 = replaceIndex(metaData3, indexName, indexProto -> changeOption(indexProto, IndexOptions.TEXT_TOKENIZER_NAME_OPTION, PrefixTextTokenizer.NAME));
    RecordMetaData metaData5 = replaceIndex(metaData4, indexName, indexProto -> changeOption(indexProto, IndexOptions.TEXT_TOKENIZER_VERSION_OPTION, "" + TextTokenizer.GLOBAL_MIN_VERSION));
    validator.validate(metaData4, metaData5);
    RecordMetaData metaData6 = replaceIndex(metaData5, indexName, indexProto -> changeOption(indexProto, IndexOptions.TEXT_TOKENIZER_VERSION_OPTION, "" + (TextTokenizer.GLOBAL_MIN_VERSION + 1)));
    validator.validate(metaData5, metaData6);
    validateIndexMutation("text tokenizer version downgraded", metaData6, indexName, indexProto -> changeOption(indexProto, IndexOptions.TEXT_TOKENIZER_VERSION_OPTION, "" + TextTokenizer.GLOBAL_MIN_VERSION));
    // Changing whether aggressive conflict ranges are allowed is safe
    RecordMetaData metaData7 = replaceIndex(metaData6, indexName, indexProto -> changeOption(indexProto, IndexOptions.TEXT_ADD_AGGRESSIVE_CONFLICT_RANGES_OPTION, "true"));
    validator.validate(metaData6, metaData7);
    RecordMetaData metaData8 = replaceIndex(metaData7, indexName, indexProto -> changeOption(indexProto, IndexOptions.TEXT_ADD_AGGRESSIVE_CONFLICT_RANGES_OPTION, "false"));
    validator.validate(metaData7, metaData8);
    // Changing whether position lists are omitted is safe
    RecordMetaData metaData9 = replaceIndex(metaData8, indexName, indexProto -> changeOption(indexProto, IndexOptions.TEXT_OMIT_POSITIONS_OPTION, "true"));
    validator.validate(metaData8, metaData9);
    RecordMetaData metaData10 = replaceIndex(metaData9, indexName, indexProto -> changeOption(indexProto, IndexOptions.TEXT_OMIT_POSITIONS_OPTION, "false"));
    validator.validate(metaData9, metaData10);
}
Also used : RecordMetaData(com.apple.foundationdb.record.RecordMetaData) RecordMetaDataBuilder(com.apple.foundationdb.record.RecordMetaDataBuilder) ByteString(com.google.protobuf.ByteString) Matchers.containsString(org.hamcrest.Matchers.containsString) Test(org.junit.jupiter.api.Test)

Example 8 with RecordMetaDataBuilder

use of com.apple.foundationdb.record.RecordMetaDataBuilder in project fdb-record-layer by FoundationDB.

the class MetaDataEvolutionValidatorTest method newIndexFromThePast.

@Test
public void newIndexFromThePast() {
    RecordMetaData metaData1 = RecordMetaData.build(TestRecords1Proto.getDescriptor());
    Index newIndex = new Index("newIndex", Key.Expressions.field("num_value_2"));
    newIndex.setAddedVersion(metaData1.getVersion() - 1);
    newIndex.setLastModifiedVersion(metaData1.getVersion() - 1);
    RecordMetaDataBuilder metaData2Builder = RecordMetaData.newBuilder().setRecords(TestRecords1Proto.getDescriptor());
    metaData2Builder.addIndex(metaData2Builder.getRecordType("MySimpleRecord"), newIndex);
    metaData2Builder.setVersion(metaData1.getVersion() + 1);
    RecordMetaData metaData2 = metaData2Builder.getRecordMetaData();
    assertInvalid("new index has version that is not newer than the old meta-data version", metaData1, metaData2);
    RecordMetaDataBuilder metaData3Builder = RecordMetaData.newBuilder().setRecords(TestRecords1Proto.getDescriptor());
    newIndex.setAddedVersion(metaData1.getVersion());
    metaData3Builder.addIndex(metaData2Builder.getRecordType("MySimpleRecord"), newIndex);
    metaData2Builder.setVersion(metaData1.getVersion() + 1);
    RecordMetaData metaData3 = metaData2.getRecordMetaData();
    assertInvalid("new index has version that is not newer than the old meta-data version", metaData1, metaData3);
}
Also used : RecordMetaData(com.apple.foundationdb.record.RecordMetaData) RecordMetaDataBuilder(com.apple.foundationdb.record.RecordMetaDataBuilder) Test(org.junit.jupiter.api.Test)

Example 9 with RecordMetaDataBuilder

use of com.apple.foundationdb.record.RecordMetaDataBuilder in project fdb-record-layer by FoundationDB.

the class MetaDataEvolutionValidatorTest method swapIsomorphicRecordTypesWithIndexes.

@Test
public void swapIsomorphicRecordTypesWithIndexes() {
    FileDescriptor updatedFile = mutateFile(fileBuilder -> {
        DescriptorProtos.DescriptorProto newMessageType = fileBuilder.getMessageTypeList().stream().filter(messageType -> messageType.getName().equals("MyOtherRecord")).findFirst().get().toBuilder().setName("MyOtherOtherRecord").build();
        fileBuilder.addMessageType(newMessageType);
        fileBuilder.getMessageTypeBuilderList().forEach(messageType -> {
            if (messageType.getName().equals(RecordMetaDataBuilder.DEFAULT_UNION_NAME)) {
                messageType.addField(DescriptorProtos.FieldDescriptorProto.newBuilder().setLabel(DescriptorProtos.FieldDescriptorProto.Label.LABEL_OPTIONAL).setType(DescriptorProtos.FieldDescriptorProto.Type.TYPE_MESSAGE).setTypeName("MyOtherOtherRecord").setName("_MyOtherOtherRecord").setNumber(messageType.getFieldList().stream().mapToInt(DescriptorProtos.FieldDescriptorProto::getNumber).max().orElse(0) + 1));
            }
        });
    });
    RecordMetaDataBuilder metaDataBuilder = RecordMetaData.newBuilder().setRecords(updatedFile);
    metaDataBuilder.addIndex("MyOtherRecord", "num_value_3_indexed");
    metaDataBuilder.addIndex("MyOtherOtherRecord", "num_value_3_indexed");
    RecordMetaData metaData1 = metaDataBuilder.getRecordMetaData();
    assertThat(metaData1.getRecordTypes().keySet(), containsInAnyOrder("MySimpleRecord", "MyOtherRecord", "MyOtherOtherRecord"));
    assertEquals(Collections.singletonList(metaData1.getRecordType("MyOtherRecord")), metaData1.recordTypesForIndex(metaData1.getIndex("MyOtherRecord$num_value_3_indexed")));
    assertEquals(Collections.singletonList(metaData1.getRecordType("MyOtherOtherRecord")), metaData1.recordTypesForIndex(metaData1.getIndex("MyOtherOtherRecord$num_value_3_indexed")));
    // Swap the two record types in the union descriptor.
    FileDescriptor secondFile = mutateFile(updatedFile, fileBuilder -> fileBuilder.getMessageTypeBuilderList().forEach(messageType -> {
        if (messageType.getName().equals(RecordMetaDataBuilder.DEFAULT_UNION_NAME)) {
            messageType.getFieldBuilderList().forEach(field -> {
                if (field.getName().equals("_MyOtherRecord")) {
                    field.setTypeName("MyOtherOtherRecord");
                }
                if (field.getName().equals("_MyOtherOtherRecord")) {
                    field.setTypeName("MyOtherRecord");
                }
            });
        }
    }));
    // Doesn't update the record types for the index which effectively swaps the definitions
    RecordMetaData metaData2 = replaceRecordsDescriptor(metaData1, secondFile);
    assertThat(metaData2.getRecordTypes().keySet(), containsInAnyOrder("MySimpleRecord", "MyOtherRecord", "MyOtherOtherRecord"));
    assertEquals(Collections.singletonList(metaData2.getRecordType("MyOtherRecord")), metaData2.recordTypesForIndex(metaData2.getIndex("MyOtherRecord$num_value_3_indexed")));
    assertEquals(Collections.singletonList(metaData2.getRecordType("MyOtherOtherRecord")), metaData2.recordTypesForIndex(metaData2.getIndex("MyOtherOtherRecord$num_value_3_indexed")));
    assertInvalid("new index removes record type", metaData1, metaData2);
    // Replace the record types in the indexes with the new names
    RecordMetaData metaData3 = replaceRecordsDescriptor(metaData2, secondFile, metaDataProtoBuilder -> metaDataProtoBuilder.getIndexesBuilderList().forEach(index -> {
        List<String> recordTypes = new ArrayList<>(index.getRecordTypeList());
        recordTypes.replaceAll(recordType -> {
            if (recordType.equals("MyOtherRecord")) {
                return "MyOtherOtherRecord";
            } else if (recordType.equals("MyOtherOtherRecord")) {
                return "MyOtherRecord";
            } else {
                return recordType;
            }
        });
        index.clearRecordType();
        index.addAllRecordType(recordTypes);
    }));
    assertEquals(Collections.singletonList(metaData3.getRecordType("MyOtherOtherRecord")), metaData3.recordTypesForIndex(metaData3.getIndex("MyOtherRecord$num_value_3_indexed")));
    assertEquals(Collections.singletonList(metaData3.getRecordType("MyOtherRecord")), metaData3.recordTypesForIndex(metaData3.getIndex("MyOtherOtherRecord$num_value_3_indexed")));
    validator.validate(metaData1, metaData3);
    // Verify that using "update records" updates the index definitions
    RecordMetaDataBuilder metaDataBuilder4 = RecordMetaData.newBuilder().setRecords(metaData1.toProto());
    metaDataBuilder4.updateRecords(secondFile);
    RecordMetaData metaData4 = metaDataBuilder4.getRecordMetaData();
    assertEquals(Collections.singletonList(metaData4.getRecordType("MyOtherOtherRecord")), metaData4.recordTypesForIndex(metaData4.getIndex("MyOtherRecord$num_value_3_indexed")));
    assertEquals(Collections.singletonList(metaData4.getRecordType("MyOtherRecord")), metaData4.recordTypesForIndex(metaData4.getIndex("MyOtherOtherRecord$num_value_3_indexed")));
    validator.validate(metaData1, metaData4);
}
Also used : DescriptorProtos(com.google.protobuf.DescriptorProtos) Assertions.assertThrows(org.junit.jupiter.api.Assertions.assertThrows) RecordMetaData(com.apple.foundationdb.record.RecordMetaData) Assertions.assertNotNull(org.junit.jupiter.api.Assertions.assertNotNull) Arrays(java.util.Arrays) Descriptor(com.google.protobuf.Descriptors.Descriptor) Descriptors(com.google.protobuf.Descriptors) Assertions.assertNotEquals(org.junit.jupiter.api.Assertions.assertNotEquals) Assertions.assertNull(org.junit.jupiter.api.Assertions.assertNull) PrefixTextTokenizer(com.apple.foundationdb.record.provider.common.text.PrefixTextTokenizer) UnaryOperator(java.util.function.UnaryOperator) TestSplitNestedTypesProto(com.apple.foundationdb.record.evolution.TestSplitNestedTypesProto) TestNewRecordTypeProto(com.apple.foundationdb.record.evolution.TestNewRecordTypeProto) TestSelfReferenceUnspooledProto(com.apple.foundationdb.record.evolution.TestSelfReferenceUnspooledProto) ArrayList(java.util.ArrayList) Tuple(com.apple.foundationdb.tuple.Tuple) RecordCoreException(com.apple.foundationdb.record.RecordCoreException) RecordMetaDataProto(com.apple.foundationdb.record.RecordMetaDataProto) RecordMetaDataOptionsProto(com.apple.foundationdb.record.RecordMetaDataOptionsProto) DefaultTextTokenizer(com.apple.foundationdb.record.provider.common.text.DefaultTextTokenizer) MatcherAssert.assertThat(org.hamcrest.MatcherAssert.assertThat) Assertions.assertEquals(org.junit.jupiter.api.Assertions.assertEquals) FileDescriptor(com.google.protobuf.Descriptors.FileDescriptor) Nonnull(javax.annotation.Nonnull) Nullable(javax.annotation.Nullable) InvalidProtocolBufferException(com.google.protobuf.InvalidProtocolBufferException) TestSelfReferenceProto(com.apple.foundationdb.record.evolution.TestSelfReferenceProto) TestRecords1Proto(com.apple.foundationdb.record.TestRecords1Proto) RecordMetaDataBuilder(com.apple.foundationdb.record.RecordMetaDataBuilder) TestUnmergedNestedTypesProto(com.apple.foundationdb.record.evolution.TestUnmergedNestedTypesProto) FieldDescriptor(com.google.protobuf.Descriptors.FieldDescriptor) Collectors(java.util.stream.Collectors) ByteString(com.google.protobuf.ByteString) Test(org.junit.jupiter.api.Test) Consumer(java.util.function.Consumer) TextTokenizer(com.apple.foundationdb.record.provider.common.text.TextTokenizer) List(java.util.List) Matchers.containsInAnyOrder(org.hamcrest.Matchers.containsInAnyOrder) TestHeaderAsGroupProto(com.apple.foundationdb.record.evolution.TestHeaderAsGroupProto) RankedSet(com.apple.foundationdb.async.RankedSet) TestRecordsEnumProto(com.apple.foundationdb.record.TestRecordsEnumProto) TestRecordsWithHeaderProto(com.apple.foundationdb.record.TestRecordsWithHeaderProto) Matchers.is(org.hamcrest.Matchers.is) TestMergedNestedTypesProto(com.apple.foundationdb.record.evolution.TestMergedNestedTypesProto) Collections(java.util.Collections) Matchers.containsString(org.hamcrest.Matchers.containsString) AllSuffixesTextTokenizer(com.apple.foundationdb.record.provider.common.text.AllSuffixesTextTokenizer) RecordMetaData(com.apple.foundationdb.record.RecordMetaData) RecordMetaDataBuilder(com.apple.foundationdb.record.RecordMetaDataBuilder) DescriptorProtos(com.google.protobuf.DescriptorProtos) ArrayList(java.util.ArrayList) List(java.util.List) FileDescriptor(com.google.protobuf.Descriptors.FileDescriptor) Test(org.junit.jupiter.api.Test)

Example 10 with RecordMetaDataBuilder

use of com.apple.foundationdb.record.RecordMetaDataBuilder in project fdb-record-layer by FoundationDB.

the class MetaDataEvolutionValidatorTest method removeIndexAndChangeName.

@Test
public void removeIndexAndChangeName() {
    RecordMetaDataBuilder metaDataBuilder = RecordMetaData.newBuilder().setRecords(TestRecords1Proto.getDescriptor());
    // FIXME: Calling getRecordMetaData appears to pollute the FormerIndexes list
    RecordMetaData metaData1 = RecordMetaData.build(metaDataBuilder.getRecordMetaData().toProto());
    metaDataBuilder.removeIndex("MySimpleRecord$str_value_indexed");
    RecordMetaDataProto.MetaData metaData2Proto = metaDataBuilder.getRecordMetaData().toProto();
    RecordMetaData metaData2 = RecordMetaData.build(metaData2Proto.toBuilder().setVersion(metaData2Proto.getVersion() + 1).removeFormerIndexes(0).addFormerIndexes(metaData2Proto.getFormerIndexes(0).toBuilder().setFormerName("some_other_name")).build());
    assertInvalid("former index has different name", metaData1, metaData2);
    // Dropping the name is fine if and only if the corresponding option is set
    RecordMetaData metaData3 = RecordMetaData.newBuilder().setRecords(metaData2Proto.toBuilder().setVersion(metaData2Proto.getVersion() + 1).removeFormerIndexes(0).addFormerIndexes(metaData2Proto.getFormerIndexes(0).toBuilder().clearFormerName()).build()).getRecordMetaData();
    assertInvalid("former index has different name", metaData1, metaData3);
    MetaDataEvolutionValidator laxerValidator = MetaDataEvolutionValidator.newBuilder().setAllowMissingFormerIndexNames(true).build();
    laxerValidator.validate(metaData1, metaData3);
}
Also used : RecordMetaData(com.apple.foundationdb.record.RecordMetaData) RecordMetaDataBuilder(com.apple.foundationdb.record.RecordMetaDataBuilder) RecordMetaDataProto(com.apple.foundationdb.record.RecordMetaDataProto) Test(org.junit.jupiter.api.Test)

Aggregations

RecordMetaDataBuilder (com.apple.foundationdb.record.RecordMetaDataBuilder)150 Test (org.junit.jupiter.api.Test)91 RecordMetaData (com.apple.foundationdb.record.RecordMetaData)69 ParameterizedTest (org.junit.jupiter.params.ParameterizedTest)43 Nonnull (javax.annotation.Nonnull)22 Index (com.apple.foundationdb.record.metadata.Index)21 Descriptors (com.google.protobuf.Descriptors)15 TestRecords1Proto (com.apple.foundationdb.record.TestRecords1Proto)14 KeyExpression (com.apple.foundationdb.record.metadata.expressions.KeyExpression)14 RecordMetaDataProto (com.apple.foundationdb.record.RecordMetaDataProto)13 ByteString (com.google.protobuf.ByteString)13 Tuple (com.apple.foundationdb.tuple.Tuple)12 Collections (java.util.Collections)12 MatcherAssert.assertThat (org.hamcrest.MatcherAssert.assertThat)11 Assertions.assertEquals (org.junit.jupiter.api.Assertions.assertEquals)11 Assertions.assertNotNull (org.junit.jupiter.api.Assertions.assertNotNull)11 Assertions.assertNull (org.junit.jupiter.api.Assertions.assertNull)11 Assertions.assertThrows (org.junit.jupiter.api.Assertions.assertThrows)11 RecordCoreException (com.apple.foundationdb.record.RecordCoreException)10 BooleanSource (com.apple.test.BooleanSource)10