Skip to content

Commit

Permalink
Feat/field delete (#91)
Browse files Browse the repository at this point in the history
* first implemtation of -f flag

* added testing

* added documentation

* update node.js to version 18 in workflow

* updated node.js version to 18 for master workflow
  • Loading branch information
Mopsgeschwindigkeit authored Oct 9, 2023
1 parent d26d751 commit 1a61abc
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 30 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/dev.workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
- name: Install Node&Npm
uses: actions/setup-node@v2
with:
node-version: '14'
node-version: '18'
- name: Checkout code
uses: actions/checkout@v2
- name: Retrieve new version
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/master.workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
- name: Install Node&Npm
uses: actions/setup-node@v2
with:
node-version: '14'
node-version: '18'
- name: Checkout code
uses: actions/checkout@v2
- name: Retrieve new version
Expand Down
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,12 @@ It's also possible to delete multiple documents without transaction
fuego delete people Rv7ZfnLQWprdXuulqMdf,Rv7ZfnLQWprdXuulqMde
```
Deleting a specific field of a document, the ```--field, -f``` flag can be used.
```sh
fuego delete people/Rv7ZfnLQWprdXuulqMdf -f age
```
This command will delete the age field from the given doument path.
To update an existing document:
Expand Down
29 changes: 27 additions & 2 deletions delete.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
package main

import (
firestore "cloud.google.com/go/firestore"
"context"
"fmt"
"log"

firestore "cloud.google.com/go/firestore"
"github.com/urfave/cli"
"google.golang.org/api/iterator"
"log"
)

func deleteCommandAction(c *cli.Context) error {
Expand All @@ -18,6 +19,11 @@ func deleteCommandAction(c *cli.Context) error {
}

deleteRecursive := c.Bool("recursive")
deleteField := c.String("field")

if deleteRecursive && deleteField != "" {
return cli.NewExitError("recursive delete and field delete can't be combined!", 82)
}

client, err := createClient(credentials)
if err != nil {
Expand All @@ -36,6 +42,8 @@ func deleteCommandAction(c *cli.Context) error {
documentRef = client.Doc(documentPath)
}

defer client.Close()

if deleteRecursive {
deleteBatch := client.Batch()
err = deleteSubCollections(documentRef, client, deleteBatch)
Expand All @@ -49,6 +57,23 @@ func deleteCommandAction(c *cli.Context) error {
}
}

if deleteField != "" {

_, err := documentRef.Update(
context.Background(),
[]firestore.Update{{
Path: deleteField,
Value: firestore.Delete,
},
})

if err != nil {
return cli.NewExitError(fmt.Sprintf("failed to delete field. \n%v", err), 82)
}

return nil
}

res, err := documentRef.Delete(context.Background())
if err != nil {
return cli.NewExitError(fmt.Sprintf("Failed to delete data. \n%v", res), 82)
Expand Down
7 changes: 6 additions & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ package main

import (
"fmt"
"github.com/urfave/cli"
"log"
"os"

"github.com/urfave/cli"
)

// Global configuration
Expand Down Expand Up @@ -48,6 +49,10 @@ func main() {
Name: "recursive, r",
Usage: "Recursively delete sub-collections",
},
cli.StringFlag{
Name: "field, f",
Usage: "Delete specific field of document",
},
}

app.Commands = []cli.Command{
Expand Down
81 changes: 56 additions & 25 deletions tests/tests
Original file line number Diff line number Diff line change
Expand Up @@ -350,31 +350,62 @@ testCopyDocumentAndCollection(){
}

testDeleteRecursive(){
# adding new documents with nested sub-collections
id=$(../fuego add ${TEST_COLLECTION} "{\"base\": \"value\"}") || fail "Failed to add document"
subDocId1=$(../fuego add "${TEST_COLLECTION}/${id}/subCollection1" "{\"base\": \"sub value1\"}") || fail "Failed to add document"
subSubDocId1=$(../fuego add "${TEST_COLLECTION}/${id}/subCollection1/${subDocId1}/subSubCollection1" "{\"base\": \"subsub value1\"}")|| fail "Failed to add document"

subDocId2=$(../fuego add "${TEST_COLLECTION}/${id}/subCollection2" "{\"base\": \"sub value2\"}") || fail "Failed to add document"
subSubDocId2=$(../fuego add "${TEST_COLLECTION}/${id}/subCollection2/${subDocId2}/subSubCollection2" "{\"base\": \"subsub value2\"}")|| fail "Failed to add document"
echo ${id} ${subDocId1} ${subSubDocId1} ${subDocId2} ${subSubDocId2}

# delete one collection without recursive flag. To test deletion of missing documents.
../fuego delete "${TEST_COLLECTION}/${id}/subCollection1" ${subDocId1}
assertFalse "Should not have read deleted value" "../fuego get ${TEST_COLLECTION}/${id}/subCollection1 ${subDocId1}"

# check that sub-collection of deleted collection still exists
expectedValue=$(echo "{\"base\": \"subsub value1\"}" | jq .)
result=$(../fuego get "${TEST_COLLECTION}/${id}/subCollection1/${subDocId1}/subSubCollection1/${subSubDocId1}" | jq .Data)
assertEquals "Should be able to read SubCollection" "${result}" "${expectedValue}"

# call delete again, but with recursive flag.
../fuego delete -r "${TEST_COLLECTION}" ${id}

# check that all documents are deleted, also the missing documents.
assertFalse "Should not have read deleted value2" "../fuego get ${TEST_COLLECTION}/${id}/subCollection1/${subDocId1}/subSubCollection1 ${subSubDocId1}"
assertFalse "Should not have read deleted value3" "../fuego get ${TEST_COLLECTION}/${id}/subCollection2 ${subDocId2}"
assertFalse "Should not have read deleted value2" "../fuego get ${TEST_COLLECTION}/${id}/subCollection2/${subDocId2}/subSubCollection2 ${subSubDocId2}"
# adding new documents with nested sub-collections
id=$(../fuego add ${TEST_COLLECTION} "{\"base\": \"value\"}") || fail "Failed to add document"
subDocId1=$(../fuego add "${TEST_COLLECTION}/${id}/subCollection1" "{\"base\": \"sub value1\"}") || fail "Failed to add document"
subSubDocId1=$(../fuego add "${TEST_COLLECTION}/${id}/subCollection1/${subDocId1}/subSubCollection1" "{\"base\": \"subsub value1\"}")|| fail "Failed to add document"

subDocId2=$(../fuego add "${TEST_COLLECTION}/${id}/subCollection2" "{\"base\": \"sub value2\"}") || fail "Failed to add document"
subSubDocId2=$(../fuego add "${TEST_COLLECTION}/${id}/subCollection2/${subDocId2}/subSubCollection2" "{\"base\": \"subsub value2\"}")|| fail "Failed to add document"
echo ${id} ${subDocId1} ${subSubDocId1} ${subDocId2} ${subSubDocId2}

# delete one collection without recursive flag. To test deletion of missing documents.
../fuego delete "${TEST_COLLECTION}/${id}/subCollection1" ${subDocId1}
assertFalse "Should not have read deleted value" "../fuego get ${TEST_COLLECTION}/${id}/subCollection1 ${subDocId1}"

# check that sub-collection of deleted collection still exists
expectedValue=$(echo "{\"base\": \"subsub value1\"}" | jq .)
result=$(../fuego get "${TEST_COLLECTION}/${id}/subCollection1/${subDocId1}/subSubCollection1/${subSubDocId1}" | jq .Data)
assertEquals "Should be able to read SubCollection" "${result}" "${expectedValue}"

# call delete again, but with recursive flag.
../fuego delete -r "${TEST_COLLECTION}" ${id}

# check that all documents are deleted, also the missing documents.
assertFalse "Should not have read deleted value2" "../fuego get ${TEST_COLLECTION}/${id}/subCollection1/${subDocId1}/subSubCollection1 ${subSubDocId1}"
assertFalse "Should not have read deleted value3" "../fuego get ${TEST_COLLECTION}/${id}/subCollection2 ${subDocId2}"
assertFalse "Should not have read deleted value2" "../fuego get ${TEST_COLLECTION}/${id}/subCollection2/${subDocId2}/subSubCollection2 ${subSubDocId2}"
}

testFieldDelete(){
# adding new documents with sub-collections and two fields
id=$(../fuego add ${TEST_COLLECTION} "{\"base\": \"value\", \"base2\": \"value2\"}") || fail "Failed to add document"
subDocId1=$(../fuego add "${TEST_COLLECTION}/${id}/subCollection1" "{\"subbase\": \"sub value1\"}") || fail "Failed to add document"
subDocId2=$(../fuego add "${TEST_COLLECTION}/${id}/subCollection1/${subDocId1}/subCollection2" "{\"sub2base\": \"sub2 value1\"}") || fail "Failed to add document"
echo ${id} ${subDocId1} ${subDocId2}

# check preconditions for first level
result=$(../fuego get ${TEST_COLLECTION}/${id} | jq -c .Data)
expectedValue='{"base":"value","base2":"value2"}'
assertEquals "Preconditions Failed" "${result}" "${expectedValue}"

# delete field from first level
../fuego delete -f "base2" ${TEST_COLLECTION}/${id}
result=$(../fuego get ${TEST_COLLECTION}/${id} | jq -c .Data)
expectedValue='{"base":"value"}'
assertEquals "Failed to delete from First level" "${result}" "${expectedValue}"

# check preconditions for second level
result=$(../fuego get ${TEST_COLLECTION}/${id}/subCollection1/${subDocId1} | jq -c .Data)
expectedValue='{"subbase":"sub value1"}'
assertEquals "Preconditions Failed" "${result}" "${expectedValue}"

# delete field from second level
../fuego delete -f "subbase" ${TEST_COLLECTION}/${id}/subCollection1/${subDocId1}
result=$(../fuego get ${TEST_COLLECTION}/${id}/subCollection1/${subDocId1} | jq -c .Data)
expectedValue='{}'
assertEquals "Failed to delete from First level" "${result}" "${expectedValue}"
}

# Load shUnit2.
. ./shunit2

0 comments on commit 1a61abc

Please sign in to comment.