diff --git a/db/collection_delete.go b/db/collection_delete.go index a7e252cf95..89d224aab8 100644 --- a/db/collection_delete.go +++ b/db/collection_delete.go @@ -271,41 +271,81 @@ func (d dagDeleter) delete( return nil } -// =================================== UNIMPLEMENTED =================================== - // DeleteWithFilter deletes using a filter to target documents for delete. -// An deleter value is provided, which could be a string Patch, string Merge Patch -// or a parsed Patch, or parsed Merge Patch. func (c *Collection) DeleteWithFilter(ctx context.Context, filter interface{}, opts ...client.DeleteOpt) (*client.DeleteResult, error) { - // txn, err := c.getTxn(ctx, false) - // if err != nil { - // return nil, err - // } - // defer c.discardImplicitTxn(ctx, txn) - // res, err := c.deleteWithFilter(ctx, txn, filter, deleter, opts...) - // if err != nil { - // return nil, err - // } - // return res, c.commitImplicitTxn(ctx, txn) + txn, err := c.getTxn(ctx, false) + if err != nil { + return nil, err + } + + defer c.discardImplicitTxn(ctx, txn) + + res, err := c.deleteWithFilter(ctx, txn, filter, opts...) + if err != nil { + return nil, err + } + + return res, c.commitImplicitTxn(ctx, txn) - return nil, nil } +func (c *Collection) deleteWithFilter(ctx context.Context, txn core.Txn, filter interface{}, opts ...client.DeleteOpt) (*client.DeleteResult, error) { + + // Do a selection query to scan through documents using the given filter. + query, err := c.makeSelectionQuery(ctx, txn, filter) + if err != nil { + return nil, err + } + if err := query.Start(); err != nil { + return nil, err + } + + results := &client.DeleteResult{ + DocKeys: make([]string, 0), + } + + // Keep looping until results from the filter query have been iterated through. + for { + next, err := query.Next() + if err != nil { + return nil, err + } + + // If no results remaining / or gotten then break out of the loop. + if !next { + break + } + + // Extract the dockey in the string format from the document value. + docKey := query.Values()["_key"].(string) + + // Convert from string to key.DocKey. + key, err := key.NewFromString(docKey) + if err != nil { + return nil, err + } + + // Delete the document that is assosiated with this key we got from the filter. + err = c.applyFullDelete(ctx, txn, key) + if err != nil { + return nil, err + } + + // Add key of successfully deleted document to our list. + results.DocKeys = append(results.DocKeys, docKey) + } + + results.Count = int64(len(results.DocKeys)) + + return results, nil +} + +// =================================== UNIMPLEMENTED =================================== + // DeleteWithKeys is the same as DeleteWithKey but accepts multiple keys as a slice. // An deleter value is provided, which could be a string Patch, string Merge Patch // or a parsed Patch, or parsed Merge Patch. func (c *Collection) DeleteWithKeys(ctx context.Context, keys []key.DocKey, opts ...client.DeleteOpt) (*client.DeleteResult, error) { - // txn, err := c.getTxn(ctx, false) - // if err != nil { - // return nil, err - // } - // defer c.discardImplicitTxn(ctx, txn) - // res, err := c.deleteWithKeys(ctx, txn, keys, deleter, opts...) - // if err != nil { - // return nil, err - // } - // return res, c.commitImplicitTxn(ctx, txn) - return nil, nil } @@ -323,114 +363,6 @@ func (c *Collection) DeleteWithDocs(docs []*document.SimpleDocument, opts ...cli return nil } -//nolint:unused func (c *Collection) deleteWithKeys(ctx context.Context, txn core.Txn, keys []key.DocKey, opts ...client.DeleteOpt) (*client.DeleteResult, error) { - // fmt.Println("updating keys:", keys) - // patch, err := parseDeleter(deleter) - // if err != nil { - // return nil, err - // } - // - // isPatch := false - // switch patch.(type) { - // case []map[string]interface{}: - // isPatch = true - // case map[string]interface{}: - // isPatch = false - // default: - // return nil, ErrInvalidDeleter - // } - // - // results := &client.DeleteResult{ - // DocKeys: make([]string, len(keys)), - // } - // for i, key := range keys { - // doc, err := c.Get(ctx, key) - // if err != nil { - // fmt.Println("error getting key to delete:", key) - // return nil, err - // } - // v, err := doc.ToMap() - // if err != nil { - // return nil, err - // } - // - // if isPatch { - // // todo - // } else { - // err = c.applyMerge(ctx, txn, v, patch.(map[string]interface{})) - // } - // if err != nil { - // return nil, nil - // } - // - // results.DocKeys[i] = key.String() - // results.Count++ - // } - // return results, nil - - return nil, nil -} - -//nolint:unused -func (c *Collection) deleteWithFilter(ctx context.Context, txn core.Txn, filter interface{}, opts ...client.DeleteOpt) (*client.DeleteResult, error) { - // patch, err := parseDeleter(deleter) - // if err != nil { - // return nil, err - // } - - // isPatch := false - // isMerge := false - // switch patch.(type) { - // case []map[string]interface{}: - // isPatch = true - // case map[string]interface{}: - // isMerge = true - // default: - // return nil, ErrInvalidDeleter - // } - - // // scan through docs with filter - // query, err := c.makeSelectionQuery(ctx, txn, filter, opts...) - // if err != nil { - // return nil, err - // } - // if err := query.Start(); err != nil { - // return nil, err - // } - - // results := &client.DeleteResult{ - // DocKeys: make([]string, 0), - // } - - // // loop while we still have results from the filter query - // for { - // next, err := query.Next() - // if err != nil { - // return nil, err - // } - // // if theres no more records from the query, jump out of the loop - // if !next { - // break - // } - - // // Get the document, and apply the patch - // doc := query.Values() - // if isPatch { - // err = c.applyPatch(txn, doc, patch.([]map[string]interface{})) - // } else if isMerge { // else is fine here - // err = c.applyMerge(ctx, txn, doc, patch.(map[string]interface{})) - // } - // if err != nil { - // return nil, err - // } - - // // add successful deleted doc to results - // results.DocKeys = append(results.DocKeys, doc["_key"].(string)) - // results.Count++ - // } - - // return results, nil - return nil, nil } diff --git a/db/collection_update.go b/db/collection_update.go index 99a1ee2fe4..ea0fbc6776 100644 --- a/db/collection_update.go +++ b/db/collection_update.go @@ -248,7 +248,7 @@ func (c *Collection) updateWithFilter(ctx context.Context, txn core.Txn, filter } // scan through docs with filter - query, err := c.makeSelectionQuery(ctx, txn, filter, opts...) + query, err := c.makeSelectionQuery(ctx, txn, filter) if err != nil { return nil, err } diff --git a/query/graphql/planner/delete.go b/query/graphql/planner/delete.go index d00b5fa6fd..3e97329e6d 100644 --- a/query/graphql/planner/delete.go +++ b/query/graphql/planner/delete.go @@ -61,6 +61,7 @@ func (n *deleteNode) Next() (bool, error) { } results, err = n.collection.DeleteWithKeys(n.p.ctx, keys) } else { // @todo: handle filter vs ID based + fmt.Println("=-=-=-=-=-=-=-=-=-=-===-=-=-=-=-=-=-=-=-=-===-=-=-=-=-=-=-=-=-=-==-") results, err = n.collection.DeleteWithFilter(n.p.ctx, n.filter) }