Skip to content

Commit

Permalink
Merge pull request #339 from uber-go/v3
Browse files Browse the repository at this point in the history
Merge in orphaned patches from V3
  • Loading branch information
phliar authored Jun 1, 2018
2 parents 441b061 + 6eda962 commit 9175a32
Show file tree
Hide file tree
Showing 11 changed files with 105 additions and 211 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
- Convert usernaems to lowercase when constructing scope names etc. (#322)
- Initial support for Adaptive Rate Limits.
- Many accidentally exported names have been unexported. (#327)
- Add new GetEntitySchema function to the Connector interface (#335)
- Remove unused PluginFunc argument from the routing connector (#337)

## v2.6.0 (2018-04-16)
- Fix bug in invalidating fallback cache on upsert (#292)
Expand Down
30 changes: 4 additions & 26 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,9 @@ type Client interface {
// Otherwise the DomainObject as key and an error message as value will be saved into
// MultiResult map.
// NOTE: This API only fetches objects of same entity type from same scope.
//
// Range should be preferred over MultiRead. If you are not sure which endpoint to use,
// use Range instead of MultiRead.
MultiRead(context.Context, []string, ...DomainObject) (MultiResult, error)

// Upsert creates or update a row. A list of fields to update can be
Expand All @@ -173,11 +176,6 @@ type Client interface {
// to update in fieldsToUpdate (or all the fields if you use dosa.All())
Upsert(ctx context.Context, fieldsToUpdate []string, objectToUpdate DomainObject) error

// TODO: Coming in v2.1
// MultiUpsert creates or updates multiple rows. A list of fields to
// update can be specified. Use All() or nil for all fields.
// MultiUpsert(context.Context, []string, ...DomainObject) (MultiResult, 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
Expand All @@ -186,11 +184,6 @@ type Client interface {
// given RemoveRangeOp.
RemoveRange(ctx context.Context, removeRangeOp *RemoveRangeOp) error

// TODO: Coming in v2.1
// MultiRemove removes multiple rows by primary key. The passed-in entity should
// contain the primary key field values.
// MultiRemove(context.Context, ...DomainObject) (MultiResult, 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
Expand Down Expand Up @@ -226,7 +219,7 @@ type Client interface {
}

// MultiResult contains the result for each entity operation in the case of
// MultiRead, MultiUpsert and MultiRemove. If the operation succeeded for
// MultiRead. 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 MultiResult map[DomainObject]error
Expand Down Expand Up @@ -466,14 +459,6 @@ func (c *client) createOrUpsert(ctx context.Context, fieldsToUpdate []string, en
return fn(ctx, ei, fieldValues)
}

// MultiUpsert updates several entities by primary key, The entities provided
// must contain values for all components of its primary key for the operation
// to succeed. If `fieldsToUpdate` is provided, only a subset of fields will be
// updated.
func (c *client) MultiUpsert(context.Context, []string, ...DomainObject) (MultiResult, error) {
panic("not implemented")
}

// Remove deletes an entity by primary key, The entity provided must contain
// values for all components of its primary key for the operation to succeed.
func (c *client) Remove(ctx context.Context, entity DomainObject) error {
Expand Down Expand Up @@ -516,13 +501,6 @@ func (c *client) RemoveRange(ctx context.Context, r *RemoveRangeOp) error {
return errors.Wrap(c.connector.RemoveRange(ctx, re.EntityInfo(), columnConditions), "RemoveRange")
}

// MultiRemove deletes several entities by primary key, The entities provided
// must contain values for all components of its primary key for the operation
// to succeed.
func (c *client) MultiRemove(context.Context, ...DomainObject) (MultiResult, error) {
panic("not implemented")
}

// Range uses the connector to fetch DOSA entities for a given range.
func (c *client) Range(ctx context.Context, r *RangeOp) ([]DomainObject, string, error) {
if !c.initialized {
Expand Down
2 changes: 2 additions & 0 deletions connector.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,8 @@ type Connector interface {
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)
// GetEntitySchema returns the entity info for a given entity in a given scope and prefix.
GetEntitySchema(ctx context.Context, scope, namePrefix, entityName string, version int32) (*EntityInfo, error)

// Datastore management
// CreateScope creates a scope for storage of data, usually implemented by a keyspace for this data
Expand Down
8 changes: 8 additions & 0 deletions connectors/base/base.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,14 @@ func (c *Connector) CheckSchemaStatus(ctx context.Context, scope string, namePre
return c.Next.CheckSchemaStatus(ctx, scope, namePrefix, version)
}

// GetEntitySchema calls next
func (c *Connector) GetEntitySchema(ctx context.Context, scope, namePrefix, entityName string, version int32) (*dosa.EntityInfo, error) {
if c.Next == nil {
return nil, NewErrNoMoreConnector()
}
return c.Next.GetEntitySchema(ctx, scope, namePrefix, entityName, version)
}

// CreateScope calls Next
func (c *Connector) CreateScope(ctx context.Context, md *dosa.ScopeMetadata) error {
if c.Next == nil {
Expand Down
5 changes: 5 additions & 0 deletions connectors/devnull/devnull.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,11 @@ func (c *Connector) CheckSchemaStatus(ctx context.Context, scope, namePrefix str
}, nil
}

// GetEntitySchema always returns a blank EntityInfo and no error.
func (c *Connector) GetEntitySchema(ctx context.Context, scope, namePrefix, entityName string, version int32) (*dosa.EntityInfo, error) {
return &dosa.EntityInfo{}, nil
}

// CreateScope returns success
func (c *Connector) CreateScope(ctx context.Context, _ *dosa.ScopeMetadata) error {
return nil
Expand Down
5 changes: 5 additions & 0 deletions connectors/random/random.go
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,11 @@ func (c *Connector) CheckSchemaStatus(ctx context.Context, scope, namePrefix str
}, nil
}

// GetEntitySchema always returns a blank EntityInfo and no error.
func (c *Connector) GetEntitySchema(ctx context.Context, scope, namePrefix, entityName string, version int32) (*dosa.EntityInfo, error) {
return &dosa.EntityInfo{}, nil
}

// CreateScope returns success
func (c *Connector) CreateScope(ctx context.Context, _ *dosa.ScopeMetadata) error {
return nil
Expand Down
75 changes: 30 additions & 45 deletions connectors/routing/connector.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,53 +26,29 @@ import (

"github.com/pkg/errors"
"github.com/uber-go/dosa"
"github.com/uber-go/dosa/connectors/base"
)

// PluginFunc is a plugin function that takes scope, namePrefix and operation name,
// then gives wanted scope and namePrefix
type PluginFunc func(scope, namePrefix, opName string) (string, string, error)

// Connector holds a slice of configured connectors to route to
type Connector struct {
base.Connector
// config connector slice is sorted in a manner:
// for the value of Config name prefix, strict string without "*" always comes first,
// and then string with "*" suffix (glob match) and pure "*".
// There shouldn't be any scope with a prefix "*" like "*.service.v1"
config Config
connectors map[string]dosa.Connector
// PluginFunc is a plugin that passes in
// the scope, namePrefix and operation name, returns wanted scope and namePrefix
PluginFunc PluginFunc
}

// NewConnector initializes the Connector
// connectorMap has a key of connectorName, and the value is a dosa.connector instance
func NewConnector(cfg Config, connectorMap map[string]dosa.Connector, plugin PluginFunc) *Connector {
func NewConnector(cfg Config, connectorMap map[string]dosa.Connector) *Connector {
return &Connector{
connectors: connectorMap,
config: cfg,
PluginFunc: plugin,
}
}

// get connector by scope, namePrefix and operation name provided
func (rc *Connector) getConnector(scope string, namePrefix string, opName string) (_ dosa.Connector, err error) {
if rc.PluginFunc != nil {
// plugin operation
// plugin should always be first considered if it exists
scope, namePrefix, err = rc.PluginFunc(scope, namePrefix, opName)
if err != nil {
return nil, errors.Wrap(err, "failed to execute getConnector due to Plugin function error")
}
}
return rc._getConnector(scope, namePrefix)
}

// if no specific scope is found,
// Connector routes to the default scope that defined in routing config yaml file
func (rc *Connector) _getConnector(scope, namePrefix string) (dosa.Connector, error) {
// get connector by scope an namePrefix
func (rc *Connector) getConnector(scope, namePrefix string) (dosa.Connector, error) {
router := rc.config.FindRouter(scope, namePrefix)

c, ok := rc.connectors[router.Connector]
Expand All @@ -85,7 +61,7 @@ func (rc *Connector) _getConnector(scope, namePrefix string) (dosa.Connector, er

// CreateIfNotExists selects corresponding connector
func (rc *Connector) CreateIfNotExists(ctx context.Context, ei *dosa.EntityInfo, values map[string]dosa.FieldValue) error {
connector, err := rc.getConnector(ei.Ref.Scope, ei.Ref.NamePrefix, "CreateIfNotExists")
connector, err := rc.getConnector(ei.Ref.Scope, ei.Ref.NamePrefix)
if err != nil {
return err
}
Expand All @@ -94,7 +70,7 @@ func (rc *Connector) CreateIfNotExists(ctx context.Context, ei *dosa.EntityInfo,

// Read selects corresponding connector
func (rc *Connector) Read(ctx context.Context, ei *dosa.EntityInfo, values map[string]dosa.FieldValue, minimumFields []string) (map[string]dosa.FieldValue, error) {
connector, err := rc.getConnector(ei.Ref.Scope, ei.Ref.NamePrefix, "Read")
connector, err := rc.getConnector(ei.Ref.Scope, ei.Ref.NamePrefix)
if err != nil {
return nil, err
}
Expand All @@ -103,7 +79,7 @@ func (rc *Connector) Read(ctx context.Context, ei *dosa.EntityInfo, values map[s

// MultiRead selects corresponding connector
func (rc *Connector) MultiRead(ctx context.Context, ei *dosa.EntityInfo, values []map[string]dosa.FieldValue, minimumFields []string) ([]*dosa.FieldValuesOrError, error) {
connector, err := rc.getConnector(ei.Ref.Scope, ei.Ref.NamePrefix, "MultiRead")
connector, err := rc.getConnector(ei.Ref.Scope, ei.Ref.NamePrefix)
if err != nil {
return nil, err
}
Expand All @@ -112,7 +88,7 @@ func (rc *Connector) MultiRead(ctx context.Context, ei *dosa.EntityInfo, values

// Upsert selects corresponding connector
func (rc *Connector) Upsert(ctx context.Context, ei *dosa.EntityInfo, values map[string]dosa.FieldValue) error {
connector, err := rc.getConnector(ei.Ref.Scope, ei.Ref.NamePrefix, "Upsert")
connector, err := rc.getConnector(ei.Ref.Scope, ei.Ref.NamePrefix)
if err != nil {
return err
}
Expand All @@ -121,7 +97,7 @@ func (rc *Connector) Upsert(ctx context.Context, ei *dosa.EntityInfo, values map

// MultiUpsert selects corresponding connector
func (rc *Connector) MultiUpsert(ctx context.Context, ei *dosa.EntityInfo, values []map[string]dosa.FieldValue) ([]error, error) {
connector, err := rc.getConnector(ei.Ref.Scope, ei.Ref.NamePrefix, "MultiUpsert")
connector, err := rc.getConnector(ei.Ref.Scope, ei.Ref.NamePrefix)
if err != nil {
return nil, err
}
Expand All @@ -130,7 +106,7 @@ func (rc *Connector) MultiUpsert(ctx context.Context, ei *dosa.EntityInfo, value

// Remove selects corresponding connector
func (rc *Connector) Remove(ctx context.Context, ei *dosa.EntityInfo, values map[string]dosa.FieldValue) error {
connector, err := rc.getConnector(ei.Ref.Scope, ei.Ref.NamePrefix, "Remove")
connector, err := rc.getConnector(ei.Ref.Scope, ei.Ref.NamePrefix)
if err != nil {
// here returns err because connector is not found
return err
Expand All @@ -141,7 +117,7 @@ func (rc *Connector) Remove(ctx context.Context, ei *dosa.EntityInfo, values map

// RemoveRange selects corresponding connector
func (rc *Connector) RemoveRange(ctx context.Context, ei *dosa.EntityInfo, columnConditions map[string][]*dosa.Condition) error {
connector, err := rc.getConnector(ei.Ref.Scope, ei.Ref.NamePrefix, "RemoveRange")
connector, err := rc.getConnector(ei.Ref.Scope, ei.Ref.NamePrefix)
if err != nil {
return err
}
Expand All @@ -150,7 +126,7 @@ func (rc *Connector) RemoveRange(ctx context.Context, ei *dosa.EntityInfo, colum

// MultiRemove selects corresponding connector
func (rc *Connector) MultiRemove(ctx context.Context, ei *dosa.EntityInfo, multiValues []map[string]dosa.FieldValue) ([]error, error) {
connector, err := rc.getConnector(ei.Ref.Scope, ei.Ref.NamePrefix, "MultiRemove")
connector, err := rc.getConnector(ei.Ref.Scope, ei.Ref.NamePrefix)
if err != nil {
return nil, err
}
Expand All @@ -159,7 +135,7 @@ func (rc *Connector) MultiRemove(ctx context.Context, ei *dosa.EntityInfo, multi

// Range selects corresponding connector
func (rc *Connector) Range(ctx context.Context, ei *dosa.EntityInfo, columnConditions map[string][]*dosa.Condition, minimumFields []string, token string, limit int) ([]map[string]dosa.FieldValue, string, error) {
connector, err := rc.getConnector(ei.Ref.Scope, ei.Ref.NamePrefix, "Range")
connector, err := rc.getConnector(ei.Ref.Scope, ei.Ref.NamePrefix)
if err != nil {
return nil, "", err
}
Expand All @@ -168,7 +144,7 @@ func (rc *Connector) Range(ctx context.Context, ei *dosa.EntityInfo, columnCondi

// Scan selects corresponding connector
func (rc *Connector) Scan(ctx context.Context, ei *dosa.EntityInfo, minimumFields []string, token string, limit int) ([]map[string]dosa.FieldValue, string, error) {
connector, err := rc.getConnector(ei.Ref.Scope, ei.Ref.NamePrefix, "Scan")
connector, err := rc.getConnector(ei.Ref.Scope, ei.Ref.NamePrefix)
if err != nil {
return nil, "", err
}
Expand All @@ -177,7 +153,7 @@ func (rc *Connector) Scan(ctx context.Context, ei *dosa.EntityInfo, minimumField

// CheckSchema calls selected connector
func (rc *Connector) CheckSchema(ctx context.Context, scope, namePrefix string, ed []*dosa.EntityDefinition) (int32, error) {
connector, err := rc.getConnector(scope, namePrefix, "CheckSchema")
connector, err := rc.getConnector(scope, namePrefix)
if err != nil {
return dosa.InvalidVersion, err
}
Expand All @@ -186,7 +162,7 @@ func (rc *Connector) CheckSchema(ctx context.Context, scope, namePrefix string,

// UpsertSchema calls selected connector
func (rc *Connector) UpsertSchema(ctx context.Context, scope, namePrefix string, ed []*dosa.EntityDefinition) (*dosa.SchemaStatus, error) {
connector, err := rc.getConnector(scope, namePrefix, "UpsertSchema")
connector, err := rc.getConnector(scope, namePrefix)
if err != nil {
return nil, err
}
Expand All @@ -195,7 +171,7 @@ func (rc *Connector) UpsertSchema(ctx context.Context, scope, namePrefix string,

// CanUpsertSchema calls selected connector
func (rc *Connector) CanUpsertSchema(ctx context.Context, scope, namePrefix string, ed []*dosa.EntityDefinition) (int32, error) {
connector, err := rc.getConnector(scope, namePrefix, "CanUpsertSchema")
connector, err := rc.getConnector(scope, namePrefix)
if err != nil {
return dosa.InvalidVersion, err
}
Expand All @@ -204,17 +180,26 @@ func (rc *Connector) CanUpsertSchema(ctx context.Context, scope, namePrefix stri

// CheckSchemaStatus calls selected connector
func (rc *Connector) CheckSchemaStatus(ctx context.Context, scope string, namePrefix string, version int32) (*dosa.SchemaStatus, error) {
connector, err := rc.getConnector(scope, namePrefix, "CheckSchemaStatus")
connector, err := rc.getConnector(scope, namePrefix)
if err != nil {
return nil, err
}
return connector.CheckSchemaStatus(ctx, scope, namePrefix, version)
}

// GetEntitySchema calls the selected connector
func (rc *Connector) GetEntitySchema(ctx context.Context, scope, namePrefix, entityName string, version int32) (*dosa.EntityInfo, error) {
connector, err := rc.getConnector(scope, namePrefix)
if err != nil {
return nil, err
}
return connector.GetEntitySchema(ctx, scope, namePrefix, entityName, version)
}

// CreateScope calls selected connector
func (rc *Connector) CreateScope(ctx context.Context, md *dosa.ScopeMetadata) error {
// will fall to default connector
connector, err := rc.getConnector(md.Name, "", "CreateScope")
connector, err := rc.getConnector(md.Name, "")
if err != nil {
return err
}
Expand All @@ -224,7 +209,7 @@ func (rc *Connector) CreateScope(ctx context.Context, md *dosa.ScopeMetadata) er
// TruncateScope calls selected connector
func (rc *Connector) TruncateScope(ctx context.Context, scope string) error {
// will fall to default connector
connector, err := rc.getConnector(scope, "", "TruncateScope")
connector, err := rc.getConnector(scope, "")
if err != nil {
return err
}
Expand All @@ -234,7 +219,7 @@ func (rc *Connector) TruncateScope(ctx context.Context, scope string) error {
// DropScope calls selected connector
func (rc *Connector) DropScope(ctx context.Context, scope string) error {
// will fall to default connector
connector, err := rc.getConnector(scope, "", "DropScope")
connector, err := rc.getConnector(scope, "")
if err != nil {
return err
}
Expand All @@ -244,7 +229,7 @@ func (rc *Connector) DropScope(ctx context.Context, scope string) error {
// ScopeExists calls selected connector
func (rc *Connector) ScopeExists(ctx context.Context, scope string) (bool, error) {
// will fall to default connector
connector, err := rc.getConnector(scope, "", "ScopeExists")
connector, err := rc.getConnector(scope, "")
if err != nil {
return false, err
}
Expand Down
Loading

0 comments on commit 9175a32

Please sign in to comment.