structured

package
v0.0.0-...-d6fed6f Latest Latest
Warning

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

Go to latest
Published: Aug 14, 2015 License: Apache-2.0 Imports: 12 Imported by: 0

Documentation

Overview

Package structured provides a high-level API for application access to an underlying cockroach datastore. Cockroach itself provides a single monolithic, sorted key-value map. Structured translates between familiar RDBMS concepts such as tables, columns and indexes to the key-value store.

NOTE: THIS IS WILDLY OUT OF DATE WHILE THIS PACKAGE IS BEING REDESIGNED.

Schemas

Schemas declare the structure of data for application access to an underlying Cockroach datastore. Data schemas are declared in YAML files with support for familiar RDBMS concepts such as tables, columns, and indexes. Tables in Cockroach's structured data API are semi-relational. Every row (synonymous with "tuple") in a table must have a unique primary key.

The term "schema" used here is synonymous with "database". A cockroach cluster may contain multiple schemas (or "databases"). Schemas are comprised of tables. Tables are comprised of columns. Columns store values corresponding to basic types including integer (int64), float (float64), string (utf8), blob ([]byte). Columns also store certain composite types including Time and LatLong (for location), IntegerSet (map[int64]struct{}), StringSet (map[string]struct{}), IntegerMap (map[string]int64) and StringMap (map[string]string).

Columns can be designated to form an index. Indexes include secondary indexes, unique secondary indexes, location indexes, and full-text indexes. Additional index types may be added.

An important convention is the use of both a name and a key to describe schemas, tables and columns. The name is used for all external access; the key is used internally for storing keys and values efficiently. Both are specified in the schema declaration; each (name, key) pair for a schema, table or column should be chosen to correspond; the key should be reminiscent of the name in order to aid when debugging. Keys should be short; they are limited to 1-3 characters and may not contain the '/' or ':' characters. Both names and keys must be unique according to the following rules: schemas must be unique in a Cockroach cluster; tables must be unique in a schema; columns must be unique in a table.

Cockroach configuration zones can be specified for the schema as a whole and overridden for individual tables.

YAML Schema Declaration

The general structure of schema files is as follows:

db:     <DB Name>
db_key: <DB Key>
tables: [<Table>, <Table>, ...]

Tables are specified as follows:

  • table: <Table Name> table_key: <Table Key> columns: [<Column>, <Column>, ...]

Columns are specified as follows:

  • column: <Column Name> column_key: <Column Key> type: (integer | float | string | blob | time | latlong | integerset | stringset | integermap | stringmap)> auto_increment: <start-value> foreign_key: <Table>.<Column> index: (secondary | unique | location | fulltext) interleave true on_delete: (cascade | setnull) primary_key: true scatter: true

An example YAML schema configuration file:

db:     PhotoDB
db_key: pdb
tables:
- table:     User
  table_key: us
  columns:
  - column:      ID
    column_key:  id
    type:        integer
    primary_key: true

  - column:     Name
    column_key: na
    type:       string

  - column:     Email
    column_key: em
    type:       string
    index:      uniquesecondary

- table:     Identity
  table_key: id
  columns:
  - column:      Key
    column_key:  ke
    type:        string
    primary_key: true

  - column:      UserID
    column_key:  ui
    type:        integer
    foreign_key: User.ID

Go-Centric Schema Declarations

Package structured also provides Go-centric access via support of struct field tags with the designation "roach". Data schemas may be declared in a style natural to Go, but which map directly to the canonical Cockroach YAML schema format. Methods are provided for easily querying individual items by key, ranges of items by key if key is sorted, or by secondary index if indexed.

Schemas may be defined simply by declaring Go structs with appropriate field tags and then invoking NewGoSchema(...). The struct field tags specify column properties, such as whether the column is part of the primary key, a foreign key, etc. See below for a full list of tag specifications.

import "github.com/cockroach/schema"

// User is a top-level table. User IDs are scattered, meaning a two
// byte hash of the ID from the UserID sequence is prepended to yield
// a randomly distributed keyspace.
type User struct {
	ID   int64 `roach:"pk,auto,scatter"`
	Name string
}

