schema

package
v1.0.0-beta.24 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 22, 2022 License: Apache-2.0 Imports: 25 Imported by: 0

Documentation

Index

Constants

View Source
const (
	PrimaryKeyIndexName = "pkey"
	AutoPrimaryKeyF     = "id"
	PrimaryKeySchemaK   = "primary_key"
	// DateTimeFormat represents the supported date time format.
	DateTimeFormat               = time.RFC3339Nano
	CollectionTypeF              = "collection_type"
	IndexingSchemaVersionKey     = "indexing_version"
	DefaultIndexingSchemaVersion = "v1"
)
View Source
const (
	ObjFlattenDelimiter = "."
)
View Source
const (
	SearchId = "id"
)

Variables

View Source
var (
	MsgFieldNameAsLanguageKeyword = "Invalid collection field name, It contains language keyword for fieldName = '%s'"
	MsgFieldNameInvalidPattern    = "" /* 131-byte string literal not displayed */
	ValidFieldNamePattern         = regexp.MustCompile(`^[a-zA-Z_$][a-zA-Z0-9_$]*$`)
)
View Source
var (
	ErrIncompatibleSchema = fmt.Errorf("error incompatible schema")
	ErrExpectedString     = fmt.Errorf("expected string type")
	ErrExpectedNumber     = fmt.Errorf("expected json.Number")
	ErrUnsupportedType    = fmt.Errorf("unsupported type")
)

Supported subtypes.

View Source
var (
	ErrMissingField           = errors.InvalidArgument("removing a field is a backward incompatible change")
	ErrCollectionNameMismatch = errors.InvalidArgument("mismatch in the collection name")
)
View Source
var FieldNames = [...]string{
	UnknownType:  "unknown",
	NullType:     "null",
	BoolType:     "bool",
	Int32Type:    "int32",
	Int64Type:    "int64",
	DoubleType:   "double",
	StringType:   "string",
	ByteType:     "byte",
	UUIDType:     "uuid",
	DateTimeType: "datetime",
	ArrayType:    "array",
	ObjectType:   "object",
}
View Source
var ReservedFields = [...]string{
	CreatedAt:           "created_at",
	UpdatedAt:           "updated_at",
	Metadata:            "metadata",
	IdToSearchKey:       "_tigris_id",
	DateSearchKeyPrefix: "_tigris_date_",
}
View Source
var SupportedFieldProperties = container.NewHashSet(
	"type",
	"format",
	"items",
	"maxLength",
	"description",
	"contentEncoding",
	"properties",
	"autoGenerate",
	"sorted",
	"default",
	"createdAt",
	"updatedAt",
)

Functions

func ApplySchemaRules

func ApplySchemaRules(existing *DefaultCollection, current *Factory) error

ApplySchemaRules is to validate incoming collection request against the existing present collection. It performs following validations,

  • Primary Key Changed, or order of fields part of the primary key is changed
  • Collection name change
  • Type of existing field is changed
  • A validation on field property is also applied like for instance if existing field has some property, but it is removed in the new schema
  • Removing a field
  • Any index exist on the collection will also have same checks like type, etc

func FacetableField

func FacetableField(fieldType FieldType) bool

func Generate

func Generate(jsonSchema []byte, format string) ([]byte, error)

Generate schema in the requested format.

func GetSearchDeltaFields

func GetSearchDeltaFields(existingFields []*QueryableField, incomingFields []*Field, fieldsInSearch []tsApi.Field) []tsApi.Field

func IndexableField

func IndexableField(fieldType FieldType, subType FieldType) bool

func Infer

func Infer(sch *schema.Schema, name string, docs [][]byte, primaryKey []string, autoGenerate []string,
	depth int,
) error

func IsPrimitiveType

func IsPrimitiveType(fieldType FieldType) bool

func IsReservedField

func IsReservedField(name string) bool

func IsSearchID

func IsSearchID(name string) bool

func IsValidKeyType

func IsValidKeyType(t FieldType) bool

func RemoveIndexingVersion

func RemoveIndexingVersion(schema jsoniter.RawMessage) jsoniter.RawMessage

func SetIndexingVersion

func SetIndexingVersion(factory *Factory) error

func SortableField

func SortableField(fieldType FieldType) bool

func ToSearchDateKey

func ToSearchDateKey(key string) string

ToSearchDateKey can be used to generate storage field for search backend Original date strings are persisted as it is under this field.

Types

type CollectionType

type CollectionType string
const (
	DocumentsType CollectionType = "documents"
	TopicType     CollectionType = "topic"
)

func GetCollectionType

func GetCollectionType(reqSchema jsoniter.RawMessage) (CollectionType, error)

type DefaultCollection

