database

package
v0.14.1 Latest Latest
Warning

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

Go to latest
Published: Dec 22, 2021 License: MIT Imports: 17 Imported by: 0

Documentation

Overview

Package database provides database primitives such as tables, transactions and indexes.

Index

Constants

View Source
const (
	TableName            = InternalPrefix + "catalog"
	RelationTableType    = "table"
	RelationIndexType    = "index"
	RelationSequenceType = "sequence"
	StoreSequence        = InternalPrefix + "store_seq"
)
View Source
const (
	// OnConflictDoNothing ignores the duplicate error and returns nothing.
	OnConflictDoNothing = iota + 1

	// OnConflictDoReplace replaces the conflicting document with a new one.
	OnConflictDoReplace
)
View Source
const (
	InternalPrefix = "__genji_"
)
View Source
const (
	SequenceTableName = "__genji_sequence"
)

Variables

View Source
var (
	// ErrIndexDuplicateValue is returned when a value is already associated with a key
	ErrIndexDuplicateValue = errors.New("duplicate value")
)

Functions

func CastConversion

func CastConversion(v types.Value, path document.Path, targetType types.ValueType) (types.Value, error)

CastConversion is a ConversionFunc that casts the value to the target type.

func NewTransientTree added in v0.14.0

func NewTransientTree(db *Database) (*tree.Tree, func() error, error)

NewTransientTree creates a temporary tree.

Types

type Catalog

type Catalog struct {
	Cache        *catalogCache
	CatalogTable *CatalogStore
	Codec        encoding.Codec
}

Catalog manages all database objects such as tables, indexes and sequences. It stores all these objects in memory for fast access. Any modification is persisted into the __genji_catalog table.

func NewCatalog added in v0.14.0

func NewCatalog() *Catalog

func (*Catalog) AddFieldConstraint

func (c *Catalog) AddFieldConstraint(tx *Transaction, tableName string, fc *FieldConstraint, tcs TableConstraints) error

AddFieldConstraint adds a field constraint to a table.

func (*Catalog) CreateIndex

func (c *Catalog) CreateIndex(tx *Transaction, info *IndexInfo) error

CreateIndex creates an index with the given name. If it already exists, returns errs.ErrIndexAlreadyExists.

func (*Catalog) CreateSequence

func (c *Catalog) CreateSequence(tx *Transaction, info *SequenceInfo) error

CreateSequence creates a sequence with the given name.

func (*Catalog) CreateTable

func (c *Catalog) CreateTable(tx *Transaction, tableName string, info *TableInfo) error

CreateTable creates a table with the given name. If it already exists, returns ErrTableAlreadyExists.

func (*Catalog) DropIndex

func (c *Catalog) DropIndex(tx *Transaction, name string) error

DropIndex deletes an index from the

func (*Catalog) DropSequence

func (c *Catalog) DropSequence(tx *Transaction, name string) error

DropSequence deletes a sequence from the catalog.

func (*Catalog) DropTable

func (c *Catalog) DropTable(tx *Transaction, tableName string) error

DropTable deletes a table from the catalog

func (*Catalog) GetIndex

func (c *Catalog) GetIndex(tx *Transaction, indexName string) (*Index, error)

GetIndex returns an index by name.

func (*Catalog) GetIndexInfo

func (c *Catalog) GetIndexInfo(indexName string) (*IndexInfo, error)

GetIndexInfo returns an index info by name.

func (*Catalog) GetSequence

func (c *Catalog) GetSequence(name string) (*Sequence, error)

func (*Catalog) GetTable

func (c *Catalog) GetTable(tx *Transaction, tableName string) (*Table, error)

func (*Catalog) GetTableInfo

func (c *Catalog) GetTableInfo(tableName string) (*TableInfo, error)

GetTableInfo returns the table info for the given table name.

func (*Catalog) Init added in v0.14.0

func (c *Catalog) Init(tx *Transaction, codec encoding.Codec) error

func (*Catalog) ListIndexes

func (c *Catalog) ListIndexes(tableName string) []string

ListIndexes returns all indexes for a given table name. If tableName is empty if returns a list of all indexes. The returned list of indexes is sorted lexicographically.

func (*Catalog) ListSequences

func (c *Catalog) ListSequences() []string

ListSequences returns all sequence names sorted lexicographically.

func (*Catalog) RenameTable

func (c *Catalog) RenameTable(tx *Transaction, oldName, newName string) error

RenameTable renames a table. If it doesn't exist, it returns errs.ErrTableNotFound.

type CatalogStore added in v0.14.0

type CatalogStore struct {
	Catalog *Catalog

	Codec encoding.Codec
	// contains filtered or unexported fields
}