// Identity key takes form of "email:<valid-email-address>"
// or "phone:<valid-phone-number>". A single user may have multiple
// identities.
type Identity struct {
	Key    string `roach:"pk,scatter"`
	UserID int64  `roach:"fk=User.ID,ondelete=setnull"`
}

// Get the schema from the go struct declarations.
sm := map[string]interface{}{
  'us': User{},
  'id': Identity{},
}
s := NewGoSchema('db', sm)

Cockroach tags for struct fields have tag name "roach" followed by the column key and a comma-separated list of <key>[=<value>] specifications, where value can be optional depending on the key. The general form is as follows:

roach:"<column-key>,[<key1[=value1]>,<key2[=value2]>...]"

The <column-key> is a 1-3 letter designation for the column (e.g. 'ui' for 'UserId' and unique within a table) which maintains stable, human readable keys for debugging but which takes minimal bytes for storage. Each instance of this struct will have non-default values encoded using the column keys. Keeping these small can make a significant difference in storage efficiency.

Tag Specifications

"roach" tag specifications are as follows:

fk=<table[.column]>: (Foreign Key) specifies the field is a foreign
key. <table.column> specifies which table and column the foreign key
references. If a foreign key references an object with a composite
primary key, all fields comprising the composite primary key must be
included in the struct with "fk" tags. "column" may be omitted if
the referenced table contains a single-valued primary key.
"ondelete" optionally specifies behavior if referenced object is
deleted. Foreign keys create a secondary index. It isn't necessary
to specify secondaryindex; however, to specify that a foreign key
denotes a one-to-one relation, specify "uniqueindex". "interleave"
optionally specifies that all of the data for structs of this type
will be placed "next to" the referenced table for data locality.

fulltextindex: the column is indexed by segmenting the text into
words and indexing each word separately. The index supports phrase
queries using word position data for each indexed term.

interleave: specified with foreign keys to co-locate dependent data
within a single "entity group" (to use Google's Megastore parlance).
Interleaved data yields faster lookups when querying complete sets
of data (e.g. a comment topic and all comments posted to it), and
faster transactional writes in certain common cases.

locationindex: the column is indexed by location. The details are
implementation-dependent, but the reference impl uses S2 geometry
patches to canvas the specified location. The column type must be
schema.LatLong.

ondelete=<behavior>: the behavior in the event that the object which
a foreign key column references is deleted. The two supported values
are "cascade" and "setnull". "cascade" deletes the object with the
foreign key reference. "setnull" is less destructive, merely setting
the foreign key column to nil. If "interleave" was specified for
this foreign key, then "cascade" is the mandatory default value;
specifying "setnull" for an interleaved foreign key results in a
schema validation error.

pk: (Primary Key) specifies the field is the primary key or part of
a composite primary key. The first field with pk specified will form
the prefix of the key, each additional field with pk specified will
be appended in order. "scatter" may be included only on the first
field with pk specified.

scatter: randomizes the placement of the data within the table's
keyspace by prepending a two-byte hash of the entire primary key to
the actual key used to store the value in cockroach. "scatter" may
only be specified on the first field with "pk" specified.

secondaryindex: a secondary index on the column value. Tuples from
this table (or alternatively, instances of this struct) may be
queried by this column value using the resulting index.

auto[=<start-value>]: specifies that the value of this field
auto-increments from a monotonically increasing sequence starting
at the optional start value.

uniqueindex: a secondary index where uniqueness of the column value
is enforced.

Disconnected Mode

Client may be used in a disconnected mode, which uses internal data structures to stand in for an actual Cockroach cluster. This is useful for unittesting data schemas and migration functions.

How Data is Stored

The structured package contrives to co-locate an arbitrary number of schemas within a single Cockroach cluster without namespace collisions. An example schema:

db:     PhotoDB
db_key: pdb
tables:
- table:     User
  table_key: us
  columns:
  - column:      ID
    column_key:  id
    type:        integer
    primary_key: true

  - column:     Name
    column_key: na
    type:       string

  - column:     Email
    column_key: em
    type:       string
    index:      uniquesecondary

- table:     Identity
  table_key: id
  columns:
  - column:      Key
    column_key:  ke
    type:        string
    primary_key: true

  - column:      UserID
    column_key:  ui
    type:        integer
    foreign_key: User.ID

All data belonging to a schema is stored with keys prefixed by <db_key>. In the configuration example above, this would correspond to a key prefix of "pdb". Tables are further prefixed by the table key. A tuple from table User would have key prefix "pdb/us". The tuple's key suffix is an encoded concatenation of column values marked as part of the primary key. For a user with ID=531, the full key would be "pdb/us/<OrderedEncode(531)>" (from here on out, we'll shorten OrderedEncode to just "E"). The value stored with the key is a gob-encoded map[string]interface{}, with each column value (excepting primary keys) as an entry in the map, indexed by column key.

