diff --git a/lib/storage/providers/SQLiteProvider.ts b/lib/storage/providers/SQLiteProvider.ts index 1d2927d8c..afbc0f405 100644 --- a/lib/storage/providers/SQLiteProvider.ts +++ b/lib/storage/providers/SQLiteProvider.ts @@ -127,7 +127,7 @@ const provider: StorageProvider = { throw new Error('Store is not initialized!'); } - const query = 'REPLACE INTO keyvaluepairs (record_key, valueJSON) VALUES (?, json(?));'; + const query = 'REPLACE INTO keyvaluepairs (record_key, valueJSON) VALUES (?, ?);'; const params = pairs.map((pair) => [pair[0], JSON.stringify(pair[1] === undefined ? null : pair[1])]); if (utils.isEmptyObject(params)) { return Promise.resolve(); @@ -143,13 +143,17 @@ const provider: StorageProvider = { // Query to merge the change into the DB value. const patchQuery = `INSERT INTO keyvaluepairs (record_key, valueJSON) - VALUES (:key, JSON(:value)) + VALUES (:key, :value) ON CONFLICT DO UPDATE - SET valueJSON = JSON_PATCH(valueJSON, JSON(:value)); + SET valueJSON = JSON_PATCH(valueJSON, :value); `; const patchQueryArguments: string[][] = []; // Query to fully replace the nested objects of the DB value. + // NOTE: The JSON() wrapper around the replacement value is required here. Unlike JSON_PATCH (which + // parses both arguments as JSON internally), JSON_REPLACE treats a plain TEXT binding as a quoted + // JSON string. Without JSON(), objects would be stored as string values (e.g. "{...}") instead of + // actual JSON objects, corrupting the stored data. const replaceQuery = `UPDATE keyvaluepairs SET valueJSON = JSON_REPLACE(valueJSON, ?, JSON(?)) WHERE record_key = ?;