Skip to content

Commit

Permalink
Correct GetCollectionsBySchemaID to return multiple cols
Browse files Browse the repository at this point in the history
  • Loading branch information
AndrewSisley committed Oct 19, 2023
1 parent 780df33 commit d4be441
Show file tree
Hide file tree
Showing 11 changed files with 92 additions and 68 deletions.
41 changes: 21 additions & 20 deletions cli/collection.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,34 +43,17 @@ func MakeCollectionCommand(cfg *config.Config) *cobra.Command {
store := mustGetStoreContext(cmd)

var col client.Collection
var cols []client.Collection
switch {
case versionID != "":
var cols []client.Collection
cols, err = store.GetCollectionsByVersionID(cmd.Context(), versionID)
if err != nil {
return err
}
if name != "" {
versionCols := cols
cols = nil
for _, c := range versionCols {
if c.Name() == name {
cols = append(cols, c)
break
}
}
}
if len(cols) != 1 {
// If more than one collection matches the given criteria we cannot set the context collection
return nil
}
col = cols[0]

case schemaID != "":
col, err = store.GetCollectionBySchemaID(cmd.Context(), schemaID)
cols, err = store.GetCollectionsBySchemaID(cmd.Context(), schemaID)

case name != "":
col, err = store.GetCollectionByName(cmd.Context(), name)
cols = []client.Collection{col}

default:
return nil
Expand All @@ -79,6 +62,24 @@ func MakeCollectionCommand(cfg *config.Config) *cobra.Command {
if err != nil {
return err
}

if name != "" {
fetchedCols := cols
cols = nil
for _, c := range fetchedCols {
if c.Name() == name {
cols = append(cols, c)
break
}
}
}

if len(cols) != 1 {
// If more than one collection matches the given criteria we cannot set the context collection
return nil
}
col = cols[0]

if tx, ok := cmd.Context().Value(txContextKey).(datastore.Txn); ok {
col = col.WithTxn(tx)
}
Expand Down
6 changes: 3 additions & 3 deletions client/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,10 +147,10 @@ type Store interface {
// If no matching collection is found an error will be returned.
GetCollectionByName(context.Context, CollectionName) (Collection, error)

// GetCollectionBySchemaID attempts to retrieve a collection matching the given schema ID.
// GetCollectionsBySchemaID attempts to retrieve all collections using the given schema ID.
//
// If no matching collection is found an error will be returned.
GetCollectionBySchemaID(context.Context, string) (Collection, error)
// If no matching collection is found an empty set will be returned.
GetCollectionsBySchemaID(context.Context, string) ([]Collection, error)

// GetCollectionsByVersionID attempts to retrieve all collections using the given schema version ID.
//
Expand Down
7 changes: 7 additions & 0 deletions client/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,3 +116,10 @@ func NewErrCollectionNotFoundForSchemaVersion(schemaVersionID string) error {
errors.NewKV("SchemaVersionID", schemaVersionID),
)
}

func NewErrCollectionNotFoundForSchema(schemaID string) error {
return errors.New(
errCollectionNotFound,
errors.NewKV("SchemaID", schemaID),
)
}
28 changes: 14 additions & 14 deletions client/mocks/db.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 12 additions & 14 deletions db/txn_db.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,13 @@ func (db *explicitTxnDB) GetCollectionByName(ctx context.Context, name string) (
return db.getCollectionByName(ctx, db.txn, name)
}

// GetCollectionBySchemaID returns an existing collection using the schema hash ID.
func (db *implicitTxnDB) GetCollectionBySchemaID(
// GetCollectionsBySchemaID attempts to retrieve all collections using the given schema ID.
//
// If no matching collection is found an empty set will be returned.
func (db *implicitTxnDB) GetCollectionsBySchemaID(
ctx context.Context,
schemaID string,
) (client.Collection, error) {
) ([]client.Collection, error) {
txn, err := db.NewTxn(ctx, true)
if err != nil {
return nil, err
Expand All @@ -94,27 +96,23 @@ func (db *implicitTxnDB) GetCollectionBySchemaID(
if err != nil {
return nil, err
}
if len(cols) == 0 {
return nil, NewErrFailedToGetCollection(schemaID, err)
}

return cols[0], nil
return cols, nil
}

// GetCollectionBySchemaID returns an existing collection using the schema hash ID.
func (db *explicitTxnDB) GetCollectionBySchemaID(
// GetCollectionsBySchemaID attempts to retrieve all collections using the given schema ID.
//
// If no matching collection is found an empty set will be returned.
func (db *explicitTxnDB) GetCollectionsBySchemaID(
ctx context.Context,
schemaID string,
) (client.Collection, error) {
) ([]client.Collection, error) {
cols, err := db.getCollectionsBySchemaID(ctx, db.txn, schemaID)
if err != nil {
return nil, err
}
if len(cols) == 0 {
return nil, NewErrFailedToGetCollection(schemaID, err)
}

return cols[0], nil
return cols, nil
}

// GetCollectionsByVersionID attempts to retrieve all collections using the given schema version ID.
Expand Down
12 changes: 8 additions & 4 deletions http/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,19 +186,23 @@ func (c *Client) GetCollectionByName(ctx context.Context, name client.Collection
return &Collection{c.http, definition}, nil
}

func (c *Client) GetCollectionBySchemaID(ctx context.Context, schemaId string) (client.Collection, error) {
func (c *Client) GetCollectionsBySchemaID(ctx context.Context, schemaId string) ([]client.Collection, error) {
methodURL := c.http.baseURL.JoinPath("collections")
methodURL.RawQuery = url.Values{"schema_id": []string{schemaId}}.Encode()

req, err := http.NewRequestWithContext(ctx, http.MethodGet, methodURL.String(), nil)
if err != nil {
return nil, err
}
var definition client.CollectionDefinition
if err := c.http.requestJson(req, &definition); err != nil {
var descriptions []client.CollectionDefinition
if err := c.http.requestJson(req, &descriptions); err != nil {
return nil, err
}
return &Collection{c.http, definition}, nil
collections := make([]client.Collection, len(descriptions))
for i, d := range descriptions {
collections[i] = &Collection{c.http, d}
}
return collections, nil
}

func (c *Client) GetCollectionsByVersionID(ctx context.Context, versionId string) ([]client.Collection, error) {
Expand Down
8 changes: 6 additions & 2 deletions http/handler_store.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,12 +118,16 @@ func (s *storeHandler) GetCollection(rw http.ResponseWriter, req *http.Request)
}
responseJSON(rw, http.StatusOK, col.Definition())
case req.URL.Query().Has("schema_id"):
col, err := store.GetCollectionBySchemaID(req.Context(), req.URL.Query().Get("schema_id"))
cols, err := store.GetCollectionsBySchemaID(req.Context(), req.URL.Query().Get("schema_id"))
if err != nil {
responseJSON(rw, http.StatusBadRequest, errorResponse{err})
return
}
responseJSON(rw, http.StatusOK, col.Definition())
colDesc := make([]client.CollectionDefinition, len(cols))
for i, col := range cols {
colDesc[i] = col.Definition()
}
responseJSON(rw, http.StatusOK, colDesc)
case req.URL.Query().Has("version_id"):
cols, err := store.GetCollectionsByVersionID(req.Context(), req.URL.Query().Get("version_id"))
if err != nil {
Expand Down
8 changes: 4 additions & 4 deletions net/peer_collection.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,11 @@ func (p *Peer) AddP2PCollections(ctx context.Context, collectionIDs []string) er
// first let's make sure the collections actually exists
storeCollections := []client.Collection{}
for _, col := range collectionIDs {
storeCol, err := p.db.WithTxn(txn).GetCollectionBySchemaID(p.ctx, col)
storeCol, err := p.db.WithTxn(txn).GetCollectionsBySchemaID(p.ctx, col)
if err != nil {
return err
}
storeCollections = append(storeCollections, storeCol)
storeCollections = append(storeCollections, storeCol...)
}

// Ensure we can add all the collections to the store on the transaction
Expand Down Expand Up @@ -93,11 +93,11 @@ func (p *Peer) RemoveP2PCollections(ctx context.Context, collectionIDs []string)
// first let's make sure the collections actually exists
storeCollections := []client.Collection{}
for _, col := range collectionIDs {
storeCol, err := p.db.WithTxn(txn).GetCollectionBySchemaID(p.ctx, col)
storeCol, err := p.db.WithTxn(txn).GetCollectionsBySchemaID(p.ctx, col)
if err != nil {
return err
}
storeCollections = append(storeCollections, storeCol)
storeCollections = append(storeCollections, storeCol...)
}

// Ensure we can remove all the collections to the store on the transaction
Expand Down
8 changes: 7 additions & 1 deletion net/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -260,10 +260,16 @@ func (s *server) PushLog(ctx context.Context, req *pb.PushLogRequest) (*pb.PushL
defer txn.Discard(ctx)
store := s.db.WithTxn(txn)

col, err := store.GetCollectionBySchemaID(ctx, schemaID)
// Currently a schema is the best way we have to link a push log request to a collection,
// this will change with https://github.com/sourcenetwork/defradb/issues/1085
cols, err := store.GetCollectionsBySchemaID(ctx, schemaID)
if err != nil {
return nil, errors.Wrap(fmt.Sprintf("Failed to get collection from schemaID %s", schemaID), err)
}
if len(cols) == 0 {
return nil, client.NewErrCollectionNotFoundForSchema(schemaID)
}
col := cols[0]

// Create a new DAG service with the current transaction
var getter format.NodeGetter = s.peer.newDAGSyncerTxn(txn)
Expand Down
12 changes: 8 additions & 4 deletions tests/clients/cli/wrapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -225,19 +225,23 @@ func (w *Wrapper) GetCollectionByName(ctx context.Context, name client.Collectio
return &Collection{w.cmd, definition}, nil
}

func (w *Wrapper) GetCollectionBySchemaID(ctx context.Context, schemaId string) (client.Collection, error) {
func (w *Wrapper) GetCollectionsBySchemaID(ctx context.Context, schemaId string) ([]client.Collection, error) {
args := []string{"client", "collection", "describe"}
args = append(args, "--schema", schemaId)

data, err := w.cmd.execute(ctx, args)
if err != nil {
return nil, err
}
var definition client.CollectionDefinition
if err := json.Unmarshal(data, &definition); err != nil {
var colDesc []client.CollectionDefinition
if err := json.Unmarshal(data, &colDesc); err != nil {
return nil, err
}
return &Collection{w.cmd, definition}, nil
cols := make([]client.Collection, len(colDesc))
for i, v := range colDesc {
cols[i] = &Collection{w.cmd, v}
}
return cols, err
}

func (w *Wrapper) GetCollectionsByVersionID(ctx context.Context, versionId string) ([]client.Collection, error) {
Expand Down
4 changes: 2 additions & 2 deletions tests/clients/http/wrapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,8 @@ func (w *Wrapper) GetCollectionByName(ctx context.Context, name client.Collectio
return w.client.GetCollectionByName(ctx, name)
}

func (w *Wrapper) GetCollectionBySchemaID(ctx context.Context, schemaId string) (client.Collection, error) {
return w.client.GetCollectionBySchemaID(ctx, schemaId)
func (w *Wrapper) GetCollectionsBySchemaID(ctx context.Context, schemaId string) ([]client.Collection, error) {
return w.client.GetCollectionsBySchemaID(ctx, schemaId)
}

func (w *Wrapper) GetCollectionsByVersionID(ctx context.Context, versionId string) ([]client.Collection, error) {
Expand Down

0 comments on commit d4be441

Please sign in to comment.