pdb/us/<E(529)>: <data for user 529>
pdb/us/<E(530)>: <data for user 530>
pdb/us/<E(531)>: <data for user 531>

If a primary key column has the "scatter" option specified, the encoded value for the key is additionally prefixed with the first two bytes of a hash of the entire primary key value. For example, If the hash of 531 is 1532079858. The first two bytes are 0xf2 and 0xae. The key would be "pdb/us/\xf2\xae<E(531)>". This provides an essentially random location for the columnar data of User 531 within the "pdb/us/..." keyspace. Using the "scatter" option prevents hotspots in non-uniformly distributed data. For example, primary keys generated from a monotonically-increasing sequence or from the current time. Keep in mind, however, that using "scatter" makes range scans impossible.

pdb/us/\x09\x31<E(530)>: <data for user 530>
...
pdb/us/\x50\xae<E(531)>: <data for user 531>
...
pdb/us/\xf2\xb9<E(529)>: <data for user 529>

If a foreign key column has the "interleave" option specified, the data for the table is co-located with the table referenced by the foreign key. For example, let's consider an additional table in the schema, Address, containing addresses for Users (abbreviated for concision).

  • table: Address table_key: ad columns:

  • column: ID column_key: id type: integer primary_key: true

  • column: UserID column_key: ui type: integer foreign_key: User.ID interleave: true

  • column: Street column_key: st type: string

  • column: City column_key: cy type: string

Because an address has no meaning outside of a user, there is value in co-locating keys for a user's addresses with the user data. Transactions modifying both a user and an address (on account creation, for example) are likely to be part of the same cockroach key range and therefore will be committed without requiring a distributed transaction. If "interleave" is specified, the referenced table entity's key is used as a key prefix. This makes for longer keys, but guarantees all data is proximately located. If User 531 has two addresses, with ids 35 & 56 respectively, the underlying data would look like:

pdb/us/<E(529)>: <data for user 529>
...
pdb/us/<E(531)>: <data for user 531>
pdb/us/<E(531)>/ad/<E(35)>: <data for address 35>
pdb/us/<E(531)>/ad/<E(56)>: <data for address 56>
...
pdb/us/<E(600)>: <data for user 600>
...

Indexes

Indexes provide efficient access to rows in the database by columnar data other than primary keys. In the example above, we might want to lookup a User by Email instead of ID, as in the case of login by email address. Email is not the primary key, so without an index, there would be no way to lookup a user without scanning the entire User table to find the email address in question.

A sensible alternative would be to create another table, UserByEmail, with (email, user) as a composite primary key. We could then do a range scan on UserByEmail starting at (<email>, _) to find a matching email and discover the associated user ID in order to then lookup the user for login. This is exactly how indexes work, but Cockroach takes care of all of the necessary work to create and maintain them behind the scenes.

An index on email address for users would require a unique secondary index. Unique because no two users should be allowed the same email address for login. Secondary simply means that the exact value of the email address must be supplied in order to do the lookup. Non-unique secondary indexes are also possible. For example, If User.Name were indexed, two or more users might have identical names. A non-unique secondary index yields a list of users on lookup.

Other index types include "location", which allows queries by latitude and longitude; and "fulltext", which segments string-valued columns into "words", any subset of which may be used to query the index. If fulltext were specified on User.Name, then user IDs could be queried by first, middle or last name separately.

How Index Data is Stored

As discussed in the thought experiment about creating the UserByEmail table, index data is simply stored as another table. In the example of a secondary index on User.Email, a new table with table_key 'us:em' is created. The primary key for this table is a composite of the index term (User.Email) and the primary key of the User table (User.ID).

