feat: JSON support for kv driver

This commit is contained in:
KernelDeimos 2024-07-08 15:24:26 -04:00 committed by Eric Dubé
parent 1f659f7c01
commit 3ed7916856
3 changed files with 51 additions and 5 deletions

View File

@ -59,6 +59,11 @@ class DBKVStore extends Driver {
[ user.id, key_hash ]
);
if ( kv[0] ) kv[0].value = db.case({
mysql: () => kv[0].value,
otherwise: () => JSON.parse(kv[0].value ?? 'null'),
})();
return kv[0]?.value ?? null;
},
set: async function ({ app_uid, key, value }) {
@ -74,10 +79,11 @@ class DBKVStore extends Driver {
}
// Validate the value
value = value === undefined ? null : String(value);
value = value === undefined ? null : value;
if (
value !== null &&
Buffer.byteLength(value, 'utf8') > config.kv_max_value_size
Buffer.byteLength(JSON.stringify(value), 'utf8') >
config.kv_max_value_size
) {
throw new Error(`value is too large. Max size is ${config.kv_max_value_size}.`);
}
@ -102,7 +108,8 @@ class DBKVStore extends Driver {
sqlite: 'ON CONFLICT(user_id, app, kkey_hash) DO UPDATE SET value = excluded.value',
}),
[
user.id, app?.uid ?? 'global', key_hash, key, value,
user.id, app?.uid ?? 'global', key_hash, key,
JSON.stringify(value),
...db.case({ mysql: [value], otherwise: [] }),
]
);
@ -164,7 +171,10 @@ class DBKVStore extends Driver {
rows = rows.map(row => ({
key: row.kkey,
value: row.value,
value: db.case({
mysql: () => row.value,
otherwise: () => JSON.parse(row.value ?? 'null')
})(),
}));
as = as || 'entries';

View File

@ -42,7 +42,7 @@ class SqliteDatabaseAccessService extends BaseDatabaseAccessService {
this.db = new Database(this.config.path);
// Database upgrade logic
const TARGET_VERSION = 20;
const TARGET_VERSION = 21;
if ( do_setup ) {
this.log.noticeme(`SETUP: creating database at ${this.config.path}`);
@ -69,6 +69,7 @@ class SqliteDatabaseAccessService extends BaseDatabaseAccessService {
'0020_dev-center.sql',
'0021_app-owner-id.sql',
'0022_dev-center-max.sql',
'0023_fix-kv.sql',
].map(p => path_.join(__dirname, 'sqlite_setup', p));
const fs = require('fs');
for ( const filename of sql_files ) {
@ -165,6 +166,10 @@ class SqliteDatabaseAccessService extends BaseDatabaseAccessService {
upgrade_files.push('0022_dev-center-max.sql');
}
if ( user_version <= 20 ) {
upgrade_files.push('0023_fix-kv.sql');
}
if ( upgrade_files.length > 0 ) {
this.log.noticeme(`Database out of date: ${this.config.path}`);
this.log.noticeme(`UPGRADING DATABASE: ${user_version} -> ${TARGET_VERSION}`);

View File

@ -0,0 +1,31 @@
CREATE TABLE `new_kv` (
`id` INTEGER PRIMARY KEY,
`app` char(40) DEFAULT NULL,
`user_id` int(10) NOT NULL,
`kkey_hash` bigint(20) NOT NULL,
`kkey` text NOT NULL,
`value` JSON,
`migrated` tinyint(1) DEFAULT '0',
UNIQUE (user_id, app, kkey_hash)
);
INSERT INTO `new_kv`
(
`app`,
`user_id`,
`kkey_hash`,
`kkey`,
`value`
)
SELECT
`app`,
`user_id`,
`kkey_hash`,
`kkey`,
json_quote(value)
FROM `kv`;
DROP TABLE `kv`;
ALTER TABLE `new_kv`
RENAME TO `kv`;