type DefaultCollection struct {
	// Id is the dictionary encoded value for this collection.
	Id uint32
	// SchVer returns the schema version
	SchVer int32
	// Name is the name of the collection.
	Name string
	// Fields are derived from the user schema.
	Fields []*Field
	// Indexes is a wrapper on the indexes part of this collection.
	Indexes *Indexes
	// Validator is used to validate the JSON document. As it is expensive to create this, it is only created once
	// during constructor of the collection.
	Validator *jsonschema.Schema
	// JSON schema
	Schema jsoniter.RawMessage
	// search schema
	Search *tsApi.CollectionSchema
	// QueryableFields are similar to Fields but these are flattened forms of fields. For instance, a simple field
	// will be one to one mapped to queryable field but complex fields like object type field there may be more than
	// one queryableFields. As queryableFields represent a flattened state these can be used as-is to index in memory.
	QueryableFields []*QueryableField
	// CollectionType is the type of the collection. Only two types of collections are supported "messages" and "documents"
	CollectionType CollectionType

	// PartitionFields are the fields that make up the partition key, if applicable to the collection.
	PartitionFields []*Field
	// This is the existing fields in search
	FieldsInSearch []tsApi.Field
	// contains filtered or unexported fields
}

DefaultCollection is used to represent a collection. The tenant in the metadata package is responsible for creating the collection.

func NewDefaultCollection

func NewDefaultCollection(name string, id uint32, schVer int, ctype CollectionType, factory *Factory, searchCollectionName string, fieldsInSearch []tsApi.Field) *DefaultCollection

func (*DefaultCollection) GetField

func (d *DefaultCollection) GetField(name string) *Field

func (*DefaultCollection) GetFields

func (d *DefaultCollection) GetFields() []*Field

func (*DefaultCollection) GetIndexes

func (d *DefaultCollection) GetIndexes() *Indexes

func (*DefaultCollection) GetInt64FieldsPath

func (d *DefaultCollection) GetInt64FieldsPath() map[string]struct{}

func (*DefaultCollection) GetName

func (d *DefaultCollection) GetName() string

func (*DefaultCollection) GetQueryableField

func (d *DefaultCollection) GetQueryableField(name string) (*QueryableField, error)

func (*DefaultCollection) GetQueryableFields

func (d *DefaultCollection) GetQueryableFields() []*QueryableField

func (*DefaultCollection) GetVersion

func (d *DefaultCollection) GetVersion() int32

func (*DefaultCollection) SearchCollectionName

func (d *DefaultCollection) SearchCollectionName() string

func (*DefaultCollection) TaggedDefaultsForInsert

func (d *DefaultCollection) TaggedDefaultsForInsert() map[string]struct{}

func (*DefaultCollection) TaggedDefaultsForUpdate

func (d *DefaultCollection) TaggedDefaultsForUpdate() map[string]struct{}

func (*DefaultCollection) Type

func (*DefaultCollection) Validate

func (d *DefaultCollection) Validate(document interface{}) error

Validate expects an unmarshalled document which it will validate again the schema of this collection.

type Factory

type Factory struct {
	// Name is the collection name of this schema.
	Name string
	// Fields are derived from the user schema.
	Fields []*Field
	// Indexes is a wrapper on the indexes part of this collection. At this point the dictionary encoded value is not
	// set for these indexes which is set as part of collection creation.
	Indexes *Indexes
	// Schema is the raw JSON schema received as part of CreateOrUpdateCollection request. This is stored as-is in the
	// schema subspace.
	Schema jsoniter.RawMessage
	// CollectionType is the type of the collection. Only two types of collections are supported "messages" and "documents"
	CollectionType  CollectionType
	IndexingVersion string
}

Factory is used as an intermediate step so that collection can be initialized with properly encoded values.

func Build

func Build(collection string, reqSchema jsoniter.RawMessage) (*Factory, error)

Build is used to deserialize the user json schema into a schema factory.

type Field

type Field struct {
	FieldName         string
	Defaulter         *FieldDefaulter
	DataType          FieldType
	MaxLength         *int32
	FillCreatedAt     *bool
	FillUpdatedAt     *bool
	UniqueKeyField    *bool
	PrimaryKeyField   *bool
	PartitionKeyField *bool
	AutoGenerated     *bool
	Sorted            *bool

	// Nested fields are the fields where we know the schema of nested attributes like if properties are
	Fields []*Field
}

func BuildPartitionFields

func BuildPartitionFields(fields []*Field) []*Field

func (*Field) GetDefaulter

func (f *Field) GetDefaulter() *FieldDefaulter

func (*Field) GetNestedField

func (f *Field) GetNestedField(name string) *Field

func (*Field) IsAutoGenerated

func (f *Field) IsAutoGenerated() bool

func (*Field) IsCompatible

func (f *Field) IsCompatible(f1 *Field) error

func (*Field) IsPartitionKey

func (f *Field) IsPartitionKey() bool

func (*Field) IsPrimaryKey

func (f *Field) IsPrimaryKey() bool

func (*Field) IsSorted

func (f *Field) IsSorted() bool

func (*Field) Name

func (f *Field) Name() string

func (*Field) Type

func (f *Field) Type() FieldType

type FieldBuilder