pdb/us/<E(531)>: <data for user 531, email foo@bar.com>
pdb/us/<E(10247)>: <data for user 10247, email baz@fubar.com>
...
pdb/us:em/<E(baz@fubar.com)><E(10247)>: nil
pdb/us:em/<E(foo@bar.com)><E(531)>: nil

As can be seen above, the keyspace taken by the UserEmail index table follows the User table. In order to lookup the user with email "foo@bar.com", a range scan is initiated for the lower bound of "foo@bar.com", and keys with matching prefix are decoded to yield the list of matching user IDs.

Secondary indexes have a single term and which exactly mirrors their value. User.Email is an example of this. For email=X, the term is X. Secondary indexes contain only keys, no values. If the secondary index is unique, then a range scan is done on insert to verify that no other index term with the same prefix is already present.

Index types other than secondary, such as "location" and "fulltext", may yield multiple index terms for a column value. Full text indexes, for example, yield one term per segmented word. With a fulltext index on User.Name, "Spencer Woolley Kimball" would yield three terms: {"Spencer", "Woolley", "Kimball"}. Full text indexing also stores a special value for each term which indicates the list of positions that term appears in the source string. Further, index types which yield multiple terms store the indexed terms in a special additional "term" column (named <column_key>:t). This list of terms is used to delete terms from the index in the event the column is deleted or updated. If Spencer had user ID 1:

pdb/us/<E(1)>: {em: "spencer.kimball@gmail.com,
                na: "Spencer Woolley Kimball",
                na:t: ["kimball", "spencer", "woolley"]}
...
pdb/us:na/<E(kimball)><E(1)>: {tp: [2]}
pdb/us:na/<E(spencer)><E(1)>: {tp: [0]}
pdb/us:na/<E(woolley)><E(1)>: {tp: [1]}

Terms can and should efficiently combine multiple source ids into a list instead of requiring a separate key for every instance. This is left as future work, as it's non-trivial to do efficiently.

Package structured is a generated protocol buffer package.

It is generated from these files:
	cockroach/structured/structured.proto

It has these top-level messages:
	ColumnType
	ColumnDescriptor
	IndexDescriptor
	PrivilegeDescriptor
	TableDescriptor
	DatabaseDescriptor

Index

Constants

This section is empty.

Variables

View Source
var ColumnType_Kind_name = map[int32]string{
	0:  "BIT",
	1:  "BOOL",
	2:  "INT",
	3:  "FLOAT",
	4:  "DECIMAL",
	5:  "DATE",
	6:  "TIME",
	7:  "TIMESTAMP",
	8:  "CHAR",
	9:  "TEXT",
	10: "BLOB",
}
View Source
var ColumnType_Kind_value = map[string]int32{
	"BIT":       0,
	"BOOL":      1,
	"INT":       2,
	"FLOAT":     3,
	"DECIMAL":   4,
	"DATE":      5,
	"TIME":      6,
	"TIMESTAMP": 7,
	"CHAR":      8,
	"TEXT":      9,
	"BLOB":      10,
}
View Source
var (
	ErrInvalidLengthStructured = fmt.Errorf("proto: negative length found during unmarshaling")
)
View Source
var ErrMissingPrimaryKey = errors.New("table must contain a primary key")

ErrMissingPrimaryKey exported to the sql package.

Functions

func MakeColumnKey

func MakeColumnKey(colID ColumnID, primaryKey []byte) proto.Key

MakeColumnKey returns the key for the column in the given row.

func MakeDescMetadataKey

func MakeDescMetadataKey(descID ID) proto.Key

MakeDescMetadataKey returns the key for the descriptor.

func MakeIndexKeyPrefix

func MakeIndexKeyPrefix(tableID ID, indexID IndexID) []byte

MakeIndexKeyPrefix returns the key prefix used for the index's data.

func MakeNameMetadataKey

func MakeNameMetadataKey(parentID ID, name string) proto.Key

MakeNameMetadataKey returns the key for the name.

func MakeTablePrefix

func MakeTablePrefix(tableID ID) []byte

MakeTablePrefix returns the key prefix used for the table's data.

Types

