mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-11-18 03:31:03 +01:00
Psql multikey (#9852)
* perf: convert promise.all to single query * perf: single query for removeBulk * perf: list
This commit is contained in:
committed by
GitHub
parent
ea04aeded4
commit
e6a17a6349
@@ -9,28 +9,18 @@ module.exports = function (module) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
await module.transaction(async (client) => {
|
await module.transaction(async (client) => {
|
||||||
async function doPrepend(value) {
|
|
||||||
await client.query({
|
|
||||||
name: 'listPrepend',
|
|
||||||
text: `
|
|
||||||
INSERT INTO "legacy_list" ("_key", "array")
|
|
||||||
VALUES ($1::TEXT, ARRAY[$2::TEXT])
|
|
||||||
ON CONFLICT ("_key")
|
|
||||||
DO UPDATE SET "array" = ARRAY[$2::TEXT] || "legacy_list"."array"`,
|
|
||||||
values: [key, value],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
await helpers.ensureLegacyObjectType(client, key, 'list');
|
await helpers.ensureLegacyObjectType(client, key, 'list');
|
||||||
if (Array.isArray(value)) {
|
value = Array.isArray(value) ? value : [value];
|
||||||
// TODO: perf make single query
|
value.reverse();
|
||||||
for (const v of value) {
|
await client.query({
|
||||||
// eslint-disable-next-line
|
name: 'listPrependValues',
|
||||||
await doPrepend(v);
|
text: `
|
||||||
}
|
INSERT INTO "legacy_list" ("_key", "array")
|
||||||
return;
|
VALUES ($1::TEXT, $2::TEXT[])
|
||||||
}
|
ON CONFLICT ("_key")
|
||||||
await doPrepend(value);
|
DO UPDATE SET "array" = EXCLUDED.array || "legacy_list"."array"`,
|
||||||
|
values: [key, value],
|
||||||
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -39,27 +29,18 @@ module.exports = function (module) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await module.transaction(async (client) => {
|
await module.transaction(async (client) => {
|
||||||
async function doAppend(value) {
|
value = Array.isArray(value) ? value : [value];
|
||||||
await client.query({
|
|
||||||
name: 'listAppend',
|
|
||||||
text: `
|
|
||||||
INSERT INTO "legacy_list" ("_key", "array")
|
|
||||||
VALUES ($1::TEXT, ARRAY[$2::TEXT])
|
|
||||||
ON CONFLICT ("_key")
|
|
||||||
DO UPDATE SET "array" = "legacy_list"."array" || ARRAY[$2::TEXT]`,
|
|
||||||
values: [key, value],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
await helpers.ensureLegacyObjectType(client, key, 'list');
|
await helpers.ensureLegacyObjectType(client, key, 'list');
|
||||||
if (Array.isArray(value)) {
|
await client.query({
|
||||||
// TODO: perf make single query
|
name: 'listAppend',
|
||||||
for (const v of value) {
|
text: `
|
||||||
// eslint-disable-next-line
|
INSERT INTO "legacy_list" ("_key", "array")
|
||||||
await doAppend(v);
|
VALUES ($1::TEXT, $2::TEXT[])
|
||||||
}
|
ON CONFLICT ("_key")
|
||||||
return;
|
DO UPDATE SET "array" = "legacy_list"."array" || EXCLUDED.array`,
|
||||||
}
|
values: [key, value],
|
||||||
await doAppend(value);
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -71,25 +71,21 @@ DELETE FROM "legacy_zset"
|
|||||||
};
|
};
|
||||||
|
|
||||||
module.sortedSetRemoveBulk = async function (data) {
|
module.sortedSetRemoveBulk = async function (data) {
|
||||||
// const keys = [];
|
if (!Array.isArray(data) || !data.length) {
|
||||||
// const values = [];
|
return;
|
||||||
|
}
|
||||||
|
const keys = data.map(d => d[0]);
|
||||||
|
const values = data.map(d => d[1]);
|
||||||
|
|
||||||
// data.forEach(function (item) {
|
await module.pool.query({
|
||||||
// keys.push(item[0]);
|
name: 'sortedSetRemoveBulk',
|
||||||
// values.push(item[1]);
|
text: `
|
||||||
// });
|
DELETE FROM "legacy_zset"
|
||||||
|
WHERE (_key, value) IN (
|
||||||
const promises = data.map(item => module.sortedSetRemove(item[0], item[1]));
|
SELECT k, v
|
||||||
await Promise.all(promises);
|
FROM UNNEST($1::TEXT[], $2::TEXT[]) vs(k, v)
|
||||||
|
)`,
|
||||||
// TODO
|
values: [keys, values],
|
||||||
// await query({
|
});
|
||||||
// name: 'sortedSetRemoveBulk',
|
|
||||||
// text: `
|
|
||||||
// DELETE FROM "legacy_zset"
|
|
||||||
// SELECT k, v
|
|
||||||
// FROM UNNEST($1::TEXT[], $2::TEXT[]) vs(k, v)`,
|
|
||||||
// values: [keys, values],
|
|
||||||
// });
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1119,6 +1119,29 @@ describe('Sorted Set methods', () => {
|
|||||||
const members = await db.getSortedSetsMembers(['bulkRemove1', 'bulkRemove2']);
|
const members = await db.getSortedSetsMembers(['bulkRemove1', 'bulkRemove2']);
|
||||||
assert.deepStrictEqual(members, [[], []]);
|
assert.deepStrictEqual(members, [[], []]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should not remove wrong elements in bulk remove', async () => {
|
||||||
|
await db.sortedSetAddBulk([
|
||||||
|
['bulkRemove4', 1, 'value1'],
|
||||||
|
['bulkRemove4', 2, 'value2'],
|
||||||
|
['bulkRemove4', 3, 'value4'],
|
||||||
|
['bulkRemove5', 1, 'value1'],
|
||||||
|
['bulkRemove5', 2, 'value2'],
|
||||||
|
['bulkRemove5', 3, 'value3'],
|
||||||
|
]);
|
||||||
|
await db.sortedSetRemoveBulk([
|
||||||
|
['bulkRemove4', 'value1'],
|
||||||
|
['bulkRemove4', 'value3'],
|
||||||
|
['bulkRemove5', 'value1'],
|
||||||
|
['bulkRemove5', 'value4'],
|
||||||
|
]);
|
||||||
|
const members = await Promise.all([
|
||||||
|
db.getSortedSetRange('bulkRemove4', 0, -1),
|
||||||
|
db.getSortedSetRange('bulkRemove5', 0, -1),
|
||||||
|
]);
|
||||||
|
assert.deepStrictEqual(members[0], ['value2', 'value4']);
|
||||||
|
assert.deepStrictEqual(members[1], ['value2', 'value3']);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('sortedSetsRemove()', () => {
|
describe('sortedSetsRemove()', () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user