@API(value=MAINTAINED) public class RecordMetaDataBuilder extends Object implements RecordMetaDataProvider
RecordMetaData
.
Meta-data can be built in two ways.
From compiled .proto
Simple single field indexes and single field primary keys can be specified in the Protobuf source file using option extensions.
Additional indexes or more complicated primary keys need to be specified with code using this builder.
The setRecords(Descriptors.FileDescriptor, boolean)
method loads the meta-data information from the Protobuf source file. Indexes and other
properties such as version are not accessible before calling setRecords
.
From a RecordMetaDataProto.MetaData
Protobuf message
The Protobuf form can store the complete meta-data. The setRecords(RecordMetaDataProto.MetaData, boolean)
method loads
the Protobuf message. Similar to loading the meta-data directly from a Protobuf file descriptor, indexes and other
properties are not accessible before calling setRecords
.
The Protobuf message may contain all of the dependencies required for resolving the record types and indexes. If some
of the dependencies are missing (e.g., when a list of excluded dependencies is passed to RecordMetaData.toProto()
), before calling
setRecords
, callers must first add the missing dependencies using
addDependency(Descriptors.FileDescriptor)
or addDependencies(Descriptors.FileDescriptor[])
.
The addDependency
or addDependencies
methods can also be used to override the embedded dependencies.
Modifier and Type | Class and Description |
---|---|
static class |
RecordMetaDataBuilder.MetaDataProtoDeserializationException
Exception thrown when meta-data cannot be loaded from serialized form.
|
Modifier and Type | Field and Description |
---|---|
static String |
DEFAULT_UNION_NAME |
Constructor and Description |
---|
RecordMetaDataBuilder(Descriptors.FileDescriptor fileDescriptor)
Deprecated.
use
RecordMetaData.newBuilder() instead |
RecordMetaDataBuilder(Descriptors.FileDescriptor fileDescriptor,
boolean processExtensionOptions)
Deprecated.
use
RecordMetaData.newBuilder() instead |
RecordMetaDataBuilder(RecordMetaDataProto.MetaData metaDataProto)
Deprecated.
use
RecordMetaData.newBuilder() instead |
RecordMetaDataBuilder(RecordMetaDataProto.MetaData metaDataProto,
boolean processExtensionOptions)
Deprecated.
use
RecordMetaData.newBuilder() instead |
RecordMetaDataBuilder(RecordMetaDataProto.MetaData metaDataProto,
Descriptors.FileDescriptor[] dependencies)
Deprecated.
use
RecordMetaData.newBuilder() instead |
RecordMetaDataBuilder(RecordMetaDataProto.MetaData metaDataProto,
Descriptors.FileDescriptor[] dependencies,
boolean processExtensionOptions)
Deprecated.
use
RecordMetaData.newBuilder() instead |
Modifier and Type | Method and Description |
---|---|
RecordMetaDataBuilder |
addDependencies(Descriptors.FileDescriptor[] fileDescriptors)
Adds dependencies to be used for loading the
RecordMetaData from a meta-data proto. |
RecordMetaDataBuilder |
addDependency(Descriptors.FileDescriptor fileDescriptor)
Adds a dependency to the list of dependencies.
|
void |
addFormerIndex(FormerIndex formerIndex) |
void |
addIndex(RecordTypeIndexesBuilder recordType,
Index index)
Adds a new index.
|
void |
addIndex(String recordType,
Index index)
Adds a new index.
|
void |
addIndex(String recordType,
String fieldName)
Adds a new index on a single field.
|
void |
addIndex(String recordType,
String indexName,
KeyExpression indexExpression)
Adds a new index.
|
void |
addIndex(String recordType,
String indexName,
String fieldName)
Adds a new index.
|
JoinedRecordTypeBuilder |
addJoinedRecordType(String name)
Add a new joined record type.
|
void |
addMultiTypeIndex(List<? extends RecordTypeIndexesBuilder> recordTypes,
Index index)
Adds a new index that contains multiple record types.
|
void |
addUniversalIndex(Index index)
Adds a new index on all record types.
|
RecordMetaData |
build()
Build and validate meta-data.
|
RecordMetaData |
build(boolean validate)
Build and validate meta-data with specific index registry.
|
static int[] |
buildPrimaryKeyComponentPositions(KeyExpression indexKey,
KeyExpression primaryKey) |
RecordMetaDataBuilder |
enableCounterBasedSubspaceKeys()
Enable counter-based subspace keys assignment.
|
MetaDataEvolutionValidator |
getEvolutionValidator()
Get the validator used to compare the local file descriptor to the descriptor included
in the meta-data proto.
|
Index |
getIndex(String indexName) |
RecordTypeIndexesBuilder |
getIndexableRecordType(String name)
Get a record type or synthetic record type by name for use with
addIndex(com.apple.foundationdb.record.metadata.RecordTypeIndexesBuilder, com.apple.foundationdb.record.metadata.Index) . |
IndexMaintainerRegistry |
getIndexMaintainerRegistry()
Get the index registry used for validation.
|
RecordTypeBuilder |
getOnlyRecordType()
If there is only one record type, get it.
|
KeyExpression |
getRecordCountKey()
Deprecated.
use
COUNT type indexes instead |
RecordMetaData |
getRecordMetaData()
Provide an instance of
RecordMetaData . |
RecordTypeBuilder |
getRecordType(String name) |
long |
getSubspaceKeyCounter()
Get the current value of the index subspace key counter.
|
SyntheticRecordTypeBuilder<?> |
getSyntheticRecordType(String name) |
Descriptors.Descriptor |
getUnionDescriptor() |
Descriptors.FieldDescriptor |
getUnionFieldForRecordType(RecordType recordType) |
int |
getVersion() |
boolean |
isSplitLongRecords() |
boolean |
isStoreRecordVersions() |
void |
removeIndex(String name) |
RecordMetaDataBuilder |
setEvolutionValidator(MetaDataEvolutionValidator evolutionValidator)
Set the validator used to compare the local file descriptor to the descriptor included
in the meta-data proto.
|
void |
setIndexMaintainerRegistry(IndexMaintainerRegistry indexMaintainerRegistry)
Set the index registry used for validation.
|
RecordMetaDataBuilder |
setLocalFileDescriptor(Descriptors.FileDescriptor localFileDescriptor)
Sets the local file descriptor.
|
void |
setRecordCountKey(KeyExpression recordCountKey)
Deprecated.
use
COUNT type indexes instead |
RecordMetaDataBuilder |
setRecords(Descriptors.FileDescriptor fileDescriptor)
Adds the root file descriptor of the
RecordMetaData and processes the extension options. |
RecordMetaDataBuilder |
setRecords(Descriptors.FileDescriptor fileDescriptor,
boolean processExtensionOptions)
Adds the root file descriptor of the
RecordMetaData . |
RecordMetaDataBuilder |
setRecords(RecordMetaDataProto.MetaData metaDataProto)
Deserializes the meta-data proto into the builder.
|
RecordMetaDataBuilder |
setRecords(RecordMetaDataProto.MetaData metaDataProto,
boolean processExtensionOptions)
Deserializes the meta-data proto into the builder.
|
void |
setSplitLongRecords(boolean splitLongRecords) |
void |
setStoreRecordVersions(boolean storeRecordVersions) |
RecordMetaDataBuilder |
setSubspaceKeyCounter(long subspaceKeyCounter)
Set the initial value of the subspace key counter.
|
void |
setVersion(int version) |
void |
updateRecords(Descriptors.FileDescriptor recordsDescriptor)
Update the records descriptor of the record meta-data.
|
void |
updateRecords(Descriptors.FileDescriptor newRecordsDescriptor,
boolean processExtensionOptions)
Update the records descriptor of the record meta-data.
|
boolean |
usesSubspaceKeyCounter()
Checks if counter-based subspace key assignment is used.
|
public static final String DEFAULT_UNION_NAME
@Deprecated public RecordMetaDataBuilder(@Nonnull Descriptors.FileDescriptor fileDescriptor)
RecordMetaData.newBuilder()
insteadfileDescriptor
- a file descriptor containing all the record types in the metadata@Deprecated public RecordMetaDataBuilder(@Nonnull Descriptors.FileDescriptor fileDescriptor, boolean processExtensionOptions)
RecordMetaData.newBuilder()
insteadfileDescriptor
- a file descriptor containing all the record types in the metadataprocessExtensionOptions
- whether to add primary keys and indexes based on extensions in the protobuf@Deprecated public RecordMetaDataBuilder(@Nonnull RecordMetaDataProto.MetaData metaDataProto)
RecordMetaData.newBuilder()
insteadmetaDataProto
is not the result of RecordMetaData.toProto()
and will not already
include all the indexes defined by any original extension options, so that they still need to be processed.
If metaDataProto
is the result of toProto
and indexes also appear in extension options, a duplicate index
error will result. In that case, RecordMetaDataBuilder(RecordMetaDataProto.MetaData, boolean)
will be needed instead.metaDataProto
- the protobuf form of the meta-data@Deprecated public RecordMetaDataBuilder(@Nonnull RecordMetaDataProto.MetaData metaDataProto, boolean processExtensionOptions)
RecordMetaData.newBuilder()
insteadmetaDataProto
is the result of RecordMetaData.toProto()
, it will already
include all the indexes defined by any original extension options, so processExtensionOptions
should be false
.metaDataProto
- the protobuf form of the meta-dataprocessExtensionOptions
- whether to add primary keys and indexes based on extensions in the protobuf@Deprecated public RecordMetaDataBuilder(@Nonnull RecordMetaDataProto.MetaData metaDataProto, @Nonnull Descriptors.FileDescriptor[] dependencies)
RecordMetaData.newBuilder()
insteadmetaDataProto
is not the result of RecordMetaData.toProto()
and will not already
include all the indexes defined by any original extension options, so that they still need to be processed.
If metaDataProto
is the result of toProto
and indexes also appear in extension options, a duplicate index
error will result. In that case, RecordMetaDataBuilder(RecordMetaDataProto.MetaData, Descriptors.FileDescriptor[], boolean)
will be needed instead.metaDataProto
- the protobuf form of the meta-datadependencies
- other files imported by the record types protobuf@Deprecated public RecordMetaDataBuilder(@Nonnull RecordMetaDataProto.MetaData metaDataProto, @Nonnull Descriptors.FileDescriptor[] dependencies, boolean processExtensionOptions)
RecordMetaData.newBuilder()
insteadmetaDataProto
is the result of RecordMetaData.toProto()
, it will already
include all the indexes defined by any original extension options, so processExtensionOptions
should be false
.metaDataProto
- the protobuf form of the meta-datadependencies
- other files imported by the record types protobufprocessExtensionOptions
- whether to add primary keys and indexes based on extensions in the protobuf@Nonnull public RecordMetaDataBuilder setRecords(@Nonnull RecordMetaDataProto.MetaData metaDataProto)
metaDataProto
- the proto of the RecordMetaData
@Nonnull public RecordMetaDataBuilder setRecords(@Nonnull RecordMetaDataProto.MetaData metaDataProto, boolean processExtensionOptions)
metaDataProto
- the proto of the RecordMetaData
processExtensionOptions
- whether to add primary keys and indexes based on extensions in the protobuf@Nonnull public RecordMetaDataBuilder setRecords(@Nonnull Descriptors.FileDescriptor fileDescriptor)
RecordMetaData
and processes the extension options.fileDescriptor
- the file descriptor of the record meta-data@Nonnull public RecordMetaDataBuilder setRecords(@Nonnull Descriptors.FileDescriptor fileDescriptor, boolean processExtensionOptions)
RecordMetaData
.fileDescriptor
- the file descriptor of the record meta-dataprocessExtensionOptions
- whether to add primary keys and indexes based on extensions in the protobufpublic void updateRecords(@Nonnull Descriptors.FileDescriptor recordsDescriptor)
This involves adding new record types and updating descriptors for the existing record types and union fields. By contract, the extension options will be processed for all of the new record types and will not be processed for any of the old record types. Also, it is not allowed to call this method when the local file descriptor is set.
See updateRecords(Descriptors.FileDescriptor, boolean)
for more information.
recordsDescriptor
- the new record descriptorpublic void updateRecords(@Nonnull Descriptors.FileDescriptor newRecordsDescriptor, boolean processExtensionOptions)
This adds any new record types and updates the descriptors for existing record types.
By contract, the extension options will not be processed for the old record types. If processExtensionOptions
is set, extension options will be processed only for the new record types. Also, this method may not be called
when localFileDescriptor
is set. This method bumps the meta-data version and sets the since version
for the new record types (and their indexes).
To avoid accidental changes, this method only updates the record types (i.e., updates the message
descriptors of the old record types and adds new record types with their primary keys and indexes). This method
does not process schema options. To update the schema options, use setSplitLongRecords(boolean)
and
setStoreRecordVersions(boolean)
.
newRecordsDescriptor
- the new record descriptorprocessExtensionOptions
- whether to add primary keys and indexes using the extensions in the protobuf (only for the new record types)@Nonnull public RecordMetaDataBuilder setLocalFileDescriptor(@Nonnull Descriptors.FileDescriptor localFileDescriptor)
This method is handy when two versions of the record meta-data are compatible (i.e., they follow the
Record Layer guidelines on schema evolution),
but their descriptors are not equal, e.g., a statically-generated proto and its serialized version stored
in a meta-data store (i.e., FDBMetaDataStore
). A
record store created using the meta-data store may not be able to store a record created
by the statically-generated proto file because the meta-data and record have mismatched descriptors. Using this method,
the meta-data can use the same version of the descriptor as the record.
This should only be used when the records descriptor is set through a meta-data Protobuf message (i.e, it is followed by a call
to setRecords(RecordMetaDataProto.MetaData)
or setRecords(RecordMetaDataProto.MetaData, boolean)
).
This will not work if the records are set using a file descriptor. Note also that once the local file descriptor is
set, the RecordMetaData
object that is produced from this builder may differ from the original Protobuf definition
in ways that make serializing the meta-data back to Protobuf unsafe. As a result, calling toProto()
on the produced RecordMetaData
is disallowed.
To verify that the file descriptor supplied here and the file descriptor included in the meta-data proto are
compatible, the two descriptors are compared using a MetaDataEvolutionValidator
. The user may provide
their own validator by calling setEvolutionValidator(MetaDataEvolutionValidator)
. By default, this
will use that class's default instance.
localFileDescriptor
- a file descriptor that contains updated record types@Nonnull public RecordMetaDataBuilder addDependency(@Nonnull Descriptors.FileDescriptor fileDescriptor)
RecordMetaData
from a meta-data proto.fileDescriptor
- the file descriptor of the dependency@Nonnull public RecordMetaDataBuilder addDependencies(@Nonnull Descriptors.FileDescriptor[] fileDescriptors)
RecordMetaData
from a meta-data proto.fileDescriptors
- a list of dependencies@Nonnull public Descriptors.Descriptor getUnionDescriptor()
@Nonnull public Descriptors.FieldDescriptor getUnionFieldForRecordType(@Nonnull RecordType recordType)
@Nonnull public RecordTypeBuilder getRecordType(@Nonnull String name)
@Nonnull @API(value=EXPERIMENTAL) public SyntheticRecordTypeBuilder<?> getSyntheticRecordType(@Nonnull String name)
@Nonnull @API(value=EXPERIMENTAL) public JoinedRecordTypeBuilder addJoinedRecordType(@Nonnull String name)
name
- the name of the new record typepublic RecordTypeIndexesBuilder getIndexableRecordType(@Nonnull String name)
addIndex(com.apple.foundationdb.record.metadata.RecordTypeIndexesBuilder, com.apple.foundationdb.record.metadata.Index)
.name
- the name of the record typepublic void addIndex(@Nullable RecordTypeIndexesBuilder recordType, @Nonnull Index index)
recordType
- if null this index will exist for all record typesindex
- the index to be addedpublic void addIndex(@Nonnull String recordType, @Nonnull Index index)
recordType
- name of the record typeindex
- the index to be addedpublic void addIndex(@Nonnull String recordType, @Nonnull String indexName, @Nonnull KeyExpression indexExpression)
recordType
- name of the record typeindexName
- the name of the new indexindexExpression
- the root expression of the new indexpublic void addIndex(@Nonnull String recordType, @Nonnull String indexName, @Nonnull String fieldName)
recordType
- name of the record typeindexName
- the name of the new indexfieldName
- the record field to be indexedpublic void addIndex(@Nonnull String recordType, @Nonnull String fieldName)
recordType
- name of the record typefieldName
- the record field to be indexedpublic void addMultiTypeIndex(@Nullable List<? extends RecordTypeIndexesBuilder> recordTypes, @Nonnull Index index)
recordTypes
- a list of record types that the index will includeindex
- the index to be addedpublic void addUniversalIndex(@Nonnull Index index)
index
- the index to be addedpublic void addFormerIndex(@Nonnull FormerIndex formerIndex)
public boolean isSplitLongRecords()
public void setSplitLongRecords(boolean splitLongRecords)
public boolean isStoreRecordVersions()
public void setStoreRecordVersions(boolean storeRecordVersions)
@Nullable @Deprecated @API(value=DEPRECATED) public KeyExpression getRecordCountKey()
COUNT
type indexes insteadnull
@Deprecated @API(value=DEPRECATED) public void setRecordCountKey(KeyExpression recordCountKey)
COUNT
type indexes insteadrecordCountKey
- grouping key for countingpublic int getVersion()
public void setVersion(int version)
@Nonnull public RecordMetaDataBuilder enableCounterBasedSubspaceKeys()
If enabled, index subspace keys will be set using a counter instead of defaulting to the indexes' names. This
must be called prior to setting the records descriptor (for example setRecords(Descriptors.FileDescriptor)
).
Existing clients should be careful about enabling this feature. The name of an index is the default
value of its subspace key when counter-based subspace keys are disabled. If a subspace key was not set
explicitly before, enabling the counter-based scheme will change the index's subspace key. Note that
it is important that the subspace key of an index that has data does not change.
See Index.setSubspaceKey(Object)
for more details.
public boolean usesSubspaceKeyCounter()
true
if the subspace key counter is usedpublic long getSubspaceKeyCounter()
enableCounterBasedSubspaceKeys()
@Nonnull public RecordMetaDataBuilder setSubspaceKeyCounter(long subspaceKeyCounter)
Note that the new counter must be greater than the current value. Also, users must first enable this feature by
calling enableCounterBasedSubspaceKeys()
before updating the counter value.
subspaceKeyCounter
- the new valueenableCounterBasedSubspaceKeys()
@Nonnull public RecordTypeBuilder getOnlyRecordType()
@Nonnull public IndexMaintainerRegistry getIndexMaintainerRegistry()
public void setIndexMaintainerRegistry(@Nonnull IndexMaintainerRegistry indexMaintainerRegistry)
indexMaintainerRegistry
- the index maintainer registryFDBRecordStoreBase.BaseBuilder.setIndexMaintainerRegistry(com.apple.foundationdb.record.provider.foundationdb.IndexMaintainerRegistry)
@Nonnull public MetaDataEvolutionValidator getEvolutionValidator()
MetaDataEvolutionValidator
's
default instance, but the
user may provide their own through setEvolutionValidator(MetaDataEvolutionValidator)
if they want to tweak certain validator options.setLocalFileDescriptor(Descriptors.FileDescriptor)
,
MetaDataEvolutionValidator
@Nonnull public RecordMetaDataBuilder setEvolutionValidator(@Nonnull MetaDataEvolutionValidator evolutionValidator)
setRecords()
through the meta-data proto, this method must be called before setRecords()
.evolutionValidator
- the validator used to check the local file descriptor against the one in the meta-data protosetLocalFileDescriptor(Descriptors.FileDescriptor)
,
MetaDataEvolutionValidator
@Nonnull public RecordMetaData getRecordMetaData()
RecordMetaDataProvider
RecordMetaData
.
Implementors should assume that this method will be called frequently, so it may
be necessary to cache the result if generating the RecordMetaData
is expensive.getRecordMetaData
in interface RecordMetaDataProvider
RecordMetaData
@Nonnull public RecordMetaData build()
@Nonnull public RecordMetaData build(boolean validate)
validate
- true
to validate the new meta-data@Nullable public static int[] buildPrimaryKeyComponentPositions(@Nonnull KeyExpression indexKey, @Nonnull KeyExpression primaryKey)