type ColumnDescriptor

type ColumnDescriptor struct {
	Name             string     `protobuf:"bytes,1,opt,name=name" json:"name"`
	ID               ColumnID   `protobuf:"varint,2,opt,name=id,casttype=ColumnID" json:"id"`
	Type             ColumnType `protobuf:"bytes,3,opt,name=type" json:"type"`
	Nullable         bool       `protobuf:"varint,4,opt,name=nullable" json:"nullable"`
	XXX_unrecognized []byte     `json:"-"`
}

func (*ColumnDescriptor) GetID

func (m *ColumnDescriptor) GetID() ColumnID

func (*ColumnDescriptor) GetName

func (m *ColumnDescriptor) GetName() string

func (*ColumnDescriptor) GetNullable

func (m *ColumnDescriptor) GetNullable() bool

func (*ColumnDescriptor) GetType

func (m *ColumnDescriptor) GetType() ColumnType

func (*ColumnDescriptor) Marshal

func (m *ColumnDescriptor) Marshal() (data []byte, err error)

func (*ColumnDescriptor) MarshalTo

func (m *ColumnDescriptor) MarshalTo(data []byte) (n int, err error)

func (*ColumnDescriptor) ProtoMessage

func (*ColumnDescriptor) ProtoMessage()

func (*ColumnDescriptor) Reset

func (m *ColumnDescriptor) Reset()

func (*ColumnDescriptor) Size

func (m *ColumnDescriptor) Size() (n int)

func (*ColumnDescriptor) String

func (m *ColumnDescriptor) String() string

func (*ColumnDescriptor) Unmarshal

func (m *ColumnDescriptor) Unmarshal(data []byte) error

type ColumnID

type ColumnID uint32

ColumnID is a custom type for ColumnDescriptor IDs.

type ColumnType

type ColumnType struct {
	Kind ColumnType_Kind `protobuf:"varint,1,opt,name=kind,enum=cockroach.structured.ColumnType_Kind" json:"kind"`
	// BIT, INT, FLOAT, DECIMAL, CHAR and BINARY
	Width int32 `protobuf:"varint,2,opt,name=width" json:"width"`
	// FLOAT and DECIMAL.
	Precision        int32  `protobuf:"varint,3,opt,name=precision" json:"precision"`
	XXX_unrecognized []byte `json:"-"`
}

func (*ColumnType) GetKind

func (m *ColumnType) GetKind() ColumnType_Kind

func (*ColumnType) GetPrecision

func (m *ColumnType) GetPrecision() int32

func (*ColumnType) GetWidth

func (m *ColumnType) GetWidth() int32

func (*ColumnType) Marshal

func (m *ColumnType) Marshal() (data []byte, err error)

func (*ColumnType) MarshalTo

func (m *ColumnType) MarshalTo(data []byte) (n int, err error)

func (*ColumnType) ProtoMessage

func (*ColumnType) ProtoMessage()

func (*ColumnType) Reset

func (m *ColumnType) Reset()

func (*ColumnType) SQLString

func (c *ColumnType) SQLString() string

SQLString returns the SQL string corresponding to the type.

func (*ColumnType) Size

func (m *ColumnType) Size() (n int)

func (*ColumnType) String

func (m *ColumnType) String() string

func (*ColumnType) Unmarshal

func (m *ColumnType) Unmarshal(data []byte) error

type ColumnType_Kind

type ColumnType_Kind int32

These mirror the types supported by the sql/parser. See sql/parser/types.go.

const (
	ColumnType_BIT       ColumnType_Kind = 0
	ColumnType_BOOL      ColumnType_Kind = 1
	ColumnType_INT       ColumnType_Kind = 2
	ColumnType_FLOAT     ColumnType_Kind = 3
	ColumnType_DECIMAL   ColumnType_Kind = 4
	ColumnType_DATE      ColumnType_Kind = 5
	ColumnType_TIME      ColumnType_Kind = 6
	ColumnType_TIMESTAMP ColumnType_Kind = 7
	ColumnType_CHAR      ColumnType_Kind = 8
	ColumnType_TEXT      ColumnType_Kind = 9
	ColumnType_BLOB      ColumnType_Kind = 10
)

