diff --git a/cli/collection_delete.go b/cli/collection_delete.go index 5bbe32a964..a9776d1985 100644 --- a/cli/collection_delete.go +++ b/cli/collection_delete.go @@ -17,18 +17,18 @@ import ( ) func MakeCollectionDeleteCommand() *cobra.Command { - var argDocIDs []string + var argDocID string var filter string var cmd = &cobra.Command{ Use: "delete [-i --identity] [--filter --docID ]", Short: "Delete documents by docID or filter.", Long: `Delete documents by docID or filter and lists the number of documents deleted. -Example: delete by docID(s): - defradb client collection delete --name User --docID bae-123,bae-456 +Example: delete by docID: + defradb client collection delete --name User --docID bae-123 -Example: delete by docID(s) with identity: - defradb client collection delete -i cosmos1f2djr7dl9vhrk3twt3xwqp09nhtzec9mdkf70j --name User --docID bae-123,bae-456 +Example: delete by docID with identity: + defradb client collection delete -i cosmos1f2djr7dl9vhrk3twt3xwqp09nhtzec9mdkf70j --name User --docID bae-123 Example: delete by filter: defradb client collection delete --name User --filter '{ "_gte": { "points": 100 } }' @@ -40,30 +40,13 @@ Example: delete by filter: } switch { - case len(argDocIDs) == 1: - docID, err := client.NewDocIDFromString(argDocIDs[0]) + case argDocID != "": + docID, err := client.NewDocIDFromString(argDocID) if err != nil { return err } - res, err := col.DeleteWithDocID(cmd.Context(), docID) - if err != nil { - return err - } - return writeJSON(cmd, res) - case len(argDocIDs) > 1: - docIDs := make([]client.DocID, len(argDocIDs)) - for i, v := range argDocIDs { - docID, err := client.NewDocIDFromString(v) - if err != nil { - return err - } - docIDs[i] = docID - } - res, err := col.DeleteWithDocIDs(cmd.Context(), docIDs) - if err != nil { - return err - } - return writeJSON(cmd, res) + _, err = col.Delete(cmd.Context(), docID) + return err case filter != "": res, err := col.DeleteWithFilter(cmd.Context(), filter) if err != nil { @@ -75,7 +58,7 @@ Example: delete by filter: } }, } - cmd.Flags().StringSliceVar(&argDocIDs, "docID", nil, "Document ID") + cmd.Flags().StringVar(&argDocID, "docID", "", "Document ID") cmd.Flags().StringVar(&filter, "filter", "", "Document filter") return cmd } diff --git a/cli/collection_update.go b/cli/collection_update.go index 2777c0ed98..3e676edce9 100644 --- a/cli/collection_update.go +++ b/cli/collection_update.go @@ -17,7 +17,7 @@ import ( ) func MakeCollectionUpdateCommand() *cobra.Command { - var argDocIDs []string + var argDocID string var filter string var updater string var cmd = &cobra.Command{ @@ -32,13 +32,13 @@ Example: update by filter: defradb client collection update --name User \ --filter '{ "_gte": { "points": 100 } }' --updater '{ "verified": true }' -Example: update by docIDs: +Example: update by docID: defradb client collection update --name User \ - --docID bae-123,bae-456 --updater '{ "verified": true }' + --docID bae-123 --updater '{ "verified": true }' -Example: update private docIDs, with identity: +Example: update private docID, with identity: defradb client collection update -i cosmos1f2djr7dl9vhrk3twt3xwqp09nhtzec9mdkf70j --name User \ - --docID bae-123,bae-456 --updater '{ "verified": true }' + --docID bae-123 --updater '{ "verified": true }' `, Args: cobra.RangeArgs(0, 1), RunE: func(cmd *cobra.Command, args []string) error { @@ -48,38 +48,14 @@ Example: update private docIDs, with identity: } switch { - case len(argDocIDs) == 1 && updater != "": - docID, err := client.NewDocIDFromString(argDocIDs[0]) - if err != nil { - return err - } - res, err := col.UpdateWithDocID(cmd.Context(), docID, updater) - if err != nil { - return err - } - return writeJSON(cmd, res) - case len(argDocIDs) > 1 && updater != "": - docIDs := make([]client.DocID, len(argDocIDs)) - for i, v := range argDocIDs { - docID, err := client.NewDocIDFromString(v) - if err != nil { - return err - } - docIDs[i] = docID - } - res, err := col.UpdateWithDocIDs(cmd.Context(), docIDs, updater) - if err != nil { - return err - } - return writeJSON(cmd, res) case filter != "" && updater != "": res, err := col.UpdateWithFilter(cmd.Context(), filter, updater) if err != nil { return err } return writeJSON(cmd, res) - case len(argDocIDs) == 1 && len(args) == 1: - docID, err := client.NewDocIDFromString(argDocIDs[0]) + case argDocID != "" && len(args) == 1: + docID, err := client.NewDocIDFromString(argDocID) if err != nil { return err } @@ -96,7 +72,7 @@ Example: update private docIDs, with identity: } }, } - cmd.Flags().StringSliceVar(&argDocIDs, "docID", nil, "Document ID") + cmd.Flags().StringVar(&argDocID, "docID", "", "Document ID") cmd.Flags().StringVar(&filter, "filter", "", "Document filter") cmd.Flags().StringVar(&updater, "updater", "", "Document updater") return cmd diff --git a/client/collection.go b/client/collection.go index 05cb821889..38c309a0e8 100644 --- a/client/collection.go +++ b/client/collection.go @@ -78,21 +78,6 @@ type Collection interface { // Will return true if a matching document exists, otherwise will return false. Exists(ctx context.Context, docID DocID) (bool, error) - // UpdateWith updates a target document using the given updater type. - // - // Target can be a Filter statement, a single DocID, a single document, - // an array of DocIDs, or an array of documents. - // It is recommended to use the respective typed versions of Update - // (e.g. UpdateWithFilter or UpdateWithDocID) over this function if you can. - // - // Returns an ErrInvalidUpdateTarget error if the target type is not supported. - // Returns an ErrInvalidUpdater error if the updater type is not supported. - UpdateWith( - ctx context.Context, - target any, - updater string, - ) (*UpdateResult, error) - // UpdateWithFilter updates using a filter to target documents for update. // // The provided updater must be a string Patch, string Merge Patch, a parsed Patch, or parsed Merge Patch @@ -103,44 +88,6 @@ type Collection interface { updater string, ) (*UpdateResult, error) - // UpdateWithDocID updates using a DocID to target a single document for update. - // - // The provided updater must be a string Patch, string Merge Patch, a parsed Patch, or parsed Merge Patch - // else an ErrInvalidUpdater will be returned. - // - // Returns an ErrDocumentNotFound if a document matching the given DocID is not found. - UpdateWithDocID( - ctx context.Context, - docID DocID, - updater string, - ) (*UpdateResult, error) - - // UpdateWithDocIDs updates documents matching the given DocIDs. - // - // The provided updater must be a string Patch, string Merge Patch, a parsed Patch, or parsed Merge Patch - // else an ErrInvalidUpdater will be returned. - // - // Returns an ErrDocumentNotFound if a document is not found for any given DocID. - UpdateWithDocIDs( - ctx context.Context, - docIDs []DocID, - updater string, - ) (*UpdateResult, error) - - // DeleteWith deletes a target document. - // - // Target can be a Filter statement, a single DocID, a single document, an array of DocIDs, - // or an array of documents. It is recommended to use the respective typed versions of Delete - // (e.g. DeleteWithFilter or DeleteWithDocID) over this function if you can. - // This operation will soft-delete documents related to the given DocID and update the composite block - // with a status of `Deleted`. - // - // Returns an ErrInvalidDeleteTarget if the target type is not supported. - DeleteWith( - ctx context.Context, - target any, - ) (*DeleteResult, error) - // DeleteWithFilter deletes documents matching the given filter. // // This operation will soft-delete documents related to the given filter and update the composite block @@ -150,28 +97,6 @@ type Collection interface { filter any, ) (*DeleteResult, error) - // DeleteWithDocID deletes using a DocID to target a single document for delete. - // - // This operation will soft-delete documents related to the given DocID and update the composite block - // with a status of `Deleted`. - // - // Returns an ErrDocumentNotFound if a document matching the given DocID is not found. - DeleteWithDocID( - ctx context.Context, - docID DocID, - ) (*DeleteResult, error) - - // DeleteWithDocIDs deletes documents matching the given DocIDs. - // - // This operation will soft-delete documents related to the given DocIDs and update the composite block - // with a status of `Deleted`. - // - // Returns an ErrDocumentNotFound if a document is not found for any given DocID. - DeleteWithDocIDs( - ctx context.Context, - docIDs []DocID, - ) (*DeleteResult, error) - // Get returns the document with the given DocID. // // Returns an ErrDocumentNotFound if a document matching the given DocID is not found. diff --git a/client/document.go b/client/document.go index 2325328b13..4534e9fa33 100644 --- a/client/document.go +++ b/client/document.go @@ -630,9 +630,6 @@ func (doc *Document) setCBOR(t CType, field string, val NormalValue) error { func (doc *Document) setAndParseObjectType(value map[string]any) error { for k, v := range value { - if v == nil { - continue - } err := doc.Set(k, v) if err != nil { return err diff --git a/db/collection_delete.go b/db/collection_delete.go index e8bf13b221..62ebd7f167 100644 --- a/db/collection_delete.go +++ b/db/collection_delete.go @@ -15,74 +15,11 @@ import ( "github.com/sourcenetwork/defradb/acp" "github.com/sourcenetwork/defradb/client" - "github.com/sourcenetwork/defradb/client/request" "github.com/sourcenetwork/defradb/core" "github.com/sourcenetwork/defradb/events" "github.com/sourcenetwork/defradb/merkle/clock" ) -// DeleteWith deletes a target document. -// -// Target can be a Filter statement, a single DocID, a single document, -// an array of DocIDs, or an array of documents. -// -// If you want more type safety, use the respective typed versions of Delete. -// Eg: DeleteWithFilter or DeleteWithDocID -func (c *collection) DeleteWith( - ctx context.Context, - target any, -) (*client.DeleteResult, error) { - switch t := target.(type) { - case string, map[string]any, *request.Filter: - return c.DeleteWithFilter(ctx, t) - case client.DocID: - return c.DeleteWithDocID(ctx, t) - case []client.DocID: - return c.DeleteWithDocIDs(ctx, t) - default: - return nil, client.ErrInvalidDeleteTarget - } -} - -// DeleteWithDocID deletes using a DocID to target a single document for delete. -func (c *collection) DeleteWithDocID( - ctx context.Context, - docID client.DocID, -) (*client.DeleteResult, error) { - ctx, txn, err := ensureContextTxn(ctx, c.db, false) - if err != nil { - return nil, err - } - defer txn.Discard(ctx) - - dsKey := c.getPrimaryKeyFromDocID(docID) - res, err := c.deleteWithKey(ctx, dsKey) - if err != nil { - return nil, err - } - - return res, txn.Commit(ctx) -} - -// DeleteWithDocIDs is the same as DeleteWithDocID but accepts multiple DocIDs as a slice. -func (c *collection) DeleteWithDocIDs( - ctx context.Context, - docIDs []client.DocID, -) (*client.DeleteResult, error) { - ctx, txn, err := ensureContextTxn(ctx, c.db, false) - if err != nil { - return nil, err - } - defer txn.Discard(ctx) - - res, err := c.deleteWithIDs(ctx, docIDs, client.Deleted) - if err != nil { - return nil, err - } - - return res, txn.Commit(ctx) -} - // DeleteWithFilter deletes using a filter to target documents for delete. func (c *collection) DeleteWithFilter( ctx context.Context, @@ -102,54 +39,6 @@ func (c *collection) DeleteWithFilter( return res, txn.Commit(ctx) } -func (c *collection) deleteWithKey( - ctx context.Context, - key core.PrimaryDataStoreKey, -) (*client.DeleteResult, error) { - // Check the key we have been given to delete with actually has a corresponding - // document (i.e. document actually exists in the collection). - err := c.applyDelete(ctx, key) - if err != nil { - return nil, err - } - - // Upon successfull deletion, record a summary. - results := &client.DeleteResult{ - Count: 1, - DocIDs: []string{key.DocID}, - } - - return results, nil -} - -func (c *collection) deleteWithIDs( - ctx context.Context, - docIDs []client.DocID, - _ client.DocumentStatus, -) (*client.DeleteResult, error) { - results := &client.DeleteResult{ - DocIDs: make([]string, 0), - } - - for _, docID := range docIDs { - primaryKey := c.getPrimaryKeyFromDocID(docID) - - // Apply the function that will perform the full deletion of this document. - err := c.applyDelete(ctx, primaryKey) - if err != nil { - return nil, err - } - - // Add this deleted docID to our list. - results.DocIDs = append(results.DocIDs, docID.String()) - } - - // Upon successfull deletion, record a summary of how many we deleted. - results.Count = int64(len(results.DocIDs)) - - return results, nil -} - func (c *collection) deleteWithFilter( ctx context.Context, filter any, diff --git a/db/collection_update.go b/db/collection_update.go index 9110976593..e59469715a 100644 --- a/db/collection_update.go +++ b/db/collection_update.go @@ -24,28 +24,6 @@ import ( "github.com/sourcenetwork/defradb/planner" ) -// UpdateWith updates a target document using the given updater type. Target -// can be a Filter statement, a single DocID, a single document, -// an array of DocIDs, or an array of documents. -// If you want more type safety, use the respective typed versions of Update. -// Eg: UpdateWithFilter or UpdateWithDocID -func (c *collection) UpdateWith( - ctx context.Context, - target any, - updater string, -) (*client.UpdateResult, error) { - switch t := target.(type) { - case string, map[string]any, *request.Filter: - return c.UpdateWithFilter(ctx, t, updater) - case client.DocID: - return c.UpdateWithDocID(ctx, t, updater) - case []client.DocID: - return c.UpdateWithDocIDs(ctx, t, updater) - default: - return nil, client.ErrInvalidUpdateTarget - } -} - // UpdateWithFilter updates using a filter to target documents for update. // An updater value is provided, which could be a string Patch, string Merge Patch // or a parsed Patch, or parsed Merge Patch. @@ -67,139 +45,6 @@ func (c *collection) UpdateWithFilter( return res, txn.Commit(ctx) } -// UpdateWithDocID updates using a DocID to target a single document for update. -// An updater value is provided, which could be a string Patch, string Merge Patch -// or a parsed Patch, or parsed Merge Patch. -func (c *collection) UpdateWithDocID( - ctx context.Context, - docID client.DocID, - updater string, -) (*client.UpdateResult, error) { - ctx, txn, err := ensureContextTxn(ctx, c.db, false) - if err != nil { - return nil, err - } - defer txn.Discard(ctx) - - res, err := c.updateWithDocID(ctx, docID, updater) - if err != nil { - return nil, err - } - - return res, txn.Commit(ctx) -} - -// UpdateWithDocIDs is the same as UpdateWithDocID but accepts multiple DocIDs as a slice. -// An updater value is provided, which could be a string Patch, string Merge Patch -// or a parsed Patch, or parsed Merge Patch. -func (c *collection) UpdateWithDocIDs( - ctx context.Context, - docIDs []client.DocID, - updater string, -) (*client.UpdateResult, error) { - ctx, txn, err := ensureContextTxn(ctx, c.db, false) - if err != nil { - return nil, err - } - defer txn.Discard(ctx) - - res, err := c.updateWithIDs(ctx, docIDs, updater) - if err != nil { - return nil, err - } - - return res, txn.Commit(ctx) -} - -func (c *collection) updateWithDocID( - ctx context.Context, - docID client.DocID, - updater string, -) (*client.UpdateResult, error) { - parsedUpdater, err := fastjson.Parse(updater) - if err != nil { - return nil, err - } - - isPatch := false - if parsedUpdater.Type() == fastjson.TypeArray { - isPatch = true - } else if parsedUpdater.Type() != fastjson.TypeObject { - return nil, client.ErrInvalidUpdater - } - - doc, err := c.Get(ctx, docID, false) - if err != nil { - return nil, err - } - - if isPatch { - // todo - } else { - err = doc.SetWithJSON([]byte(updater)) - } - if err != nil { - return nil, err - } - - err = c.update(ctx, doc) - if err != nil { - return nil, err - } - - results := &client.UpdateResult{ - Count: 1, - DocIDs: []string{docID.String()}, - } - return results, nil -} - -func (c *collection) updateWithIDs( - ctx context.Context, - docIDs []client.DocID, - updater string, -) (*client.UpdateResult, error) { - parsedUpdater, err := fastjson.Parse(updater) - if err != nil { - return nil, err - } - - isPatch := false - if parsedUpdater.Type() == fastjson.TypeArray { - isPatch = true - } else if parsedUpdater.Type() != fastjson.TypeObject { - return nil, client.ErrInvalidUpdater - } - - results := &client.UpdateResult{ - DocIDs: make([]string, len(docIDs)), - } - for i, docIDs := range docIDs { - doc, err := c.Get(ctx, docIDs, false) - if err != nil { - return nil, err - } - - if isPatch { - // todo - } else { - err = doc.SetWithJSON([]byte(updater)) - } - if err != nil { - return nil, err - } - - err = c.update(ctx, doc) - if err != nil { - return nil, err - } - - results.DocIDs[i] = docIDs.String() - results.Count++ - } - return results, nil -} - func (c *collection) updateWithFilter( ctx context.Context, filter any, diff --git a/docs/cli/defradb_client_collection_delete.md b/docs/cli/defradb_client_collection_delete.md index f3c678e857..110654ff5d 100644 --- a/docs/cli/defradb_client_collection_delete.md +++ b/docs/cli/defradb_client_collection_delete.md @@ -6,11 +6,11 @@ Delete documents by docID or filter. Delete documents by docID or filter and lists the number of documents deleted. -Example: delete by docID(s): - defradb client collection delete --name User --docID bae-123,bae-456 +Example: delete by docID: + defradb client collection delete --name User --docID bae-123 -Example: delete by docID(s) with identity: - defradb client collection delete -i cosmos1f2djr7dl9vhrk3twt3xwqp09nhtzec9mdkf70j --name User --docID bae-123,bae-456 +Example: delete by docID with identity: + defradb client collection delete -i cosmos1f2djr7dl9vhrk3twt3xwqp09nhtzec9mdkf70j --name User --docID bae-123 Example: delete by filter: defradb client collection delete --name User --filter '{ "_gte": { "points": 100 } }' @@ -23,7 +23,7 @@ defradb client collection delete [-i --identity] [--filter --docID --docID