func (*CatalogStore) Delete added in v0.14.0

func (s *CatalogStore) Delete(tx *Transaction, name string) error

func (*CatalogStore) Info added in v0.14.0

func (s *CatalogStore) Info() *TableInfo

func (*CatalogStore) Init added in v0.14.0

func (s *CatalogStore) Init(tx *Transaction, ctg *Catalog) error

func (*CatalogStore) Insert added in v0.14.0

func (s *CatalogStore) Insert(tx *Transaction, r Relation) error

Insert a catalog object to the table.

func (*CatalogStore) Replace added in v0.14.0

func (s *CatalogStore) Replace(tx *Transaction, name string, r Relation) error

Replace a catalog object with another.

func (*CatalogStore) Table added in v0.14.0

func (s *CatalogStore) Table(tx *Transaction) *Table

type ConversionFunc

type ConversionFunc func(v types.Value, path document.Path, targetType types.ValueType) (types.Value, error)

ConversionFunc is called when the type of a value is different than the expected type and the value needs to be converted.

type Database

type Database struct {
	Catalog *Catalog

	// Codec used to encode documents. Defaults to MessagePack.
	Codec encoding.Codec

	// Pool of reusable transient engines to use for temporary indices.
	TransientDatabasePool *TransientDatabasePool
	// contains filtered or unexported fields
}

func New

func New(ctx context.Context, ng engine.Engine, opts Options) (*Database, error)

New initializes the DB using the given engine.

func (*Database) Begin

func (db *Database) Begin(writable bool) (*Transaction, error)

Begin starts a new transaction with default options. The returned transaction must be closed either by calling Rollback or Commit.

func (*Database) BeginTx

func (db *Database) BeginTx(ctx context.Context, opts *TxOptions) (*Transaction, error)

BeginTx starts a new transaction with the given options. If opts is empty, it will use the default options. The returned transaction must be closed either by calling Rollback or Commit. If the Attached option is passed, it opens a database level transaction, which gets attached to the database and prevents any other transaction to be opened afterwards until it gets rolled back or commited.

func (*Database) Close

func (db *Database) Close() error

Close the database and the underlying engine.

func (*Database) GetAttachedTx

func (db *Database) GetAttachedTx() *Transaction

GetAttachedTx returns the transaction attached to the database. It returns nil if there is no such transaction. The returned transaction is not thread safe.

func (*Database) NewTransientDB added in v0.14.0

func (db *Database) NewTransientDB(ctx context.Context) (*Database, func() error, error)

NewTransientDB creates a temporary database to be used for creating temporary indices.

type FieldConstraint

type FieldConstraint struct {
	Path         document.Path
	Type         types.ValueType
	IsNotNull    bool
	DefaultValue TableExpression
	IsInferred   bool
	InferredBy   []document.Path
}

FieldConstraint describes constraints on a particular field.

func (*FieldConstraint) HasDefaultValue

func (f *FieldConstraint) HasDefaultValue() bool

HasDefaultValue returns this field contains a default value constraint.

func (*FieldConstraint) IsEmpty added in v0.14.0

func (f *FieldConstraint) IsEmpty() bool

func (*FieldConstraint) IsEqual

func (f *FieldConstraint) IsEqual(other *FieldConstraint) bool

IsEqual compares f with other member by member. Inference is not compared.

func (*FieldConstraint) MergeInferred

func (f *FieldConstraint) MergeInferred(other *FieldConstraint)

MergeInferred adds the other.InferredBy to f.InferredBy and ensures there are no duplicates.

func (*FieldConstraint) String

func (f *FieldConstraint) String() string

type FieldConstraints

type FieldConstraints []*FieldConstraint

FieldConstraints is a list of field constraints.

func NewFieldConstraints

func NewFieldConstraints(userConstraints []*FieldConstraint) (FieldConstraints, error)

NewFieldConstraints takes user-defined field constraints, validates them, infers additional constraints if needed, and returns a valid FieldConstraints type that can be assigned to a table.

func (*FieldConstraints) Add

func (f *FieldConstraints) Add(newFc *FieldConstraint) error

Add a field constraint to the list. If another constraint exists for the same path and they are equal, newFc will be ignored. Otherwise an error will be returned. If newFc has been inferred by another constraint and another constraint exists with the same path, their InferredBy member will be merged.

func (FieldConstraints) ConvertDocument

func (f FieldConstraints) ConvertDocument(d types.Document) (*document.FieldBuffer, error)

ConvertDocument the document using the field constraints. It converts any path that has a field constraint on it into the specified type using CAST. If there is no constraint on an integer field or value, it converts it into a double. Default values on missing fields are not applied.