func (ColumnType_Kind) Enum

func (x ColumnType_Kind) Enum() *ColumnType_Kind

func (ColumnType_Kind) String

func (x ColumnType_Kind) String() string

func (*ColumnType_Kind) UnmarshalJSON

func (x *ColumnType_Kind) UnmarshalJSON(data []byte) error

type DatabaseDescriptor

type DatabaseDescriptor struct {
	Name                string `protobuf:"bytes,1,opt,name=name" json:"name"`
	ID                  ID     `protobuf:"varint,2,opt,name=id,casttype=ID" json:"id"`
	PrivilegeDescriptor `protobuf:"bytes,3,opt,name=privileges,embedded=privileges" json:"privileges"`
	XXX_unrecognized    []byte `json:"-"`
}

DatabaseDescriptor represents a namespace (aka database) and is stored in a structured metadata key. The DatabaseDescriptor has a globally-unique ID shared with the TableDescriptor ID. Permissions are applied to all tables in the namespace.

func (*DatabaseDescriptor) GetID

func (m *DatabaseDescriptor) GetID() ID

func (*DatabaseDescriptor) GetName

func (m *DatabaseDescriptor) GetName() string

func (*DatabaseDescriptor) Marshal

func (m *DatabaseDescriptor) Marshal() (data []byte, err error)

func (*DatabaseDescriptor) MarshalTo

func (m *DatabaseDescriptor) MarshalTo(data []byte) (n int, err error)

func (*DatabaseDescriptor) ProtoMessage

func (*DatabaseDescriptor) ProtoMessage()

func (*DatabaseDescriptor) Reset

func (m *DatabaseDescriptor) Reset()

func (*DatabaseDescriptor) SetID

func (desc *DatabaseDescriptor) SetID(id ID)

SetID implements the sql.descriptorProto interface.

func (*DatabaseDescriptor) SetName

func (desc *DatabaseDescriptor) SetName(name string)

SetName implements the sql.descriptorProto interface.

func (*DatabaseDescriptor) Size

func (m *DatabaseDescriptor) Size() (n int)

func (*DatabaseDescriptor) String

func (m *DatabaseDescriptor) String() string

func (*DatabaseDescriptor) TypeName

func (desc *DatabaseDescriptor) TypeName() string

TypeName returns the plain type of this descriptor.

func (*DatabaseDescriptor) Unmarshal

func (m *DatabaseDescriptor) Unmarshal(data []byte) error

func (*DatabaseDescriptor) Validate

func (desc *DatabaseDescriptor) Validate() error

Validate validates that the database descriptor is well formed. Checks include validate the database name, and verifying that there is at least one read and write user.

type ID

type ID uint32

ID is a custom type for {Database,Table}Descriptor IDs.

const (
	// PrimaryKeyIndexName is the name of the index for the primary key.
	PrimaryKeyIndexName = "primary"
	// MaxReservedDescID is the maximum reserved descriptor ID.
	MaxReservedDescID ID = 999
	// RootNamespaceID is the ID of the root namespace.
	RootNamespaceID ID = 0
)

type IndexDescriptor

type IndexDescriptor struct {
	Name   string  `protobuf:"bytes,1,opt,name=name" json:"name"`
	ID     IndexID `protobuf:"varint,2,opt,name=id,casttype=IndexID" json:"id"`
	Unique bool    `protobuf:"varint,3,opt,name=unique" json:"unique"`
	// An ordered list of column names of which the index is comprised. This list
	// parallels the column_ids list. If duplicating the storage of the column
	// names here proves to be prohibitive, we could clear this field before
	// saving and reconstruct it after loading.
	ColumnNames []string `protobuf:"bytes,4,rep,name=column_names" json:"column_names,omitempty"`
	// An ordered list of column ids of which the index is comprised. This list
	// parallels the column_names list.
	ColumnIDs        []ColumnID `protobuf:"varint,5,rep,name=column_ids,casttype=ColumnID" json:"column_ids,omitempty"`
	XXX_unrecognized []byte     `json:"-"`
}

func (*IndexDescriptor) GetColumnIDs

func (m *IndexDescriptor) GetColumnIDs() []ColumnID

func (*IndexDescriptor) GetColumnNames

