diff --git a/lib/Onyx.js b/lib/Onyx.js index 4a4196da1..70c421dee 100644 --- a/lib/Onyx.js +++ b/lib/Onyx.js @@ -1102,7 +1102,8 @@ function clear(keysToPreserve = []) { notifyCollectionSubscribersOnNextTick(key, value); }); - return Storage.multiSet(keyValuesToReset); + return Storage.multiSet(defaultKeyValuePairs) + .then(() => Storage.multiRemove(keysToClear)); }); } diff --git a/lib/storage/providers/AsyncStorage.js b/lib/storage/providers/AsyncStorage.js index 2398916c0..0e62094d7 100644 --- a/lib/storage/providers/AsyncStorage.js +++ b/lib/storage/providers/AsyncStorage.js @@ -78,6 +78,13 @@ const provider = { * @returns {Promise} */ clear: AsyncStorage.clear, + + /** + * Removes all the keys specified in the array + * @param {Array} keys + * @returns {Promise} + */ + multiRemove: AsyncStorage.multiRemove, }; export default provider; diff --git a/lib/storage/providers/LocalForage.js b/lib/storage/providers/LocalForage.js index ea85a9153..11749d386 100644 --- a/lib/storage/providers/LocalForage.js +++ b/lib/storage/providers/LocalForage.js @@ -74,6 +74,18 @@ const provider = { return Promise.all(tasks).then(() => Promise.resolve()); }, + /** + * Removes all the keys specified in the array + * @param {Array} keys + * @returns {Promise} + */ + multiRemove(keys) { + const tasks = _.map(keys, key => this.removeItem(key)); + + // We're returning Promise.resolve, otherwise the array of task results will be returned to the caller + return Promise.all(tasks).then(() => Promise.resolve()); + }, + /** * Clear absolutely everything from storage * @returns {Promise} diff --git a/lib/storage/providers/SQLiteStorage.js b/lib/storage/providers/SQLiteStorage.js index 5a1c3b485..7a6fc46de 100644 --- a/lib/storage/providers/SQLiteStorage.js +++ b/lib/storage/providers/SQLiteStorage.js @@ -108,6 +108,16 @@ const provider = { */ removeItem: key => db.executeAsync('DELETE FROM keyvaluepairs WHERE record_key = ?;', [key]), + /** + * Removes all of the given keys + * @param {Array} keys + * @returns {Promise} + */ + multiRemove: (keys) => { + const placeholders = _.map(keys, () => '?').join(','); + return db.executeAsync(`DELETE FROM keyvaluepairs WHERE record_key IN (${placeholders});`, keys); + }, + /** * Clears absolutely everything from storage * @returns {Promise} diff --git a/tests/unit/onyxMultiMergeWebStorageTest.js b/tests/unit/onyxMultiMergeWebStorageTest.js index f60e24d81..cb9a0e1af 100644 --- a/tests/unit/onyxMultiMergeWebStorageTest.js +++ b/tests/unit/onyxMultiMergeWebStorageTest.js @@ -142,11 +142,7 @@ describe('Onyx.mergeCollection() amd WebStorage', () => { it('setItem() and multiMerge()', () => { // When Onyx is cleared, since it uses multiSet() to clear out all the values, the keys will remain with null for all the values - expect(localforageMock.storageMap).toEqual({ - test_1: null, - test_2: null, - test_3: null, - }); + expect(localforageMock.storageMap).toEqual({}); // Given no previous data and several calls to setItem and call to mergeCollection to update a given key diff --git a/tests/unit/storage/providers/AsyncStorageProviderTest.js b/tests/unit/storage/providers/AsyncStorageProviderTest.js index 3c45ef1ad..4ae8f173e 100644 --- a/tests/unit/storage/providers/AsyncStorageProviderTest.js +++ b/tests/unit/storage/providers/AsyncStorageProviderTest.js @@ -108,4 +108,18 @@ describe('storage/providers/AsyncStorage', () => { .then(values => expect(values).toEqual(items)); }); }); + + describe('multiRemove', () => { + it('Call multiRemove() with the list of keys', () => { + // Given sample content of all basic types + const pairs = SAMPLE_ITEMS.slice(); + const keys = _.map(pairs, pair => pair[0]); + + // When multiple keys are removed + StorageProvider.multiRemove(keys); + + // multiRemove should be called + expect(AsyncStorageMock.multiRemove).toHaveBeenCalledWith(keys); + }); + }); }); diff --git a/tests/unit/storage/providers/LocalForageProviderTest.js b/tests/unit/storage/providers/LocalForageProviderTest.js index e2c3b57c4..004eb20f0 100644 --- a/tests/unit/storage/providers/LocalForageProviderTest.js +++ b/tests/unit/storage/providers/LocalForageProviderTest.js @@ -104,4 +104,17 @@ describe('storage/providers/LocalForage', () => { }); }); }); + + it('multiRemove', () => { + // Given multiple pairs to be saved in storage + const pairs = SAMPLE_ITEMS.slice(); + const keys = _.map(pairs, pair => pair[0]); + + // When they are saved + return StorageProvider.multiRemove(keys) + .then(() => { + // We expect a call to localForage.removeItem for each pair + _.each(keys, key => expect(localforage.removeItem).toHaveBeenCalledWith(key)); + }); + }); });