diff --git a/lib/storage/providers/SQLiteProvider.ts b/lib/storage/providers/SQLiteProvider.ts index 56fadc588..ff1fbf4d6 100644 --- a/lib/storage/providers/SQLiteProvider.ts +++ b/lib/storage/providers/SQLiteProvider.ts @@ -201,11 +201,17 @@ const provider: StorageProvider = { throw new Error('Store is not initialized!'); } - return provider.store.executeAsync('SELECT record_key, valueJSON FROM keyvaluepairs;').then(({rows}) => { - // eslint-disable-next-line no-underscore-dangle - const result = rows?._array.map((row) => [row.record_key, JSON.parse(row.valueJSON)]); - return (result ?? []) as StorageKeyValuePair[]; - }); + // Aggregate the whole table into a single JSON string in SQLite so we only run JSON.parse + // once, instead of returning every row and parsing each one individually in JavaScript. + return provider.store + .executeAsync<{aggregated: string | null}>('SELECT json_group_array(json_array(record_key, json(valueJSON))) AS aggregated FROM keyvaluepairs;') + .then(({rows}) => { + const aggregated = rows?.item(0)?.aggregated; + if (aggregated == null) { + return []; + } + return JSON.parse(aggregated) as StorageKeyValuePair[]; + }); }, removeItem(key) { if (!provider.store) { diff --git a/tests/unit/storage/providers/SQLiteProviderTest.ts b/tests/unit/storage/providers/SQLiteProviderTest.ts index bc0cac00a..acc2e1d63 100644 --- a/tests/unit/storage/providers/SQLiteProviderTest.ts +++ b/tests/unit/storage/providers/SQLiteProviderTest.ts @@ -290,6 +290,23 @@ describe('SQLiteProvider', () => { }); }); + describe('getAll', () => { + it('should return every stored key-value pair with correct values', async () => { + await SQLiteProvider.multiSet(testEntries); + + const out = await SQLiteProvider.getAll(); + const sortedActual = [...out].sort((a, b) => a[0].localeCompare(b[0])); + const sortedExpected = [...testEntries].sort((a, b) => a[0].localeCompare(b[0])); + + expect(out).toHaveLength(5); + expect(sortedActual).toEqual(sortedExpected); + }); + + it('should return an empty array when the store is empty', async () => { + expect(await SQLiteProvider.getAll()).toEqual([]); + }); + }); + describe('removeItem', () => { it('should remove the key from the store', async () => { await SQLiteProvider.multiSet(testEntries);