func (m *IndexDescriptor) GetColumnNames() []string

func (*IndexDescriptor) GetID

func (m *IndexDescriptor) GetID() IndexID

func (*IndexDescriptor) GetName

func (m *IndexDescriptor) GetName() string

func (*IndexDescriptor) GetUnique

func (m *IndexDescriptor) GetUnique() bool

func (*IndexDescriptor) Marshal

func (m *IndexDescriptor) Marshal() (data []byte, err error)

func (*IndexDescriptor) MarshalTo

func (m *IndexDescriptor) MarshalTo(data []byte) (n int, err error)

func (*IndexDescriptor) ProtoMessage

func (*IndexDescriptor) ProtoMessage()

func (*IndexDescriptor) Reset

func (m *IndexDescriptor) Reset()

func (*IndexDescriptor) Size

func (m *IndexDescriptor) Size() (n int)

func (*IndexDescriptor) String

func (m *IndexDescriptor) String() string

func (*IndexDescriptor) Unmarshal

func (m *IndexDescriptor) Unmarshal(data []byte) error

type IndexID

type IndexID uint32

IndexID is a custom type for IndexDescriptor IDs.

type PrivilegeDescriptor

type PrivilegeDescriptor struct {
	// lists of users with read permissions.
	Read []string `protobuf:"bytes,1,rep,name=read" json:"read,omitempty"`
	// lists of users with write permissions.
	Write            []string `protobuf:"bytes,2,rep,name=write" json:"write,omitempty"`
	XXX_unrecognized []byte   `json:"-"`
}

PrivilegeDescriptor represents the sets of privileges on a descriptor.

func (*PrivilegeDescriptor) GetRead

func (m *PrivilegeDescriptor) GetRead() []string

func (*PrivilegeDescriptor) GetWrite

func (m *PrivilegeDescriptor) GetWrite() []string

func (*PrivilegeDescriptor) Grant

func (p *PrivilegeDescriptor) Grant(n *parser.Grant) error

Grant adds new privileges to this descriptor for a given list of users.

func (*PrivilegeDescriptor) HasPrivilege

func (p *PrivilegeDescriptor) HasPrivilege(user string, privilege parser.PrivilegeType) bool

HasPrivilege returns true if `user` has `privilege` on this descriptor.

func (*PrivilegeDescriptor) Marshal

func (m *PrivilegeDescriptor) Marshal() (data []byte, err error)

func (*PrivilegeDescriptor) MarshalTo

func (m *PrivilegeDescriptor) MarshalTo(data []byte) (n int, err error)

func (*PrivilegeDescriptor) ProtoMessage

func (*PrivilegeDescriptor) ProtoMessage()

func (*PrivilegeDescriptor) Reset

func (m *PrivilegeDescriptor) Reset()

func (*PrivilegeDescriptor) Revoke

func (p *PrivilegeDescriptor) Revoke(n *parser.Revoke) error

Revoke removes privileges from this descriptor for a given list of users.

func (*PrivilegeDescriptor) Show

Show returns the list of users and associated privileges for this descriptor.

func (*PrivilegeDescriptor) Size

func (m *PrivilegeDescriptor) Size() (n int)

func (*PrivilegeDescriptor) String

func (m *PrivilegeDescriptor) String() string

func (*PrivilegeDescriptor) Unmarshal

func (m *PrivilegeDescriptor) Unmarshal(data []byte) error

type TableDescriptor

type TableDescriptor struct {
	Name string `protobuf:"bytes,1,opt,name=name" json:"name"`
	// The alias for the table. This is only used during query
	// processing and not stored persistently.
	Alias   string             `protobuf:"bytes,2,opt,name=alias" json:"alias"`
	ID      ID                 `protobuf:"varint,3,opt,name=id,casttype=ID" json:"id"`
	Columns []ColumnDescriptor `protobuf:"bytes,4,rep,name=columns" json:"columns"`
	// next_column_id is used to ensure that deleted column ids are not reused.
	NextColumnID ColumnID        `protobuf:"varint,5,opt,name=next_column_id,casttype=ColumnID" json:"next_column_id"`
	PrimaryIndex IndexDescriptor `protobuf:"bytes,6,opt,name=primary_index" json:"primary_index"`
	// indexes are all the secondary indexes.
	Indexes []IndexDescriptor `protobuf:"bytes,7,rep,name=indexes" json:"indexes"`
	// next_index_id is used to ensure that deleted index ids are not reused.
	NextIndexID         IndexID `protobuf:"varint,8,opt,name=next_index_id,casttype=IndexID" json:"next_index_id"`
	PrivilegeDescriptor `protobuf:"bytes,9,opt,name=privileges,embedded=privileges" json:"privileges"`
	XXX_unrecognized    []byte `json:"-"`
}

