Documentation
¶
Overview ¶
Package dosa is the DOSA - Declarative Object Storage Abstraction.
Abstract ¶
:warning: DOSA is BETA software. It is not recommended for production use. We will announce when it's ready.
DOSA (https://github.com/uber-go/dosa/wiki) is a storage framework that provides a delcarative object storage abstraction for applications in Golang and (eventually) Java. DOSA is designed to relieve common headaches developers face while building stateful, database-dependent services.
If you'd like to start by writing a small DOSA-enabled program, check out the getting started guide (https://github.com/uber-go/dosa/wiki/Getting-Started-Guide).
Overview ¶
DOSA is a storage library that supports:
• methods to store and retrieve go structs
• struct annotations to describe queries against data
• tools to create and/or migrate database schemas
• implementations that serialize requests to remote stateless servers
Annotations ¶
This project is released under the MIT License (LICENSE.txt).
Index ¶
- Constants
- Variables
- func All() []string
- func EnsureValidRangeConditions(ed *EntityDefinition, pk *PrimaryKey, columnConditions map[string][]*Condition, ...) error
- func EqRangeOp(op *RangeOp) gomock.Matcher
- func EqScanOp(op *ScanOp) gomock.Matcher
- func ErrorIsAlreadyExists(err error) bool
- func ErrorIsNotFound(err error) bool
- func ErrorIsNotInitialized(err error) bool
- func IsValidName(name string) error
- func NormalizeName(name string) (string, error)
- func RegisterConnector(name string, creationFunc func(CreationArgs) (Connector, error))
- type AdminClient
- type Client
- type ClusteringKey
- type ColumnDefinition
- type Condition
- type Connector
- type CreationArgs
- type CreationFuncType
- type DomainIndex
- type DomainObject
- type Entity
- type EntityDefinition
- func (e *EntityDefinition) Clone() *EntityDefinition
- func (e *EntityDefinition) ColumnMap() map[string]*ColumnDefinition
- func (e *EntityDefinition) ColumnTypes() map[string]Type
- func (e *EntityDefinition) EnsureValid() error
- func (e *EntityDefinition) FindColumnDefinition(name string) *ColumnDefinition
- func (e *EntityDefinition) IsCompatible(e2 *EntityDefinition) error
- func (e *EntityDefinition) KeySet() map[string]struct{}
- func (e *EntityDefinition) PartitionKeySet() map[string]struct{}
- func (e *EntityDefinition) UniqueKey(oldKey *PrimaryKey) *PrimaryKey
- type EntityErrors
- type EntityInfo
- type EntityRecordingVisitor
- type ErrAlreadyExists
- type ErrNotFound
- type ErrNotInitialized
- type FQN
- type FieldNameValuePair
- type FieldValue
- type FieldValuesOrError
- type Index
- type IndexDefinition
- type MultiResult
- type Operator
- type PrimaryKey
- type RangeOp
- func (r *RangeOp) Eq(fieldName string, value interface{}) *RangeOp
- func (r *RangeOp) Fields(fields []string) *RangeOp
- func (r *RangeOp) Gt(fieldName string, value interface{}) *RangeOp
- func (r *RangeOp) GtOrEq(fieldName string, value interface{}) *RangeOp
- func (r *RangeOp) Limit(n int) *RangeOp
- func (r *RangeOp) Lt(fieldName string, value interface{}) *RangeOp
- func (r *RangeOp) LtOrEq(fieldName string, value interface{}) *RangeOp
- func (r *RangeOp) Offset(token string) *RangeOp
- func (r *RangeOp) String() string
- type RegisteredEntity
- func (e *RegisteredEntity) ColumnNames(fieldNames []string) ([]string, error)
- func (e *RegisteredEntity) EntityDefinition() *EntityDefinition
- func (e *RegisteredEntity) EntityInfo() *EntityInfo
- func (e *RegisteredEntity) KeyFieldValues(entity DomainObject) map[string]FieldValue
- func (e *RegisteredEntity) OnlyFieldValues(entity DomainObject, fieldNames []string) (map[string]FieldValue, error)
- func (e *RegisteredEntity) SchemaRef() *SchemaRef
- func (e *RegisteredEntity) SetFieldValues(entity DomainObject, fieldValues map[string]FieldValue, fieldsToRead []string)
- func (e *RegisteredEntity) SetVersion(v int32)
- type Registrar
- type RemoveRangeOp
- func (r *RemoveRangeOp) Eq(fieldName string, value interface{}) *RemoveRangeOp
- func (r *RemoveRangeOp) Gt(fieldName string, value interface{}) *RemoveRangeOp
- func (r *RemoveRangeOp) GtOrEq(fieldName string, value interface{}) *RemoveRangeOp
- func (r *RemoveRangeOp) Lt(fieldName string, value interface{}) *RemoveRangeOp
- func (r *RemoveRangeOp) LtOrEq(fieldName string, value interface{}) *RemoveRangeOp
- type ScanOp
- type SchemaRef
- type SchemaStatus
- type SearchOp
- type Table
- type Type
- type UUID
Examples ¶
Constants ¶
const DosaPackageName = `"github.com/uber-go/dosa"`
DosaPackageName is the name of the dosa package, fully qualified and quoted
const VERSION = "2.3.0"
VERSION indicates the dosa client version
Variables ¶
var ErrNullValue = errors.New("Value is null")
ErrNullValue is returned if a caller tries to call Get() on a nullable primitive value.
Functions ¶
func All ¶
func All() []string
All is used for "fields []string" to read/update all fields. It's a convenience function for code readability.
func EnsureValidRangeConditions ¶
func EnsureValidRangeConditions(ed *EntityDefinition, pk *PrimaryKey, columnConditions map[string][]*Condition, transform func(string) string) error
EnsureValidRangeConditions checks if the conditions for a range query is valid. The transform arg is a function to transform the column name to a better representation for error message under different circumstances. For example, on client side it can transform the column name to actual go struct field name; and on the server side, an identity transformer func can be used.
func EqRangeOp ¶
EqRangeOp creates a gomock Matcher that will match any RangeOp with the same conditions, limit, token, and fields as those specified in the op argument.
func EqScanOp ¶
EqScanOp provides a gomock Matcher that matches any ScanOp with a limit, token, and fields to read that are the same as those specificed by the op argument.
func ErrorIsAlreadyExists ¶
ErrorIsAlreadyExists checks if the error is caused by "ErrAlreadyExists"
func ErrorIsNotFound ¶
ErrorIsNotFound checks if the error is a "ErrNotFound" (possibly wrapped)
func ErrorIsNotInitialized ¶
ErrorIsNotInitialized checks if the error is a "ErrNotInitialized" (possibly wrapped)
func IsValidName ¶
IsValidName checks if a name conforms the following rules: 1. name starts with [a-z_] 2. the rest of name can contain only [a-z0-9_] 3. the length of name must be greater than 0 and less than or equal to maxNameLen
func NormalizeName ¶
NormalizeName normalizes names to a canonical representation by lowercase everything. It returns error if the resultant canonical name is invalid.
func RegisterConnector ¶
func RegisterConnector(name string, creationFunc func(CreationArgs) (Connector, error))
RegisterConnector registers a connector given a name
Types ¶
type AdminClient ¶
type AdminClient interface { // Directories sets admin client search path Directories(dirs []string) AdminClient // Excludes sets patters to exclude when searching for entities Excludes(excludes []string) AdminClient // Scope sets the admin client scope Scope(scope string) AdminClient // CheckSchema checks the compatibility of schemas CheckSchema(ctx context.Context, namePrefix string) (*SchemaStatus, error) // CheckSchemaStatus checks the status of schema application CheckSchemaStatus(ctx context.Context, namePrefix string, version int32) (*SchemaStatus, error) // UpsertSchema upserts the schemas UpsertSchema(ctx context.Context, namePrefix string) (*SchemaStatus, error) // GetSchema finds entity definitions GetSchema() ([]*EntityDefinition, error) // CreateScope creates a new scope CreateScope(ctx context.Context, s string) error // TruncateScope keeps the scope and the schemas, but drops the data associated with the scope TruncateScope(ctx context.Context, s string) error // DropScope drops the scope and the data and schemas in the scope DropScope(ctx context.Context, s string) error }
AdminClient has methods to manage schemas and scopes
func NewAdminClient ¶
func NewAdminClient(conn Connector) AdminClient
NewAdminClient returns a new DOSA admin client for the connector provided.
type Client ¶
type Client interface { // Initialize must be called before any data operation Initialize(ctx context.Context) error // Create creates an entity; it fails if the entity already exists. // You must fill in all of the fields of the DomainObject before // calling this method, or they will be inserted with the zero value // This is a relatively expensive operation. Use Upsert whenever possible. CreateIfNotExists(ctx context.Context, objectToCreate DomainObject) error // Read fetches a row by primary key. A list of fields to read can be // specified. Use All() or nil for all fields. // Before calling this method, fill in the DomainObject with ALL // of the primary key fields; the other field values will be populated // as a result of the read Read(ctx context.Context, fieldsToRead []string, objectToRead DomainObject) error // Upsert creates or update a row. A list of fields to update can be // specified. Use All() or nil for all fields. // Before calling this method, fill in the DomainObject with ALL // of the primary key fields, along with whatever fields you specify // to update in fieldsToUpdate (or all the fields if you use dosa.All()) Upsert(ctx context.Context, fieldsToUpdate []string, objectToUpdate DomainObject) error // Remove removes a row by primary key. The passed-in entity should contain // the primary key field values, all other fields are ignored. Remove(ctx context.Context, objectToRemove DomainObject) error // RemoveRange removes all of the rows that fall within the range specified by the // given RemoveRangeOp. RemoveRange(ctx context.Context, removeRangeOp *RemoveRangeOp) error // Range fetches entities within a range // Before calling range, create a RangeOp and fill in the table // along with the partition key information. You will get back // an array of DomainObjects, which will be of the type you requested // in the rangeOp. // // Range only fetches a portion of the range at a time (the size of that portion is defined // by the Limit parameter of the RangeOp). A continuation token is returned so subsequent portions // of the range can be fetched with additional calls to the range function. Range(ctx context.Context, rangeOp *RangeOp) ([]DomainObject, string, error) // WalkRange starts at the offset specified by the RangeOp and walks the entire // range of values that fall within the RangeOp conditions. It will make multiple, sequential // range requests, fetching values until there are no more left in the range. // // For each value fetched, the provided onNext function is called with the value as it's argument. WalkRange(ctx context.Context, r *RangeOp, onNext func(value DomainObject) error) error // ScanEverything fetches all entities of a type // Before calling ScanEverything, create a scanOp to specify the // table to scan. The return values are an array of objects, that // you can type-assert to the appropriate dosa.Entity, a string // that contains the continuation token, and any error. // To scan the next set of rows, modify the scanOp to provide // the string returned as an Offset() ScanEverything(ctx context.Context, scanOp *ScanOp) ([]DomainObject, string, error) }
Client defines the methods to operate with DOSA entities
func NewClient ¶
NewClient returns a new DOSA client for the registry and connector provided. This is currently only a partial implementation to demonstrate basic CRUD functionality.
Example ¶
ExampleNewClient initializes a client using the devnull connector, which discards all the data you send it and always returns no rows. It's only useful for testing dosa.
package main import ( "context" "fmt" dosaRenamed "github.com/uber-go/dosa" _ "github.com/uber-go/dosa/connectors/devnull" _ "github.com/uber-go/dosa/connectors/memory" ) type ClientTestEntity1 struct { dosaRenamed.Entity `dosa:"primaryKey=(ID)"` dosaRenamed.Index `dosa:"key=Name, name=username"` ID int64 Name string Email string } type ClientTestEntity2 struct { dosaRenamed.Entity `dosa:"primaryKey=(UUID,Color)"` SearchByColor dosaRenamed.Index `dosa:"key=Color"` UUID string Color string IsActive bool ignoreme int32 } var cte1 = &ClientTestEntity1{ID: int64(1), Name: "foo", Email: "foo@uber.com"} func main() { // initialize registrar reg, err := dosaRenamed.NewRegistrar("test", "myteam.myservice", cte1) if err != nil { // registration will fail if the object is tagged incorrectly fmt.Printf("NewRegistrar error: %s", err) return } // use a devnull connector for example purposes conn, err := dosaRenamed.GetConnector("devnull", nil) if err != nil { fmt.Printf("GetConnector error: %s", err) return } // create the client using the registry and connector client := dosaRenamed.NewClient(reg, conn) err = client.Initialize(context.Background()) if err != nil { fmt.Printf("Initialize error: %s", err) return } }
Output:
type ClusteringKey ¶
ClusteringKey stores name and ordering of a clustering key
func (ClusteringKey) String ¶
func (ck ClusteringKey) String() string
String takes a ClusteringKey and returns "column-name ASC|DESC"
type ColumnDefinition ¶
type ColumnDefinition struct { Name string // normalized column name Type Type IsPointer bool // used by client only to indicate whether this field is pointer // TODO: change as need to support tags like pii, searchable, etc // currently it's in the form of a map from tag name to (optional) tag value Tags map[string]string }
ColumnDefinition stores information about a column
func (*ColumnDefinition) Clone ¶
func (cd *ColumnDefinition) Clone() *ColumnDefinition
Clone returns a deep copy of ColumnDefinition
type Condition ¶
type Condition struct { Op Operator Value FieldValue }
Condition holds an operator and a value for a condition on a field.
type Connector ¶
type Connector interface { // DML operations (CRUD + search) // CreateIfNotExists creates a row, but only if it does not exist. CreateIfNotExists(ctx context.Context, ei *EntityInfo, values map[string]FieldValue) error // Read fetches a row by primary key // If minimumFields is empty or nil, all non-key fields would be fetched. Read(ctx context.Context, ei *EntityInfo, keys map[string]FieldValue, minimumFields []string) (values map[string]FieldValue, err error) // MultiRead fetches several rows by primary key // If minimumFields is empty or nil, all non-key fields would be fetched. MultiRead(ctx context.Context, ei *EntityInfo, keys []map[string]FieldValue, minimumFields []string) (results []*FieldValuesOrError, err error) // Upsert updates some columns of a row, or creates a new one if it doesn't exist yet. Upsert(ctx context.Context, ei *EntityInfo, values map[string]FieldValue) error // MultiUpsert updates some columns of several rows, or creates a new ones if they doesn't exist yet MultiUpsert(ctx context.Context, ei *EntityInfo, multiValues []map[string]FieldValue) (result []error, err error) // Remove deletes a row Remove(ctx context.Context, ei *EntityInfo, keys map[string]FieldValue) error // RemoveRange removes all entities in a particular range RemoveRange(ctx context.Context, ei *EntityInfo, columnConditions map[string][]*Condition) error // MultiRemove removes multiple rows MultiRemove(ctx context.Context, ei *EntityInfo, multiKeys []map[string]FieldValue) (result []error, err error) // Range does a range scan using a set of conditions. // If minimumFields is empty or nil, all fields (including key fields) would be fetched. Range(ctx context.Context, ei *EntityInfo, columnConditions map[string][]*Condition, minimumFields []string, token string, limit int) ([]map[string]FieldValue, string, error) // Search does a search against a field marked 'searchable' // If minimumFields is empty or nil, all fields (including key fields) would be fetched. Search(ctx context.Context, ei *EntityInfo, fieldPairs FieldNameValuePair, minimumFields []string, token string, limit int) (multiValues []map[string]FieldValue, nextToken string, err error) // Scan reads the whole table, for doing a sequential search or dump/load use cases // If minimumFields is empty or nil, all fields (including key fields) would be fetched. Scan(ctx context.Context, ei *EntityInfo, minimumFields []string, token string, limit int) (multiValues []map[string]FieldValue, nextToken string, err error) // DDL operations (schema) // CheckSchema validates that the set of entities you have provided is valid and registered already // It returns a list of SchemaRef objects for use with later DML operations. CheckSchema(ctx context.Context, scope string, namePrefix string, ed []*EntityDefinition) (version int32, err error) // UpsertSchema updates the schema to match what you provide as entities, if possible UpsertSchema(ctx context.Context, scope string, namePrefix string, ed []*EntityDefinition) (status *SchemaStatus, err error) // CheckSchemaStatus checks the status of the schema whether it is accepted or in progress of application. CheckSchemaStatus(ctx context.Context, scope string, namePrefix string, version int32) (*SchemaStatus, error) // Datastore management // CreateScope creates a scope for storage of data, usually implemented by a keyspace for this data // This is usually followed by UpsertSchema CreateScope(ctx context.Context, scope string) error // TruncateScope keeps the scope around, but removes all the data TruncateScope(ctx context.Context, scope string) error // DropScope removes the scope and all of the data DropScope(ctx context.Context, scope string) error // ScopeExists checks whether a scope exists or not ScopeExists(ctx context.Context, scope string) (bool, error) // Shutdown finishes the connector to do clean up work Shutdown() error }
Connector is the interface that must be implemented for a backend service It can also be implemented using an RPC such as thrift (dosa-idl) When fields are returned from read/range/search/scan methods, it's legal for the connector to return more fields than originally requested. The caller of the connector should never mutate the returned columns either, in case they are from a cache
func GetConnector ¶
func GetConnector(name string, args CreationArgs) (Connector, error)
GetConnector gets a connector by name, along with some options
Example ¶
ExampleGetConnector gets an in-memory connector that can be used for testing your code. The in-memory connector always starts off with no rows, so you'll need to add rows to your "database" before reading them
package main import ( "context" "fmt" dosaRenamed "github.com/uber-go/dosa" _ "github.com/uber-go/dosa/connectors/devnull" _ "github.com/uber-go/dosa/connectors/memory" ) type ClientTestEntity1 struct { dosaRenamed.Entity `dosa:"primaryKey=(ID)"` dosaRenamed.Index `dosa:"key=Name, name=username"` ID int64 Name string Email string } func main() { // register your entities so the engine can separate your data based on table names. // Scopes and prefixes are not used by the in-memory connector, and are ignored, but // your list of entities is important. In this case, we only have one, our ClientTestEntity1 reg, err := dosaRenamed.NewRegistrar("test", "myteam.myservice", &ClientTestEntity1{}) if err != nil { fmt.Printf("NewRegistrar error: %s", err) return } // Find the memory connector. There is no configuration information so pass a nil // For this to work, you must force the init method of memory to run first, which happens // when we imported memory in the import list, with an underscore to just get the side effects conn, _ := dosaRenamed.GetConnector("memory", nil) // now construct a client from the registry and the connector client := dosaRenamed.NewClient(reg, conn) // initialize the client; this should always work for the in-memory connector if err = client.Initialize(context.Background()); err != nil { fmt.Printf("Initialize error: %s", err) return } // now populate an entity and insert it into the memory store if err := client.CreateIfNotExists(context.Background(), &ClientTestEntity1{ ID: int64(1), Name: "rkuris", Email: "rkuris@uber.com"}); err != nil { fmt.Printf("CreateIfNotExists error: %s", err) return } // create an entity to hold the read result, just populate the key e := ClientTestEntity1{ID: int64(1)} // now read the data from the "database", all columns err = client.Read(context.Background(), dosaRenamed.All(), &e) if err != nil { fmt.Printf("Read error: %s", err) return } // great! It worked, so display the information we stored earlier fmt.Printf("id:%d Name:%q Email:%q\n", e.ID, e.Name, e.Email) }
Output: id:1 Name:"rkuris" Email:"rkuris@uber.com"
type CreationArgs ¶
type CreationArgs map[string]interface{}
CreationArgs contains values for configuring different connectors
type CreationFuncType ¶
type CreationFuncType func(CreationArgs) (Connector, error)
CreationFuncType is the type of a creation function that creates an instance of a registered connector
type DomainIndex ¶
type DomainIndex interface {
// contains filtered or unexported methods
}
DomainIndex is a marker interface method for an Index
type DomainObject ¶
type DomainObject interface {
// contains filtered or unexported methods
}
DomainObject is a marker interface method for an Entity
type EntityDefinition ¶
type EntityDefinition struct { Name string // normalized entity name Key *PrimaryKey Columns []*ColumnDefinition Indexes map[string]*IndexDefinition }
EntityDefinition stores information about a DOSA entity
func (*EntityDefinition) Clone ¶
func (e *EntityDefinition) Clone() *EntityDefinition
Clone returns a deep copy of EntityDefinition
func (*EntityDefinition) ColumnMap ¶
func (e *EntityDefinition) ColumnMap() map[string]*ColumnDefinition
ColumnMap returns a map of column name to column definition for all columns.
func (*EntityDefinition) ColumnTypes ¶
func (e *EntityDefinition) ColumnTypes() map[string]Type
ColumnTypes returns a map of column name to column type for all columns.
func (*EntityDefinition) EnsureValid ¶
func (e *EntityDefinition) EnsureValid() error
EnsureValid ensures the entity definition is valid. All the names used (entity name, column name) must be valid. No duplicate names can be used in column names or key names. The primary key must not be nil and must contain at least one partition key.
func (*EntityDefinition) FindColumnDefinition ¶
func (e *EntityDefinition) FindColumnDefinition(name string) *ColumnDefinition
FindColumnDefinition finds the column definition by the column name
func (*EntityDefinition) IsCompatible ¶
func (e *EntityDefinition) IsCompatible(e2 *EntityDefinition) error
IsCompatible checks if two entity definitions are compatible or not. e1.g. edA.IsCompatible(edB) return true, means edA is compatible with edB. edA is the one to compare and edB is the one to be compared.
func (*EntityDefinition) KeySet ¶
func (e *EntityDefinition) KeySet() map[string]struct{}
KeySet returns a set of all keys, including partition keys and clustering keys.
func (*EntityDefinition) PartitionKeySet ¶
func (e *EntityDefinition) PartitionKeySet() map[string]struct{}
PartitionKeySet returns a set of all partition keys.
func (*EntityDefinition) UniqueKey ¶
func (e *EntityDefinition) UniqueKey(oldKey *PrimaryKey) *PrimaryKey
UniqueKey adds any missing keys from the entity's primary key to the keys specified in the index, to guarantee that the returned key is unique This method is used to create materialized views
type EntityErrors ¶
type EntityErrors struct {
// contains filtered or unexported fields
}
EntityErrors is a container for parse errors/warning.
func NewEntityErrors ¶
func NewEntityErrors(warns []error) *EntityErrors
NewEntityErrors returns a wrapper for errors encountered while parsing entity struct tags.
func (*EntityErrors) Error ¶
func (ee *EntityErrors) Error() string
Error makes parse errors discernable to end-user.
type EntityInfo ¶
type EntityInfo struct { Ref *SchemaRef Def *EntityDefinition }
EntityInfo is all the information about an entity, including the schema reference as well as the entity definition
func (*EntityInfo) IndexFromConditions ¶
func (ei *EntityInfo) IndexFromConditions(conditions map[string][]*Condition) (name string, key *PrimaryKey, err error)
IndexFromConditions returns the name of the index or the base table to use, along with the key info for that index. If no suitable index could be found, an error is returned
type EntityRecordingVisitor ¶
EntityRecordingVisitor is a visitor that records entities it finds It also keeps track of all failed entities that pass the basic "looks like a DOSA object" test (see isDosaEntity to understand that test)
type ErrAlreadyExists ¶
type ErrAlreadyExists struct{}
ErrAlreadyExists is an error returned when CreateIfNotExists but a row already exists
func (*ErrAlreadyExists) Error ¶
func (*ErrAlreadyExists) Error() string
type ErrNotFound ¶
type ErrNotFound struct{}
ErrNotFound is an error when a row is not found (single or multiple)
func (*ErrNotFound) Error ¶
func (*ErrNotFound) Error() string
Error returns a constant string "Not found" for this error
type ErrNotInitialized ¶
type ErrNotInitialized struct{}
ErrNotInitialized is returned when a user didn't call Initialize
func (*ErrNotInitialized) Error ¶
func (*ErrNotInitialized) Error() string
Error returns a constant string "client not initialized"
type FQN ¶
type FQN string
FQN is the fully qualified name for an entity
type FieldNameValuePair ¶
type FieldNameValuePair struct { Name string Value FieldValue }
FieldNameValuePair is a field name and value
type FieldValuesOrError ¶
type FieldValuesOrError struct { Values map[string]FieldValue Error error }
FieldValuesOrError either holds a slice of field values for a row, or an error
type IndexDefinition ¶
type IndexDefinition struct {
Key *PrimaryKey
}
IndexDefinition stores information about a DOSA entity's index
func (*IndexDefinition) Clone ¶
func (id *IndexDefinition) Clone() *IndexDefinition
Clone returns a deep copy of IndexDefinition
type MultiResult ¶
type MultiResult map[DomainObject]error
MultiResult contains the result for each entity operation in the case of MultiRead, MultiUpsert and MultiRemove. If the operation succeeded for an entity, the value for in the map will be nil; otherwise, the entity is untouched and error is not nil.
type Operator ¶
type Operator int
Operator defines an operator against some data for range scans
const ( // Eq is the equals operator Eq Operator = iota + 1 // Lt is the less than operator Lt // LtOrEq is the less than or equal operator LtOrEq // Gt is the greater than operator Gt // GtOrEq is the greater than or equal operator GtOrEq // InvalidVersion is version which is less than 1 InvalidVersion = -1 )
order of appearance matter here
type PrimaryKey ¶
type PrimaryKey struct { PartitionKeys []string ClusteringKeys []*ClusteringKey }
PrimaryKey stores information about partition keys and clustering keys
func (PrimaryKey) Clone ¶
func (pk PrimaryKey) Clone() *PrimaryKey
Clone returns a deep copy of PrimaryKey
func (PrimaryKey) ClusteringKeySet ¶
func (pk PrimaryKey) ClusteringKeySet() map[string]struct{}
ClusteringKeySet returns a set of all clustering keys.
func (PrimaryKey) PartitionKeySet ¶
func (pk PrimaryKey) PartitionKeySet() map[string]struct{}
PartitionKeySet returns the set of partition keys
func (PrimaryKey) PrimaryKeySet ¶
func (pk PrimaryKey) PrimaryKeySet() map[string]struct{}
PrimaryKeySet returns the union of the set of partition keys and clustering keys
func (PrimaryKey) String ¶
func (pk PrimaryKey) String() string
String method produces the following output: for multiple partition keys: ((partition-key, ...), clustering-key ASC/DESC, ...) for one partition key: (partition-key, clustering-key ASC/DESC, ...)
type RangeOp ¶
type RangeOp struct {
// contains filtered or unexported fields
}
RangeOp is used to specify constraints to Range calls
func NewRangeOp ¶
func NewRangeOp(object DomainObject) *RangeOp
NewRangeOp returns a new RangeOp instance
func (*RangeOp) Fields ¶
Fields list the non-key fields users want to fetch. PrimaryKey fields are always fetched.
func (*RangeOp) GtOrEq ¶
GtOrEq is used to express an "greater than or equal" constraint for a range query
func (*RangeOp) LtOrEq ¶
LtOrEq is used to express a "less than or equal" constraint for a range query
type RegisteredEntity ¶
type RegisteredEntity struct {
// contains filtered or unexported fields
}
RegisteredEntity is the structure that holds all information necessary for performing operations on an entity as well as helper methods for accessing type data so that reflection can be minimized.
func NewRegisteredEntity ¶
func NewRegisteredEntity(scope, prefix string, table *Table) *RegisteredEntity
NewRegisteredEntity is a constructor for creating a RegisteredEntity
func (*RegisteredEntity) ColumnNames ¶
func (e *RegisteredEntity) ColumnNames(fieldNames []string) ([]string, error)
ColumnNames translates field names to column names.
func (*RegisteredEntity) EntityDefinition ¶
func (e *RegisteredEntity) EntityDefinition() *EntityDefinition
EntityDefinition is a helper for accessing the registered entity's EntityDefinition instance.
func (*RegisteredEntity) EntityInfo ¶
func (e *RegisteredEntity) EntityInfo() *EntityInfo
EntityInfo is a helper for accessing the registered entity's EntityInfo instance which is required by clients to call connector methods.
func (*RegisteredEntity) KeyFieldValues ¶
func (e *RegisteredEntity) KeyFieldValues(entity DomainObject) map[string]FieldValue
KeyFieldValues is a helper for generating a map of field values to be used in a query.
func (*RegisteredEntity) OnlyFieldValues ¶
func (e *RegisteredEntity) OnlyFieldValues(entity DomainObject, fieldNames []string) (map[string]FieldValue, error)
OnlyFieldValues is a helper for generating a map of field values for a a subset of fields. If a field name provided does not map to an entity field, an error will be returned.
func (*RegisteredEntity) SchemaRef ¶
func (e *RegisteredEntity) SchemaRef() *SchemaRef
SchemaRef is a helper for accessing the registered entity's SchemaRef instance.
func (*RegisteredEntity) SetFieldValues ¶
func (e *RegisteredEntity) SetFieldValues(entity DomainObject, fieldValues map[string]FieldValue, fieldsToRead []string)
SetFieldValues is a helper for populating a DOSA entity with the given fieldName->value map
func (*RegisteredEntity) SetVersion ¶
func (e *RegisteredEntity) SetVersion(v int32)
SetVersion sets the current schema version on the registered entity.
type Registrar ¶
type Registrar interface { Scope() string NamePrefix() string Find(DomainObject) (*RegisteredEntity, error) FindAll() ([]*RegisteredEntity, error) }
Registrar is the interface to register DOSA entities.
func NewRegistrar ¶
func NewRegistrar(scope, prefix string, entities ...DomainObject) (Registrar, error)
NewRegistrar returns a new Registrar for the scope, name prefix and entities provided. `dosa.Client` implementations are intended to use scope and prefix to uniquely identify where entities should live but the registrar itself is only responsible for basic accounting of entities. DEPRECATED: use (github.com/uber-go/dosa/registry).NewRegistrar instead.
type RemoveRangeOp ¶
type RemoveRangeOp struct {
// contains filtered or unexported fields
}
RemoveRangeOp is used to specify contraints on RemoveRange calls
func NewRemoveRangeOp ¶
func NewRemoveRangeOp(object DomainObject) *RemoveRangeOp
NewRemoveRangeOp returns a new RangeOp instance
func (*RemoveRangeOp) Eq ¶
func (r *RemoveRangeOp) Eq(fieldName string, value interface{}) *RemoveRangeOp
Eq is used to express an equality constraint for a remove range operation
func (*RemoveRangeOp) Gt ¶
func (r *RemoveRangeOp) Gt(fieldName string, value interface{}) *RemoveRangeOp
Gt is used to express an "greater than" constraint for a remove range operation
func (*RemoveRangeOp) GtOrEq ¶
func (r *RemoveRangeOp) GtOrEq(fieldName string, value interface{}) *RemoveRangeOp
GtOrEq is used to express an "greater than or equal" constraint for a remove range operation
func (*RemoveRangeOp) Lt ¶
func (r *RemoveRangeOp) Lt(fieldName string, value interface{}) *RemoveRangeOp
Lt is used to express a "less than" constraint for a remove range operation
func (*RemoveRangeOp) LtOrEq ¶
func (r *RemoveRangeOp) LtOrEq(fieldName string, value interface{}) *RemoveRangeOp
LtOrEq is used to express a "less than or equal" constraint for a remove range operation
type ScanOp ¶
type ScanOp struct {
// contains filtered or unexported fields
}
ScanOp represents the scan query
func (*ScanOp) Fields ¶
Fields list the non-key fields users want to fetch. PrimaryKey fields are always fetched.
type SchemaRef ¶
type SchemaRef struct { Scope string NamePrefix string EntityName string IndexName string Version int32 }
SchemaRef is a reference to the table and schema version of an object
type SchemaStatus ¶
type SchemaStatus struct { // the version of the schema Version int32 // the application status of the schema Status string }
SchemaStatus saves the version and application status of a schema
type SearchOp ¶
type SearchOp struct{}
SearchOp represents the search query using a "searchable" field.
func NewSearchOp ¶
func NewSearchOp(DomainObject) *SearchOp
NewSearchOp returns a new SearchOp instance
func (*SearchOp) Fields ¶
Fields list the non-key fields users want to fetch. If not set, all normalized fields (supplied with “storing” annotation) would be fetched. PrimaryKey fields are always fetched.
type Table ¶
type Table struct { EntityDefinition StructName string ColToField map[string]string // map from column name -> field name FieldToCol map[string]string // map from field name -> column name }
Table represents a parsed entity format on the client side In addition to shared EntityDefinition, it records struct name and field names.
func FindEntities ¶
FindEntities finds all entities in the given file paths. An error is returned if there are naming colisions, otherwise, return a slice of warnings (or nil).
func TableFromInstance ¶
func TableFromInstance(object DomainObject) (*Table, error)
TableFromInstance creates a dosa.Table from a dosa.DomainObject instance. Note: this method is not cheap as it does a lot of reflection to build the Table instances. It is recommended to only be called once and cache results.
type Type ¶
type Type int
Type defines a data type for an entity field
const ( // Invalid type to be used as zero value for Type Invalid Type = iota // TUUID is different from dosa.UUID TUUID // String represents a string String // Int32 represents an int32 Int32 // Int64 represents either an int64 or a regular int Int64 // Double is a float64 Double // Blob is a byte slice Blob // Timestamp is a time.Time Timestamp // Bool is a bool type Bool )
type UUID ¶
type UUID string
UUID stores a string format of uuid. Validation is done before saving to datastore. The format of uuid used in datastore is orthogonal to the string format here.
func BytesToUUID ¶
BytesToUUID creates a UUID from a byte slice
Source Files
¶
Directories
¶
Path | Synopsis |
---|---|
Package cmd contains all standalone binaries
|
Package cmd contains all standalone binaries |
dosa
Package main is the entrypoint for the dosa CLI.
|
Package main is the entrypoint for the dosa CLI. |
cassandra
Package cassandra includes convenient functions to start the embedded server
|
Package cassandra includes convenient functions to start the embedded server |
Package examples is the Runnable examples.
|
Package examples is the Runnable examples. |
testing
Package testingexamples is the Examples: Testing.
|
Package testingexamples is the Examples: Testing. |
Package mocks is the Mocks generated by mockgen..
|
Package mocks is the Mocks generated by mockgen.. |
schema
|
|