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());
}
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);
}
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);
}
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);
}
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);
}
Aggregations