diff --git a/storage/localStorage.go b/storage/localStorage.go index d300e7fbdb02c4427bcb6be03fdd587e35630f82..d54039c99c427640b3298c7aeb87dfb819d046be 100644 --- a/storage/localStorage.go +++ b/storage/localStorage.go @@ -114,36 +114,46 @@ func (ls *LocalStorage) Clear() { ls.clear() } -// ClearPrefix clears all keys with the given prefix. -func (ls *LocalStorage) ClearPrefix(prefix string) { +// ClearPrefix clears all keys with the given prefix. Returns the number of +// keys cleared. +func (ls *LocalStorage) ClearPrefix(prefix string) int { // Get a copy of all key names at once keys := ls.keys() // Loop through each key + var n int for i := 0; i < keys.Length(); i++ { if v := keys.Index(i); !v.IsNull() { keyName := strings.TrimPrefix(v.String(), ls.prefix) if strings.HasPrefix(keyName, prefix) { ls.removeItem(v.String()) + n++ } } } + + return n } -// ClearWASM clears all the keys in storage created by WASM. -func (ls *LocalStorage) ClearWASM() { +// ClearWASM clears all the keys in storage created by WASM. Returns the number +// of keys cleared. +func (ls *LocalStorage) ClearWASM() int { // Get a copy of all key names at once keys := ls.keys() // Loop through each key + var n int for i := 0; i < keys.Length(); i++ { if v := keys.Index(i); !v.IsNull() { keyName := v.String() if strings.HasPrefix(keyName, ls.prefix) { ls.RemoveItem(strings.TrimPrefix(keyName, ls.prefix)) + n++ } } } + + return n } // Key returns the name of the nth key in localStorage. Return os.ErrNotExist if diff --git a/storage/localStorage_test.go b/storage/localStorage_test.go index 5c347308e35dd7438dabd520a7e011e5d8389c46..20e424108af9b7ed64c9c4ba00e348b121beefc4 100644 --- a/storage/localStorage_test.go +++ b/storage/localStorage_test.go @@ -91,10 +91,11 @@ func TestLocalStorage_ClearPrefix(t *testing.T) { s := newLocalStorage("") s.clear() prng := rand.New(rand.NewSource(11)) + const numKeys = 10 var yesPrefix, noPrefix []string prefix := "keyNamePrefix/" - for i := 0; i < 10; i++ { + for i := 0; i < numKeys; i++ { keyName := "keyNum" + strconv.Itoa(i) if prng.Intn(2) == 0 { keyName = prefix + keyName @@ -106,7 +107,11 @@ func TestLocalStorage_ClearPrefix(t *testing.T) { s.SetItem(keyName, []byte(strconv.Itoa(i))) } - s.ClearPrefix(prefix) + n := s.ClearPrefix(prefix) + if n != numKeys/2 { + t.Errorf("Incorrect number of keys.\nexpected: %d\nreceived: %d", + numKeys/2, n) + } for _, keyName := range noPrefix { if _, err := s.GetItem(keyName); err != nil { @@ -126,8 +131,10 @@ func TestLocalStorage_ClearPrefix(t *testing.T) { func TestLocalStorage_ClearWASM(t *testing.T) { jsStorage.clear() prng := rand.New(rand.NewSource(11)) + const numKeys = 10 var yesPrefix, noPrefix []string - for i := 0; i < 10; i++ { + + for i := 0; i < numKeys; i++ { keyName := "keyNum" + strconv.Itoa(i) if prng.Intn(2) == 0 { yesPrefix = append(yesPrefix, keyName) @@ -138,7 +145,11 @@ func TestLocalStorage_ClearWASM(t *testing.T) { } } - jsStorage.ClearWASM() + n := jsStorage.ClearWASM() + if n != numKeys/2 { + t.Errorf("Incorrect number of keys.\nexpected: %d\nreceived: %d", + numKeys/2, n) + } for _, keyName := range noPrefix { if v := jsStorage.getItem(keyName); v.IsNull() { diff --git a/storage/purge.go b/storage/purge.go index 025c36cfe7c59a58dd188c08bda1abb55705b5e7..b80481b470863c32dee6cad894858cb081a08abe 100644 --- a/storage/purge.go +++ b/storage/purge.go @@ -12,6 +12,7 @@ package storage import ( "github.com/hack-pad/go-indexeddb/idb" "github.com/pkg/errors" + jww "github.com/spf13/jwalterweatherman" "gitlab.com/elixxir/client/v4/storage/utility" "gitlab.com/elixxir/xxdk-wasm/utils" "sync/atomic" @@ -61,11 +62,11 @@ func Purge(_ js.Value, args []js.Value) any { } // Verify all Cmix followers are stopped - // if n := atomic.LoadUint64(&numClientsRunning); n != 0 { - // utils.Throw(utils.TypeError, errors.Errorf( - // "%d cMix followers running; all need to be stopped", n)) - // return nil - // } + if n := atomic.LoadUint64(&numClientsRunning); n != 0 { + utils.Throw(utils.TypeError, errors.Errorf( + "%d cMix followers running; all need to be stopped", n)) + return nil + } // Get all indexedDb database names databaseList, err := GetIndexedDbList() @@ -74,6 +75,8 @@ func Purge(_ js.Value, args []js.Value) any { "failed to get list of indexedDb database names: %+v", err)) return nil } + jww.DEBUG.Printf("[PURGE] Found %d databases to delete: %s", + len(databaseList), databaseList) // Delete each database for dbName := range databaseList { @@ -89,13 +92,18 @@ func Purge(_ js.Value, args []js.Value) any { ls := GetLocalStorage() // Clear all local storage saved by this WASM project - ls.ClearWASM() + n := ls.ClearWASM() + jww.DEBUG.Printf("[PURGE] Cleared %d WASM keys in local storage", n) // Clear all EKV from local storage - ls.ClearPrefix(storageDirectory) + n = ls.ClearPrefix(storageDirectory) + jww.DEBUG.Printf("[PURGE] Cleared %d keys with the prefix %q (for EKV)", + n, storageDirectory) // Clear all NDFs saved to local storage - ls.ClearPrefix(utility.NdfStorageKeyNamePrefix) + n = ls.ClearPrefix(utility.NdfStorageKeyNamePrefix) + jww.DEBUG.Printf("[PURGE] Cleared %d keys with the prefix %q (for NDF)", + n, utility.NdfStorageKeyNamePrefix) return nil }