@event-driven-io/pongo 0.17.0-beta.40 → 0.17.0-beta.42
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/dist/cli.cjs +1 -1
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +1 -1
- package/dist/cli.js.map +1 -1
- package/dist/cloudflare.cjs +5 -2
- package/dist/cloudflare.cjs.map +1 -1
- package/dist/cloudflare.d.cts +1 -1
- package/dist/cloudflare.d.ts +1 -1
- package/dist/cloudflare.js +5 -2
- package/dist/cloudflare.js.map +1 -1
- package/dist/{core-CH0SOCr3.js → core-5npofT4H.js} +32 -45
- package/dist/core-5npofT4H.js.map +1 -0
- package/dist/{core-CkmE5dkK.cjs → core-q2eF-VHQ.cjs} +31 -44
- package/dist/core-q2eF-VHQ.cjs.map +1 -0
- package/dist/pg.cjs +33 -25
- package/dist/pg.cjs.map +1 -1
- package/dist/pg.js +34 -26
- package/dist/pg.js.map +1 -1
- package/dist/sqlite3.cjs +1 -1
- package/dist/sqlite3.js +1 -1
- package/package.json +2 -2
- package/dist/core-CH0SOCr3.js.map +0 -1
- package/dist/core-CkmE5dkK.cjs.map +0 -1
package/dist/pg.cjs
CHANGED
|
@@ -3,29 +3,36 @@ const require_core = require('./core-C9SB3XMx.cjs');
|
|
|
3
3
|
const require_cli = require('./cli.cjs');
|
|
4
4
|
let _event_driven_io_dumbo = require("@event-driven-io/dumbo");
|
|
5
5
|
let _event_driven_io_dumbo_pg = require("@event-driven-io/dumbo/pg");
|
|
6
|
+
let _event_driven_io_dumbo_postgresql = require("@event-driven-io/dumbo/postgresql");
|
|
6
7
|
|
|
7
8
|
//#region src/storage/postgresql/core/sqlBuilder/filter/queryOperators.ts
|
|
8
9
|
const handleOperator = (path, operator, value, serializer) => {
|
|
9
10
|
if (path === "_id" || path === "_version") return handleMetadataOperator(path, operator, value);
|
|
10
11
|
switch (operator) {
|
|
11
12
|
case "$eq": {
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
return _event_driven_io_dumbo.SQL`(data @> ${nestedPath}::jsonb OR jsonb_path_exists(data, '$.${_event_driven_io_dumbo.SQL.plain(path)}[*] ? (@ == ${_event_driven_io_dumbo.SQL.plain(serializedValue)})'))`;
|
|
13
|
+
const field = _event_driven_io_dumbo_postgresql.PostgreSQLJSON.field(_event_driven_io_dumbo.SQL`data`, path);
|
|
14
|
+
return _event_driven_io_dumbo.SQL`(${field} = ${_event_driven_io_dumbo.JSONParam.value(value, serializer)}::jsonb OR ${field} @> ${_event_driven_io_dumbo.JSONParam.arrayContaining(value, serializer)}::jsonb)`;
|
|
15
15
|
}
|
|
16
16
|
case "$gt":
|
|
17
17
|
case "$gte":
|
|
18
18
|
case "$lt":
|
|
19
19
|
case "$lte":
|
|
20
|
-
case "$ne": return _event_driven_io_dumbo.SQL
|
|
21
|
-
case "$in": return _event_driven_io_dumbo.SQL`data
|
|
22
|
-
case "$nin": return _event_driven_io_dumbo.SQL`data
|
|
20
|
+
case "$ne": return _event_driven_io_dumbo.SQL`${_event_driven_io_dumbo_postgresql.PostgreSQLJSON.textField(_event_driven_io_dumbo.SQL`data`, path)} ${_event_driven_io_dumbo.SQL.plain(require_core.OperatorMap[operator])} ${value}`;
|
|
21
|
+
case "$in": return _event_driven_io_dumbo.SQL`${_event_driven_io_dumbo_postgresql.PostgreSQLJSON.textField(_event_driven_io_dumbo.SQL`data`, path)} = ANY (${value})`;
|
|
22
|
+
case "$nin": return _event_driven_io_dumbo.SQL`${_event_driven_io_dumbo_postgresql.PostgreSQLJSON.textField(_event_driven_io_dumbo.SQL`data`, path)} != ALL (${value})`;
|
|
23
23
|
case "$elemMatch": {
|
|
24
|
-
const
|
|
25
|
-
return _event_driven_io_dumbo.SQL`
|
|
24
|
+
const field = _event_driven_io_dumbo_postgresql.PostgreSQLJSON.field(_event_driven_io_dumbo.SQL`data`, path);
|
|
25
|
+
return _event_driven_io_dumbo.SQL`EXISTS (
|
|
26
|
+
SELECT 1
|
|
27
|
+
FROM jsonb_array_elements(${_event_driven_io_dumbo.SQL`CASE WHEN jsonb_typeof(${field}) = 'array' THEN ${field} ELSE '[]'::jsonb END`}) AS elem(value)
|
|
28
|
+
WHERE elem.value @> ${_event_driven_io_dumbo.JSONParam.value(value, serializer)}::jsonb
|
|
29
|
+
)`;
|
|
26
30
|
}
|
|
27
|
-
case "$all":
|
|
28
|
-
|
|
31
|
+
case "$all": {
|
|
32
|
+
const serializedValue = _event_driven_io_dumbo.JSONParam.value(value, serializer);
|
|
33
|
+
return _event_driven_io_dumbo.SQL`${_event_driven_io_dumbo_postgresql.PostgreSQLJSON.field(_event_driven_io_dumbo.SQL`data`, path)} @> ${serializedValue}::jsonb`;
|
|
34
|
+
}
|
|
35
|
+
case "$size": return _event_driven_io_dumbo.SQL`jsonb_array_length(${_event_driven_io_dumbo_postgresql.PostgreSQLJSON.field(_event_driven_io_dumbo.SQL`data`, path)}) = ${value}`;
|
|
29
36
|
default: throw new Error(`Unsupported operator: ${operator}`);
|
|
30
37
|
}
|
|
31
38
|
};
|
|
@@ -42,7 +49,6 @@ const handleMetadataOperator = (fieldName, operator, value) => {
|
|
|
42
49
|
default: throw new Error(`Unsupported operator: ${operator}`);
|
|
43
50
|
}
|
|
44
51
|
};
|
|
45
|
-
const buildNestedObject = (path, value) => path.split(".").reverse().reduce((acc, key) => ({ [key]: acc }), value);
|
|
46
52
|
|
|
47
53
|
//#endregion
|
|
48
54
|
//#region src/storage/postgresql/core/sqlBuilder/filter/index.ts
|
|
@@ -105,16 +111,20 @@ const buildUpdateQuery = (update, serializer) => require_core.objectEntries(upda
|
|
|
105
111
|
default: return currentUpdateQuery;
|
|
106
112
|
}
|
|
107
113
|
}, _event_driven_io_dumbo.SQL`data`);
|
|
108
|
-
const buildSetQuery = (set, currentUpdateQuery, serializer) => _event_driven_io_dumbo.SQL`${currentUpdateQuery} || ${
|
|
109
|
-
const buildUnsetQuery = (unset, currentUpdateQuery) =>
|
|
114
|
+
const buildSetQuery = (set, currentUpdateQuery, serializer) => _event_driven_io_dumbo.SQL`${currentUpdateQuery} || ${_event_driven_io_dumbo.JSONParam.value(set, serializer)}::jsonb`;
|
|
115
|
+
const buildUnsetQuery = (unset, currentUpdateQuery) => {
|
|
116
|
+
let query = currentUpdateQuery;
|
|
117
|
+
for (const key of Object.keys(unset)) query = _event_driven_io_dumbo.SQL`${query} - ${key}`;
|
|
118
|
+
return query;
|
|
119
|
+
};
|
|
110
120
|
const buildIncQuery = (inc, currentUpdateQuery) => {
|
|
111
|
-
for (const [key, value] of Object.entries(inc)) currentUpdateQuery = typeof value === "bigint" ? _event_driven_io_dumbo.SQL`jsonb_set(${currentUpdateQuery},
|
|
121
|
+
for (const [key, value] of Object.entries(inc)) currentUpdateQuery = typeof value === "bigint" ? _event_driven_io_dumbo.SQL`jsonb_set(${currentUpdateQuery}, ${_event_driven_io_dumbo_postgresql.PostgreSQLJSON.path(key)}, to_jsonb((COALESCE((${_event_driven_io_dumbo_postgresql.PostgreSQLJSON.textField(_event_driven_io_dumbo.SQL`data`, key)})::BIGINT, 0) + ${value})::TEXT), true)` : _event_driven_io_dumbo.SQL`jsonb_set(${currentUpdateQuery}, ${_event_driven_io_dumbo_postgresql.PostgreSQLJSON.path(key)}, to_jsonb(COALESCE((${_event_driven_io_dumbo_postgresql.PostgreSQLJSON.textField(_event_driven_io_dumbo.SQL`data`, key)})::NUMERIC, 0) + ${value}), true)`;
|
|
112
122
|
return currentUpdateQuery;
|
|
113
123
|
};
|
|
114
124
|
const buildPushQuery = (push, currentUpdateQuery, serializer) => {
|
|
115
125
|
for (const [key, value] of Object.entries(push)) {
|
|
116
|
-
const serializedValue =
|
|
117
|
-
currentUpdateQuery = _event_driven_io_dumbo.SQL`jsonb_set(${currentUpdateQuery},
|
|
126
|
+
const serializedValue = _event_driven_io_dumbo.JSONParam.arrayContaining(value, serializer);
|
|
127
|
+
currentUpdateQuery = _event_driven_io_dumbo.SQL`jsonb_set(${currentUpdateQuery}, ${_event_driven_io_dumbo_postgresql.PostgreSQLJSON.path(key)}, (coalesce(${_event_driven_io_dumbo_postgresql.PostgreSQLJSON.field(_event_driven_io_dumbo.SQL`data`, key)}, '[]'::jsonb) || ${serializedValue}::jsonb), true)`;
|
|
118
128
|
}
|
|
119
129
|
return currentUpdateQuery;
|
|
120
130
|
};
|
|
@@ -141,7 +151,7 @@ const pongoCollectionPostgreSQLMigrations = (collectionName) => [(0, _event_driv
|
|
|
141
151
|
const postgresSQLBuilder = (collectionName, serializer) => ({
|
|
142
152
|
createCollection: () => createCollection(collectionName),
|
|
143
153
|
insertOne: (document) => {
|
|
144
|
-
const serialized =
|
|
154
|
+
const serialized = _event_driven_io_dumbo.JSONParam.document(document, serializer);
|
|
145
155
|
const id = document._id;
|
|
146
156
|
const version = document._version ?? 1n;
|
|
147
157
|
return _event_driven_io_dumbo.SQL`
|
|
@@ -149,7 +159,7 @@ const postgresSQLBuilder = (collectionName, serializer) => ({
|
|
|
149
159
|
VALUES (${id}, ${serialized}, ${version}) ON CONFLICT(_id) DO NOTHING;`;
|
|
150
160
|
},
|
|
151
161
|
insertMany: (documents) => {
|
|
152
|
-
const values = _event_driven_io_dumbo.SQL.merge(documents.map((doc) => _event_driven_io_dumbo.SQL`(${doc._id}, ${
|
|
162
|
+
const values = _event_driven_io_dumbo.SQL.merge(documents.map((doc) => _event_driven_io_dumbo.SQL`(${doc._id}, ${_event_driven_io_dumbo.JSONParam.document(doc, serializer)}, ${doc._version ?? 1n})`), ",");
|
|
153
163
|
return _event_driven_io_dumbo.SQL`
|
|
154
164
|
INSERT INTO ${_event_driven_io_dumbo.SQL.identifier(collectionName)} (_id, data, _version) VALUES ${values}
|
|
155
165
|
ON CONFLICT(_id) DO NOTHING
|
|
@@ -159,7 +169,7 @@ const postgresSQLBuilder = (collectionName, serializer) => ({
|
|
|
159
169
|
const col = _event_driven_io_dumbo.SQL.identifier(collectionName);
|
|
160
170
|
return _event_driven_io_dumbo.SQL`
|
|
161
171
|
INSERT INTO ${col} (_id, data, _version)
|
|
162
|
-
VALUES ${_event_driven_io_dumbo.SQL.merge(documents.map((d) => _event_driven_io_dumbo.SQL`(${d._id}::text, ${
|
|
172
|
+
VALUES ${_event_driven_io_dumbo.SQL.merge(documents.map((d) => _event_driven_io_dumbo.SQL`(${d._id}::text, ${_event_driven_io_dumbo.JSONParam.document(d, serializer)}::jsonb || jsonb_build_object('_id', ${d._id}::text) || jsonb_build_object('_version', '1'::text), 1::bigint)`), ",")}
|
|
163
173
|
ON CONFLICT(_id) DO UPDATE SET
|
|
164
174
|
data = EXCLUDED.data
|
|
165
175
|
|| jsonb_build_object('_id', ${col}._id)
|
|
@@ -207,7 +217,7 @@ const postgresSQLBuilder = (collectionName, serializer) => ({
|
|
|
207
217
|
updated AS (
|
|
208
218
|
UPDATE ${_event_driven_io_dumbo.SQL.identifier(collectionName)}
|
|
209
219
|
SET
|
|
210
|
-
data = ${
|
|
220
|
+
data = ${_event_driven_io_dumbo.JSONParam.document(document, serializer)} || jsonb_build_object('_id', ${_event_driven_io_dumbo.SQL.identifier(collectionName)}._id) || jsonb_build_object('_version', (_version + 1)::text),
|
|
211
221
|
_version = _version + 1
|
|
212
222
|
FROM existing
|
|
213
223
|
WHERE ${_event_driven_io_dumbo.SQL.identifier(collectionName)}._id = existing._id ${expectedVersionUpdate}
|
|
@@ -264,7 +274,7 @@ const postgresSQLBuilder = (collectionName, serializer) => ({
|
|
|
264
274
|
WITH replacements(_id, data, expected_version) AS (
|
|
265
275
|
VALUES ${_event_driven_io_dumbo.SQL.merge(documents.map((d) => {
|
|
266
276
|
const expectedVersion = d._version;
|
|
267
|
-
return expectedVersion !== void 0 ? _event_driven_io_dumbo.SQL`(${d._id}::text, ${
|
|
277
|
+
return expectedVersion !== void 0 ? _event_driven_io_dumbo.SQL`(${d._id}::text, ${_event_driven_io_dumbo.JSONParam.document(d, serializer)}::jsonb, ${expectedVersion}::bigint)` : _event_driven_io_dumbo.SQL`(${d._id}::text, ${_event_driven_io_dumbo.JSONParam.document(d, serializer)}::jsonb, NULL::bigint)`;
|
|
268
278
|
}), ",")}
|
|
269
279
|
)
|
|
270
280
|
UPDATE ${_event_driven_io_dumbo.SQL.identifier(collectionName)} t
|
|
@@ -278,7 +288,7 @@ const postgresSQLBuilder = (collectionName, serializer) => ({
|
|
|
278
288
|
RETURNING t._id, t._version AS version;`;
|
|
279
289
|
return _event_driven_io_dumbo.SQL`
|
|
280
290
|
WITH replacements(_id, data) AS (
|
|
281
|
-
VALUES ${_event_driven_io_dumbo.SQL.merge(documents.map((d) => _event_driven_io_dumbo.SQL`(${d._id}::text, ${
|
|
291
|
+
VALUES ${_event_driven_io_dumbo.SQL.merge(documents.map((d) => _event_driven_io_dumbo.SQL`(${d._id}::text, ${_event_driven_io_dumbo.JSONParam.document(d, serializer)}::jsonb)`), ",")}
|
|
282
292
|
)
|
|
283
293
|
UPDATE ${_event_driven_io_dumbo.SQL.identifier(collectionName)} t
|
|
284
294
|
SET
|
|
@@ -331,9 +341,7 @@ const postgresSQLBuilder = (collectionName, serializer) => ({
|
|
|
331
341
|
query.push(where(filterQuery));
|
|
332
342
|
if (options?.sort && Object.keys(options.sort).length > 0) {
|
|
333
343
|
const clauses = Object.entries(options.sort).map(([field, dir]) => {
|
|
334
|
-
const
|
|
335
|
-
const isNested = !isMetadata && field.includes(".");
|
|
336
|
-
const accessor = isMetadata ? _event_driven_io_dumbo.SQL`${_event_driven_io_dumbo.SQL.plain(field)}` : isNested ? _event_driven_io_dumbo.SQL`data #> '${_event_driven_io_dumbo.SQL.plain(`{${field.split(".").join(",")}}`)}'` : _event_driven_io_dumbo.SQL`data -> '${_event_driven_io_dumbo.SQL.plain(field)}'`;
|
|
344
|
+
const accessor = field === "_id" || field === "_version" ? _event_driven_io_dumbo.SQL`${_event_driven_io_dumbo.SQL.plain(field)}` : _event_driven_io_dumbo_postgresql.PostgreSQLJSON.field(_event_driven_io_dumbo.SQL`data`, field);
|
|
337
345
|
return dir === 1 ? _event_driven_io_dumbo.SQL`${accessor} ASC NULLS FIRST` : _event_driven_io_dumbo.SQL`${accessor} DESC NULLS LAST`;
|
|
338
346
|
});
|
|
339
347
|
query.push(_event_driven_io_dumbo.SQL`ORDER BY ${_event_driven_io_dumbo.SQL.merge(clauses, ",")}`);
|
package/dist/pg.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pg.cjs","names":["SQL","OperatorMap","objectEntries","SQL","objectEntries","QueryOperators","hasOperators","objectEntries","SQL","SQL","expectedVersionPredicate","PgDriverType","postgreSQLMetadata","PongoDatabase","dumboDriver","PongoDatabaseSchemaComponent","PongoCollectionSchemaComponent","JSONSerializer","pongoSchema"],"sources":["../src/storage/postgresql/core/sqlBuilder/filter/queryOperators.ts","../src/storage/postgresql/core/sqlBuilder/filter/index.ts","../src/storage/postgresql/core/sqlBuilder/update/index.ts","../src/storage/postgresql/core/sqlBuilder/index.ts","../src/storage/postgresql/pg/index.ts"],"sourcesContent":["import type { JSONSerializer } from '@event-driven-io/dumbo';\nimport { SQL } from '@event-driven-io/dumbo';\nimport { objectEntries, OperatorMap } from '../../../../../core';\n\nexport const handleOperator = (\n path: string,\n operator: string,\n value: unknown,\n serializer: JSONSerializer,\n): SQL => {\n if (path === '_id' || path === '_version') {\n return handleMetadataOperator(path, operator, value);\n }\n\n switch (operator) {\n case '$eq': {\n const nestedPath = serializer.serialize(buildNestedObject(path, value));\n const serializedValue = serializer.serialize(value);\n\n return SQL`(data @> ${nestedPath}::jsonb OR jsonb_path_exists(data, '$.${SQL.plain(path)}[*] ? (@ == ${SQL.plain(serializedValue)})'))`;\n }\n case '$gt':\n case '$gte':\n case '$lt':\n case '$lte':\n case '$ne': {\n const jsonPath = SQL.plain(path.split('.').join(','));\n\n return SQL`data ->> '${jsonPath}' ${SQL.plain(OperatorMap[operator])} ${value}`;\n }\n case '$in': {\n const jsonPath = `{${path.split('.').join(',')}}`;\n\n return SQL`data #>> ${jsonPath} = ANY (${value})`;\n }\n case '$nin': {\n const jsonPath = `{${path.split('.').join(',')}}`;\n\n return SQL`data #>> ${jsonPath} != ALL (${value})`;\n }\n case '$elemMatch': {\n const subQuery = objectEntries(value as Record<string, unknown>)\n .map(\n ([subKey, subValue]) =>\n `@.\"${subKey}\" == ${serializer.serialize(subValue)}`,\n )\n .join(' && ');\n return SQL`jsonb_path_exists(data, '$.${SQL.plain(path)}[*] ? (${SQL.plain(subQuery)})')`;\n }\n case '$all': {\n const nestedPath = serializer.serialize(buildNestedObject(path, value));\n return SQL`data @> ${nestedPath}::jsonb`;\n }\n case '$size': {\n const jsonPath = `{${path.split('.').join(',')}}`;\n\n return SQL`jsonb_array_length(data #> ${jsonPath}) = ${value}`;\n }\n default:\n throw new Error(`Unsupported operator: ${operator}`);\n }\n};\n\nconst handleMetadataOperator = (\n fieldName: string,\n operator: string,\n value: unknown,\n): SQL => {\n switch (operator) {\n case '$eq':\n return SQL`${SQL.plain(fieldName)} = ${value}`;\n case '$gt':\n case '$gte':\n case '$lt':\n case '$lte':\n case '$ne':\n return SQL`${SQL.plain(fieldName)} ${SQL.plain(OperatorMap[operator])} ${value}`;\n case '$in':\n return SQL`${SQL.plain(fieldName)} = ANY (${value})`;\n case '$nin':\n return SQL`${SQL.plain(fieldName)} != ALL (${value})`;\n default:\n throw new Error(`Unsupported operator: ${operator}`);\n }\n};\n\nconst buildNestedObject = (\n path: string,\n value: unknown,\n): Record<string, unknown> =>\n path\n .split('.')\n .reverse()\n .reduce((acc, key) => ({ [key]: acc }), value as Record<string, unknown>);\n","import type { JSONSerializer } from '@event-driven-io/dumbo';\nimport { SQL } from '@event-driven-io/dumbo';\nimport {\n hasOperators,\n objectEntries,\n QueryOperators,\n type PongoFilter,\n} from '../../../../../core';\nimport { handleOperator } from './queryOperators';\n\nexport * from './queryOperators';\n\nconst AND = 'AND';\nconst OR = 'OR';\n\nconst unsupportedRootOperators = ['$text', '$where', '$comment'] as const;\n\nexport const constructFilterQuery = <T>(\n filter: PongoFilter<T>,\n serializer: JSONSerializer,\n): SQL => {\n ensureSupportedRootOperators(filter);\n const parts: SQL[] = [];\n\n const fieldFilterQuery = constructFieldFilterQuery(filter, serializer);\n if (!SQL.check.isEmpty(fieldFilterQuery)) {\n parts.push(fieldFilterQuery);\n }\n\n const orFilterQuery = constructLogicalFilterQuery(filter.$or, OR, serializer);\n if (!SQL.check.isEmpty(orFilterQuery)) {\n parts.push(orFilterQuery);\n }\n\n const andFilterQuery = constructLogicalFilterQuery(\n filter.$and,\n AND,\n serializer,\n );\n if (!SQL.check.isEmpty(andFilterQuery)) {\n parts.push(andFilterQuery);\n }\n\n const norFilterQuery = constructNorFilterQuery(filter.$nor, serializer);\n if (!SQL.check.isEmpty(norFilterQuery)) {\n parts.push(norFilterQuery);\n }\n\n return SQL.merge(parts, ` ${AND} `);\n};\n\nconst constructFieldFilterQuery = <T>(\n filter: PongoFilter<T>,\n serializer: JSONSerializer,\n): SQL =>\n SQL.merge(\n objectEntries(filter).flatMap(([key, value]) =>\n isLogicalRootOperator(key)\n ? []\n : [\n isRecord(value)\n ? constructComplexFilterQuery(key, value, serializer)\n : handleOperator(key, QueryOperators.$eq, value, serializer),\n ],\n ),\n ` ${AND} `,\n );\n\nconst constructLogicalFilterQuery = <T>(\n filters: PongoFilter<T>[] | undefined,\n joinOperator: typeof AND | typeof OR,\n serializer: JSONSerializer,\n): SQL => {\n if (!filters?.length) {\n return SQL.EMPTY;\n }\n\n const subFilterQueries = filters.reduce<SQL[]>((queries, filter) => {\n const query = constructFilterQuery(filter, serializer);\n if (!SQL.check.isEmpty(query)) {\n queries.push(query);\n }\n\n return queries;\n }, []);\n\n if (subFilterQueries.length === 0) {\n return SQL.EMPTY;\n }\n\n if (subFilterQueries.length === 1) {\n return wrapFilterQuery(subFilterQueries[0]!);\n }\n\n return SQL`(${SQL.merge(subFilterQueries.map(wrapFilterQuery), ` ${joinOperator} `)})`;\n};\n\nconst constructNorFilterQuery = <T>(\n filters: PongoFilter<T>[] | undefined,\n serializer: JSONSerializer,\n): SQL => {\n if (!filters?.length) {\n return SQL.EMPTY;\n }\n\n const logicalFilterQuery = constructLogicalFilterQuery(\n filters,\n OR,\n serializer,\n );\n return SQL.check.isEmpty(logicalFilterQuery)\n ? SQL.EMPTY\n : SQL`NOT ${logicalFilterQuery}`;\n};\n\nconst constructComplexFilterQuery = (\n key: string,\n value: Record<string, unknown>,\n serializer: JSONSerializer,\n): SQL => {\n const isEquality = !hasOperators(value);\n\n return SQL.merge(\n objectEntries(value).map(([nestedKey, val]) =>\n isEquality\n ? handleOperator(\n `${key}.${nestedKey}`,\n QueryOperators.$eq,\n val,\n serializer,\n )\n : handleOperator(key, nestedKey, val, serializer),\n ),\n ` ${AND} `,\n );\n};\n\nconst wrapFilterQuery = (filterQuery: SQL): SQL => SQL`(${filterQuery})`;\n\nconst ensureSupportedRootOperators = (filter: object): void => {\n for (const operator of unsupportedRootOperators) {\n if (operator in filter) {\n throw new Error(`Unsupported root operator: ${operator}`);\n }\n }\n};\n\nconst isLogicalRootOperator = (key: string): key is '$and' | '$nor' | '$or' =>\n key === '$and' || key === '$nor' || key === '$or';\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n value !== null && typeof value === 'object' && !Array.isArray(value);\n","import type { JSONSerializer } from '@event-driven-io/dumbo';\nimport { SQL } from '@event-driven-io/dumbo';\nimport {\n objectEntries,\n type $inc,\n type $push,\n type $set,\n type $unset,\n type PongoUpdate,\n} from '../../../../../core';\n\nexport const buildUpdateQuery = <T>(\n update: PongoUpdate<T>,\n serializer: JSONSerializer,\n): SQL =>\n objectEntries(update).reduce(\n (currentUpdateQuery, [op, value]) => {\n switch (op) {\n case '$set':\n return buildSetQuery(value, currentUpdateQuery, serializer);\n case '$unset':\n return buildUnsetQuery(value, currentUpdateQuery);\n case '$inc':\n return buildIncQuery(value, currentUpdateQuery);\n case '$push':\n return buildPushQuery(value, currentUpdateQuery, serializer);\n default:\n return currentUpdateQuery;\n }\n },\n SQL`data`,\n );\n\nexport const buildSetQuery = <T>(\n set: $set<T>,\n currentUpdateQuery: SQL,\n serializer: JSONSerializer,\n): SQL => SQL`${currentUpdateQuery} || ${serializer.serialize(set)}::jsonb`;\n\nexport const buildUnsetQuery = <T>(\n unset: $unset<T>,\n currentUpdateQuery: SQL,\n): SQL =>\n SQL`${currentUpdateQuery} - ${Object.keys(unset)\n .map((k) => `{${k}}`)\n .join(', ')}`;\n\nexport const buildIncQuery = <T>(\n inc: $inc<T>,\n currentUpdateQuery: SQL,\n): SQL => {\n for (const [key, value] of Object.entries(inc)) {\n currentUpdateQuery =\n typeof value === 'bigint'\n ? SQL`jsonb_set(${currentUpdateQuery}, '{${SQL.plain(key)}}', to_jsonb((COALESCE((data->>'${SQL.plain(key)}')::BIGINT, 0) + ${value})::TEXT), true)`\n : SQL`jsonb_set(${currentUpdateQuery}, '{${SQL.plain(key)}}', to_jsonb(COALESCE((data->>'${SQL.plain(key)}')::NUMERIC, 0) + ${value}), true)`;\n }\n return currentUpdateQuery;\n};\n\nexport const buildPushQuery = <T>(\n push: $push<T>,\n currentUpdateQuery: SQL,\n serializer: JSONSerializer,\n): SQL => {\n for (const [key, value] of Object.entries(push)) {\n const serializedValue = serializer.serialize([value]);\n currentUpdateQuery = SQL`jsonb_set(${currentUpdateQuery}, '{${SQL.plain(key)}}', (coalesce(data->'${SQL.plain(key)}', '[]'::jsonb) || ${serializedValue}::jsonb), true)`;\n }\n return currentUpdateQuery;\n};\n","import type { JSONSerializer } from '@event-driven-io/dumbo';\nimport { isSQL, SQL, sqlMigration } from '@event-driven-io/dumbo';\nimport {\n expectedVersionPredicate,\n type DeleteOneOptions,\n type ExpectedDocumentVersion,\n type FindOptions,\n type OptionalUnlessRequiredIdAndVersion,\n type PongoCollectionSQLBuilder,\n type PongoFilter,\n type PongoUpdate,\n type ReplaceOneOptions,\n type UpdateOneOptions,\n type WithId,\n type WithIdAndVersion,\n type WithoutId,\n} from '../../../../core';\nimport { constructFilterQuery } from './filter';\nimport { buildUpdateQuery } from './update';\n\nconst versionCheckClause = (\n collectionName: string,\n expectedVersion: ExpectedDocumentVersion | undefined,\n): SQL => {\n const col = SQL.identifier(collectionName);\n const predicate = expectedVersionPredicate(expectedVersion);\n return predicate.operator === 'none'\n ? SQL.EMPTY\n : SQL`AND ${col}._version = ${predicate.value}`;\n};\n\nconst createCollection = (collectionName: string): SQL =>\n SQL`\n CREATE TABLE IF NOT EXISTS ${SQL.identifier(collectionName)} (\n _id TEXT PRIMARY KEY, \n data JSONB NOT NULL, \n metadata JSONB NOT NULL DEFAULT '{}',\n _version BIGINT NOT NULL DEFAULT 1,\n _partition TEXT NOT NULL DEFAULT 'png_global',\n _archived BOOLEAN NOT NULL DEFAULT FALSE,\n _created TIMESTAMPTZ NOT NULL DEFAULT now(),\n _updated TIMESTAMPTZ NOT NULL DEFAULT now()\n )`;\n\nexport const pongoCollectionPostgreSQLMigrations = (collectionName: string) => [\n sqlMigration(`pongoCollection:${collectionName}:001:createtable`, [\n createCollection(collectionName),\n ]),\n];\n\nexport const postgresSQLBuilder = (\n collectionName: string,\n serializer: JSONSerializer,\n): PongoCollectionSQLBuilder => ({\n createCollection: (): SQL => createCollection(collectionName),\n insertOne: <T>(document: OptionalUnlessRequiredIdAndVersion<T>): SQL => {\n const serialized = serializer.serialize(document);\n const id = document._id;\n const version = document._version ?? 1n;\n\n return SQL`\n INSERT INTO ${SQL.identifier(collectionName)} (_id, data, _version) \n VALUES (${id}, ${serialized}, ${version}) ON CONFLICT(_id) DO NOTHING;`;\n },\n insertMany: <T>(documents: OptionalUnlessRequiredIdAndVersion<T>[]): SQL => {\n const values = SQL.merge(\n documents.map(\n (doc) =>\n SQL`(${doc._id}, ${serializer.serialize(doc)}, ${doc._version ?? 1n})`,\n ),\n ',',\n );\n\n return SQL`\n INSERT INTO ${SQL.identifier(collectionName)} (_id, data, _version) VALUES ${values}\n ON CONFLICT(_id) DO NOTHING\n RETURNING _id;`;\n },\n insertOrReplace: <T>(documents: Array<WithId<T>>): SQL => {\n const col = SQL.identifier(collectionName);\n const values = SQL.merge(\n documents.map(\n (d) =>\n SQL`(${d._id}::text, ${serializer.serialize(d)}::jsonb || jsonb_build_object('_id', ${d._id}::text) || jsonb_build_object('_version', '1'::text), 1::bigint)`,\n ),\n ',',\n );\n\n return SQL`\n INSERT INTO ${col} (_id, data, _version)\n VALUES ${values}\n ON CONFLICT(_id) DO UPDATE SET\n data = EXCLUDED.data\n || jsonb_build_object('_id', ${col}._id)\n || jsonb_build_object('_version', (${col}._version + 1)::text),\n _version = ${col}._version + 1\n RETURNING _id, _version AS version;`;\n },\n updateOne: <T>(\n filter: PongoFilter<T> | SQL,\n update: PongoUpdate<T> | SQL,\n options?: UpdateOneOptions,\n ): SQL => {\n const expectedVersionUpdate = versionCheckClause(\n collectionName,\n options?.expectedVersion,\n );\n\n const filterQuery = isSQL(filter)\n ? filter\n : constructFilterQuery(filter, serializer);\n const updateQuery = isSQL(update)\n ? update\n : buildUpdateQuery(update, serializer);\n\n return SQL`\n WITH existing AS (\n SELECT _id, _version as current_version\n FROM ${SQL.identifier(collectionName)} ${where(filterQuery)}\n LIMIT 1\n ),\n updated AS (\n UPDATE ${SQL.identifier(collectionName)} \n SET \n data = ${updateQuery} || jsonb_build_object('_id', ${SQL.identifier(collectionName)}._id) || jsonb_build_object('_version', (_version + 1)::text),\n _version = _version + 1\n FROM existing \n WHERE ${SQL.identifier(collectionName)}._id = existing._id ${expectedVersionUpdate}\n RETURNING ${SQL.identifier(collectionName)}._id, ${SQL.identifier(collectionName)}._version\n )\n SELECT \n existing._id,\n COALESCE(updated._version, existing.current_version) AS version,\n COUNT(existing._id) over() AS matched,\n COUNT(updated._id) over() AS modified\n FROM existing\n LEFT JOIN updated \n ON existing._id = updated._id;`;\n },\n replaceOne: <T>(\n filter: PongoFilter<T> | SQL,\n document: WithoutId<T>,\n options?: ReplaceOneOptions,\n ): SQL => {\n const expectedVersionUpdate = versionCheckClause(\n collectionName,\n options?.expectedVersion,\n );\n\n const filterQuery = isSQL(filter)\n ? filter\n : constructFilterQuery(filter, serializer);\n\n return SQL`\n WITH existing AS (\n SELECT _id, _version as current_version\n FROM ${SQL.identifier(collectionName)} ${where(filterQuery)}\n LIMIT 1\n ),\n updated AS (\n UPDATE ${SQL.identifier(collectionName)} \n SET \n data = ${serializer.serialize(document)} || jsonb_build_object('_id', ${SQL.identifier(collectionName)}._id) || jsonb_build_object('_version', (_version + 1)::text),\n _version = _version + 1\n FROM existing \n WHERE ${SQL.identifier(collectionName)}._id = existing._id ${expectedVersionUpdate}\n RETURNING ${SQL.identifier(collectionName)}._id, ${SQL.identifier(collectionName)}._version\n )\n SELECT \n existing._id,\n COALESCE(updated._version, existing.current_version) AS version,\n COUNT(existing._id) over() AS matched,\n COUNT(updated._id) over() AS modified\n FROM existing\n LEFT JOIN updated \n ON existing._id = updated._id;`;\n },\n updateMany: <T>(\n filter: PongoFilter<T> | SQL,\n update: PongoUpdate<T> | SQL,\n ): SQL => {\n const filterQuery = isSQL(filter)\n ? filter\n : constructFilterQuery(filter, serializer);\n const updateQuery = isSQL(update)\n ? update\n : buildUpdateQuery(update, serializer);\n\n return SQL`\n UPDATE ${SQL.identifier(collectionName)} \n SET \n data = ${updateQuery} || jsonb_build_object('_version', (_version + 1)::text),\n _version = _version + 1\n ${where(filterQuery)};`;\n },\n deleteOne: <T>(\n filter: PongoFilter<T> | SQL,\n options?: DeleteOneOptions,\n ): SQL => {\n const expectedVersionUpdate = versionCheckClause(\n collectionName,\n options?.expectedVersion,\n );\n\n const filterQuery = isSQL(filter)\n ? filter\n : constructFilterQuery(filter, serializer);\n\n return SQL`\n WITH existing AS (\n SELECT _id\n FROM ${SQL.identifier(collectionName)} ${where(filterQuery)}\n LIMIT 1\n ),\n deleted AS (\n DELETE FROM ${SQL.identifier(collectionName)}\n USING existing\n WHERE ${SQL.identifier(collectionName)}._id = existing._id ${expectedVersionUpdate}\n RETURNING ${SQL.identifier(collectionName)}._id\n )\n SELECT \n existing._id,\n COUNT(existing._id) over() AS matched,\n COUNT(deleted._id) over() AS deleted\n FROM existing\n LEFT JOIN deleted \n ON existing._id = deleted._id;`;\n },\n deleteMany: <T>(filter: PongoFilter<T> | SQL): SQL => {\n const filterQuery = isSQL(filter)\n ? filter\n : constructFilterQuery(filter, serializer);\n\n return SQL`DELETE FROM ${SQL.identifier(collectionName)} ${where(filterQuery)}`;\n },\n replaceMany: <T>(\n documents: Array<WithIdAndVersion<T>> | Array<WithId<T>>,\n ): SQL => {\n const hasVersions = documents.some(\n (d) => '_version' in d && d._version !== undefined,\n );\n\n if (hasVersions) {\n const values = SQL.merge(\n documents.map((d) => {\n const expectedVersion = (d as WithIdAndVersion<T>)._version;\n return expectedVersion !== undefined\n ? SQL`(${d._id}::text, ${serializer.serialize(d)}::jsonb, ${expectedVersion}::bigint)`\n : SQL`(${d._id}::text, ${serializer.serialize(d)}::jsonb, NULL::bigint)`;\n }),\n ',',\n );\n return SQL`\n WITH replacements(_id, data, expected_version) AS (\n VALUES ${values}\n )\n UPDATE ${SQL.identifier(collectionName)} t\n SET\n data = r.data\n || jsonb_build_object('_id', t._id)\n || jsonb_build_object('_version', (t._version + 1)::text),\n _version = t._version + 1\n FROM replacements r\n WHERE t._id = r._id AND (r.expected_version IS NULL OR t._version = r.expected_version)\n RETURNING t._id, t._version AS version;`;\n }\n\n const values = SQL.merge(\n documents.map(\n (d) => SQL`(${d._id}::text, ${serializer.serialize(d)}::jsonb)`,\n ),\n ',',\n );\n return SQL`\n WITH replacements(_id, data) AS (\n VALUES ${values}\n )\n UPDATE ${SQL.identifier(collectionName)} t\n SET\n data = r.data\n || jsonb_build_object('_id', t._id)\n || jsonb_build_object('_version', (t._version + 1)::text),\n _version = t._version + 1\n FROM replacements r\n WHERE t._id = r._id\n RETURNING t._id, t._version AS version;`;\n },\n deleteManyByIds: (ids: Array<{ _id: string; _version?: bigint }>): SQL => {\n const hasVersions = ids.some((d) => d._version !== undefined);\n\n if (hasVersions) {\n const values = SQL.merge(\n ids.map((d) => SQL`(${d._id}::text, ${d._version ?? 0n}::bigint)`),\n ',',\n );\n\n return SQL`\n WITH targets(_id, expected_version) AS (\n VALUES ${values}\n ),\n deleted AS (\n DELETE FROM ${SQL.identifier(collectionName)} t\n USING targets r\n WHERE t._id = r._id AND t._version = r.expected_version\n RETURNING t._id\n )\n SELECT r._id,\n CASE WHEN d._id IS NOT NULL THEN 1 ELSE 0 END as deleted\n FROM targets r\n LEFT JOIN deleted d ON r._id = d._id;`;\n }\n\n const values = SQL.merge(\n ids.map((d) => SQL`(${d._id}::text)`),\n ',',\n );\n\n return SQL`\n WITH targets(_id) AS (\n VALUES ${values}\n ),\n deleted AS (\n DELETE FROM ${SQL.identifier(collectionName)} t\n USING targets r\n WHERE t._id = r._id\n RETURNING t._id\n )\n SELECT r._id,\n CASE WHEN d._id IS NOT NULL THEN 1 ELSE 0 END as deleted\n FROM targets r\n LEFT JOIN deleted d ON r._id = d._id;`;\n },\n findOne: <T>(filter: PongoFilter<T> | SQL): SQL => {\n const filterQuery = isSQL(filter)\n ? filter\n : constructFilterQuery(filter, serializer);\n\n return SQL`SELECT data, _id, _version FROM ${SQL.identifier(collectionName)} ${where(filterQuery)} LIMIT 1;`;\n },\n find: <T>(filter: PongoFilter<T> | SQL, options?: FindOptions): SQL => {\n const filterQuery = isSQL(filter)\n ? filter\n : constructFilterQuery(filter, serializer);\n const query: SQL[] = [];\n\n query.push(\n SQL`SELECT data, _id, _version FROM ${SQL.identifier(collectionName)}`,\n );\n\n query.push(where(filterQuery));\n\n if (options?.sort && Object.keys(options.sort).length > 0) {\n const clauses = Object.entries(options.sort).map(([field, dir]) => {\n const isMetadata = field === '_id' || field === '_version';\n const isNested = !isMetadata && field.includes('.');\n // _id and _version are native columns, not JSON fields.\n // Use -> / #> (returns jsonb) rather than ->> / #>> (returns text) so\n // that numeric fields are sorted numerically, not lexicographically.\n const accessor = isMetadata\n ? SQL`${SQL.plain(field)}`\n : isNested\n ? SQL`data #> '${SQL.plain(`{${field.split('.').join(',')}}`)}'`\n : SQL`data -> '${SQL.plain(field)}'`;\n // Match MongoDB's null ordering: missing/null values sort first on ASC,\n // last on DESC. PostgreSQL's default is the opposite for ASC (NULLS LAST).\n return dir === 1\n ? SQL`${accessor} ASC NULLS FIRST`\n : SQL`${accessor} DESC NULLS LAST`;\n });\n query.push(SQL`ORDER BY ${SQL.merge(clauses, ',')}`);\n }\n\n if (options?.limit) {\n query.push(SQL`LIMIT ${options.limit}`);\n }\n\n if (options?.skip) {\n query.push(SQL`OFFSET ${options.skip}`);\n }\n\n return SQL.merge([...query, SQL`;`]);\n },\n countDocuments: <T>(filter: PongoFilter<T> | SQL): SQL => {\n const filterQuery = SQL.check.isSQL(filter)\n ? filter\n : constructFilterQuery(filter, serializer);\n return SQL`SELECT COUNT(1) as count FROM ${SQL.identifier(collectionName)} ${where(filterQuery)};`;\n },\n rename: (newName: string): SQL =>\n SQL`ALTER TABLE ${SQL.identifier(collectionName)} RENAME TO ${SQL.identifier(newName)};`,\n drop: (targetName: string = collectionName): SQL =>\n SQL`DROP TABLE IF EXISTS ${SQL.identifier(targetName)}`,\n});\n\nconst where = (filterQuery: SQL): SQL =>\n SQL.check.isEmpty(filterQuery)\n ? SQL.EMPTY\n : SQL.merge([SQL`WHERE `, filterQuery]);\n","import { dumbo, JSONSerializer } from '@event-driven-io/dumbo';\nimport {\n pgDumboDriver as dumboDriver,\n PgDriverType,\n postgreSQLMetadata,\n type PgConnection,\n} from '@event-driven-io/dumbo/pg';\nimport type pg from 'pg';\nimport {\n PongoCollectionSchemaComponent,\n PongoDatabase,\n PongoDatabaseSchemaComponent,\n pongoDriverRegistry,\n pongoSchema,\n type PongoDb,\n type PongoDriver,\n type PongoDriverOptions,\n} from '../../../core';\nimport {\n pongoCollectionPostgreSQLMigrations,\n postgresSQLBuilder,\n} from '../core';\n\nexport type PgPongoClientOptions =\n PooledPongoClientOptions | NotPooledPongoOptions;\n\nexport type PooledPongoClientOptions =\n | {\n pool: pg.Pool;\n }\n | {\n pooled: true;\n }\n | {\n pool: pg.Pool;\n pooled: true;\n }\n | object;\n\nexport type NotPooledPongoOptions =\n | {\n client: pg.Client;\n }\n | {\n pooled: false;\n }\n | {\n client: pg.Client;\n pooled: false;\n }\n | {\n connection: PgConnection;\n pooled?: false;\n };\n\ntype PgDatabaseDriverOptions = PongoDriverOptions<PgPongoClientOptions> & {\n databaseName?: string | undefined;\n connectionString: string;\n};\n\nconst pgPongoDriver: PongoDriver<\n PongoDb<PgDriverType>,\n PgDatabaseDriverOptions\n> = {\n driverType: PgDriverType,\n databaseFactory: (options) => {\n const databaseName =\n options.databaseName ??\n postgreSQLMetadata.parseDatabaseName(options.connectionString) ??\n postgreSQLMetadata.defaultDatabaseName;\n\n return PongoDatabase({\n ...options,\n pool: dumbo({\n connectionString: options.connectionString,\n driver: dumboDriver,\n ...options.connectionOptions,\n serialization: { serializer: options.serializer },\n }),\n schemaComponent: PongoDatabaseSchemaComponent({\n driverType: PgDriverType,\n collectionFactory: (schema) =>\n PongoCollectionSchemaComponent({\n driverType: PgDriverType,\n definition: schema,\n migrationsOrSchemaComponents: {\n migrations: pongoCollectionPostgreSQLMigrations(schema.name),\n },\n sqlBuilder: postgresSQLBuilder(\n schema.name,\n options.serialization?.serializer ?? JSONSerializer,\n ),\n }),\n definition:\n options.schema?.definition ?? pongoSchema.db(databaseName, {}),\n }),\n databaseName,\n });\n },\n};\n\nexport const usePgPongoDriver = () => {\n pongoDriverRegistry.register(PgDriverType, pgPongoDriver);\n};\n\nusePgPongoDriver();\n\nexport { pgPongoDriver as pgDriver, pgPongoDriver as pongoDriver };\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"pg.cjs","names":["PostgreSQLJSON","JSONParam","SQL","OperatorMap","SQL","objectEntries","QueryOperators","hasOperators","objectEntries","JSONParam","PostgreSQLJSON","SQL","expectedVersionPredicate","JSONParam","PostgreSQLJSON","PgDriverType","postgreSQLMetadata","PongoDatabase","dumboDriver","PongoDatabaseSchemaComponent","PongoCollectionSchemaComponent","JSONSerializer","pongoSchema"],"sources":["../src/storage/postgresql/core/sqlBuilder/filter/queryOperators.ts","../src/storage/postgresql/core/sqlBuilder/filter/index.ts","../src/storage/postgresql/core/sqlBuilder/update/index.ts","../src/storage/postgresql/core/sqlBuilder/index.ts","../src/storage/postgresql/pg/index.ts"],"sourcesContent":["import type { JSONSerializer } from '@event-driven-io/dumbo';\nimport { JSONParam, SQL } from '@event-driven-io/dumbo';\nimport { PostgreSQLJSON } from '@event-driven-io/dumbo/postgresql';\nimport { OperatorMap } from '../../../../../core';\n\nexport const handleOperator = (\n path: string,\n operator: string,\n value: unknown,\n serializer: JSONSerializer,\n): SQL => {\n if (path === '_id' || path === '_version') {\n return handleMetadataOperator(path, operator, value);\n }\n\n switch (operator) {\n case '$eq': {\n const field = PostgreSQLJSON.field(SQL`data`, path);\n const serializedValue = JSONParam.value(value, serializer);\n const serializedArrayValue = JSONParam.arrayContaining(value, serializer);\n\n return SQL`(${field} = ${serializedValue}::jsonb OR ${field} @> ${serializedArrayValue}::jsonb)`;\n }\n case '$gt':\n case '$gte':\n case '$lt':\n case '$lte':\n case '$ne': {\n const field = PostgreSQLJSON.textField(SQL`data`, path);\n\n return SQL`${field} ${SQL.plain(OperatorMap[operator])} ${value}`;\n }\n case '$in': {\n const field = PostgreSQLJSON.textField(SQL`data`, path);\n\n return SQL`${field} = ANY (${value})`;\n }\n case '$nin': {\n const field = PostgreSQLJSON.textField(SQL`data`, path);\n\n return SQL`${field} != ALL (${value})`;\n }\n case '$elemMatch': {\n const field = PostgreSQLJSON.field(SQL`data`, path);\n const arrayField = SQL`CASE WHEN jsonb_typeof(${field}) = 'array' THEN ${field} ELSE '[]'::jsonb END`;\n const serializedValue = JSONParam.value(value, serializer);\n return SQL`EXISTS (\n SELECT 1\n FROM jsonb_array_elements(${arrayField}) AS elem(value)\n WHERE elem.value @> ${serializedValue}::jsonb\n )`;\n }\n case '$all': {\n const serializedValue = JSONParam.value(value, serializer);\n return SQL`${PostgreSQLJSON.field(SQL`data`, path)} @> ${serializedValue}::jsonb`;\n }\n case '$size': {\n return SQL`jsonb_array_length(${PostgreSQLJSON.field(SQL`data`, path)}) = ${value}`;\n }\n default:\n throw new Error(`Unsupported operator: ${operator}`);\n }\n};\n\nconst handleMetadataOperator = (\n fieldName: string,\n operator: string,\n value: unknown,\n): SQL => {\n switch (operator) {\n case '$eq':\n return SQL`${SQL.plain(fieldName)} = ${value}`;\n case '$gt':\n case '$gte':\n case '$lt':\n case '$lte':\n case '$ne':\n return SQL`${SQL.plain(fieldName)} ${SQL.plain(OperatorMap[operator])} ${value}`;\n case '$in':\n return SQL`${SQL.plain(fieldName)} = ANY (${value})`;\n case '$nin':\n return SQL`${SQL.plain(fieldName)} != ALL (${value})`;\n default:\n throw new Error(`Unsupported operator: ${operator}`);\n }\n};\n","import type { JSONSerializer } from '@event-driven-io/dumbo';\nimport { SQL } from '@event-driven-io/dumbo';\nimport {\n hasOperators,\n objectEntries,\n QueryOperators,\n type PongoFilter,\n} from '../../../../../core';\nimport { handleOperator } from './queryOperators';\n\nexport * from './queryOperators';\n\nconst AND = 'AND';\nconst OR = 'OR';\n\nconst unsupportedRootOperators = ['$text', '$where', '$comment'] as const;\n\nexport const constructFilterQuery = <T>(\n filter: PongoFilter<T>,\n serializer: JSONSerializer,\n): SQL => {\n ensureSupportedRootOperators(filter);\n const parts: SQL[] = [];\n\n const fieldFilterQuery = constructFieldFilterQuery(filter, serializer);\n if (!SQL.check.isEmpty(fieldFilterQuery)) {\n parts.push(fieldFilterQuery);\n }\n\n const orFilterQuery = constructLogicalFilterQuery(filter.$or, OR, serializer);\n if (!SQL.check.isEmpty(orFilterQuery)) {\n parts.push(orFilterQuery);\n }\n\n const andFilterQuery = constructLogicalFilterQuery(\n filter.$and,\n AND,\n serializer,\n );\n if (!SQL.check.isEmpty(andFilterQuery)) {\n parts.push(andFilterQuery);\n }\n\n const norFilterQuery = constructNorFilterQuery(filter.$nor, serializer);\n if (!SQL.check.isEmpty(norFilterQuery)) {\n parts.push(norFilterQuery);\n }\n\n return SQL.merge(parts, ` ${AND} `);\n};\n\nconst constructFieldFilterQuery = <T>(\n filter: PongoFilter<T>,\n serializer: JSONSerializer,\n): SQL =>\n SQL.merge(\n objectEntries(filter).flatMap(([key, value]) =>\n isLogicalRootOperator(key)\n ? []\n : [\n isRecord(value)\n ? constructComplexFilterQuery(key, value, serializer)\n : handleOperator(key, QueryOperators.$eq, value, serializer),\n ],\n ),\n ` ${AND} `,\n );\n\nconst constructLogicalFilterQuery = <T>(\n filters: PongoFilter<T>[] | undefined,\n joinOperator: typeof AND | typeof OR,\n serializer: JSONSerializer,\n): SQL => {\n if (!filters?.length) {\n return SQL.EMPTY;\n }\n\n const subFilterQueries = filters.reduce<SQL[]>((queries, filter) => {\n const query = constructFilterQuery(filter, serializer);\n if (!SQL.check.isEmpty(query)) {\n queries.push(query);\n }\n\n return queries;\n }, []);\n\n if (subFilterQueries.length === 0) {\n return SQL.EMPTY;\n }\n\n if (subFilterQueries.length === 1) {\n return wrapFilterQuery(subFilterQueries[0]!);\n }\n\n return SQL`(${SQL.merge(subFilterQueries.map(wrapFilterQuery), ` ${joinOperator} `)})`;\n};\n\nconst constructNorFilterQuery = <T>(\n filters: PongoFilter<T>[] | undefined,\n serializer: JSONSerializer,\n): SQL => {\n if (!filters?.length) {\n return SQL.EMPTY;\n }\n\n const logicalFilterQuery = constructLogicalFilterQuery(\n filters,\n OR,\n serializer,\n );\n return SQL.check.isEmpty(logicalFilterQuery)\n ? SQL.EMPTY\n : SQL`NOT ${logicalFilterQuery}`;\n};\n\nconst constructComplexFilterQuery = (\n key: string,\n value: Record<string, unknown>,\n serializer: JSONSerializer,\n): SQL => {\n const isEquality = !hasOperators(value);\n\n return SQL.merge(\n objectEntries(value).map(([nestedKey, val]) =>\n isEquality\n ? handleOperator(\n `${key}.${nestedKey}`,\n QueryOperators.$eq,\n val,\n serializer,\n )\n : handleOperator(key, nestedKey, val, serializer),\n ),\n ` ${AND} `,\n );\n};\n\nconst wrapFilterQuery = (filterQuery: SQL): SQL => SQL`(${filterQuery})`;\n\nconst ensureSupportedRootOperators = (filter: object): void => {\n for (const operator of unsupportedRootOperators) {\n if (operator in filter) {\n throw new Error(`Unsupported root operator: ${operator}`);\n }\n }\n};\n\nconst isLogicalRootOperator = (key: string): key is '$and' | '$nor' | '$or' =>\n key === '$and' || key === '$nor' || key === '$or';\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n value !== null && typeof value === 'object' && !Array.isArray(value);\n","import type { JSONSerializer } from '@event-driven-io/dumbo';\nimport { JSONParam, SQL } from '@event-driven-io/dumbo';\nimport { PostgreSQLJSON } from '@event-driven-io/dumbo/postgresql';\nimport {\n objectEntries,\n type $inc,\n type $push,\n type $set,\n type $unset,\n type PongoUpdate,\n} from '../../../../../core';\n\nexport const buildUpdateQuery = <T>(\n update: PongoUpdate<T>,\n serializer: JSONSerializer,\n): SQL =>\n objectEntries(update).reduce(\n (currentUpdateQuery, [op, value]) => {\n switch (op) {\n case '$set':\n return buildSetQuery(value, currentUpdateQuery, serializer);\n case '$unset':\n return buildUnsetQuery(value, currentUpdateQuery);\n case '$inc':\n return buildIncQuery(value, currentUpdateQuery);\n case '$push':\n return buildPushQuery(value, currentUpdateQuery, serializer);\n default:\n return currentUpdateQuery;\n }\n },\n SQL`data`,\n );\n\nexport const buildSetQuery = <T>(\n set: $set<T>,\n currentUpdateQuery: SQL,\n serializer: JSONSerializer,\n): SQL =>\n SQL`${currentUpdateQuery} || ${JSONParam.value(set, serializer)}::jsonb`;\n\nexport const buildUnsetQuery = <T>(\n unset: $unset<T>,\n currentUpdateQuery: SQL,\n): SQL => {\n let query = currentUpdateQuery;\n for (const key of Object.keys(unset)) {\n query = SQL`${query} - ${key}`;\n }\n return query;\n};\n\nexport const buildIncQuery = <T>(\n inc: $inc<T>,\n currentUpdateQuery: SQL,\n): SQL => {\n for (const [key, value] of Object.entries(inc)) {\n currentUpdateQuery =\n typeof value === 'bigint'\n ? SQL`jsonb_set(${currentUpdateQuery}, ${PostgreSQLJSON.path(key)}, to_jsonb((COALESCE((${PostgreSQLJSON.textField(SQL`data`, key)})::BIGINT, 0) + ${value})::TEXT), true)`\n : SQL`jsonb_set(${currentUpdateQuery}, ${PostgreSQLJSON.path(key)}, to_jsonb(COALESCE((${PostgreSQLJSON.textField(SQL`data`, key)})::NUMERIC, 0) + ${value}), true)`;\n }\n return currentUpdateQuery;\n};\n\nexport const buildPushQuery = <T>(\n push: $push<T>,\n currentUpdateQuery: SQL,\n serializer: JSONSerializer,\n): SQL => {\n for (const [key, value] of Object.entries(push)) {\n const serializedValue = JSONParam.arrayContaining(value, serializer);\n currentUpdateQuery = SQL`jsonb_set(${currentUpdateQuery}, ${PostgreSQLJSON.path(key)}, (coalesce(${PostgreSQLJSON.field(SQL`data`, key)}, '[]'::jsonb) || ${serializedValue}::jsonb), true)`;\n }\n return currentUpdateQuery;\n};\n","import type { JSONSerializer } from '@event-driven-io/dumbo';\nimport { isSQL, JSONParam, SQL, sqlMigration } from '@event-driven-io/dumbo';\nimport { PostgreSQLJSON } from '@event-driven-io/dumbo/postgresql';\nimport {\n expectedVersionPredicate,\n type DeleteOneOptions,\n type ExpectedDocumentVersion,\n type FindOptions,\n type OptionalUnlessRequiredIdAndVersion,\n type PongoCollectionSQLBuilder,\n type PongoFilter,\n type PongoUpdate,\n type ReplaceOneOptions,\n type UpdateOneOptions,\n type WithId,\n type WithIdAndVersion,\n type WithoutId,\n} from '../../../../core';\nimport { constructFilterQuery } from './filter';\nimport { buildUpdateQuery } from './update';\n\nconst versionCheckClause = (\n collectionName: string,\n expectedVersion: ExpectedDocumentVersion | undefined,\n): SQL => {\n const col = SQL.identifier(collectionName);\n const predicate = expectedVersionPredicate(expectedVersion);\n return predicate.operator === 'none'\n ? SQL.EMPTY\n : SQL`AND ${col}._version = ${predicate.value}`;\n};\n\nconst createCollection = (collectionName: string): SQL =>\n SQL`\n CREATE TABLE IF NOT EXISTS ${SQL.identifier(collectionName)} (\n _id TEXT PRIMARY KEY, \n data JSONB NOT NULL, \n metadata JSONB NOT NULL DEFAULT '{}',\n _version BIGINT NOT NULL DEFAULT 1,\n _partition TEXT NOT NULL DEFAULT 'png_global',\n _archived BOOLEAN NOT NULL DEFAULT FALSE,\n _created TIMESTAMPTZ NOT NULL DEFAULT now(),\n _updated TIMESTAMPTZ NOT NULL DEFAULT now()\n )`;\n\nexport const pongoCollectionPostgreSQLMigrations = (collectionName: string) => [\n sqlMigration(`pongoCollection:${collectionName}:001:createtable`, [\n createCollection(collectionName),\n ]),\n];\n\nexport const postgresSQLBuilder = (\n collectionName: string,\n serializer: JSONSerializer,\n): PongoCollectionSQLBuilder => ({\n createCollection: (): SQL => createCollection(collectionName),\n insertOne: <T>(document: OptionalUnlessRequiredIdAndVersion<T>): SQL => {\n const serialized = JSONParam.document(document, serializer);\n const id = document._id;\n const version = document._version ?? 1n;\n\n return SQL`\n INSERT INTO ${SQL.identifier(collectionName)} (_id, data, _version) \n VALUES (${id}, ${serialized}, ${version}) ON CONFLICT(_id) DO NOTHING;`;\n },\n insertMany: <T>(documents: OptionalUnlessRequiredIdAndVersion<T>[]): SQL => {\n const values = SQL.merge(\n documents.map(\n (doc) =>\n SQL`(${doc._id}, ${JSONParam.document(doc, serializer)}, ${doc._version ?? 1n})`,\n ),\n ',',\n );\n\n return SQL`\n INSERT INTO ${SQL.identifier(collectionName)} (_id, data, _version) VALUES ${values}\n ON CONFLICT(_id) DO NOTHING\n RETURNING _id;`;\n },\n insertOrReplace: <T>(documents: Array<WithId<T>>): SQL => {\n const col = SQL.identifier(collectionName);\n const values = SQL.merge(\n documents.map(\n (d) =>\n SQL`(${d._id}::text, ${JSONParam.document(d, serializer)}::jsonb || jsonb_build_object('_id', ${d._id}::text) || jsonb_build_object('_version', '1'::text), 1::bigint)`,\n ),\n ',',\n );\n\n return SQL`\n INSERT INTO ${col} (_id, data, _version)\n VALUES ${values}\n ON CONFLICT(_id) DO UPDATE SET\n data = EXCLUDED.data\n || jsonb_build_object('_id', ${col}._id)\n || jsonb_build_object('_version', (${col}._version + 1)::text),\n _version = ${col}._version + 1\n RETURNING _id, _version AS version;`;\n },\n updateOne: <T>(\n filter: PongoFilter<T> | SQL,\n update: PongoUpdate<T> | SQL,\n options?: UpdateOneOptions,\n ): SQL => {\n const expectedVersionUpdate = versionCheckClause(\n collectionName,\n options?.expectedVersion,\n );\n\n const filterQuery = isSQL(filter)\n ? filter\n : constructFilterQuery(filter, serializer);\n const updateQuery = isSQL(update)\n ? update\n : buildUpdateQuery(update, serializer);\n\n return SQL`\n WITH existing AS (\n SELECT _id, _version as current_version\n FROM ${SQL.identifier(collectionName)} ${where(filterQuery)}\n LIMIT 1\n ),\n updated AS (\n UPDATE ${SQL.identifier(collectionName)} \n SET \n data = ${updateQuery} || jsonb_build_object('_id', ${SQL.identifier(collectionName)}._id) || jsonb_build_object('_version', (_version + 1)::text),\n _version = _version + 1\n FROM existing \n WHERE ${SQL.identifier(collectionName)}._id = existing._id ${expectedVersionUpdate}\n RETURNING ${SQL.identifier(collectionName)}._id, ${SQL.identifier(collectionName)}._version\n )\n SELECT \n existing._id,\n COALESCE(updated._version, existing.current_version) AS version,\n COUNT(existing._id) over() AS matched,\n COUNT(updated._id) over() AS modified\n FROM existing\n LEFT JOIN updated \n ON existing._id = updated._id;`;\n },\n replaceOne: <T>(\n filter: PongoFilter<T> | SQL,\n document: WithoutId<T>,\n options?: ReplaceOneOptions,\n ): SQL => {\n const expectedVersionUpdate = versionCheckClause(\n collectionName,\n options?.expectedVersion,\n );\n\n const filterQuery = isSQL(filter)\n ? filter\n : constructFilterQuery(filter, serializer);\n\n return SQL`\n WITH existing AS (\n SELECT _id, _version as current_version\n FROM ${SQL.identifier(collectionName)} ${where(filterQuery)}\n LIMIT 1\n ),\n updated AS (\n UPDATE ${SQL.identifier(collectionName)} \n SET \n data = ${JSONParam.document(document, serializer)} || jsonb_build_object('_id', ${SQL.identifier(collectionName)}._id) || jsonb_build_object('_version', (_version + 1)::text),\n _version = _version + 1\n FROM existing \n WHERE ${SQL.identifier(collectionName)}._id = existing._id ${expectedVersionUpdate}\n RETURNING ${SQL.identifier(collectionName)}._id, ${SQL.identifier(collectionName)}._version\n )\n SELECT \n existing._id,\n COALESCE(updated._version, existing.current_version) AS version,\n COUNT(existing._id) over() AS matched,\n COUNT(updated._id) over() AS modified\n FROM existing\n LEFT JOIN updated \n ON existing._id = updated._id;`;\n },\n updateMany: <T>(\n filter: PongoFilter<T> | SQL,\n update: PongoUpdate<T> | SQL,\n ): SQL => {\n const filterQuery = isSQL(filter)\n ? filter\n : constructFilterQuery(filter, serializer);\n const updateQuery = isSQL(update)\n ? update\n : buildUpdateQuery(update, serializer);\n\n return SQL`\n UPDATE ${SQL.identifier(collectionName)} \n SET \n data = ${updateQuery} || jsonb_build_object('_version', (_version + 1)::text),\n _version = _version + 1\n ${where(filterQuery)};`;\n },\n deleteOne: <T>(\n filter: PongoFilter<T> | SQL,\n options?: DeleteOneOptions,\n ): SQL => {\n const expectedVersionUpdate = versionCheckClause(\n collectionName,\n options?.expectedVersion,\n );\n\n const filterQuery = isSQL(filter)\n ? filter\n : constructFilterQuery(filter, serializer);\n\n return SQL`\n WITH existing AS (\n SELECT _id\n FROM ${SQL.identifier(collectionName)} ${where(filterQuery)}\n LIMIT 1\n ),\n deleted AS (\n DELETE FROM ${SQL.identifier(collectionName)}\n USING existing\n WHERE ${SQL.identifier(collectionName)}._id = existing._id ${expectedVersionUpdate}\n RETURNING ${SQL.identifier(collectionName)}._id\n )\n SELECT \n existing._id,\n COUNT(existing._id) over() AS matched,\n COUNT(deleted._id) over() AS deleted\n FROM existing\n LEFT JOIN deleted \n ON existing._id = deleted._id;`;\n },\n deleteMany: <T>(filter: PongoFilter<T> | SQL): SQL => {\n const filterQuery = isSQL(filter)\n ? filter\n : constructFilterQuery(filter, serializer);\n\n return SQL`DELETE FROM ${SQL.identifier(collectionName)} ${where(filterQuery)}`;\n },\n replaceMany: <T>(\n documents: Array<WithIdAndVersion<T>> | Array<WithId<T>>,\n ): SQL => {\n const hasVersions = documents.some(\n (d) => '_version' in d && d._version !== undefined,\n );\n\n if (hasVersions) {\n const values = SQL.merge(\n documents.map((d) => {\n const expectedVersion = (d as WithIdAndVersion<T>)._version;\n return expectedVersion !== undefined\n ? SQL`(${d._id}::text, ${JSONParam.document(d, serializer)}::jsonb, ${expectedVersion}::bigint)`\n : SQL`(${d._id}::text, ${JSONParam.document(d, serializer)}::jsonb, NULL::bigint)`;\n }),\n ',',\n );\n return SQL`\n WITH replacements(_id, data, expected_version) AS (\n VALUES ${values}\n )\n UPDATE ${SQL.identifier(collectionName)} t\n SET\n data = r.data\n || jsonb_build_object('_id', t._id)\n || jsonb_build_object('_version', (t._version + 1)::text),\n _version = t._version + 1\n FROM replacements r\n WHERE t._id = r._id AND (r.expected_version IS NULL OR t._version = r.expected_version)\n RETURNING t._id, t._version AS version;`;\n }\n\n const values = SQL.merge(\n documents.map(\n (d) =>\n SQL`(${d._id}::text, ${JSONParam.document(d, serializer)}::jsonb)`,\n ),\n ',',\n );\n return SQL`\n WITH replacements(_id, data) AS (\n VALUES ${values}\n )\n UPDATE ${SQL.identifier(collectionName)} t\n SET\n data = r.data\n || jsonb_build_object('_id', t._id)\n || jsonb_build_object('_version', (t._version + 1)::text),\n _version = t._version + 1\n FROM replacements r\n WHERE t._id = r._id\n RETURNING t._id, t._version AS version;`;\n },\n deleteManyByIds: (ids: Array<{ _id: string; _version?: bigint }>): SQL => {\n const hasVersions = ids.some((d) => d._version !== undefined);\n\n if (hasVersions) {\n const values = SQL.merge(\n ids.map((d) => SQL`(${d._id}::text, ${d._version ?? 0n}::bigint)`),\n ',',\n );\n\n return SQL`\n WITH targets(_id, expected_version) AS (\n VALUES ${values}\n ),\n deleted AS (\n DELETE FROM ${SQL.identifier(collectionName)} t\n USING targets r\n WHERE t._id = r._id AND t._version = r.expected_version\n RETURNING t._id\n )\n SELECT r._id,\n CASE WHEN d._id IS NOT NULL THEN 1 ELSE 0 END as deleted\n FROM targets r\n LEFT JOIN deleted d ON r._id = d._id;`;\n }\n\n const values = SQL.merge(\n ids.map((d) => SQL`(${d._id}::text)`),\n ',',\n );\n\n return SQL`\n WITH targets(_id) AS (\n VALUES ${values}\n ),\n deleted AS (\n DELETE FROM ${SQL.identifier(collectionName)} t\n USING targets r\n WHERE t._id = r._id\n RETURNING t._id\n )\n SELECT r._id,\n CASE WHEN d._id IS NOT NULL THEN 1 ELSE 0 END as deleted\n FROM targets r\n LEFT JOIN deleted d ON r._id = d._id;`;\n },\n findOne: <T>(filter: PongoFilter<T> | SQL): SQL => {\n const filterQuery = isSQL(filter)\n ? filter\n : constructFilterQuery(filter, serializer);\n\n return SQL`SELECT data, _id, _version FROM ${SQL.identifier(collectionName)} ${where(filterQuery)} LIMIT 1;`;\n },\n find: <T>(filter: PongoFilter<T> | SQL, options?: FindOptions): SQL => {\n const filterQuery = isSQL(filter)\n ? filter\n : constructFilterQuery(filter, serializer);\n const query: SQL[] = [];\n\n query.push(\n SQL`SELECT data, _id, _version FROM ${SQL.identifier(collectionName)}`,\n );\n\n query.push(where(filterQuery));\n\n if (options?.sort && Object.keys(options.sort).length > 0) {\n const clauses = Object.entries(options.sort).map(([field, dir]) => {\n const isMetadata = field === '_id' || field === '_version';\n // _id and _version are native columns, not JSON fields.\n // Use -> / #> (returns jsonb) rather than ->> / #>> (returns text) so\n // that numeric fields are sorted numerically, not lexicographically.\n const accessor = isMetadata\n ? SQL`${SQL.plain(field)}`\n : PostgreSQLJSON.field(SQL`data`, field);\n // Match MongoDB's null ordering: missing/null values sort first on ASC,\n // last on DESC. PostgreSQL's default is the opposite for ASC (NULLS LAST).\n return dir === 1\n ? SQL`${accessor} ASC NULLS FIRST`\n : SQL`${accessor} DESC NULLS LAST`;\n });\n query.push(SQL`ORDER BY ${SQL.merge(clauses, ',')}`);\n }\n\n if (options?.limit) {\n query.push(SQL`LIMIT ${options.limit}`);\n }\n\n if (options?.skip) {\n query.push(SQL`OFFSET ${options.skip}`);\n }\n\n return SQL.merge([...query, SQL`;`]);\n },\n countDocuments: <T>(filter: PongoFilter<T> | SQL): SQL => {\n const filterQuery = SQL.check.isSQL(filter)\n ? filter\n : constructFilterQuery(filter, serializer);\n return SQL`SELECT COUNT(1) as count FROM ${SQL.identifier(collectionName)} ${where(filterQuery)};`;\n },\n rename: (newName: string): SQL =>\n SQL`ALTER TABLE ${SQL.identifier(collectionName)} RENAME TO ${SQL.identifier(newName)};`,\n drop: (targetName: string = collectionName): SQL =>\n SQL`DROP TABLE IF EXISTS ${SQL.identifier(targetName)}`,\n});\n\nconst where = (filterQuery: SQL): SQL =>\n SQL.check.isEmpty(filterQuery)\n ? SQL.EMPTY\n : SQL.merge([SQL`WHERE `, filterQuery]);\n","import { dumbo, JSONSerializer } from '@event-driven-io/dumbo';\nimport {\n pgDumboDriver as dumboDriver,\n PgDriverType,\n postgreSQLMetadata,\n type PgConnection,\n} from '@event-driven-io/dumbo/pg';\nimport type pg from 'pg';\nimport {\n PongoCollectionSchemaComponent,\n PongoDatabase,\n PongoDatabaseSchemaComponent,\n pongoDriverRegistry,\n pongoSchema,\n type PongoDb,\n type PongoDriver,\n type PongoDriverOptions,\n} from '../../../core';\nimport {\n pongoCollectionPostgreSQLMigrations,\n postgresSQLBuilder,\n} from '../core';\n\nexport type PgPongoClientOptions =\n PooledPongoClientOptions | NotPooledPongoOptions;\n\nexport type PooledPongoClientOptions =\n | {\n pool: pg.Pool;\n }\n | {\n pooled: true;\n }\n | {\n pool: pg.Pool;\n pooled: true;\n }\n | object;\n\nexport type NotPooledPongoOptions =\n | {\n client: pg.Client;\n }\n | {\n pooled: false;\n }\n | {\n client: pg.Client;\n pooled: false;\n }\n | {\n connection: PgConnection;\n pooled?: false;\n };\n\ntype PgDatabaseDriverOptions = PongoDriverOptions<PgPongoClientOptions> & {\n databaseName?: string | undefined;\n connectionString: string;\n};\n\nconst pgPongoDriver: PongoDriver<\n PongoDb<PgDriverType>,\n PgDatabaseDriverOptions\n> = {\n driverType: PgDriverType,\n databaseFactory: (options) => {\n const databaseName =\n options.databaseName ??\n postgreSQLMetadata.parseDatabaseName(options.connectionString) ??\n postgreSQLMetadata.defaultDatabaseName;\n\n return PongoDatabase({\n ...options,\n pool: dumbo({\n connectionString: options.connectionString,\n driver: dumboDriver,\n ...options.connectionOptions,\n serialization: { serializer: options.serializer },\n }),\n schemaComponent: PongoDatabaseSchemaComponent({\n driverType: PgDriverType,\n collectionFactory: (schema) =>\n PongoCollectionSchemaComponent({\n driverType: PgDriverType,\n definition: schema,\n migrationsOrSchemaComponents: {\n migrations: pongoCollectionPostgreSQLMigrations(schema.name),\n },\n sqlBuilder: postgresSQLBuilder(\n schema.name,\n options.serialization?.serializer ?? JSONSerializer,\n ),\n }),\n definition:\n options.schema?.definition ?? pongoSchema.db(databaseName, {}),\n }),\n databaseName,\n });\n },\n};\n\nexport const usePgPongoDriver = () => {\n pongoDriverRegistry.register(PgDriverType, pgPongoDriver);\n};\n\nusePgPongoDriver();\n\nexport { pgPongoDriver as pgDriver, pgPongoDriver as pongoDriver };\n"],"mappings":";;;;;;;;AAKA,MAAa,kBACX,MACA,UACA,OACA,eACQ;AACR,KAAI,SAAS,SAAS,SAAS,WAC7B,QAAO,uBAAuB,MAAM,UAAU,MAAM;AAGtD,SAAQ,UAAR;EACE,KAAK,OAAO;GACV,MAAM,QAAQA,iDAAe,MAAM,0BAAG,QAAQ,KAAK;AAInD,UAAO,0BAAG,IAAI,MAAM,KAHIC,iCAAU,MAAM,OAAO,WAGP,CAAC,aAAa,MAAM,MAF/BA,iCAAU,gBAAgB,OAAO,WAEwB,CAAC;;EAEzF,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK,MAGH,QAAO,0BAAG,GAFID,iDAAe,UAAU,0BAAG,QAAQ,KAEhC,CAAC,GAAGE,2BAAI,MAAMC,yBAAY,UAAU,CAAC,GAAG;EAE5D,KAAK,MAGH,QAAO,0BAAG,GAFIH,iDAAe,UAAU,0BAAG,QAAQ,KAEhC,CAAC,UAAU,MAAM;EAErC,KAAK,OAGH,QAAO,0BAAG,GAFIA,iDAAe,UAAU,0BAAG,QAAQ,KAEhC,CAAC,WAAW,MAAM;EAEtC,KAAK,cAAc;GACjB,MAAM,QAAQA,iDAAe,MAAM,0BAAG,QAAQ,KAAK;AAGnD,UAAO,0BAAG;;oCAEoB,AAJXE,0BAAG,0BAA0B,MAAM,mBAAmB,MAAM,uBAItC;8BAHjBD,iCAAU,MAAM,OAAO,WAIR,CAAC;;;EAG1C,KAAK,QAAQ;GACX,MAAM,kBAAkBA,iCAAU,MAAM,OAAO,WAAW;AAC1D,UAAO,0BAAG,GAAGD,iDAAe,MAAM,0BAAG,QAAQ,KAAK,CAAC,MAAM,gBAAgB;;EAE3E,KAAK,QACH,QAAO,0BAAG,sBAAsBA,iDAAe,MAAM,0BAAG,QAAQ,KAAK,CAAC,MAAM;EAE9E,QACE,OAAM,IAAI,MAAM,yBAAyB,WAAW;;;AAI1D,MAAM,0BACJ,WACA,UACA,UACQ;AACR,SAAQ,UAAR;EACE,KAAK,MACH,QAAO,0BAAG,GAAGE,2BAAI,MAAM,UAAU,CAAC,KAAK;EACzC,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK,MACH,QAAO,0BAAG,GAAGA,2BAAI,MAAM,UAAU,CAAC,GAAGA,2BAAI,MAAMC,yBAAY,UAAU,CAAC,GAAG;EAC3E,KAAK,MACH,QAAO,0BAAG,GAAGD,2BAAI,MAAM,UAAU,CAAC,UAAU,MAAM;EACpD,KAAK,OACH,QAAO,0BAAG,GAAGA,2BAAI,MAAM,UAAU,CAAC,WAAW,MAAM;EACrD,QACE,OAAM,IAAI,MAAM,yBAAyB,WAAW;;;;;;ACvE1D,MAAM,MAAM;AACZ,MAAM,KAAK;AAEX,MAAM,2BAA2B;CAAC;CAAS;CAAU;CAAW;AAEhE,MAAa,wBACX,QACA,eACQ;AACR,8BAA6B,OAAO;CACpC,MAAM,QAAe,EAAE;CAEvB,MAAM,mBAAmB,0BAA0B,QAAQ,WAAW;AACtE,KAAI,CAACE,2BAAI,MAAM,QAAQ,iBAAiB,CACtC,OAAM,KAAK,iBAAiB;CAG9B,MAAM,gBAAgB,4BAA4B,OAAO,KAAK,IAAI,WAAW;AAC7E,KAAI,CAACA,2BAAI,MAAM,QAAQ,cAAc,CACnC,OAAM,KAAK,cAAc;CAG3B,MAAM,iBAAiB,4BACrB,OAAO,MACP,KACA,WACD;AACD,KAAI,CAACA,2BAAI,MAAM,QAAQ,eAAe,CACpC,OAAM,KAAK,eAAe;CAG5B,MAAM,iBAAiB,wBAAwB,OAAO,MAAM,WAAW;AACvE,KAAI,CAACA,2BAAI,MAAM,QAAQ,eAAe,CACpC,OAAM,KAAK,eAAe;AAG5B,QAAOA,2BAAI,MAAM,OAAO,IAAI,IAAI,GAAG;;AAGrC,MAAM,6BACJ,QACA,eAEAA,2BAAI,MACFC,2BAAc,OAAO,CAAC,SAAS,CAAC,KAAK,WACnC,sBAAsB,IAAI,GACtB,EAAE,GACF,CACE,SAAS,MAAM,GACX,4BAA4B,KAAK,OAAO,WAAW,GACnD,eAAe,KAAKC,4BAAe,KAAK,OAAO,WAAW,CAC/D,CACN,EACD,IAAI,IAAI,GACT;AAEH,MAAM,+BACJ,SACA,cACA,eACQ;AACR,KAAI,CAAC,SAAS,OACZ,QAAOF,2BAAI;CAGb,MAAM,mBAAmB,QAAQ,QAAe,SAAS,WAAW;EAClE,MAAM,QAAQ,qBAAqB,QAAQ,WAAW;AACtD,MAAI,CAACA,2BAAI,MAAM,QAAQ,MAAM,CAC3B,SAAQ,KAAK,MAAM;AAGrB,SAAO;IACN,EAAE,CAAC;AAEN,KAAI,iBAAiB,WAAW,EAC9B,QAAOA,2BAAI;AAGb,KAAI,iBAAiB,WAAW,EAC9B,QAAO,gBAAgB,iBAAiB,GAAI;AAG9C,QAAO,0BAAG,IAAIA,2BAAI,MAAM,iBAAiB,IAAI,gBAAgB,EAAE,IAAI,aAAa,GAAG,CAAC;;AAGtF,MAAM,2BACJ,SACA,eACQ;AACR,KAAI,CAAC,SAAS,OACZ,QAAOA,2BAAI;CAGb,MAAM,qBAAqB,4BACzB,SACA,IACA,WACD;AACD,QAAOA,2BAAI,MAAM,QAAQ,mBAAmB,GACxCA,2BAAI,QACJ,0BAAG,OAAO;;AAGhB,MAAM,+BACJ,KACA,OACA,eACQ;CACR,MAAM,aAAa,CAACG,0BAAa,MAAM;AAEvC,QAAOH,2BAAI,MACTC,2BAAc,MAAM,CAAC,KAAK,CAAC,WAAW,SACpC,aACI,eACE,GAAG,IAAI,GAAG,aACVC,4BAAe,KACf,KACA,WACD,GACD,eAAe,KAAK,WAAW,KAAK,WAAW,CACpD,EACD,IAAI,IAAI,GACT;;AAGH,MAAM,mBAAmB,gBAA0B,0BAAG,IAAI,YAAY;AAEtE,MAAM,gCAAgC,WAAyB;AAC7D,MAAK,MAAM,YAAY,yBACrB,KAAI,YAAY,OACd,OAAM,IAAI,MAAM,8BAA8B,WAAW;;AAK/D,MAAM,yBAAyB,QAC7B,QAAQ,UAAU,QAAQ,UAAU,QAAQ;AAE9C,MAAM,YAAY,UAChB,UAAU,QAAQ,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,MAAM;;;;AC3ItE,MAAa,oBACX,QACA,eAEAE,2BAAc,OAAO,CAAC,QACnB,oBAAoB,CAAC,IAAI,WAAW;AACnC,SAAQ,IAAR;EACE,KAAK,OACH,QAAO,cAAc,OAAO,oBAAoB,WAAW;EAC7D,KAAK,SACH,QAAO,gBAAgB,OAAO,mBAAmB;EACnD,KAAK,OACH,QAAO,cAAc,OAAO,mBAAmB;EACjD,KAAK,QACH,QAAO,eAAe,OAAO,oBAAoB,WAAW;EAC9D,QACE,QAAO;;GAGb,0BAAG,OACJ;AAEH,MAAa,iBACX,KACA,oBACA,eAEA,0BAAG,GAAG,mBAAmB,MAAMC,iCAAU,MAAM,KAAK,WAAW,CAAC;AAElE,MAAa,mBACX,OACA,uBACQ;CACR,IAAI,QAAQ;AACZ,MAAK,MAAM,OAAO,OAAO,KAAK,MAAM,CAClC,SAAQ,0BAAG,GAAG,MAAM,KAAK;AAE3B,QAAO;;AAGT,MAAa,iBACX,KACA,uBACQ;AACR,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,IAAI,CAC5C,sBACE,OAAO,UAAU,WACb,0BAAG,aAAa,mBAAmB,IAAIC,iDAAe,KAAK,IAAI,CAAC,wBAAwBA,iDAAe,UAAU,0BAAG,QAAQ,IAAI,CAAC,kBAAkB,MAAM,mBACzJ,0BAAG,aAAa,mBAAmB,IAAIA,iDAAe,KAAK,IAAI,CAAC,uBAAuBA,iDAAe,UAAU,0BAAG,QAAQ,IAAI,CAAC,mBAAmB,MAAM;AAEjK,QAAO;;AAGT,MAAa,kBACX,MACA,oBACA,eACQ;AACR,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,KAAK,EAAE;EAC/C,MAAM,kBAAkBD,iCAAU,gBAAgB,OAAO,WAAW;AACpE,uBAAqB,0BAAG,aAAa,mBAAmB,IAAIC,iDAAe,KAAK,IAAI,CAAC,cAAcA,iDAAe,MAAM,0BAAG,QAAQ,IAAI,CAAC,oBAAoB,gBAAgB;;AAE9K,QAAO;;;;;ACrDT,MAAM,sBACJ,gBACA,oBACQ;CACR,MAAM,MAAMC,2BAAI,WAAW,eAAe;CAC1C,MAAM,YAAYC,sCAAyB,gBAAgB;AAC3D,QAAO,UAAU,aAAa,SAC1BD,2BAAI,QACJ,0BAAG,OAAO,IAAI,cAAc,UAAU;;AAG5C,MAAM,oBAAoB,mBACxB,0BAAG;iCAC4BA,2BAAI,WAAW,eAAe,CAAC;;;;;;;;;;AAWhE,MAAa,uCAAuC,mBAA2B,0CAChE,mBAAmB,eAAe,mBAAmB,CAChE,iBAAiB,eAAe,CACjC,CAAC,CACH;AAED,MAAa,sBACX,gBACA,gBAC+B;CAC/B,wBAA6B,iBAAiB,eAAe;CAC7D,YAAe,aAAyD;EACtE,MAAM,aAAaE,iCAAU,SAAS,UAAU,WAAW;EAC3D,MAAM,KAAK,SAAS;EACpB,MAAM,UAAU,SAAS,YAAY;AAErC,SAAO,0BAAG;oBACMF,2BAAI,WAAW,eAAe,CAAC;gBACnC,GAAG,IAAI,WAAW,IAAI,QAAQ;;CAE5C,aAAgB,cAA4D;EAC1E,MAAM,SAASA,2BAAI,MACjB,UAAU,KACP,QACC,0BAAG,IAAI,IAAI,IAAI,IAAIE,iCAAU,SAAS,KAAK,WAAW,CAAC,IAAI,IAAI,YAAY,GAAG,GACjF,EACD,IACD;AAED,SAAO,0BAAG;oBACMF,2BAAI,WAAW,eAAe,CAAC,gCAAgC,OAAO;;;;CAIxF,kBAAqB,cAAqC;EACxD,MAAM,MAAMA,2BAAI,WAAW,eAAe;AAS1C,SAAO,0BAAG;oBACM,IAAI;eATLA,2BAAI,MACjB,UAAU,KACP,MACC,0BAAG,IAAI,EAAE,IAAI,UAAUE,iCAAU,SAAS,GAAG,WAAW,CAAC,uCAAuC,EAAE,IAAI,kEACzG,EACD,IAKe,CAAC;;;yCAGmB,IAAI;+CACE,IAAI;qBAC9B,IAAI;;;CAGvB,YACE,QACA,QACA,YACQ;EACR,MAAM,wBAAwB,mBAC5B,gBACA,SAAS,gBACV;EAED,MAAM,gDAAoB,OAAO,GAC7B,SACA,qBAAqB,QAAQ,WAAW;EAC5C,MAAM,gDAAoB,OAAO,GAC7B,SACA,iBAAiB,QAAQ,WAAW;AAExC,SAAO,0BAAG;;;eAGCF,2BAAI,WAAW,eAAe,CAAC,GAAG,MAAM,YAAY,CAAC;;;;iBAInDA,2BAAI,WAAW,eAAe,CAAC;;mBAE7B,YAAY,gCAAgCA,2BAAI,WAAW,eAAe,CAAC;;;gBAG9EA,2BAAI,WAAW,eAAe,CAAC,sBAAsB,sBAAsB;oBACvEA,2BAAI,WAAW,eAAe,CAAC,QAAQA,2BAAI,WAAW,eAAe,CAAC;;;;;;;;;;;CAWxF,aACE,QACA,UACA,YACQ;EACR,MAAM,wBAAwB,mBAC5B,gBACA,SAAS,gBACV;EAED,MAAM,gDAAoB,OAAO,GAC7B,SACA,qBAAqB,QAAQ,WAAW;AAE5C,SAAO,0BAAG;;;eAGCA,2BAAI,WAAW,eAAe,CAAC,GAAG,MAAM,YAAY,CAAC;;;;iBAInDA,2BAAI,WAAW,eAAe,CAAC;;mBAE7BE,iCAAU,SAAS,UAAU,WAAW,CAAC,gCAAgCF,2BAAI,WAAW,eAAe,CAAC;;;gBAG3GA,2BAAI,WAAW,eAAe,CAAC,sBAAsB,sBAAsB;oBACvEA,2BAAI,WAAW,eAAe,CAAC,QAAQA,2BAAI,WAAW,eAAe,CAAC;;;;;;;;;;;CAWxF,aACE,QACA,WACQ;EACR,MAAM,gDAAoB,OAAO,GAC7B,SACA,qBAAqB,QAAQ,WAAW;EAC5C,MAAM,gDAAoB,OAAO,GAC7B,SACA,iBAAiB,QAAQ,WAAW;AAExC,SAAO,0BAAG;eACCA,2BAAI,WAAW,eAAe,CAAC;;iBAE7B,YAAY;;QAErB,MAAM,YAAY,CAAC;;CAEzB,YACE,QACA,YACQ;EACR,MAAM,wBAAwB,mBAC5B,gBACA,SAAS,gBACV;EAED,MAAM,gDAAoB,OAAO,GAC7B,SACA,qBAAqB,QAAQ,WAAW;AAE5C,SAAO,0BAAG;;;eAGCA,2BAAI,WAAW,eAAe,CAAC,GAAG,MAAM,YAAY,CAAC;;;;sBAI9CA,2BAAI,WAAW,eAAe,CAAC;;gBAErCA,2BAAI,WAAW,eAAe,CAAC,sBAAsB,sBAAsB;oBACvEA,2BAAI,WAAW,eAAe,CAAC;;;;;;;;;;CAUjD,aAAgB,WAAsC;EACpD,MAAM,gDAAoB,OAAO,GAC7B,SACA,qBAAqB,QAAQ,WAAW;AAE5C,SAAO,0BAAG,eAAeA,2BAAI,WAAW,eAAe,CAAC,GAAG,MAAM,YAAY;;CAE/E,cACE,cACQ;AAKR,MAJoB,UAAU,MAC3B,MAAM,cAAc,KAAK,EAAE,aAAa,OAG5B,CAUb,QAAO,0BAAG;;mBATKA,2BAAI,MACjB,UAAU,KAAK,MAAM;GACnB,MAAM,kBAAmB,EAA0B;AACnD,UAAO,oBAAoB,SACvB,0BAAG,IAAI,EAAE,IAAI,UAAUE,iCAAU,SAAS,GAAG,WAAW,CAAC,WAAW,gBAAgB,aACpF,0BAAG,IAAI,EAAE,IAAI,UAAUA,iCAAU,SAAS,GAAG,WAAW,CAAC;IAC7D,EACF,IAIiB,CAAC;;iBAETF,2BAAI,WAAW,eAAe,CAAC;;;;;;;;;AAkB5C,SAAO,0BAAG;;iBAPKA,2BAAI,MACjB,UAAU,KACP,MACC,0BAAG,IAAI,EAAE,IAAI,UAAUE,iCAAU,SAAS,GAAG,WAAW,CAAC,UAC5D,EACD,IAIiB,CAAC;;eAETF,2BAAI,WAAW,eAAe,CAAC;;;;;;;;;;CAU5C,kBAAkB,QAAwD;AAGxE,MAFoB,IAAI,MAAM,MAAM,EAAE,aAAa,OAEpC,CAMb,QAAO,0BAAG;;mBALKA,2BAAI,MACjB,IAAI,KAAK,MAAM,0BAAG,IAAI,EAAE,IAAI,UAAU,EAAE,YAAY,GAAG,WAAW,EAClE,IAKiB,CAAC;;;wBAGFA,2BAAI,WAAW,eAAe,CAAC;;;;;;;;;AAgBnD,SAAO,0BAAG;;iBALKA,2BAAI,MACjB,IAAI,KAAK,MAAM,0BAAG,IAAI,EAAE,IAAI,SAAS,EACrC,IAKiB,CAAC;;;sBAGFA,2BAAI,WAAW,eAAe,CAAC;;;;;;;;;;CAUnD,UAAa,WAAsC;EACjD,MAAM,gDAAoB,OAAO,GAC7B,SACA,qBAAqB,QAAQ,WAAW;AAE5C,SAAO,0BAAG,mCAAmCA,2BAAI,WAAW,eAAe,CAAC,GAAG,MAAM,YAAY,CAAC;;CAEpG,OAAU,QAA8B,YAA+B;EACrE,MAAM,gDAAoB,OAAO,GAC7B,SACA,qBAAqB,QAAQ,WAAW;EAC5C,MAAM,QAAe,EAAE;AAEvB,QAAM,KACJ,0BAAG,mCAAmCA,2BAAI,WAAW,eAAe,GACrE;AAED,QAAM,KAAK,MAAM,YAAY,CAAC;AAE9B,MAAI,SAAS,QAAQ,OAAO,KAAK,QAAQ,KAAK,CAAC,SAAS,GAAG;GACzD,MAAM,UAAU,OAAO,QAAQ,QAAQ,KAAK,CAAC,KAAK,CAAC,OAAO,SAAS;IAKjE,MAAM,WAJa,UAAU,SAAS,UAAU,aAK5C,0BAAG,GAAGA,2BAAI,MAAM,MAAM,KACtBG,iDAAe,MAAM,0BAAG,QAAQ,MAAM;AAG1C,WAAO,QAAQ,IACX,0BAAG,GAAG,SAAS,oBACf,0BAAG,GAAG,SAAS;KACnB;AACF,SAAM,KAAK,0BAAG,YAAYH,2BAAI,MAAM,SAAS,IAAI,GAAG;;AAGtD,MAAI,SAAS,MACX,OAAM,KAAK,0BAAG,SAAS,QAAQ,QAAQ;AAGzC,MAAI,SAAS,KACX,OAAM,KAAK,0BAAG,UAAU,QAAQ,OAAO;AAGzC,SAAOA,2BAAI,MAAM,CAAC,GAAG,OAAO,0BAAG,IAAI,CAAC;;CAEtC,iBAAoB,WAAsC;EACxD,MAAM,cAAcA,2BAAI,MAAM,MAAM,OAAO,GACvC,SACA,qBAAqB,QAAQ,WAAW;AAC5C,SAAO,0BAAG,iCAAiCA,2BAAI,WAAW,eAAe,CAAC,GAAG,MAAM,YAAY,CAAC;;CAElG,SAAS,YACP,0BAAG,eAAeA,2BAAI,WAAW,eAAe,CAAC,aAAaA,2BAAI,WAAW,QAAQ,CAAC;CACxF,OAAO,aAAqB,mBAC1B,0BAAG,wBAAwBA,2BAAI,WAAW,WAAW;CACxD;AAED,MAAM,SAAS,gBACbA,2BAAI,MAAM,QAAQ,YAAY,GAC1BA,2BAAI,QACJA,2BAAI,MAAM,CAAC,0BAAG,UAAU,YAAY,CAAC;;;;AChV3C,MAAM,gBAGF;CACF,YAAYI;CACZ,kBAAkB,YAAY;EAC5B,MAAM,eACJ,QAAQ,gBACRC,6CAAmB,kBAAkB,QAAQ,iBAAiB,IAC9DA,6CAAmB;AAErB,SAAOC,2BAAc;GACnB,GAAG;GACH,wCAAY;IACV,kBAAkB,QAAQ;IAC1B,QAAQC;IACR,GAAG,QAAQ;IACX,eAAe,EAAE,YAAY,QAAQ,YAAY;IAClD,CAAC;GACF,iBAAiBC,0CAA6B;IAC5C,YAAYJ;IACZ,oBAAoB,WAClBK,4CAA+B;KAC7B,YAAYL;KACZ,YAAY;KACZ,8BAA8B,EAC5B,YAAY,oCAAoC,OAAO,KAAK,EAC7D;KACD,YAAY,mBACV,OAAO,MACP,QAAQ,eAAe,cAAcM,sCACtC;KACF,CAAC;IACJ,YACE,QAAQ,QAAQ,cAAcC,yBAAY,GAAG,cAAc,EAAE,CAAC;IACjE,CAAC;GACF;GACD,CAAC;;CAEL;AAED,MAAa,yBAAyB;AACpC,kCAAoB,SAASP,wCAAc,cAAc;;AAG3D,kBAAkB"}
|
package/dist/pg.js
CHANGED
|
@@ -1,29 +1,36 @@
|
|
|
1
1
|
import { C as expectedVersionPredicate, F as hasOperators, L as PongoCollectionSchemaComponent, N as OperatorMap, P as QueryOperators, d as PongoDatabase, f as PongoDatabaseSchemaComponent, j as objectEntries, p as pongoSchema, u as pongoDriverRegistry } from "./core-BHdOCUrr.js";
|
|
2
|
-
import { JSONSerializer, SQL, dumbo, isSQL, sqlMigration } from "@event-driven-io/dumbo";
|
|
2
|
+
import { JSONParam, JSONSerializer, SQL, dumbo, isSQL, sqlMigration } from "@event-driven-io/dumbo";
|
|
3
3
|
import { PgDriverType, pgDumboDriver, postgreSQLMetadata } from "@event-driven-io/dumbo/pg";
|
|
4
|
+
import { PostgreSQLJSON } from "@event-driven-io/dumbo/postgresql";
|
|
4
5
|
|
|
5
6
|
//#region src/storage/postgresql/core/sqlBuilder/filter/queryOperators.ts
|
|
6
7
|
const handleOperator = (path, operator, value, serializer) => {
|
|
7
8
|
if (path === "_id" || path === "_version") return handleMetadataOperator(path, operator, value);
|
|
8
9
|
switch (operator) {
|
|
9
10
|
case "$eq": {
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
return SQL`(data @> ${nestedPath}::jsonb OR jsonb_path_exists(data, '$.${SQL.plain(path)}[*] ? (@ == ${SQL.plain(serializedValue)})'))`;
|
|
11
|
+
const field = PostgreSQLJSON.field(SQL`data`, path);
|
|
12
|
+
return SQL`(${field} = ${JSONParam.value(value, serializer)}::jsonb OR ${field} @> ${JSONParam.arrayContaining(value, serializer)}::jsonb)`;
|
|
13
13
|
}
|
|
14
14
|
case "$gt":
|
|
15
15
|
case "$gte":
|
|
16
16
|
case "$lt":
|
|
17
17
|
case "$lte":
|
|
18
|
-
case "$ne": return SQL`data
|
|
19
|
-
case "$in": return SQL`data
|
|
20
|
-
case "$nin": return SQL`data
|
|
18
|
+
case "$ne": return SQL`${PostgreSQLJSON.textField(SQL`data`, path)} ${SQL.plain(OperatorMap[operator])} ${value}`;
|
|
19
|
+
case "$in": return SQL`${PostgreSQLJSON.textField(SQL`data`, path)} = ANY (${value})`;
|
|
20
|
+
case "$nin": return SQL`${PostgreSQLJSON.textField(SQL`data`, path)} != ALL (${value})`;
|
|
21
21
|
case "$elemMatch": {
|
|
22
|
-
const
|
|
23
|
-
return SQL`
|
|
22
|
+
const field = PostgreSQLJSON.field(SQL`data`, path);
|
|
23
|
+
return SQL`EXISTS (
|
|
24
|
+
SELECT 1
|
|
25
|
+
FROM jsonb_array_elements(${SQL`CASE WHEN jsonb_typeof(${field}) = 'array' THEN ${field} ELSE '[]'::jsonb END`}) AS elem(value)
|
|
26
|
+
WHERE elem.value @> ${JSONParam.value(value, serializer)}::jsonb
|
|
27
|
+
)`;
|
|
24
28
|
}
|
|
25
|
-
case "$all":
|
|
26
|
-
|
|
29
|
+
case "$all": {
|
|
30
|
+
const serializedValue = JSONParam.value(value, serializer);
|
|
31
|
+
return SQL`${PostgreSQLJSON.field(SQL`data`, path)} @> ${serializedValue}::jsonb`;
|
|
32
|
+
}
|
|
33
|
+
case "$size": return SQL`jsonb_array_length(${PostgreSQLJSON.field(SQL`data`, path)}) = ${value}`;
|
|
27
34
|
default: throw new Error(`Unsupported operator: ${operator}`);
|
|
28
35
|
}
|
|
29
36
|
};
|
|
@@ -40,7 +47,6 @@ const handleMetadataOperator = (fieldName, operator, value) => {
|
|
|
40
47
|
default: throw new Error(`Unsupported operator: ${operator}`);
|
|
41
48
|
}
|
|
42
49
|
};
|
|
43
|
-
const buildNestedObject = (path, value) => path.split(".").reverse().reduce((acc, key) => ({ [key]: acc }), value);
|
|
44
50
|
|
|
45
51
|
//#endregion
|
|
46
52
|
//#region src/storage/postgresql/core/sqlBuilder/filter/index.ts
|
|
@@ -103,16 +109,20 @@ const buildUpdateQuery = (update, serializer) => objectEntries(update).reduce((c
|
|
|
103
109
|
default: return currentUpdateQuery;
|
|
104
110
|
}
|
|
105
111
|
}, SQL`data`);
|
|
106
|
-
const buildSetQuery = (set, currentUpdateQuery, serializer) => SQL`${currentUpdateQuery} || ${
|
|
107
|
-
const buildUnsetQuery = (unset, currentUpdateQuery) =>
|
|
112
|
+
const buildSetQuery = (set, currentUpdateQuery, serializer) => SQL`${currentUpdateQuery} || ${JSONParam.value(set, serializer)}::jsonb`;
|
|
113
|
+
const buildUnsetQuery = (unset, currentUpdateQuery) => {
|
|
114
|
+
let query = currentUpdateQuery;
|
|
115
|
+
for (const key of Object.keys(unset)) query = SQL`${query} - ${key}`;
|
|
116
|
+
return query;
|
|
117
|
+
};
|
|
108
118
|
const buildIncQuery = (inc, currentUpdateQuery) => {
|
|
109
|
-
for (const [key, value] of Object.entries(inc)) currentUpdateQuery = typeof value === "bigint" ? SQL`jsonb_set(${currentUpdateQuery},
|
|
119
|
+
for (const [key, value] of Object.entries(inc)) currentUpdateQuery = typeof value === "bigint" ? SQL`jsonb_set(${currentUpdateQuery}, ${PostgreSQLJSON.path(key)}, to_jsonb((COALESCE((${PostgreSQLJSON.textField(SQL`data`, key)})::BIGINT, 0) + ${value})::TEXT), true)` : SQL`jsonb_set(${currentUpdateQuery}, ${PostgreSQLJSON.path(key)}, to_jsonb(COALESCE((${PostgreSQLJSON.textField(SQL`data`, key)})::NUMERIC, 0) + ${value}), true)`;
|
|
110
120
|
return currentUpdateQuery;
|
|
111
121
|
};
|
|
112
122
|
const buildPushQuery = (push, currentUpdateQuery, serializer) => {
|
|
113
123
|
for (const [key, value] of Object.entries(push)) {
|
|
114
|
-
const serializedValue =
|
|
115
|
-
currentUpdateQuery = SQL`jsonb_set(${currentUpdateQuery},
|
|
124
|
+
const serializedValue = JSONParam.arrayContaining(value, serializer);
|
|
125
|
+
currentUpdateQuery = SQL`jsonb_set(${currentUpdateQuery}, ${PostgreSQLJSON.path(key)}, (coalesce(${PostgreSQLJSON.field(SQL`data`, key)}, '[]'::jsonb) || ${serializedValue}::jsonb), true)`;
|
|
116
126
|
}
|
|
117
127
|
return currentUpdateQuery;
|
|
118
128
|
};
|
|
@@ -139,7 +149,7 @@ const pongoCollectionPostgreSQLMigrations = (collectionName) => [sqlMigration(`p
|
|
|
139
149
|
const postgresSQLBuilder = (collectionName, serializer) => ({
|
|
140
150
|
createCollection: () => createCollection(collectionName),
|
|
141
151
|
insertOne: (document) => {
|
|
142
|
-
const serialized =
|
|
152
|
+
const serialized = JSONParam.document(document, serializer);
|
|
143
153
|
const id = document._id;
|
|
144
154
|
const version = document._version ?? 1n;
|
|
145
155
|
return SQL`
|
|
@@ -147,7 +157,7 @@ const postgresSQLBuilder = (collectionName, serializer) => ({
|
|
|
147
157
|
VALUES (${id}, ${serialized}, ${version}) ON CONFLICT(_id) DO NOTHING;`;
|
|
148
158
|
},
|
|
149
159
|
insertMany: (documents) => {
|
|
150
|
-
const values = SQL.merge(documents.map((doc) => SQL`(${doc._id}, ${
|
|
160
|
+
const values = SQL.merge(documents.map((doc) => SQL`(${doc._id}, ${JSONParam.document(doc, serializer)}, ${doc._version ?? 1n})`), ",");
|
|
151
161
|
return SQL`
|
|
152
162
|
INSERT INTO ${SQL.identifier(collectionName)} (_id, data, _version) VALUES ${values}
|
|
153
163
|
ON CONFLICT(_id) DO NOTHING
|
|
@@ -157,7 +167,7 @@ const postgresSQLBuilder = (collectionName, serializer) => ({
|
|
|
157
167
|
const col = SQL.identifier(collectionName);
|
|
158
168
|
return SQL`
|
|
159
169
|
INSERT INTO ${col} (_id, data, _version)
|
|
160
|
-
VALUES ${SQL.merge(documents.map((d) => SQL`(${d._id}::text, ${
|
|
170
|
+
VALUES ${SQL.merge(documents.map((d) => SQL`(${d._id}::text, ${JSONParam.document(d, serializer)}::jsonb || jsonb_build_object('_id', ${d._id}::text) || jsonb_build_object('_version', '1'::text), 1::bigint)`), ",")}
|
|
161
171
|
ON CONFLICT(_id) DO UPDATE SET
|
|
162
172
|
data = EXCLUDED.data
|
|
163
173
|
|| jsonb_build_object('_id', ${col}._id)
|
|
@@ -205,7 +215,7 @@ const postgresSQLBuilder = (collectionName, serializer) => ({
|
|
|
205
215
|
updated AS (
|
|
206
216
|
UPDATE ${SQL.identifier(collectionName)}
|
|
207
217
|
SET
|
|
208
|
-
data = ${
|
|
218
|
+
data = ${JSONParam.document(document, serializer)} || jsonb_build_object('_id', ${SQL.identifier(collectionName)}._id) || jsonb_build_object('_version', (_version + 1)::text),
|
|
209
219
|
_version = _version + 1
|
|
210
220
|
FROM existing
|
|
211
221
|
WHERE ${SQL.identifier(collectionName)}._id = existing._id ${expectedVersionUpdate}
|
|
@@ -262,7 +272,7 @@ const postgresSQLBuilder = (collectionName, serializer) => ({
|
|
|
262
272
|
WITH replacements(_id, data, expected_version) AS (
|
|
263
273
|
VALUES ${SQL.merge(documents.map((d) => {
|
|
264
274
|
const expectedVersion = d._version;
|
|
265
|
-
return expectedVersion !== void 0 ? SQL`(${d._id}::text, ${
|
|
275
|
+
return expectedVersion !== void 0 ? SQL`(${d._id}::text, ${JSONParam.document(d, serializer)}::jsonb, ${expectedVersion}::bigint)` : SQL`(${d._id}::text, ${JSONParam.document(d, serializer)}::jsonb, NULL::bigint)`;
|
|
266
276
|
}), ",")}
|
|
267
277
|
)
|
|
268
278
|
UPDATE ${SQL.identifier(collectionName)} t
|
|
@@ -276,7 +286,7 @@ const postgresSQLBuilder = (collectionName, serializer) => ({
|
|
|
276
286
|
RETURNING t._id, t._version AS version;`;
|
|
277
287
|
return SQL`
|
|
278
288
|
WITH replacements(_id, data) AS (
|
|
279
|
-
VALUES ${SQL.merge(documents.map((d) => SQL`(${d._id}::text, ${
|
|
289
|
+
VALUES ${SQL.merge(documents.map((d) => SQL`(${d._id}::text, ${JSONParam.document(d, serializer)}::jsonb)`), ",")}
|
|
280
290
|
)
|
|
281
291
|
UPDATE ${SQL.identifier(collectionName)} t
|
|
282
292
|
SET
|
|
@@ -329,9 +339,7 @@ const postgresSQLBuilder = (collectionName, serializer) => ({
|
|
|
329
339
|
query.push(where(filterQuery));
|
|
330
340
|
if (options?.sort && Object.keys(options.sort).length > 0) {
|
|
331
341
|
const clauses = Object.entries(options.sort).map(([field, dir]) => {
|
|
332
|
-
const
|
|
333
|
-
const isNested = !isMetadata && field.includes(".");
|
|
334
|
-
const accessor = isMetadata ? SQL`${SQL.plain(field)}` : isNested ? SQL`data #> '${SQL.plain(`{${field.split(".").join(",")}}`)}'` : SQL`data -> '${SQL.plain(field)}'`;
|
|
342
|
+
const accessor = field === "_id" || field === "_version" ? SQL`${SQL.plain(field)}` : PostgreSQLJSON.field(SQL`data`, field);
|
|
335
343
|
return dir === 1 ? SQL`${accessor} ASC NULLS FIRST` : SQL`${accessor} DESC NULLS LAST`;
|
|
336
344
|
});
|
|
337
345
|
query.push(SQL`ORDER BY ${SQL.merge(clauses, ",")}`);
|