func (FieldConstraints) ConvertValueAtPath

func (f FieldConstraints) ConvertValueAtPath(path document.Path, v types.Value, conversionFn ConversionFunc) (types.Value, error)

ConvertValueAtPath converts the value using the field constraints that are applicable at the given path.

func (FieldConstraints) Get

Get a field constraint by path. Returns nil if not found.

func (FieldConstraints) Infer

Infer additional constraints based on user defined ones. For example, given the following table:

CREATE TABLE foo (
   a.b[1] TEXT,
   c.e DEFAULT 10
 )

this function will return a TableInfo that behaves as if the table had been created like this:

CREATE TABLE foo(
   a DOCUMENT
   a.b ARRAY
   a.b[0] TEXT
   c DOCUMENT DEFAULT {}
   c.d DEFAULT 10
)

func (FieldConstraints) ValidateDocument

func (f FieldConstraints) ValidateDocument(tx *Transaction, fb *document.FieldBuffer) (*document.FieldBuffer, error)

ValidateDocument calls Convert then ensures the document validates against the field constraints.

type Index

type Index struct {
	// How many values the index is operating on.
	// For example, an index created with `CREATE INDEX idx_a_b ON foo (a, b)` has an arity of 2.
	Arity int
	Tree  *tree.Tree
}

An Index associates encoded values with keys.

The association is performed by encoding the values in a binary format that preserve ordering when compared lexicographically. For the implementation, see the binarysort package and the types.ValueEncoder.

func NewIndex

func NewIndex(tr *tree.Tree, opts IndexInfo) *Index

NewIndex creates an index that associates values with a list of keys.

func (*Index) Delete

func (idx *Index) Delete(vs []types.Value, key tree.Key) error

Delete all the references to the key from the index.

func (*Index) Exists

func (idx *Index) Exists(vs []types.Value) (bool, tree.Key, error)

Exists iterates over the index and check if the value exists

func (*Index) IterateOnRange added in v0.14.0

func (idx *Index) IterateOnRange(rng *tree.Range, reverse bool, fn func(key tree.Key) error) error

IterateOnRange seeks for the pivot and then goes through all the subsequent key value pairs in increasing or decreasing order and calls the given function for each pair. If the given function returns an error, the iteration stops and returns that error. If the pivot(s) is/are empty, starts from the beginning.

Valid pivots are: - zero value pivot

  • iterate on everything

- n elements pivot (where n is the index arity) with each element having a value and a type

  • iterate starting at the closest index value
  • optionally, the last pivot element can have just a type and no value, which will scope the value of that element to that type

- less than n elements pivot, with each element having a value and a type

  • iterate starting at the closest index value, using the first known value for missing elements
  • optionally, the last pivot element can have just a type and no value, which will scope the value of that element to that type

- a single element with a type but nil value: will iterate on everything of that type

Any other variation of a pivot are invalid and will panic.

func (*Index) Set

func (idx *Index) Set(vs []types.Value, key tree.Key) error

Set associates values with a key. If Unique is set to false, it is possible to associate multiple keys for the same value but a key can be associated to only one value.

Values are stored in the index following the "index format". Every record is stored like this:

k: <encoded values><primary key>
v: length of the encoded value, as an unsigned varint

func (*Index) Truncate

func (idx *Index) Truncate() error

Truncate deletes all the index data.

type IndexInfo

type IndexInfo struct {
	TableName string
	// name of the store associated with the index.
	StoreName []byte
	IndexName string
	Paths     []document.Path

	// If set to true, values will be associated with at most one key. False by default.
	Unique bool

	// If set, this index has been created from a table constraint
	// i.e CREATE TABLE tbl(a INT UNIQUE)
	// The path refers to the path this index is related to.
	Owner Owner
}

IndexInfo holds the configuration of an index.

func (IndexInfo) Clone

func (i IndexInfo) Clone() *IndexInfo

Clone returns a copy of the index information.

func (*IndexInfo) GenerateBaseName

func (i *IndexInfo) GenerateBaseName() string

func (*IndexInfo) Name

func (i *IndexInfo) Name() string

func (*IndexInfo) SetName

func (i *IndexInfo) SetName(name string)

func (*IndexInfo) String

func (i *IndexInfo) String() string

String returns a SQL representation.

func (*IndexInfo) Type

func (i *IndexInfo) Type() string

type OnConflictAction added in v0.14.0

type OnConflictAction int

OnConflictAction is a function triggered when trying to insert a document that already exists. This function is triggered if the key is duplicated or if there is a unique constraint violation on one of the fields of the document.

func (OnConflictAction) String added in v0.14.0