A TableDescriptor represents a table and is stored in a structured metadata key. The TableDescriptor has a globally-unique ID, while its member {Column,Index}Descriptors have locally-unique IDs.

func (*TableDescriptor) AllocateIDs

func (desc *TableDescriptor) AllocateIDs() error

AllocateIDs allocates column and index ids for any column or index which has an ID of 0.

func (*TableDescriptor) FindColumnByID

func (desc *TableDescriptor) FindColumnByID(id ColumnID) (*ColumnDescriptor, error)

FindColumnByID finds the column with specified ID.

func (*TableDescriptor) FindColumnByName

func (desc *TableDescriptor) FindColumnByName(name string) (*ColumnDescriptor, error)

FindColumnByName finds the column with specified name.

func (*TableDescriptor) GetAlias

func (m *TableDescriptor) GetAlias() string

func (*TableDescriptor) GetColumns

func (m *TableDescriptor) GetColumns() []ColumnDescriptor

func (*TableDescriptor) GetID

func (m *TableDescriptor) GetID() ID

func (*TableDescriptor) GetIndexes

func (m *TableDescriptor) GetIndexes() []IndexDescriptor

func (*TableDescriptor) GetName

func (m *TableDescriptor) GetName() string

func (*TableDescriptor) GetNextColumnID

func (m *TableDescriptor) GetNextColumnID() ColumnID

func (*TableDescriptor) GetNextIndexID

func (m *TableDescriptor) GetNextIndexID() IndexID

func (*TableDescriptor) GetPrimaryIndex

func (m *TableDescriptor) GetPrimaryIndex() IndexDescriptor

func (*TableDescriptor) Marshal

func (m *TableDescriptor) Marshal() (data []byte, err error)

func (*TableDescriptor) MarshalTo

func (m *TableDescriptor) MarshalTo(data []byte) (n int, err error)

func (*TableDescriptor) ProtoMessage

func (*TableDescriptor) ProtoMessage()

func (*TableDescriptor) Reset

func (m *TableDescriptor) Reset()

func (*TableDescriptor) SetID

func (desc *TableDescriptor) SetID(id ID)

SetID implements the sql.descriptorProto interface.

func (*TableDescriptor) SetName

func (desc *TableDescriptor) SetName(name string)

SetName implements the sql.descriptorProto interface.

func (*TableDescriptor) Size

func (m *TableDescriptor) Size() (n int)

func (*TableDescriptor) String

func (m *TableDescriptor) String() string

func (*TableDescriptor) TypeName

func (desc *TableDescriptor) TypeName() string

TypeName returns the plain type of this descriptor.

func (*TableDescriptor) Unmarshal

func (m *TableDescriptor) Unmarshal(data []byte) error

func (*TableDescriptor) Validate

func (desc *TableDescriptor) Validate() error

Validate validates that the table descriptor is well formed. Checks include validating the table, column and index names, verifying that column names and index names are unique and verifying that column IDs and index IDs are consistent.

type UserPrivilegeList

type UserPrivilegeList []*UserPrivileges

UserPrivilegeList is a list of UserPrivileges.

func (UserPrivilegeList) Len

func (upl UserPrivilegeList) Len() int

func (UserPrivilegeList) Less

func (upl UserPrivilegeList) Less(i, j int) bool

func (UserPrivilegeList) Swap

func (upl UserPrivilegeList) Swap(i, j int)

type UserPrivileges

type UserPrivileges struct {
	User       string
	Privileges parser.PrivilegeList
}

UserPrivileges contains a user and list of associated privileges.

Jump to

Keyboard shortcuts

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