dosa

package module
v2.3.0+incompatible Latest Latest
Warning

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

Go to latest
Published: Aug 29, 2017 License: MIT Imports: 19 Imported by: 0

README

DOSA - Declarative Object Storage Abstraction

GoDoc Coverage Status Build Status

Abstract

⚠ DOSA is BETA software. It is not recommended for production use. We will announce when it's ready.

DOSA 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.

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.

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

Examples

Constants

View Source
const DosaPackageName = `"github.com/uber-go/dosa"`

DosaPackageName is the name of the dosa package, fully qualified and quoted

View Source
const VERSION = "2.3.0"

VERSION indicates the dosa client version

Variables

View Source
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

func EqRangeOp(op *RangeOp) gomock.Matcher

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

func EqScanOp(op *ScanOp) gomock.Matcher

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

func ErrorIsAlreadyExists(err error) bool

ErrorIsAlreadyExists checks if the error is caused by "ErrAlreadyExists"

func ErrorIsNotFound

func ErrorIsNotFound(err error) bool

ErrorIsNotFound checks if the error is a "ErrNotFound" (possibly wrapped)

func ErrorIsNotInitialized

func ErrorIsNotInitialized(err error) bool

ErrorIsNotInitialized checks if the error is a "ErrNotInitialized" (possibly wrapped)

func IsValidName

func IsValidName(name string) error

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

func NormalizeName(name string) (string, error)

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

func NewClient(reg Registrar, conn Connector) Client

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

type ClusteringKey struct {
	Name       string
	Descending bool
}

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 Entity

type Entity struct{}

Entity represents any object that can be persisted by DOSA

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

type EntityRecordingVisitor struct {
	Entities      []*Table
	Warnings      []error
	PackagePrefix string
}

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)

func (*EntityRecordingVisitor) Visit

Visit records all the entities seen into the EntityRecordingVisitor structure

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

func ToFQN

func ToFQN(s string) (FQN, error)

ToFQN converts the input string to FQN

func (FQN) Child

func (f FQN) Child(s string) (FQN, error)

Child returns a new child FQN with the given comp at the end

func (FQN) String

func (f FQN) String() string

String satisfies fmt.Stringer interface

type FieldNameValuePair

type FieldNameValuePair struct {
	Name  string
	Value FieldValue
}

FieldNameValuePair is a field name and value

type FieldValue

type FieldValue interface{}

FieldValue holds a field value. It's just a marker.

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 Index

type Index struct{}

Index represents any object that can be indexed by by DOSA

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

func (Operator) String

func (i Operator) String() string

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) Eq

func (r *RangeOp) Eq(fieldName string, value interface{}) *RangeOp

Eq is used to express an equality constraint for a range query

func (*RangeOp) Fields

func (r *RangeOp) Fields(fields []string) *RangeOp

Fields list the non-key fields users want to fetch. PrimaryKey fields are always fetched.

func (*RangeOp) Gt

func (r *RangeOp) Gt(fieldName string, value interface{}) *RangeOp

Gt is used to express an "greater than" constraint for a range query

func (*RangeOp) GtOrEq

func (r *RangeOp) GtOrEq(fieldName string, value interface{}) *RangeOp

GtOrEq is used to express an "greater than or equal" constraint for a range query

func (*RangeOp) Limit

func (r *RangeOp) Limit(n int) *RangeOp

Limit sets the number of rows returned per call. Default is 100

func (*RangeOp) Lt

func (r *RangeOp) Lt(fieldName string, value interface{}) *RangeOp

Lt is used to express a "less than" constraint for a range query

func (*RangeOp) LtOrEq

func (r *RangeOp) LtOrEq(fieldName string, value interface{}) *RangeOp

LtOrEq is used to express a "less than or equal" constraint for a range query

func (*RangeOp) Offset

func (r *RangeOp) Offset(token string) *RangeOp

Offset sets the pagination token. If not set, an empty token would be used.

func (*RangeOp) String

func (r *RangeOp) String() string

String satisfies the Stringer interface

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 NewScanOp

func NewScanOp(obj DomainObject) *ScanOp

NewScanOp returns a new ScanOp instance

func (*ScanOp) Fields

func (s *ScanOp) Fields(fields []string) *ScanOp

Fields list the non-key fields users want to fetch. PrimaryKey fields are always fetched.

func (*ScanOp) Limit

func (s *ScanOp) Limit(n int) *ScanOp

Limit sets the number of rows returned per call. Default is 100

func (*ScanOp) Offset

func (s *ScanOp) Offset(token string) *ScanOp

Offset sets the pagination token. If not set, an empty token would be used.

func (*ScanOp) String

func (s *ScanOp) String() string

String satisfies the Stringer interface

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) By

func (s *SearchOp) By(fieldName string, fieldValue interface{}) *SearchOp

By indicates the "searchable" field name and its value.

func (*SearchOp) Fields

func (s *SearchOp) Fields([]string) *SearchOp

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.

func (*SearchOp) Limit

func (s *SearchOp) Limit(n int) *SearchOp

Limit sets the number of rows returned per call. Default is 128.

func (*SearchOp) Offset

func (s *SearchOp) Offset(token string) *SearchOp

Offset sets the pagination token. If not set, an empty token would be used.

func (*SearchOp) String

func (s *SearchOp) String() string

String satisfies the stringer interface

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

func FindEntities(paths, excludes []string) ([]*Table, []error, error)

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.

func (Table) String

func (d Table) String() string

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
)

func FromString

func FromString(s string) Type

FromString converts string to dosa Type

func (Type) String

func (i Type) String() string

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

func BytesToUUID(bs []byte) (UUID, error)

BytesToUUID creates a UUID from a byte slice

func NewUUID

func NewUUID() UUID

NewUUID is a helper for returning a new dosa.UUID value

func (UUID) Bytes

func (u UUID) Bytes() ([]byte, error)

Bytes gets the bytes from a UUID

Directories

Path Synopsis
cmd
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
cql
uql

Jump to

Keyboard shortcuts

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