func (o OnConflictAction) String() string

type Options

type Options struct {
	Codec encoding.Codec
}

type Owner

type Owner struct {
	TableName string
	Paths     document.Paths
}

Owner is used to determine who owns a relation. If the relation has been created by a table (for docids for example), only the TableName is filled. If it has been created by a field constraint (for identities for example), the path must also be filled.

type Pivot

type Pivot []types.Value

type PrimaryKey added in v0.14.0

type PrimaryKey struct {
	Paths document.Paths
	Types []types.ValueType
}

type Range added in v0.14.0

type Range struct {
	Min, Max  Pivot
	Exclusive bool
	Exact     bool
}

func (*Range) Convert added in v0.14.0

func (r *Range) Convert(constraints *FieldConstraints, v types.Value, p document.Path, isMin bool) (types.Value, error)

func (*Range) IsEqual added in v0.14.0

func (r *Range) IsEqual(other *Range) bool

func (*Range) ToTreeRange added in v0.14.0

func (r *Range) ToTreeRange(constraints *FieldConstraints, paths []document.Path) (*tree.Range, error)

type Relation added in v0.14.0

type Relation interface {
	Type() string
	Name() string
	SetName(name string)
	GenerateBaseName() string
}

type Sequence

type Sequence struct {
	Info *SequenceInfo

	CurrentValue *int64
	Cached       uint64
	Key          tree.Key
}

A Sequence manages a sequence of numbers. It is not thread safe.

func NewSequence

func NewSequence(info *SequenceInfo, currentValue *int64) Sequence

NewSequence creates a new or existing sequence. If currentValue is not nil next call to Next will increase the lease.

func (*Sequence) Clone added in v0.14.0

func (s *Sequence) Clone() *Sequence

func (*Sequence) Drop

func (s *Sequence) Drop(tx *Transaction, catalog *Catalog) error

func (*Sequence) GenerateBaseName

func (s *Sequence) GenerateBaseName() string

func (*Sequence) GetOrCreateTable

func (s *Sequence) GetOrCreateTable(tx *Transaction, catalog *Catalog) (*Table, error)

func (*Sequence) Init

func (s *Sequence) Init(tx *Transaction, catalog *Catalog) error

func (*Sequence) Name

func (s *Sequence) Name() string

func (*Sequence) Next

func (s *Sequence) Next(tx *Transaction, catalog *Catalog) (int64, error)

func (*Sequence) Release

func (s *Sequence) Release(tx *Transaction, catalog *Catalog) error

Release the sequence by storing the actual current value to the sequence table. If the sequence has cache, the cached value is overwritten.

func (*Sequence) SetLease

func (s *Sequence) SetLease(tx *Transaction, catalog *Catalog, name string, v int64) error

func (*Sequence) SetName

func (s *Sequence) SetName(name string)

func (*Sequence) Type

func (s *Sequence) Type() string

type SequenceInfo

type SequenceInfo struct {
	Name        string
	IncrementBy int64
	Min, Max    int64
	Start       int64
	Cache       uint64
	Cycle       bool
	Owner       Owner
}

SequenceInfo holds the configuration of a sequence.

func (SequenceInfo) Clone

func (s SequenceInfo) Clone() *SequenceInfo

Clone returns a copy of the sequence information.

func (*SequenceInfo) String

func (s *SequenceInfo) String() string

String returns a SQL representation.

type Table

type Table struct {
	Tx   *Transaction
	Tree *tree.Tree
	// Table information.
	// May not represent the most up to date data.
	// Always get a fresh Table instance before relying on this field.
	Info *TableInfo

	Catalog *Catalog
	Codec   encoding.Codec
}

A Table represents a collection of documents.

func (*Table) Delete

func (t *Table) Delete(key tree.Key) error

Delete a document by key.

func (*Table) GetDocument

func (t *Table) GetDocument(key tree.Key) (types.Document, error)

GetDocument returns one document by key.

func (*Table) Insert

func (t *Table) Insert(d types.Document) (tree.Key, types.Document, error)

Insert the document into the table. If a primary key has been specified during the table creation, the field is expected to be present in the given document. If no primary key has been selected, a monotonic autoincremented integer key will be generated. It returns the inserted document alongside its key.

func (*Table) IterateOnRange added in v0.14.0

func (t *Table) IterateOnRange(rng *Range, reverse bool, fn func(key tree.Key, d types.Document) error) error

func (*Table) Replace

func (t *Table) Replace(key tree.Key, d types.Document) (types.Document, error)

Replace a document by key. An error is returned if the key doesn't exist. Indexes are automatically updated.

func (*Table) Truncate

