|
|
|
@ -16,7 +16,20 @@ module.exports = function (module) {
|
|
|
|
|
}
|
|
|
|
|
await module.transaction(async (client) => {
|
|
|
|
|
const dataString = JSON.stringify(data);
|
|
|
|
|
async function setOne(key) {
|
|
|
|
|
|
|
|
|
|
if (Array.isArray(key)) {
|
|
|
|
|
await helpers.ensureLegacyObjectsType(client, key, 'hash');
|
|
|
|
|
await client.query({
|
|
|
|
|
name: 'setObjectKeys',
|
|
|
|
|
text: `
|
|
|
|
|
INSERT INTO "legacy_hash" ("_key", "data")
|
|
|
|
|
SELECT k, $2::TEXT::JSONB
|
|
|
|
|
FROM UNNEST($1::TEXT[]) vs(k)
|
|
|
|
|
ON CONFLICT ("_key")
|
|
|
|
|
DO UPDATE SET "data" = "legacy_hash"."data" || $2::TEXT::JSONB`,
|
|
|
|
|
values: [key, dataString],
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
await helpers.ensureLegacyObjectType(client, key, 'hash');
|
|
|
|
|
await client.query({
|
|
|
|
|
name: 'setObject',
|
|
|
|
@ -28,11 +41,6 @@ module.exports = function (module) {
|
|
|
|
|
values: [key, dataString],
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
if (Array.isArray(key)) {
|
|
|
|
|
await Promise.all(key.map(k => setOne(k)));
|
|
|
|
|
} else {
|
|
|
|
|
await setOne(key);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
@ -40,8 +48,36 @@ module.exports = function (module) {
|
|
|
|
|
if (!keys.length || !data.length) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
// TODO: single query?
|
|
|
|
|
await Promise.all(keys.map((k, i) => module.setObject(k, data[i])));
|
|
|
|
|
await module.transaction(async (client) => {
|
|
|
|
|
keys = keys.slice();
|
|
|
|
|
data = data.filter((d, i) => {
|
|
|
|
|
if (d.hasOwnProperty('')) {
|
|
|
|
|
delete d[''];
|
|
|
|
|
}
|
|
|
|
|
const keep = !!Object.keys(d).length;
|
|
|
|
|
if (!keep) {
|
|
|
|
|
keys.splice(i, 1);
|
|
|
|
|
}
|
|
|
|
|
return keep;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (!keys.length) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
await helpers.ensureLegacyObjectsType(client, keys, 'hash');
|
|
|
|
|
const dataStrings = data.map(JSON.stringify);
|
|
|
|
|
await client.query({
|
|
|
|
|
name: 'setObjectBulk',
|
|
|
|
|
text: `
|
|
|
|
|
INSERT INTO "legacy_hash" ("_key", "data")
|
|
|
|
|
SELECT k, d
|
|
|
|
|
FROM UNNEST($1::TEXT[], $2::TEXT::JSONB[]) vs(k, d)
|
|
|
|
|
ON CONFLICT ("_key")
|
|
|
|
|
DO UPDATE SET "data" = "legacy_hash"."data" || EXCLUDED.data`,
|
|
|
|
|
values: [keys, dataStrings],
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
module.setObjectField = async function (key, field, value) {
|
|
|
|
@ -51,7 +87,9 @@ module.exports = function (module) {
|
|
|
|
|
|
|
|
|
|
await module.transaction(async (client) => {
|
|
|
|
|
const valueString = JSON.stringify(value);
|
|
|
|
|
async function setOne(key) {
|
|
|
|
|
if (Array.isArray(key)) {
|
|
|
|
|
await module.setObject(key, { [field]: value });
|
|
|
|
|
} else {
|
|
|
|
|
await helpers.ensureLegacyObjectType(client, key, 'hash');
|
|
|
|
|
await client.query({
|
|
|
|
|
name: 'setObjectField',
|
|
|
|
@ -63,12 +101,6 @@ module.exports = function (module) {
|
|
|
|
|
values: [key, field, valueString],
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (Array.isArray(key)) {
|
|
|
|
|
await Promise.all(key.map(k => setOne(k)));
|
|
|
|
|
} else {
|
|
|
|
|
await setOne(key);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
@ -269,7 +301,19 @@ SELECT (h."data" ? $2::TEXT AND h."data"->>$2::TEXT IS NOT NULL) b
|
|
|
|
|
if (!key || (Array.isArray(key) && !key.length) || !Array.isArray(fields) || !fields.length) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
async function delKey(key, fields) {
|
|
|
|
|
|
|
|
|
|
if (Array.isArray(key)) {
|
|
|
|
|
await module.pool.query({
|
|
|
|
|
name: 'deleteObjectFieldsKeys',
|
|
|
|
|
text: `
|
|
|
|
|
UPDATE "legacy_hash"
|
|
|
|
|
SET "data" = COALESCE((SELECT jsonb_object_agg("key", "value")
|
|
|
|
|
FROM jsonb_each("data")
|
|
|
|
|
WHERE "key" <> ALL ($2::TEXT[])), '{}')
|
|
|
|
|
WHERE "_key" = ANY($1::TEXT[])`,
|
|
|
|
|
values: [key, fields],
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
await module.pool.query({
|
|
|
|
|
name: 'deleteObjectFields',
|
|
|
|
|
text: `
|
|
|
|
@ -281,11 +325,6 @@ SELECT (h."data" ? $2::TEXT AND h."data"->>$2::TEXT IS NOT NULL) b
|
|
|
|
|
values: [key, fields],
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
if (Array.isArray(key)) {
|
|
|
|
|
await Promise.all(key.map(k => delKey(k, fields)));
|
|
|
|
|
} else {
|
|
|
|
|
await delKey(key, fields);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
module.incrObjectField = async function (key, field) {
|
|
|
|
|