@hotmeshio/hotmesh 0.4.0 → 0.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +39 -14
- package/build/modules/enums.d.ts +110 -0
- package/build/modules/enums.js +134 -0
- package/build/modules/errors.d.ts +124 -0
- package/build/modules/errors.js +191 -0
- package/build/modules/key.d.ts +66 -0
- package/build/modules/key.js +190 -0
- package/build/modules/storage.d.ts +3 -0
- package/build/modules/storage.js +5 -0
- package/build/modules/utils.d.ts +119 -0
- package/build/modules/utils.js +374 -0
- package/build/package.json +1 -1
- package/build/services/activities/activity.d.ts +104 -0
- package/build/services/activities/activity.js +549 -0
- package/build/services/activities/await.d.ts +12 -0
- package/build/services/activities/await.js +114 -0
- package/build/services/activities/cycle.d.ts +19 -0
- package/build/services/activities/cycle.js +112 -0
- package/build/services/activities/hook.d.ts +27 -0
- package/build/services/activities/hook.js +168 -0
- package/build/services/activities/index.d.ts +19 -0
- package/build/services/activities/index.js +20 -0
- package/build/services/activities/interrupt.d.ts +16 -0
- package/build/services/activities/interrupt.js +158 -0
- package/build/services/activities/signal.d.ts +20 -0
- package/build/services/activities/signal.js +134 -0
- package/build/services/activities/trigger.d.ts +37 -0
- package/build/services/activities/trigger.js +246 -0
- package/build/services/activities/worker.d.ts +12 -0
- package/build/services/activities/worker.js +106 -0
- package/build/services/collator/index.d.ts +111 -0
- package/build/services/collator/index.js +293 -0
- package/build/services/compiler/deployer.d.ts +40 -0
- package/build/services/compiler/deployer.js +488 -0
- package/build/services/compiler/index.d.ts +32 -0
- package/build/services/compiler/index.js +112 -0
- package/build/services/compiler/validator.d.ts +34 -0
- package/build/services/compiler/validator.js +147 -0
- package/build/services/connector/factory.d.ts +22 -0
- package/build/services/connector/factory.js +99 -0
- package/build/services/connector/index.d.ts +30 -0
- package/build/services/connector/index.js +54 -0
- package/build/services/connector/providers/ioredis.d.ts +9 -0
- package/build/services/connector/providers/ioredis.js +26 -0
- package/build/services/connector/providers/nats.d.ts +9 -0
- package/build/services/connector/providers/nats.js +34 -0
- package/build/services/connector/providers/postgres.d.ts +20 -0
- package/build/services/connector/providers/postgres.js +102 -0
- package/build/services/connector/providers/redis.d.ts +9 -0
- package/build/services/connector/providers/redis.js +38 -0
- package/build/services/engine/index.d.ts +264 -0
- package/build/services/engine/index.js +761 -0
- package/build/services/exporter/index.d.ts +44 -0
- package/build/services/exporter/index.js +126 -0
- package/build/services/hotmesh/index.d.ts +483 -0
- package/build/services/hotmesh/index.js +622 -0
- package/build/services/logger/index.d.ts +16 -0
- package/build/services/logger/index.js +54 -0
- package/build/services/mapper/index.d.ts +28 -0
- package/build/services/mapper/index.js +81 -0
- package/build/services/memflow/client.d.ts +108 -0
- package/build/services/memflow/client.js +372 -0
- package/build/services/memflow/connection.d.ts +23 -0
- package/build/services/memflow/connection.js +33 -0
- package/build/services/memflow/context.d.ts +143 -0
- package/build/services/memflow/context.js +299 -0
- package/build/services/memflow/exporter.d.ts +51 -0
- package/build/services/memflow/exporter.js +215 -0
- package/build/services/memflow/handle.d.ts +90 -0
- package/build/services/memflow/handle.js +176 -0
- package/build/services/memflow/index.d.ts +116 -0
- package/build/services/memflow/index.js +122 -0
- package/build/services/memflow/schemas/factory.d.ts +29 -0
- package/build/services/memflow/schemas/factory.js +2492 -0
- package/build/services/memflow/search.d.ts +142 -0
- package/build/services/memflow/search.js +320 -0
- package/build/services/memflow/worker.d.ts +124 -0
- package/build/services/memflow/worker.js +514 -0
- package/build/services/memflow/workflow/all.d.ts +7 -0
- package/build/services/memflow/workflow/all.js +15 -0
- package/build/services/memflow/workflow/common.d.ts +20 -0
- package/build/services/memflow/workflow/common.js +47 -0
- package/build/services/memflow/workflow/context.d.ts +6 -0
- package/build/services/memflow/workflow/context.js +45 -0
- package/build/services/memflow/workflow/contextMethods.d.ts +14 -0
- package/build/services/memflow/workflow/contextMethods.js +33 -0
- package/build/services/memflow/workflow/didRun.d.ts +7 -0
- package/build/services/memflow/workflow/didRun.js +22 -0
- package/build/services/memflow/workflow/emit.d.ts +11 -0
- package/build/services/memflow/workflow/emit.js +29 -0
- package/build/services/memflow/workflow/enrich.d.ts +9 -0
- package/build/services/memflow/workflow/enrich.js +17 -0
- package/build/services/memflow/workflow/execChild.d.ts +18 -0
- package/build/services/memflow/workflow/execChild.js +102 -0
- package/build/services/memflow/workflow/execHook.d.ts +65 -0
- package/build/services/memflow/workflow/execHook.js +73 -0
- package/build/services/memflow/workflow/hook.d.ts +9 -0
- package/build/services/memflow/workflow/hook.js +56 -0
- package/build/services/memflow/workflow/index.d.ts +74 -0
- package/build/services/memflow/workflow/index.js +87 -0
- package/build/services/memflow/workflow/interrupt.d.ts +9 -0
- package/build/services/memflow/workflow/interrupt.js +24 -0
- package/build/services/memflow/workflow/isSideEffectAllowed.d.ts +10 -0
- package/build/services/memflow/workflow/isSideEffectAllowed.js +33 -0
- package/build/services/memflow/workflow/proxyActivities.d.ts +20 -0
- package/build/services/memflow/workflow/proxyActivities.js +97 -0
- package/build/services/memflow/workflow/random.d.ts +6 -0
- package/build/services/memflow/workflow/random.js +16 -0
- package/build/services/memflow/workflow/searchMethods.d.ts +6 -0
- package/build/services/memflow/workflow/searchMethods.js +25 -0
- package/build/services/memflow/workflow/signal.d.ts +29 -0
- package/build/services/memflow/workflow/signal.js +50 -0
- package/build/services/memflow/workflow/sleepFor.d.ts +24 -0
- package/build/services/memflow/workflow/sleepFor.js +51 -0
- package/build/services/memflow/workflow/trace.d.ts +14 -0
- package/build/services/memflow/workflow/trace.js +33 -0
- package/build/services/memflow/workflow/waitFor.d.ts +29 -0
- package/build/services/memflow/workflow/waitFor.js +56 -0
- package/build/services/meshcall/index.d.ts +194 -0
- package/build/services/meshcall/index.js +452 -0
- package/build/services/meshcall/schemas/factory.d.ts +9 -0
- package/build/services/meshcall/schemas/factory.js +189 -0
- package/build/services/meshdata/index.d.ts +795 -0
- package/build/services/meshdata/index.js +1235 -0
- package/build/services/meshos/index.d.ts +293 -0
- package/build/services/meshos/index.js +547 -0
- package/build/services/pipe/functions/array.d.ts +17 -0
- package/build/services/pipe/functions/array.js +74 -0
- package/build/services/pipe/functions/bitwise.d.ts +9 -0
- package/build/services/pipe/functions/bitwise.js +24 -0
- package/build/services/pipe/functions/conditional.d.ts +13 -0
- package/build/services/pipe/functions/conditional.js +36 -0
- package/build/services/pipe/functions/cron.d.ts +12 -0
- package/build/services/pipe/functions/cron.js +40 -0
- package/build/services/pipe/functions/date.d.ts +58 -0
- package/build/services/pipe/functions/date.js +171 -0
- package/build/services/pipe/functions/index.d.ts +29 -0
- package/build/services/pipe/functions/index.js +30 -0
- package/build/services/pipe/functions/json.d.ts +5 -0
- package/build/services/pipe/functions/json.js +12 -0
- package/build/services/pipe/functions/logical.d.ts +5 -0
- package/build/services/pipe/functions/logical.js +12 -0
- package/build/services/pipe/functions/math.d.ts +42 -0
- package/build/services/pipe/functions/math.js +184 -0
- package/build/services/pipe/functions/number.d.ts +21 -0
- package/build/services/pipe/functions/number.js +60 -0
- package/build/services/pipe/functions/object.d.ts +25 -0
- package/build/services/pipe/functions/object.js +81 -0
- package/build/services/pipe/functions/string.d.ts +23 -0
- package/build/services/pipe/functions/string.js +69 -0
- package/build/services/pipe/functions/symbol.d.ts +12 -0
- package/build/services/pipe/functions/symbol.js +33 -0
- package/build/services/pipe/functions/unary.d.ts +7 -0
- package/build/services/pipe/functions/unary.js +18 -0
- package/build/services/pipe/index.d.ts +48 -0
- package/build/services/pipe/index.js +242 -0
- package/build/services/quorum/index.d.ts +90 -0
- package/build/services/quorum/index.js +263 -0
- package/build/services/reporter/index.d.ts +50 -0
- package/build/services/reporter/index.js +348 -0
- package/build/services/router/config/index.d.ts +11 -0
- package/build/services/router/config/index.js +36 -0
- package/build/services/router/consumption/index.d.ts +34 -0
- package/build/services/router/consumption/index.js +395 -0
- package/build/services/router/error-handling/index.d.ts +8 -0
- package/build/services/router/error-handling/index.js +98 -0
- package/build/services/router/index.d.ts +57 -0
- package/build/services/router/index.js +121 -0
- package/build/services/router/lifecycle/index.d.ts +27 -0
- package/build/services/router/lifecycle/index.js +80 -0
- package/build/services/router/telemetry/index.d.ts +11 -0
- package/build/services/router/telemetry/index.js +32 -0
- package/build/services/router/throttling/index.d.ts +23 -0
- package/build/services/router/throttling/index.js +76 -0
- package/build/services/search/factory.d.ts +7 -0
- package/build/services/search/factory.js +24 -0
- package/build/services/search/index.d.ts +23 -0
- package/build/services/search/index.js +10 -0
- package/build/services/search/providers/postgres/postgres.d.ts +25 -0
- package/build/services/search/providers/postgres/postgres.js +149 -0
- package/build/services/search/providers/redis/ioredis.d.ts +19 -0
- package/build/services/search/providers/redis/ioredis.js +121 -0
- package/build/services/search/providers/redis/redis.d.ts +19 -0
- package/build/services/search/providers/redis/redis.js +134 -0
- package/build/services/serializer/index.d.ts +42 -0
- package/build/services/serializer/index.js +282 -0
- package/build/services/store/cache.d.ts +67 -0
- package/build/services/store/cache.js +128 -0
- package/build/services/store/factory.d.ts +8 -0
- package/build/services/store/factory.js +24 -0
- package/build/services/store/index.d.ts +89 -0
- package/build/services/store/index.js +9 -0
- package/build/services/store/providers/postgres/kvsql.d.ts +168 -0
- package/build/services/store/providers/postgres/kvsql.js +198 -0
- package/build/services/store/providers/postgres/kvtables.d.ts +20 -0
- package/build/services/store/providers/postgres/kvtables.js +441 -0
- package/build/services/store/providers/postgres/kvtransaction.d.ts +36 -0
- package/build/services/store/providers/postgres/kvtransaction.js +248 -0
- package/build/services/store/providers/postgres/kvtypes/hash.d.ts +60 -0
- package/build/services/store/providers/postgres/kvtypes/hash.js +1287 -0
- package/build/services/store/providers/postgres/kvtypes/list.d.ts +33 -0
- package/build/services/store/providers/postgres/kvtypes/list.js +194 -0
- package/build/services/store/providers/postgres/kvtypes/string.d.ts +20 -0
- package/build/services/store/providers/postgres/kvtypes/string.js +115 -0
- package/build/services/store/providers/postgres/kvtypes/zset.d.ts +41 -0
- package/build/services/store/providers/postgres/kvtypes/zset.js +214 -0
- package/build/services/store/providers/postgres/postgres.d.ts +178 -0
- package/build/services/store/providers/postgres/postgres.js +1244 -0
- package/build/services/store/providers/redis/_base.d.ts +137 -0
- package/build/services/store/providers/redis/_base.js +980 -0
- package/build/services/store/providers/redis/ioredis.d.ts +20 -0
- package/build/services/store/providers/redis/ioredis.js +180 -0
- package/build/services/store/providers/redis/redis.d.ts +18 -0
- package/build/services/store/providers/redis/redis.js +199 -0
- package/build/services/store/providers/store-initializable.d.ts +5 -0
- package/build/services/store/providers/store-initializable.js +2 -0
- package/build/services/stream/factory.d.ts +8 -0
- package/build/services/stream/factory.js +37 -0
- package/build/services/stream/index.d.ts +69 -0
- package/build/services/stream/index.js +11 -0
- package/build/services/stream/providers/nats/nats.d.ts +60 -0
- package/build/services/stream/providers/nats/nats.js +225 -0
- package/build/services/stream/providers/postgres/kvtables.d.ts +3 -0
- package/build/services/stream/providers/postgres/kvtables.js +146 -0
- package/build/services/stream/providers/postgres/postgres.d.ts +107 -0
- package/build/services/stream/providers/postgres/postgres.js +519 -0
- package/build/services/stream/providers/redis/ioredis.d.ts +61 -0
- package/build/services/stream/providers/redis/ioredis.js +272 -0
- package/build/services/stream/providers/redis/redis.d.ts +61 -0
- package/build/services/stream/providers/redis/redis.js +305 -0
- package/build/services/stream/providers/stream-initializable.d.ts +4 -0
- package/build/services/stream/providers/stream-initializable.js +2 -0
- package/build/services/sub/factory.d.ts +7 -0
- package/build/services/sub/factory.js +29 -0
- package/build/services/sub/index.d.ts +22 -0
- package/build/services/sub/index.js +10 -0
- package/build/services/sub/providers/nats/nats.d.ts +19 -0
- package/build/services/sub/providers/nats/nats.js +105 -0
- package/build/services/sub/providers/postgres/postgres.d.ts +19 -0
- package/build/services/sub/providers/postgres/postgres.js +92 -0
- package/build/services/sub/providers/redis/ioredis.d.ts +17 -0
- package/build/services/sub/providers/redis/ioredis.js +81 -0
- package/build/services/sub/providers/redis/redis.d.ts +17 -0
- package/build/services/sub/providers/redis/redis.js +72 -0
- package/build/services/task/index.d.ts +48 -0
- package/build/services/task/index.js +253 -0
- package/build/services/telemetry/index.d.ts +52 -0
- package/build/services/telemetry/index.js +306 -0
- package/build/services/worker/index.d.ts +77 -0
- package/build/services/worker/index.js +197 -0
- package/package.json +1 -1
- package/.github/ISSUE_TEMPLATE/bug_report.md +0 -38
- package/.github/ISSUE_TEMPLATE/feature_request.md +0 -20
- package/typedoc.json +0 -47
- package/types/activity.ts +0 -268
- package/types/app.ts +0 -20
- package/types/async.ts +0 -6
- package/types/cache.ts +0 -1
- package/types/collator.ts +0 -9
- package/types/error.ts +0 -56
- package/types/exporter.ts +0 -102
- package/types/hook.ts +0 -44
- package/types/hotmesh.ts +0 -314
- package/types/index.ts +0 -306
- package/types/job.ts +0 -233
- package/types/logger.ts +0 -8
- package/types/manifest.ts +0 -70
- package/types/map.ts +0 -5
- package/types/memflow.ts +0 -645
- package/types/meshcall.ts +0 -235
- package/types/meshdata.ts +0 -278
- package/types/ms.d.ts +0 -7
- package/types/nats.ts +0 -270
- package/types/pipe.ts +0 -90
- package/types/postgres.ts +0 -114
- package/types/provider.ts +0 -161
- package/types/quorum.ts +0 -167
- package/types/redis.ts +0 -404
- package/types/serializer.ts +0 -40
- package/types/stats.ts +0 -117
- package/types/stream.ts +0 -231
- package/types/task.ts +0 -7
- package/types/telemetry.ts +0 -16
- package/types/transition.ts +0 -20
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { ProviderTransaction } from '../../../../../types/provider';
|
|
2
|
+
export declare const listModule: (context: any) => {
|
|
3
|
+
lrange(key: string, start: number, end: number, multi?: ProviderTransaction): Promise<string[]>;
|
|
4
|
+
_lrange(key: string, start: number, end: number): {
|
|
5
|
+
sql: string;
|
|
6
|
+
params: any[];
|
|
7
|
+
};
|
|
8
|
+
rpush(key: string, value: string | string[], multi?: ProviderTransaction): Promise<number>;
|
|
9
|
+
_rpush(key: string, value: string | string[]): {
|
|
10
|
+
sql: string;
|
|
11
|
+
params: any[];
|
|
12
|
+
};
|
|
13
|
+
lpush(key: string, value: string | string[], multi?: ProviderTransaction): Promise<number>;
|
|
14
|
+
_lpush(key: string, value: string | string[]): {
|
|
15
|
+
sql: string;
|
|
16
|
+
params: any[];
|
|
17
|
+
};
|
|
18
|
+
lpop(key: string, multi?: ProviderTransaction): Promise<string | null>;
|
|
19
|
+
_lpop(key: string): {
|
|
20
|
+
sql: string;
|
|
21
|
+
params: any[];
|
|
22
|
+
};
|
|
23
|
+
lmove(source: string, destination: string, srcPosition: 'LEFT' | 'RIGHT', destPosition: 'LEFT' | 'RIGHT', multi?: ProviderTransaction): Promise<string | null>;
|
|
24
|
+
_lmove(source: string, destination: string, srcPosition: 'LEFT' | 'RIGHT', destPosition: 'LEFT' | 'RIGHT'): {
|
|
25
|
+
sql: string;
|
|
26
|
+
params: any[];
|
|
27
|
+
};
|
|
28
|
+
rename(oldKey: string, newKey: string, multi?: ProviderTransaction): Promise<void>;
|
|
29
|
+
_rename(oldKey: string, newKey: string): {
|
|
30
|
+
sql: string;
|
|
31
|
+
params: any[];
|
|
32
|
+
};
|
|
33
|
+
};
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.listModule = void 0;
|
|
4
|
+
const listModule = (context) => ({
|
|
5
|
+
async lrange(key, start, end, multi) {
|
|
6
|
+
const { sql, params } = this._lrange(key, start, end);
|
|
7
|
+
if (multi) {
|
|
8
|
+
multi.addCommand(sql, params, 'array', (rows) => rows.map((row) => row.value));
|
|
9
|
+
return Promise.resolve([]);
|
|
10
|
+
}
|
|
11
|
+
else {
|
|
12
|
+
const res = await context.pgClient.query(sql, params);
|
|
13
|
+
return res.rows.map((row) => row.value);
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
_lrange(key, start, end) {
|
|
17
|
+
const tableName = context.tableForKey(key, 'list');
|
|
18
|
+
const sql = `
|
|
19
|
+
WITH numbered AS (
|
|
20
|
+
SELECT value,
|
|
21
|
+
ROW_NUMBER() OVER (ORDER BY "index" ASC) - 1 AS rn,
|
|
22
|
+
COUNT(*) OVER() - 1 AS max_index
|
|
23
|
+
FROM ${tableName}
|
|
24
|
+
WHERE key = $1 AND (expiry IS NULL OR expiry > NOW())
|
|
25
|
+
),
|
|
26
|
+
indices AS (
|
|
27
|
+
SELECT
|
|
28
|
+
LEAST(GREATEST(CASE WHEN $2 >= 0 THEN $2 ELSE max_index + $2 + 1 END, 0), max_index) AS adjusted_start,
|
|
29
|
+
LEAST(GREATEST(CASE WHEN $3 >= 0 THEN $3 ELSE max_index + $3 + 1 END, 0), max_index) AS adjusted_end
|
|
30
|
+
FROM (SELECT max_index FROM numbered LIMIT 1) AS mi
|
|
31
|
+
)
|
|
32
|
+
SELECT value
|
|
33
|
+
FROM numbered, indices
|
|
34
|
+
WHERE rn BETWEEN indices.adjusted_start AND indices.adjusted_end
|
|
35
|
+
ORDER BY rn ASC
|
|
36
|
+
`;
|
|
37
|
+
const params = [key, start, end];
|
|
38
|
+
return { sql, params };
|
|
39
|
+
},
|
|
40
|
+
async rpush(key, value, multi) {
|
|
41
|
+
const { sql, params } = this._rpush(key, value);
|
|
42
|
+
if (multi) {
|
|
43
|
+
multi.addCommand(sql, params, 'number', (rows) => rows[0]?.count || 0);
|
|
44
|
+
return Promise.resolve(0);
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
const res = await context.pgClient.query(sql, params);
|
|
48
|
+
return Number(res.rows[0]?.count || 0);
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
_rpush(key, value) {
|
|
52
|
+
const tableName = context.tableForKey(key, 'list');
|
|
53
|
+
const values = Array.isArray(value) ? value : [value];
|
|
54
|
+
const placeholders = values
|
|
55
|
+
.map((_, i) => `($1, (SELECT COALESCE(MAX("index"), 0) + ${i + 1} FROM ${tableName} WHERE key = $1), $${i + 2})`)
|
|
56
|
+
.join(', ');
|
|
57
|
+
const sql = `
|
|
58
|
+
WITH inserted AS (
|
|
59
|
+
INSERT INTO ${tableName} (key, "index", value)
|
|
60
|
+
VALUES ${placeholders}
|
|
61
|
+
RETURNING 1
|
|
62
|
+
)
|
|
63
|
+
SELECT COUNT(*) as count FROM inserted
|
|
64
|
+
`;
|
|
65
|
+
const params = [key, ...values];
|
|
66
|
+
return { sql, params };
|
|
67
|
+
},
|
|
68
|
+
async lpush(key, value, multi) {
|
|
69
|
+
const { sql, params } = this._lpush(key, value);
|
|
70
|
+
if (multi) {
|
|
71
|
+
multi.addCommand(sql, params, 'number', (rows) => rows[0]?.count || 0);
|
|
72
|
+
return Promise.resolve(0);
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
const res = await context.pgClient.query(sql, params);
|
|
76
|
+
return Number(res.rows[0]?.count || 0);
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
_lpush(key, value) {
|
|
80
|
+
const tableName = context.tableForKey(key, 'list');
|
|
81
|
+
const values = Array.isArray(value) ? value : [value];
|
|
82
|
+
const placeholders = values
|
|
83
|
+
.map((_, i) => `($1, (SELECT COALESCE(MIN("index"), 0) - ${i + 1} FROM ${tableName} WHERE key = $1), $${i + 2})`)
|
|
84
|
+
.join(', ');
|
|
85
|
+
const sql = `
|
|
86
|
+
WITH inserted AS (
|
|
87
|
+
INSERT INTO ${tableName} (key, "index", value)
|
|
88
|
+
VALUES ${placeholders}
|
|
89
|
+
RETURNING 1
|
|
90
|
+
)
|
|
91
|
+
SELECT COUNT(*) as count FROM inserted
|
|
92
|
+
`;
|
|
93
|
+
const params = [key, ...values];
|
|
94
|
+
return { sql, params };
|
|
95
|
+
},
|
|
96
|
+
async lpop(key, multi) {
|
|
97
|
+
const { sql, params } = this._lpop(key);
|
|
98
|
+
if (multi) {
|
|
99
|
+
multi.addCommand(sql, params, 'string');
|
|
100
|
+
return Promise.resolve(null);
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
const res = await context.pgClient.query(sql, params);
|
|
104
|
+
return res.rows[0]?.value || null;
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
_lpop(key) {
|
|
108
|
+
const tableName = context.tableForKey(key, 'list');
|
|
109
|
+
const sql = `
|
|
110
|
+
DELETE FROM ${tableName}
|
|
111
|
+
WHERE key = $1 AND "index" = (
|
|
112
|
+
SELECT MIN("index") FROM ${tableName} WHERE key = $1 AND (expiry IS NULL OR expiry > NOW())
|
|
113
|
+
)
|
|
114
|
+
RETURNING value
|
|
115
|
+
`;
|
|
116
|
+
const params = [key];
|
|
117
|
+
return { sql, params };
|
|
118
|
+
},
|
|
119
|
+
async lmove(source, destination, srcPosition, destPosition, multi) {
|
|
120
|
+
const { sql, params } = this._lmove(source, destination, srcPosition, destPosition);
|
|
121
|
+
if (multi) {
|
|
122
|
+
multi.addCommand(sql, params, 'string');
|
|
123
|
+
return Promise.resolve(null);
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
const client = context.pgClient;
|
|
127
|
+
try {
|
|
128
|
+
await client.query('BEGIN');
|
|
129
|
+
const res = await client.query(sql, params);
|
|
130
|
+
await client.query('COMMIT');
|
|
131
|
+
return res.rows[0]?.value || null;
|
|
132
|
+
}
|
|
133
|
+
catch (err) {
|
|
134
|
+
await client.query('ROLLBACK');
|
|
135
|
+
throw err;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
},
|
|
139
|
+
_lmove(source, destination, srcPosition, destPosition) {
|
|
140
|
+
const tableName = context.tableForKey(source, 'list');
|
|
141
|
+
const srcOrder = srcPosition === 'LEFT' ? 'ASC' : 'DESC';
|
|
142
|
+
const destIndexAdjustment = destPosition === 'LEFT'
|
|
143
|
+
? `(SELECT COALESCE(MIN("index"), 0) - 1 FROM ${tableName} WHERE key = $2)`
|
|
144
|
+
: `(SELECT COALESCE(MAX("index"), 0) + 1 FROM ${tableName} WHERE key = $2)`;
|
|
145
|
+
const sql = `
|
|
146
|
+
WITH moved AS (
|
|
147
|
+
DELETE FROM ${tableName}
|
|
148
|
+
WHERE ctid IN (
|
|
149
|
+
SELECT ctid FROM ${tableName}
|
|
150
|
+
WHERE key = $1 AND (expiry IS NULL OR expiry > NOW())
|
|
151
|
+
ORDER BY "index" ${srcOrder}
|
|
152
|
+
LIMIT 1
|
|
153
|
+
)
|
|
154
|
+
RETURNING value
|
|
155
|
+
),
|
|
156
|
+
inserted AS (
|
|
157
|
+
INSERT INTO ${tableName} (key, "index", value)
|
|
158
|
+
SELECT $2, ${destIndexAdjustment}, value FROM moved
|
|
159
|
+
RETURNING value
|
|
160
|
+
)
|
|
161
|
+
SELECT value FROM inserted
|
|
162
|
+
`;
|
|
163
|
+
const params = [source, destination];
|
|
164
|
+
return { sql, params };
|
|
165
|
+
},
|
|
166
|
+
async rename(oldKey, newKey, multi) {
|
|
167
|
+
const { sql, params } = this._rename(oldKey, newKey);
|
|
168
|
+
if (multi) {
|
|
169
|
+
multi.addCommand(sql, params, 'void');
|
|
170
|
+
return Promise.resolve();
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
const client = context.pgClient;
|
|
174
|
+
try {
|
|
175
|
+
await client.query('BEGIN');
|
|
176
|
+
await client.query(sql, params);
|
|
177
|
+
await client.query('COMMIT');
|
|
178
|
+
}
|
|
179
|
+
catch (err) {
|
|
180
|
+
await client.query('ROLLBACK');
|
|
181
|
+
throw err;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
},
|
|
185
|
+
_rename(oldKey, newKey) {
|
|
186
|
+
const tableName = context.tableForKey(oldKey, 'list');
|
|
187
|
+
const sql = `
|
|
188
|
+
UPDATE ${tableName} SET key = $2 WHERE key = $1;
|
|
189
|
+
`;
|
|
190
|
+
const params = [oldKey, newKey];
|
|
191
|
+
return { sql, params };
|
|
192
|
+
},
|
|
193
|
+
});
|
|
194
|
+
exports.listModule = listModule;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { ProviderTransaction, SetOptions } from '../../../../../types/provider';
|
|
2
|
+
export declare const stringModule: (context: any) => {
|
|
3
|
+
get(key: string, multi?: ProviderTransaction): Promise<string | null>;
|
|
4
|
+
_get(key: string): {
|
|
5
|
+
sql: string;
|
|
6
|
+
params: any[];
|
|
7
|
+
};
|
|
8
|
+
setnx(key: string, value: string, multi?: ProviderTransaction): Promise<boolean>;
|
|
9
|
+
setnxex(key: string, value: string, delay: number, multi?: ProviderTransaction): Promise<boolean>;
|
|
10
|
+
set(key: string, value: string, options?: SetOptions, multi?: ProviderTransaction): Promise<boolean>;
|
|
11
|
+
_set(key: string, value: string, options?: SetOptions): {
|
|
12
|
+
sql: string;
|
|
13
|
+
params: any[];
|
|
14
|
+
};
|
|
15
|
+
del(key: string, multi?: ProviderTransaction): Promise<number>;
|
|
16
|
+
_del(key: string): {
|
|
17
|
+
sql: string;
|
|
18
|
+
params: any[];
|
|
19
|
+
};
|
|
20
|
+
};
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.stringModule = void 0;
|
|
4
|
+
const stringModule = (context) => ({
|
|
5
|
+
async get(key, multi) {
|
|
6
|
+
const { sql, params } = this._get(key);
|
|
7
|
+
if (multi) {
|
|
8
|
+
multi.addCommand(sql, params, 'string');
|
|
9
|
+
return Promise.resolve(null);
|
|
10
|
+
}
|
|
11
|
+
else {
|
|
12
|
+
const res = await context.pgClient.query(sql, params);
|
|
13
|
+
return res.rows[0]?.value || null;
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
_get(key) {
|
|
17
|
+
const tableName = context.tableForKey(key);
|
|
18
|
+
const sql = `
|
|
19
|
+
SELECT value FROM ${tableName}
|
|
20
|
+
WHERE key = $1 AND (expiry IS NULL OR expiry > NOW())
|
|
21
|
+
LIMIT 1
|
|
22
|
+
`;
|
|
23
|
+
const params = [key];
|
|
24
|
+
return { sql, params };
|
|
25
|
+
},
|
|
26
|
+
async setnx(key, value, multi) {
|
|
27
|
+
const { sql, params } = this._set(key, value, { nx: true });
|
|
28
|
+
if (multi) {
|
|
29
|
+
multi.addCommand(sql, params, 'boolean');
|
|
30
|
+
return Promise.resolve(true);
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
const res = await context.pgClient.query(sql, params);
|
|
34
|
+
return res.rowCount > 0;
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
async setnxex(key, value, delay, multi) {
|
|
38
|
+
const { sql, params } = this._set(key, value, { nx: true, ex: delay });
|
|
39
|
+
if (multi) {
|
|
40
|
+
multi.addCommand(sql, params, 'boolean');
|
|
41
|
+
return Promise.resolve(true);
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
const res = await context.pgClient.query(sql, params);
|
|
45
|
+
return res.rowCount > 0;
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
async set(key, value, options, multi) {
|
|
49
|
+
const { sql, params } = this._set(key, value, options);
|
|
50
|
+
if (multi) {
|
|
51
|
+
multi.addCommand(sql, params, 'boolean');
|
|
52
|
+
return Promise.resolve(true);
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
const res = await context.pgClient.query(sql, params);
|
|
56
|
+
return res.rowCount > 0;
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
_set(key, value, options) {
|
|
60
|
+
const tableName = context.tableForKey(key);
|
|
61
|
+
let sql = '';
|
|
62
|
+
const params = [key, value];
|
|
63
|
+
let expiryClause = '';
|
|
64
|
+
if (options?.ex) {
|
|
65
|
+
expiryClause = ", expiry = NOW() + INTERVAL '" + options.ex + " seconds'";
|
|
66
|
+
}
|
|
67
|
+
if (options?.nx) {
|
|
68
|
+
// INSERT only if no valid ownership exists
|
|
69
|
+
sql = `
|
|
70
|
+
INSERT INTO ${tableName} (key, value${expiryClause ? ', expiry' : ''})
|
|
71
|
+
VALUES ($1, $2${expiryClause ? ", NOW() + INTERVAL '" + options.ex + " seconds'" : ''})
|
|
72
|
+
ON CONFLICT (key) DO UPDATE
|
|
73
|
+
SET value = EXCLUDED.value${expiryClause ? ', expiry = EXCLUDED.expiry' : ''}
|
|
74
|
+
WHERE ${tableName}.expiry IS NULL OR ${tableName}.expiry <= NOW()
|
|
75
|
+
RETURNING true as success
|
|
76
|
+
`;
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
// INSERT or UPDATE, reclaiming expired ownership if necessary
|
|
80
|
+
sql = `
|
|
81
|
+
INSERT INTO ${tableName} (key, value${expiryClause ? ', expiry' : ''})
|
|
82
|
+
VALUES ($1, $2${expiryClause ? ", NOW() + INTERVAL '" + options.ex + " seconds'" : ''})
|
|
83
|
+
ON CONFLICT (key) DO UPDATE
|
|
84
|
+
SET value = EXCLUDED.value${expiryClause ? ', expiry = EXCLUDED.expiry' : ''}
|
|
85
|
+
WHERE ${tableName}.expiry IS NULL OR ${tableName}.expiry <= NOW()
|
|
86
|
+
RETURNING true as success
|
|
87
|
+
`;
|
|
88
|
+
}
|
|
89
|
+
return { sql, params };
|
|
90
|
+
},
|
|
91
|
+
async del(key, multi) {
|
|
92
|
+
const { sql, params } = this._del(key);
|
|
93
|
+
if (multi) {
|
|
94
|
+
multi.addCommand(sql, params, 'number');
|
|
95
|
+
return Promise.resolve(0);
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
const res = await context.pgClient.query(sql, params);
|
|
99
|
+
return Number(res.rows[0]?.count || 0);
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
_del(key) {
|
|
103
|
+
const tableName = context.tableForKey(key);
|
|
104
|
+
const sql = `
|
|
105
|
+
WITH deleted AS (
|
|
106
|
+
DELETE FROM ${tableName} WHERE key = $1
|
|
107
|
+
RETURNING 1
|
|
108
|
+
)
|
|
109
|
+
SELECT COUNT(*) as count FROM deleted
|
|
110
|
+
`;
|
|
111
|
+
const params = [key];
|
|
112
|
+
return { sql, params };
|
|
113
|
+
},
|
|
114
|
+
});
|
|
115
|
+
exports.stringModule = stringModule;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { ProviderTransaction, ZAddOptions } from '../../../../../types/provider';
|
|
2
|
+
export declare const zsetModule: (context: any) => {
|
|
3
|
+
zadd(key: string, score: number, member: string, options?: ZAddOptions, multi?: ProviderTransaction): Promise<number>;
|
|
4
|
+
_zadd(key: string, score: number, member: string, options?: ZAddOptions): {
|
|
5
|
+
sql: string;
|
|
6
|
+
params: any[];
|
|
7
|
+
};
|
|
8
|
+
zrange(key: string, start: number, stop: number, facet?: 'WITHSCORES', multi?: ProviderTransaction): Promise<string[]>;
|
|
9
|
+
_zrange(key: string, start: number, stop: number, facet?: 'WITHSCORES'): {
|
|
10
|
+
sql: string;
|
|
11
|
+
params: any[];
|
|
12
|
+
};
|
|
13
|
+
zscore(key: string, member: string, multi?: ProviderTransaction): Promise<number | null>;
|
|
14
|
+
_zscore(key: string, member: string): {
|
|
15
|
+
sql: string;
|
|
16
|
+
params: any[];
|
|
17
|
+
};
|
|
18
|
+
zrangebyscore(key: string, min: number, max: number, multi?: ProviderTransaction): Promise<string[]>;
|
|
19
|
+
_zrangebyscore(key: string, min: number, max: number): {
|
|
20
|
+
sql: string;
|
|
21
|
+
params: any[];
|
|
22
|
+
};
|
|
23
|
+
zrangebyscore_withscores(key: string, min: number, max: number, multi?: ProviderTransaction): Promise<{
|
|
24
|
+
member: string;
|
|
25
|
+
score: number;
|
|
26
|
+
}[]>;
|
|
27
|
+
_zrangebyscore_withscores(key: string, min: number, max: number): {
|
|
28
|
+
sql: string;
|
|
29
|
+
params: any[];
|
|
30
|
+
};
|
|
31
|
+
zrem(key: string, member: string, multi?: ProviderTransaction): Promise<number>;
|
|
32
|
+
_zrem(key: string, member: string): {
|
|
33
|
+
sql: string;
|
|
34
|
+
params: any[];
|
|
35
|
+
};
|
|
36
|
+
zrank(key: string, member: string, multi?: ProviderTransaction): Promise<number | null>;
|
|
37
|
+
_zrank(key: string, member: string): {
|
|
38
|
+
sql: string;
|
|
39
|
+
params: any[];
|
|
40
|
+
};
|
|
41
|
+
};
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.zsetModule = void 0;
|
|
4
|
+
const zsetModule = (context) => ({
|
|
5
|
+
async zadd(key, score, member, options, multi) {
|
|
6
|
+
const { sql, params } = this._zadd(key, score, member, options);
|
|
7
|
+
if (multi) {
|
|
8
|
+
multi.addCommand(sql, params, 'number', (rows) => rows[0]?.count || 0);
|
|
9
|
+
return Promise.resolve(0);
|
|
10
|
+
}
|
|
11
|
+
else {
|
|
12
|
+
const res = await context.pgClient.query(sql, params);
|
|
13
|
+
return Number(res.rows[0]?.count || 0);
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
_zadd(key, score, member, options) {
|
|
17
|
+
const tableName = context.tableForKey(key, 'sorted_set');
|
|
18
|
+
let sql = '';
|
|
19
|
+
const params = [key, member, score];
|
|
20
|
+
if (options?.nx) {
|
|
21
|
+
sql = `
|
|
22
|
+
INSERT INTO ${tableName} (key, member, score)
|
|
23
|
+
VALUES ($1, $2, $3)
|
|
24
|
+
ON CONFLICT DO NOTHING
|
|
25
|
+
RETURNING 1 as count
|
|
26
|
+
`;
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
sql = `
|
|
30
|
+
INSERT INTO ${tableName} (key, member, score)
|
|
31
|
+
VALUES ($1, $2, $3)
|
|
32
|
+
ON CONFLICT (key, member) DO UPDATE SET score = $3
|
|
33
|
+
RETURNING 1 as count
|
|
34
|
+
`;
|
|
35
|
+
}
|
|
36
|
+
return { sql, params };
|
|
37
|
+
},
|
|
38
|
+
async zrange(key, start, stop, facet, multi) {
|
|
39
|
+
const { sql, params } = this._zrange(key, start, stop, facet);
|
|
40
|
+
if (multi) {
|
|
41
|
+
multi.addCommand(sql, params, 'array', (rows) => {
|
|
42
|
+
if (facet === 'WITHSCORES') {
|
|
43
|
+
// Include scores in the result
|
|
44
|
+
return rows.flatMap((row) => [row.member, row.score.toString()]);
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
return rows.map((row) => row.member);
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
return Promise.resolve([]);
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
const res = await context.pgClient.query(sql, params);
|
|
54
|
+
if (facet === 'WITHSCORES') {
|
|
55
|
+
// Include scores in the result
|
|
56
|
+
return res.rows.flatMap((row) => [row.member, row.score.toString()]);
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
return res.rows.map((row) => row.member);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
_zrange(key, start, stop, facet) {
|
|
64
|
+
const tableName = context.tableForKey(key, 'sorted_set');
|
|
65
|
+
const selectColumns = facet === 'WITHSCORES' ? 'member, score' : 'member';
|
|
66
|
+
const sql = `
|
|
67
|
+
WITH total_entries AS (
|
|
68
|
+
SELECT COUNT(*) - 1 AS max_index FROM ${tableName}
|
|
69
|
+
WHERE key = $1 AND (expiry IS NULL OR expiry > NOW())
|
|
70
|
+
), ordered_entries AS (
|
|
71
|
+
SELECT ${selectColumns},
|
|
72
|
+
ROW_NUMBER() OVER (ORDER BY score ASC, member ASC) - 1 AS rn,
|
|
73
|
+
(SELECT max_index FROM total_entries) AS max_index
|
|
74
|
+
FROM ${tableName}
|
|
75
|
+
WHERE key = $1 AND (expiry IS NULL OR expiry > NOW())
|
|
76
|
+
), indices AS (
|
|
77
|
+
SELECT
|
|
78
|
+
CASE WHEN $2 >= 0 THEN $2 ELSE max_index + $2 + 1 END AS adjusted_start,
|
|
79
|
+
CASE WHEN $3 >= 0 THEN $3 ELSE max_index + $3 + 1 END AS adjusted_stop
|
|
80
|
+
FROM total_entries
|
|
81
|
+
)
|
|
82
|
+
SELECT ${selectColumns}
|
|
83
|
+
FROM ordered_entries, indices
|
|
84
|
+
WHERE rn BETWEEN LEAST(GREATEST(adjusted_start, 0), max_index)
|
|
85
|
+
AND LEAST(GREATEST(adjusted_stop, 0), max_index)
|
|
86
|
+
ORDER BY rn ASC;
|
|
87
|
+
`;
|
|
88
|
+
const params = [key, start, stop];
|
|
89
|
+
return { sql, params };
|
|
90
|
+
},
|
|
91
|
+
async zscore(key, member, multi) {
|
|
92
|
+
const { sql, params } = this._zscore(key, member);
|
|
93
|
+
if (multi) {
|
|
94
|
+
multi.addCommand(sql, params, 'single', (row) => {
|
|
95
|
+
return row
|
|
96
|
+
? parseFloat(row.score)
|
|
97
|
+
: null;
|
|
98
|
+
});
|
|
99
|
+
return Promise.resolve(null);
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
const res = await context.pgClient.query(sql, params);
|
|
103
|
+
return res.rows.length ? parseFloat(res.rows[0].score) : null;
|
|
104
|
+
}
|
|
105
|
+
},
|
|
106
|
+
_zscore(key, member) {
|
|
107
|
+
const tableName = context.tableForKey(key, 'sorted_set');
|
|
108
|
+
const sql = `
|
|
109
|
+
SELECT score
|
|
110
|
+
FROM ${tableName}
|
|
111
|
+
WHERE key = $1 AND member = $2
|
|
112
|
+
AND (expiry IS NULL OR expiry > NOW())
|
|
113
|
+
LIMIT 1
|
|
114
|
+
`;
|
|
115
|
+
const params = [key, member];
|
|
116
|
+
return { sql, params };
|
|
117
|
+
},
|
|
118
|
+
async zrangebyscore(key, min, max, multi) {
|
|
119
|
+
const { sql, params } = this._zrangebyscore(key, min, max);
|
|
120
|
+
if (multi) {
|
|
121
|
+
multi.addCommand(sql, params, 'array', (rows) => rows.map((row) => row.member));
|
|
122
|
+
return Promise.resolve([]);
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
const res = await context.pgClient.query(sql, params);
|
|
126
|
+
return res.rows.map((row) => row.member);
|
|
127
|
+
}
|
|
128
|
+
},
|
|
129
|
+
_zrangebyscore(key, min, max) {
|
|
130
|
+
const tableName = context.tableForKey(key, 'sorted_set');
|
|
131
|
+
const sql = `
|
|
132
|
+
SELECT member FROM ${tableName}
|
|
133
|
+
WHERE key = $1 AND score BETWEEN $2 AND $3 AND (expiry IS NULL OR expiry > NOW())
|
|
134
|
+
ORDER BY score ASC, member ASC
|
|
135
|
+
`;
|
|
136
|
+
const params = [key, min, max];
|
|
137
|
+
return { sql, params };
|
|
138
|
+
},
|
|
139
|
+
async zrangebyscore_withscores(key, min, max, multi) {
|
|
140
|
+
const { sql, params } = this._zrangebyscore_withscores(key, min, max);
|
|
141
|
+
if (multi) {
|
|
142
|
+
multi.addCommand(sql, params, 'array', (rows) => rows.map((row) => ({ member: row.member, score: row.score })));
|
|
143
|
+
return Promise.resolve([]);
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
const res = await context.pgClient.query(sql, params);
|
|
147
|
+
return res.rows.map((row) => ({ member: row.member, score: row.score }));
|
|
148
|
+
}
|
|
149
|
+
},
|
|
150
|
+
_zrangebyscore_withscores(key, min, max) {
|
|
151
|
+
const tableName = context.tableForKey(key, 'sorted_set');
|
|
152
|
+
const sql = `
|
|
153
|
+
SELECT member, score FROM ${tableName}
|
|
154
|
+
WHERE key = $1 AND score BETWEEN $2 AND $3 AND (expiry IS NULL OR expiry > NOW())
|
|
155
|
+
ORDER BY score ASC, member ASC
|
|
156
|
+
`;
|
|
157
|
+
const params = [key, min, max];
|
|
158
|
+
return { sql, params };
|
|
159
|
+
},
|
|
160
|
+
async zrem(key, member, multi) {
|
|
161
|
+
const { sql, params } = this._zrem(key, member);
|
|
162
|
+
if (multi) {
|
|
163
|
+
multi.addCommand(sql, params, 'number', (rows) => rows[0]?.count || 0);
|
|
164
|
+
return Promise.resolve(0);
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
const res = await context.pgClient.query(sql, params);
|
|
168
|
+
return Number(res.rows[0]?.count || 0);
|
|
169
|
+
}
|
|
170
|
+
},
|
|
171
|
+
_zrem(key, member) {
|
|
172
|
+
const tableName = context.tableForKey(key, 'sorted_set');
|
|
173
|
+
const sql = `
|
|
174
|
+
WITH deleted AS (
|
|
175
|
+
DELETE FROM ${tableName}
|
|
176
|
+
WHERE key = $1 AND member = $2
|
|
177
|
+
RETURNING 1
|
|
178
|
+
)
|
|
179
|
+
SELECT COUNT(*) as count FROM deleted
|
|
180
|
+
`;
|
|
181
|
+
const params = [key, member];
|
|
182
|
+
return { sql, params };
|
|
183
|
+
},
|
|
184
|
+
async zrank(key, member, multi) {
|
|
185
|
+
const { sql, params } = this._zrank(key, member);
|
|
186
|
+
if (multi) {
|
|
187
|
+
multi.addCommand(sql, params, 'number', (rows) => rows[0]?.rank !== undefined ? parseInt(rows[0].rank, 10) - 1 : null);
|
|
188
|
+
return Promise.resolve(null);
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
const res = await context.pgClient.query(sql, params);
|
|
192
|
+
return res.rows[0]?.rank
|
|
193
|
+
? parseInt(res.rows[0].rank, 10) > 0
|
|
194
|
+
? parseInt(res.rows[0].rank, 10) - 1
|
|
195
|
+
: null
|
|
196
|
+
: null;
|
|
197
|
+
}
|
|
198
|
+
},
|
|
199
|
+
_zrank(key, member) {
|
|
200
|
+
const tableName = context.tableForKey(key, 'sorted_set');
|
|
201
|
+
const sql = `
|
|
202
|
+
WITH member_score AS (
|
|
203
|
+
SELECT score FROM ${tableName}
|
|
204
|
+
WHERE key = $1 AND member = $2 AND (expiry IS NULL OR expiry > NOW())
|
|
205
|
+
)
|
|
206
|
+
SELECT COUNT(*) AS rank FROM ${tableName} ms, member_score
|
|
207
|
+
WHERE ms.key = $1 AND (expiry IS NULL OR expiry > NOW())
|
|
208
|
+
AND (ms.score < member_score.score OR (ms.score = member_score.score AND ms.member < $2))
|
|
209
|
+
`;
|
|
210
|
+
const params = [key, member];
|
|
211
|
+
return { sql, params };
|
|
212
|
+
},
|
|
213
|
+
});
|
|
214
|
+
exports.zsetModule = zsetModule;
|