func (t *Table) Truncate() error

Truncate deletes all the documents from the table.

type TableConstraint added in v0.14.0

type TableConstraint struct {
	Name       string
	Paths      document.Paths
	Check      TableExpression
	Unique     bool
	PrimaryKey bool
}

A TableConstraint represent a constraint specific to a table and not necessarily to a single field path.

func (*TableConstraint) String added in v0.14.0

func (t *TableConstraint) String() string

type TableConstraints added in v0.14.0

type TableConstraints []*TableConstraint

TableConstraints holds the list of CHECK constraints.

func (*TableConstraints) AddCheck added in v0.14.0

func (t *TableConstraints) AddCheck(tableName string, e TableExpression)

func (*TableConstraints) AddPrimaryKey added in v0.14.0

func (t *TableConstraints) AddPrimaryKey(tableName string, p document.Paths) error

func (*TableConstraints) AddUnique added in v0.14.0

func (t *TableConstraints) AddUnique(p document.Paths)

AddUnique adds a unique constraint to the table. If the constraint is already present, it is ignored.

func (*TableConstraints) Merge added in v0.14.0

func (t *TableConstraints) Merge(other TableConstraints) error

func (*TableConstraints) ValidateDocument added in v0.14.0

func (t *TableConstraints) ValidateDocument(tx *Transaction, fb *document.FieldBuffer) error

ValidateDocument checks all the table constraint for the given document.

type TableExpression

type TableExpression interface {
	Bind(catalog *Catalog)
	Eval(tx *Transaction, d types.Document) (types.Value, error)
	IsEqual(other TableExpression) bool
	String() string
}

type TableInfo

type TableInfo struct {
	// name of the table.
	TableName string
	// name of the store associated with the table.
	StoreName []byte
	ReadOnly  bool

	FieldConstraints FieldConstraints
	TableConstraints TableConstraints

	// Name of the docid sequence if any.
	DocidSequenceName string
}

TableInfo contains information about a table.

func (*TableInfo) Clone

func (ti *TableInfo) Clone() *TableInfo

Clone creates another tableInfo with the same values.

func (*TableInfo) GenerateBaseName

func (ti *TableInfo) GenerateBaseName() string

func (*TableInfo) GetFieldConstraintForPath added in v0.14.0

func (ti *TableInfo) GetFieldConstraintForPath(p document.Path) *FieldConstraint

func (*TableInfo) GetPrimaryKey added in v0.14.0

func (ti *TableInfo) GetPrimaryKey() *PrimaryKey

func (*TableInfo) Name

func (ti *TableInfo) Name() string

func (*TableInfo) SetName

func (ti *TableInfo) SetName(name string)

func (*TableInfo) String

func (ti *TableInfo) String() string

String returns a SQL representation.

func (*TableInfo) Type

func (ti *TableInfo) Type() string

func (*TableInfo) ValidateDocument added in v0.14.0

func (ti *TableInfo) ValidateDocument(tx *Transaction, d types.Document) (*document.FieldBuffer, error)

ValidateDocument calls Convert then ensures the document validates against the field constraints.

type Transaction

type Transaction struct {
	Tx       engine.Transaction
	Writable bool
	DBMu     *sync.RWMutex

	// these functions are run after a successful rollback.
	OnRollbackHooks []func()
	// these functions are run after a successful commit.
	OnCommitHooks []func()
}

Transaction represents a database transaction. It provides methods for managing the collection of tables and the transaction itself. Transaction is either read-only or read/write. Read-only can be used to read tables and read/write can be used to read, create, delete and modify tables.

func (*Transaction) Commit

func (tx *Transaction) Commit() error

Commit the transaction. Calling this method on read-only transactions will return an error.

func (*Transaction) Rollback

func (tx *Transaction) Rollback() error

Rollback the transaction. Can be used safely after commit.

type TransientDatabasePool added in v0.14.0

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

TransientDatabasePool manages a pool of transient databases. It keeps a pool of maxTransientPoolSize databases.

func (*TransientDatabasePool) Get added in v0.14.0

Get returns a free engine from the pool, if any. Otherwise it creates a new engine and returns it.

func (*TransientDatabasePool) Release added in v0.14.0

func (t *TransientDatabasePool) Release(ctx context.Context, db *Database) error

Release sets the engine for reuse. If the pool is full, it drops the given engine.

type TxOptions

type TxOptions struct {
	// Open a read-only transaction.
	ReadOnly bool
	// Set the transaction as global at the database level.
	// Any queries run by the database will use that transaction until it is
	// rolled back or commited.
	Attached bool
}

TxOptions are passed to Begin to configure transactions.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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