type FieldBuilder struct {
	FieldName   string
	Description string              `json:"description,omitempty"`
	Type        string              `json:"type,omitempty"`
	Format      string              `json:"format,omitempty"`
	Encoding    string              `json:"contentEncoding,omitempty"`
	Default     interface{}         `json:"default,omitempty"`
	CreatedAt   *bool               `json:"createdAt,omitempty"`
	UpdatedAt   *bool               `json:"updatedAt,omitempty"`
	MaxLength   *int32              `json:"maxLength,omitempty"`
	Auto        *bool               `json:"autoGenerate,omitempty"`
	Sorted      *bool               `json:"sorted,omitempty"`
	Items       *FieldBuilder       `json:"items,omitempty"`
	Properties  jsoniter.RawMessage `json:"properties,omitempty"`
	Primary     *bool
	Partition   *bool
	Fields      []*Field
}

func (*FieldBuilder) Build

func (f *FieldBuilder) Build(isArrayElement bool) (*Field, error)

func (*FieldBuilder) Validate

func (f *FieldBuilder) Validate(v []byte) error

type FieldDefaulter

type FieldDefaulter struct {
	// contains filtered or unexported fields
}

func (*FieldDefaulter) GetValue

func (defaulter *FieldDefaulter) GetValue() interface{}

GetValue returns the value if there is default tag set for a field. For functions, it will execute it and return the value. If the function is now() then it is converted to createdAt during the construction of the defaulter.

func (*FieldDefaulter) TaggedWithCreatedAt

func (defaulter *FieldDefaulter) TaggedWithCreatedAt() bool

func (*FieldDefaulter) TaggedWithUpdatedAt

func (defaulter *FieldDefaulter) TaggedWithUpdatedAt() bool

type FieldSchemaValidator

type FieldSchemaValidator struct{}

func (*FieldSchemaValidator) Validate

func (v *FieldSchemaValidator) Validate(existing *DefaultCollection, current *Factory) error

type FieldType

type FieldType int
const (
	UnknownType FieldType = iota
	NullType
	BoolType
	Int32Type
	Int64Type
	DoubleType
	StringType
	// ByteType is a base64 encoded characters, this means if this type is used as key then we need to decode it
	// and then use it as key.
	ByteType
	UUIDType
	// DateTimeType is a valid date representation as defined by RFC 3339, see https://datatracker.ietf.org/doc/html/rfc3339#section-5.6
	DateTimeType
	ArrayType
	ObjectType
)

func ToFieldType

func ToFieldType(jsonType string, encoding string, format string) FieldType

type Index

type Index struct {
	// Fields that are part of this index. An index can have a single or composite fields.
	Fields []*Field
	// Name is used by dictionary encoder for this index.
	Name string
	// Id is assigned to this index by the dictionary encoder.
	Id uint32
}

Index can be composite, so it has a list of fields, each index has name and encoded id. The encoded is used for key building.

func (*Index) IsCompatible

func (i *Index) IsCompatible(i1 *Index) error

type IndexSchemaValidator

type IndexSchemaValidator struct{}

func (*IndexSchemaValidator) Validate

func (v *IndexSchemaValidator) Validate(existing *DefaultCollection, current *Factory) error

type Indexes

type Indexes struct {
	PrimaryKey *Index
}

Indexes is to wrap different index that a collection can have.

func (*Indexes) GetIndexes

func (i *Indexes) GetIndexes() []*Index

type JSONSchema

type JSONSchema struct {
	Name            string              `json:"title,omitempty"`
	Description     string              `json:"description,omitempty"`
	Properties      jsoniter.RawMessage `json:"properties,omitempty"`
	PrimaryKeys     []string            `json:"primary_key,omitempty"`
	PartitionKeys   []string            `json:"key,omitempty"`
	CollectionType  string              `json:"collection_type,omitempty"`
	IndexingVersion string              `json:"indexing_version,omitempty"`
}

type QueryableField

type QueryableField struct {
	FieldName     string
	InMemoryAlias string
	Faceted       bool
	Indexed       bool
	Sortable      bool
	DataType      FieldType
	SubType       FieldType
	SearchType    string
	// contains filtered or unexported fields
}

func BuildQueryableFields

func BuildQueryableFields(fields []*Field, fieldsInSearch []tsApi.Field) []*QueryableField

func NewQueryableField

func NewQueryableField(name string, tigrisType FieldType, subType FieldType, sorted *bool, fieldsInSearch []tsApi.Field) *QueryableField

func (*QueryableField) InMemoryName

func (q *QueryableField) InMemoryName() string

InMemoryName returns key name that is used to index this field in the indexing store. For example, an "id" key is indexed with "_tigris_id" name.

func (*QueryableField) IsReserved

func (q *QueryableField) IsReserved() bool

IsReserved returns true if the queryable field is internal field.

func (*QueryableField) Name

func (q *QueryableField) Name() string

Name returns the name of this field as defined in the schema.

func (*QueryableField) ShouldPack

func (q *QueryableField) ShouldPack() bool

ShouldPack returns true if we need to pack this field before sending to indexing store.

type ReservedField

type ReservedField uint8
const (
	CreatedAt ReservedField = iota
	UpdatedAt
	Metadata
	IdToSearchKey
	DateSearchKeyPrefix
)

type Validator

type Validator interface {
	Validate(existing *DefaultCollection, current *Factory) error
}

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL