@event-driven-io/pongo 0.17.0-beta.4 → 0.17.0-beta.40
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 +311 -487
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.d.cts +4 -4
- package/dist/cli.d.ts +4 -3
- package/dist/cli.js +279 -487
- package/dist/cli.js.map +1 -1
- package/dist/cloudflare.cjs +41 -0
- package/dist/cloudflare.cjs.map +1 -0
- package/dist/cloudflare.d.cts +12 -0
- package/dist/cloudflare.d.ts +12 -0
- package/dist/cloudflare.js +35 -0
- package/dist/cloudflare.js.map +1 -0
- package/dist/core-BHdOCUrr.js +1429 -0
- package/dist/core-BHdOCUrr.js.map +1 -0
- package/dist/core-C9SB3XMx.cjs +1717 -0
- package/dist/core-C9SB3XMx.cjs.map +1 -0
- package/dist/core-CH0SOCr3.js +361 -0
- package/dist/core-CH0SOCr3.js.map +1 -0
- package/dist/core-CkmE5dkK.cjs +373 -0
- package/dist/core-CkmE5dkK.cjs.map +1 -0
- package/dist/index-C3pnS1S_.d.cts +720 -0
- package/dist/index-CZOmOsQt.d.ts +10 -0
- package/dist/index-FXnldVnn.d.cts +10 -0
- package/dist/index-r7V4paf_.d.ts +720 -0
- package/dist/index.cjs +67 -74
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +16 -105
- package/dist/index.d.ts +16 -105
- package/dist/index.js +17 -73
- package/dist/index.js.map +1 -1
- package/dist/pg.cjs +319 -288
- package/dist/pg.cjs.map +1 -1
- package/dist/pg.d.cts +29 -25
- package/dist/pg.d.ts +29 -25
- package/dist/pg.js +309 -284
- package/dist/pg.js.map +1 -1
- package/dist/shim.cjs +291 -368
- package/dist/shim.cjs.map +1 -1
- package/dist/shim.d.cts +141 -137
- package/dist/shim.d.ts +141 -137
- package/dist/shim.js +285 -367
- package/dist/shim.js.map +1 -1
- package/dist/sqlite3.cjs +43 -62
- package/dist/sqlite3.cjs.map +1 -1
- package/dist/sqlite3.d.cts +12 -11
- package/dist/sqlite3.d.ts +12 -11
- package/dist/sqlite3.js +36 -61
- package/dist/sqlite3.js.map +1 -1
- package/package.json +42 -44
- package/dist/chunk-4BL6YWLW.cjs +0 -872
- package/dist/chunk-4BL6YWLW.cjs.map +0 -1
- package/dist/chunk-ECQ2CKZE.cjs +0 -330
- package/dist/chunk-ECQ2CKZE.cjs.map +0 -1
- package/dist/chunk-NCNRRYVE.js +0 -872
- package/dist/chunk-NCNRRYVE.js.map +0 -1
- package/dist/chunk-Y7LRKJLJ.js +0 -330
- package/dist/chunk-Y7LRKJLJ.js.map +0 -1
- package/dist/d1.cjs +0 -53
- package/dist/d1.cjs.map +0 -1
- package/dist/d1.d.cts +0 -11
- package/dist/d1.d.ts +0 -11
- package/dist/d1.js +0 -53
- package/dist/d1.js.map +0 -1
- package/dist/index-BJopB-em.d.cts +0 -7
- package/dist/index-G5DECNb_.d.ts +0 -7
- package/dist/pongoCollectionSchemaComponent-t_e9n2Wc.d.cts +0 -426
- package/dist/pongoCollectionSchemaComponent-t_e9n2Wc.d.ts +0 -426
package/dist/pg.js
CHANGED
|
@@ -1,154 +1,131 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
PongoDatabase,
|
|
5
|
-
PongoDatabaseSchemaComponent,
|
|
6
|
-
QueryOperators,
|
|
7
|
-
expectedVersionValue,
|
|
8
|
-
hasOperators,
|
|
9
|
-
objectEntries,
|
|
10
|
-
pongoDatabaseDriverRegistry,
|
|
11
|
-
pongoSchema
|
|
12
|
-
} from "./chunk-NCNRRYVE.js";
|
|
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";
|
|
3
|
+
import { PgDriverType, pgDumboDriver, postgreSQLMetadata } from "@event-driven-io/dumbo/pg";
|
|
13
4
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}
|
|
39
|
-
case "$gt":
|
|
40
|
-
case "$gte":
|
|
41
|
-
case "$lt":
|
|
42
|
-
case "$lte":
|
|
43
|
-
case "$ne": {
|
|
44
|
-
const jsonPath = SQL.plain(path.split(".").join(","));
|
|
45
|
-
return SQL`data ->> '${jsonPath}' ${SQL.plain(OperatorMap[operator])} ${value}`;
|
|
46
|
-
}
|
|
47
|
-
case "$in": {
|
|
48
|
-
const jsonPath = `{${path.split(".").join(",")}}`;
|
|
49
|
-
return SQL`data #>> ${jsonPath} IN ${value}`;
|
|
50
|
-
}
|
|
51
|
-
case "$nin": {
|
|
52
|
-
const jsonPath = `{${path.split(".").join(",")}}`;
|
|
53
|
-
return SQL`data #>> ${jsonPath} NOT IN ${value}`;
|
|
54
|
-
}
|
|
55
|
-
case "$elemMatch": {
|
|
56
|
-
const subQuery = objectEntries(value).map(
|
|
57
|
-
([subKey, subValue]) => `@."${subKey}" == ${JSONSerializer.serialize(subValue)}`
|
|
58
|
-
).join(" && ");
|
|
59
|
-
return SQL`jsonb_path_exists(data, '$.${SQL.plain(path)}[*] ? (${SQL.plain(subQuery)})')`;
|
|
60
|
-
}
|
|
61
|
-
case "$all": {
|
|
62
|
-
const nestedPath = JSONSerializer.serialize(
|
|
63
|
-
buildNestedObject(path, value)
|
|
64
|
-
);
|
|
65
|
-
return SQL`data @> ${nestedPath}::jsonb`;
|
|
66
|
-
}
|
|
67
|
-
case "$size": {
|
|
68
|
-
const jsonPath = `{${path.split(".").join(",")}}`;
|
|
69
|
-
return SQL`jsonb_array_length(data #> ${jsonPath}) = ${value}`;
|
|
70
|
-
}
|
|
71
|
-
default:
|
|
72
|
-
throw new Error(`Unsupported operator: ${operator}`);
|
|
73
|
-
}
|
|
5
|
+
//#region src/storage/postgresql/core/sqlBuilder/filter/queryOperators.ts
|
|
6
|
+
const handleOperator = (path, operator, value, serializer) => {
|
|
7
|
+
if (path === "_id" || path === "_version") return handleMetadataOperator(path, operator, value);
|
|
8
|
+
switch (operator) {
|
|
9
|
+
case "$eq": {
|
|
10
|
+
const nestedPath = serializer.serialize(buildNestedObject(path, value));
|
|
11
|
+
const serializedValue = serializer.serialize(value);
|
|
12
|
+
return SQL`(data @> ${nestedPath}::jsonb OR jsonb_path_exists(data, '$.${SQL.plain(path)}[*] ? (@ == ${SQL.plain(serializedValue)})'))`;
|
|
13
|
+
}
|
|
14
|
+
case "$gt":
|
|
15
|
+
case "$gte":
|
|
16
|
+
case "$lt":
|
|
17
|
+
case "$lte":
|
|
18
|
+
case "$ne": return SQL`data ->> '${SQL.plain(path.split(".").join(","))}' ${SQL.plain(OperatorMap[operator])} ${value}`;
|
|
19
|
+
case "$in": return SQL`data #>> ${`{${path.split(".").join(",")}}`} = ANY (${value})`;
|
|
20
|
+
case "$nin": return SQL`data #>> ${`{${path.split(".").join(",")}}`} != ALL (${value})`;
|
|
21
|
+
case "$elemMatch": {
|
|
22
|
+
const subQuery = objectEntries(value).map(([subKey, subValue]) => `@."${subKey}" == ${serializer.serialize(subValue)}`).join(" && ");
|
|
23
|
+
return SQL`jsonb_path_exists(data, '$.${SQL.plain(path)}[*] ? (${SQL.plain(subQuery)})')`;
|
|
24
|
+
}
|
|
25
|
+
case "$all": return SQL`data @> ${serializer.serialize(buildNestedObject(path, value))}::jsonb`;
|
|
26
|
+
case "$size": return SQL`jsonb_array_length(data #> ${`{${path.split(".").join(",")}}`}) = ${value}`;
|
|
27
|
+
default: throw new Error(`Unsupported operator: ${operator}`);
|
|
28
|
+
}
|
|
74
29
|
};
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
case "$nin":
|
|
88
|
-
return SQL`${SQL.plain(fieldName)} NOT IN ${value}`;
|
|
89
|
-
default:
|
|
90
|
-
throw new Error(`Unsupported operator: ${operator}`);
|
|
91
|
-
}
|
|
30
|
+
const handleMetadataOperator = (fieldName, operator, value) => {
|
|
31
|
+
switch (operator) {
|
|
32
|
+
case "$eq": return SQL`${SQL.plain(fieldName)} = ${value}`;
|
|
33
|
+
case "$gt":
|
|
34
|
+
case "$gte":
|
|
35
|
+
case "$lt":
|
|
36
|
+
case "$lte":
|
|
37
|
+
case "$ne": return SQL`${SQL.plain(fieldName)} ${SQL.plain(OperatorMap[operator])} ${value}`;
|
|
38
|
+
case "$in": return SQL`${SQL.plain(fieldName)} = ANY (${value})`;
|
|
39
|
+
case "$nin": return SQL`${SQL.plain(fieldName)} != ALL (${value})`;
|
|
40
|
+
default: throw new Error(`Unsupported operator: ${operator}`);
|
|
41
|
+
}
|
|
92
42
|
};
|
|
93
|
-
|
|
43
|
+
const buildNestedObject = (path, value) => path.split(".").reverse().reduce((acc, key) => ({ [key]: acc }), value);
|
|
94
44
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
45
|
+
//#endregion
|
|
46
|
+
//#region src/storage/postgresql/core/sqlBuilder/filter/index.ts
|
|
47
|
+
const AND = "AND";
|
|
48
|
+
const OR = "OR";
|
|
49
|
+
const unsupportedRootOperators = [
|
|
50
|
+
"$text",
|
|
51
|
+
"$where",
|
|
52
|
+
"$comment"
|
|
53
|
+
];
|
|
54
|
+
const constructFilterQuery = (filter, serializer) => {
|
|
55
|
+
ensureSupportedRootOperators(filter);
|
|
56
|
+
const parts = [];
|
|
57
|
+
const fieldFilterQuery = constructFieldFilterQuery(filter, serializer);
|
|
58
|
+
if (!SQL.check.isEmpty(fieldFilterQuery)) parts.push(fieldFilterQuery);
|
|
59
|
+
const orFilterQuery = constructLogicalFilterQuery(filter.$or, OR, serializer);
|
|
60
|
+
if (!SQL.check.isEmpty(orFilterQuery)) parts.push(orFilterQuery);
|
|
61
|
+
const andFilterQuery = constructLogicalFilterQuery(filter.$and, AND, serializer);
|
|
62
|
+
if (!SQL.check.isEmpty(andFilterQuery)) parts.push(andFilterQuery);
|
|
63
|
+
const norFilterQuery = constructNorFilterQuery(filter.$nor, serializer);
|
|
64
|
+
if (!SQL.check.isEmpty(norFilterQuery)) parts.push(norFilterQuery);
|
|
65
|
+
return SQL.merge(parts, ` ${AND} `);
|
|
66
|
+
};
|
|
67
|
+
const constructFieldFilterQuery = (filter, serializer) => SQL.merge(objectEntries(filter).flatMap(([key, value]) => isLogicalRootOperator(key) ? [] : [isRecord(value) ? constructComplexFilterQuery(key, value, serializer) : handleOperator(key, QueryOperators.$eq, value, serializer)]), ` ${AND} `);
|
|
68
|
+
const constructLogicalFilterQuery = (filters, joinOperator, serializer) => {
|
|
69
|
+
if (!filters?.length) return SQL.EMPTY;
|
|
70
|
+
const subFilterQueries = filters.reduce((queries, filter) => {
|
|
71
|
+
const query = constructFilterQuery(filter, serializer);
|
|
72
|
+
if (!SQL.check.isEmpty(query)) queries.push(query);
|
|
73
|
+
return queries;
|
|
74
|
+
}, []);
|
|
75
|
+
if (subFilterQueries.length === 0) return SQL.EMPTY;
|
|
76
|
+
if (subFilterQueries.length === 1) return wrapFilterQuery(subFilterQueries[0]);
|
|
77
|
+
return SQL`(${SQL.merge(subFilterQueries.map(wrapFilterQuery), ` ${joinOperator} `)})`;
|
|
111
78
|
};
|
|
112
|
-
|
|
79
|
+
const constructNorFilterQuery = (filters, serializer) => {
|
|
80
|
+
if (!filters?.length) return SQL.EMPTY;
|
|
81
|
+
const logicalFilterQuery = constructLogicalFilterQuery(filters, OR, serializer);
|
|
82
|
+
return SQL.check.isEmpty(logicalFilterQuery) ? SQL.EMPTY : SQL`NOT ${logicalFilterQuery}`;
|
|
83
|
+
};
|
|
84
|
+
const constructComplexFilterQuery = (key, value, serializer) => {
|
|
85
|
+
const isEquality = !hasOperators(value);
|
|
86
|
+
return SQL.merge(objectEntries(value).map(([nestedKey, val]) => isEquality ? handleOperator(`${key}.${nestedKey}`, QueryOperators.$eq, val, serializer) : handleOperator(key, nestedKey, val, serializer)), ` ${AND} `);
|
|
87
|
+
};
|
|
88
|
+
const wrapFilterQuery = (filterQuery) => SQL`(${filterQuery})`;
|
|
89
|
+
const ensureSupportedRootOperators = (filter) => {
|
|
90
|
+
for (const operator of unsupportedRootOperators) if (operator in filter) throw new Error(`Unsupported root operator: ${operator}`);
|
|
91
|
+
};
|
|
92
|
+
const isLogicalRootOperator = (key) => key === "$and" || key === "$nor" || key === "$or";
|
|
93
|
+
const isRecord = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
113
94
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
},
|
|
131
|
-
SQL3`data`
|
|
132
|
-
);
|
|
133
|
-
var buildSetQuery = (set, currentUpdateQuery) => SQL3`${currentUpdateQuery} || ${JSONSerializer2.serialize(set)}::jsonb`;
|
|
134
|
-
var buildUnsetQuery = (unset, currentUpdateQuery) => SQL3`${currentUpdateQuery} - ${Object.keys(unset).map((k) => `{${k}}`).join(", ")}`;
|
|
135
|
-
var buildIncQuery = (inc, currentUpdateQuery) => {
|
|
136
|
-
for (const [key, value] of Object.entries(inc)) {
|
|
137
|
-
currentUpdateQuery = typeof value === "bigint" ? SQL3`jsonb_set(${currentUpdateQuery}, '{${SQL3.plain(key)}}', to_jsonb((COALESCE((data->>'${SQL3.plain(key)}')::BIGINT, 0) + ${value})::TEXT), true)` : SQL3`jsonb_set(${currentUpdateQuery}, '{${SQL3.plain(key)}}', to_jsonb(COALESCE((data->>'${SQL3.plain(key)}')::NUMERIC, 0) + ${value}), true)`;
|
|
138
|
-
}
|
|
139
|
-
return currentUpdateQuery;
|
|
95
|
+
//#endregion
|
|
96
|
+
//#region src/storage/postgresql/core/sqlBuilder/update/index.ts
|
|
97
|
+
const buildUpdateQuery = (update, serializer) => objectEntries(update).reduce((currentUpdateQuery, [op, value]) => {
|
|
98
|
+
switch (op) {
|
|
99
|
+
case "$set": return buildSetQuery(value, currentUpdateQuery, serializer);
|
|
100
|
+
case "$unset": return buildUnsetQuery(value, currentUpdateQuery);
|
|
101
|
+
case "$inc": return buildIncQuery(value, currentUpdateQuery);
|
|
102
|
+
case "$push": return buildPushQuery(value, currentUpdateQuery, serializer);
|
|
103
|
+
default: return currentUpdateQuery;
|
|
104
|
+
}
|
|
105
|
+
}, SQL`data`);
|
|
106
|
+
const buildSetQuery = (set, currentUpdateQuery, serializer) => SQL`${currentUpdateQuery} || ${serializer.serialize(set)}::jsonb`;
|
|
107
|
+
const buildUnsetQuery = (unset, currentUpdateQuery) => SQL`${currentUpdateQuery} - ${Object.keys(unset).map((k) => `{${k}}`).join(", ")}`;
|
|
108
|
+
const buildIncQuery = (inc, currentUpdateQuery) => {
|
|
109
|
+
for (const [key, value] of Object.entries(inc)) currentUpdateQuery = typeof value === "bigint" ? SQL`jsonb_set(${currentUpdateQuery}, '{${SQL.plain(key)}}', to_jsonb((COALESCE((data->>'${SQL.plain(key)}')::BIGINT, 0) + ${value})::TEXT), true)` : SQL`jsonb_set(${currentUpdateQuery}, '{${SQL.plain(key)}}', to_jsonb(COALESCE((data->>'${SQL.plain(key)}')::NUMERIC, 0) + ${value}), true)`;
|
|
110
|
+
return currentUpdateQuery;
|
|
140
111
|
};
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
112
|
+
const buildPushQuery = (push, currentUpdateQuery, serializer) => {
|
|
113
|
+
for (const [key, value] of Object.entries(push)) {
|
|
114
|
+
const serializedValue = serializer.serialize([value]);
|
|
115
|
+
currentUpdateQuery = SQL`jsonb_set(${currentUpdateQuery}, '{${SQL.plain(key)}}', (coalesce(data->'${SQL.plain(key)}', '[]'::jsonb) || ${serializedValue}::jsonb), true)`;
|
|
116
|
+
}
|
|
117
|
+
return currentUpdateQuery;
|
|
147
118
|
};
|
|
148
119
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
120
|
+
//#endregion
|
|
121
|
+
//#region src/storage/postgresql/core/sqlBuilder/index.ts
|
|
122
|
+
const versionCheckClause = (collectionName, expectedVersion) => {
|
|
123
|
+
const col = SQL.identifier(collectionName);
|
|
124
|
+
const predicate = expectedVersionPredicate(expectedVersion);
|
|
125
|
+
return predicate.operator === "none" ? SQL.EMPTY : SQL`AND ${col}._version = ${predicate.value}`;
|
|
126
|
+
};
|
|
127
|
+
const createCollection = (collectionName) => SQL`
|
|
128
|
+
CREATE TABLE IF NOT EXISTS ${SQL.identifier(collectionName)} (
|
|
152
129
|
_id TEXT PRIMARY KEY,
|
|
153
130
|
data JSONB NOT NULL,
|
|
154
131
|
metadata JSONB NOT NULL DEFAULT '{}',
|
|
@@ -158,52 +135,54 @@ var createCollection = (collectionName) => SQL4`
|
|
|
158
135
|
_created TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
159
136
|
_updated TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
160
137
|
)`;
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
const id = document._id;
|
|
171
|
-
const version = document._version ?? 1n;
|
|
172
|
-
return SQL4`
|
|
173
|
-
INSERT INTO ${SQL4.identifier(collectionName)} (_id, data, _version)
|
|
138
|
+
const pongoCollectionPostgreSQLMigrations = (collectionName) => [sqlMigration(`pongoCollection:${collectionName}:001:createtable`, [createCollection(collectionName)])];
|
|
139
|
+
const postgresSQLBuilder = (collectionName, serializer) => ({
|
|
140
|
+
createCollection: () => createCollection(collectionName),
|
|
141
|
+
insertOne: (document) => {
|
|
142
|
+
const serialized = serializer.serialize(document);
|
|
143
|
+
const id = document._id;
|
|
144
|
+
const version = document._version ?? 1n;
|
|
145
|
+
return SQL`
|
|
146
|
+
INSERT INTO ${SQL.identifier(collectionName)} (_id, data, _version)
|
|
174
147
|
VALUES (${id}, ${serialized}, ${version}) ON CONFLICT(_id) DO NOTHING;`;
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
),
|
|
181
|
-
","
|
|
182
|
-
);
|
|
183
|
-
return SQL4`
|
|
184
|
-
INSERT INTO ${SQL4.identifier(collectionName)} (_id, data, _version) VALUES ${values}
|
|
148
|
+
},
|
|
149
|
+
insertMany: (documents) => {
|
|
150
|
+
const values = SQL.merge(documents.map((doc) => SQL`(${doc._id}, ${serializer.serialize(doc)}, ${doc._version ?? 1n})`), ",");
|
|
151
|
+
return SQL`
|
|
152
|
+
INSERT INTO ${SQL.identifier(collectionName)} (_id, data, _version) VALUES ${values}
|
|
185
153
|
ON CONFLICT(_id) DO NOTHING
|
|
186
154
|
RETURNING _id;`;
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
155
|
+
},
|
|
156
|
+
insertOrReplace: (documents) => {
|
|
157
|
+
const col = SQL.identifier(collectionName);
|
|
158
|
+
return SQL`
|
|
159
|
+
INSERT INTO ${col} (_id, data, _version)
|
|
160
|
+
VALUES ${SQL.merge(documents.map((d) => SQL`(${d._id}::text, ${serializer.serialize(d)}::jsonb || jsonb_build_object('_id', ${d._id}::text) || jsonb_build_object('_version', '1'::text), 1::bigint)`), ",")}
|
|
161
|
+
ON CONFLICT(_id) DO UPDATE SET
|
|
162
|
+
data = EXCLUDED.data
|
|
163
|
+
|| jsonb_build_object('_id', ${col}._id)
|
|
164
|
+
|| jsonb_build_object('_version', (${col}._version + 1)::text),
|
|
165
|
+
_version = ${col}._version + 1
|
|
166
|
+
RETURNING _id, _version AS version;`;
|
|
167
|
+
},
|
|
168
|
+
updateOne: (filter, update, options) => {
|
|
169
|
+
const expectedVersionUpdate = versionCheckClause(collectionName, options?.expectedVersion);
|
|
170
|
+
const filterQuery = isSQL(filter) ? filter : constructFilterQuery(filter, serializer);
|
|
171
|
+
const updateQuery = isSQL(update) ? update : buildUpdateQuery(update, serializer);
|
|
172
|
+
return SQL`
|
|
194
173
|
WITH existing AS (
|
|
195
174
|
SELECT _id, _version as current_version
|
|
196
|
-
FROM ${
|
|
175
|
+
FROM ${SQL.identifier(collectionName)} ${where(filterQuery)}
|
|
197
176
|
LIMIT 1
|
|
198
177
|
),
|
|
199
178
|
updated AS (
|
|
200
|
-
UPDATE ${
|
|
179
|
+
UPDATE ${SQL.identifier(collectionName)}
|
|
201
180
|
SET
|
|
202
|
-
data = ${updateQuery} || jsonb_build_object('_id', ${
|
|
181
|
+
data = ${updateQuery} || jsonb_build_object('_id', ${SQL.identifier(collectionName)}._id) || jsonb_build_object('_version', (_version + 1)::text),
|
|
203
182
|
_version = _version + 1
|
|
204
183
|
FROM existing
|
|
205
|
-
WHERE ${
|
|
206
|
-
RETURNING ${
|
|
184
|
+
WHERE ${SQL.identifier(collectionName)}._id = existing._id ${expectedVersionUpdate}
|
|
185
|
+
RETURNING ${SQL.identifier(collectionName)}._id, ${SQL.identifier(collectionName)}._version
|
|
207
186
|
)
|
|
208
187
|
SELECT
|
|
209
188
|
existing._id,
|
|
@@ -213,25 +192,24 @@ var postgresSQLBuilder = (collectionName) => ({
|
|
|
213
192
|
FROM existing
|
|
214
193
|
LEFT JOIN updated
|
|
215
194
|
ON existing._id = updated._id;`;
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
return SQL4`
|
|
195
|
+
},
|
|
196
|
+
replaceOne: (filter, document, options) => {
|
|
197
|
+
const expectedVersionUpdate = versionCheckClause(collectionName, options?.expectedVersion);
|
|
198
|
+
const filterQuery = isSQL(filter) ? filter : constructFilterQuery(filter, serializer);
|
|
199
|
+
return SQL`
|
|
222
200
|
WITH existing AS (
|
|
223
201
|
SELECT _id, _version as current_version
|
|
224
|
-
FROM ${
|
|
202
|
+
FROM ${SQL.identifier(collectionName)} ${where(filterQuery)}
|
|
225
203
|
LIMIT 1
|
|
226
204
|
),
|
|
227
205
|
updated AS (
|
|
228
|
-
UPDATE ${
|
|
206
|
+
UPDATE ${SQL.identifier(collectionName)}
|
|
229
207
|
SET
|
|
230
|
-
data = ${
|
|
208
|
+
data = ${serializer.serialize(document)} || jsonb_build_object('_id', ${SQL.identifier(collectionName)}._id) || jsonb_build_object('_version', (_version + 1)::text),
|
|
231
209
|
_version = _version + 1
|
|
232
210
|
FROM existing
|
|
233
|
-
WHERE ${
|
|
234
|
-
RETURNING ${
|
|
211
|
+
WHERE ${SQL.identifier(collectionName)}._id = existing._id ${expectedVersionUpdate}
|
|
212
|
+
RETURNING ${SQL.identifier(collectionName)}._id, ${SQL.identifier(collectionName)}._version
|
|
235
213
|
)
|
|
236
214
|
SELECT
|
|
237
215
|
existing._id,
|
|
@@ -241,32 +219,31 @@ var postgresSQLBuilder = (collectionName) => ({
|
|
|
241
219
|
FROM existing
|
|
242
220
|
LEFT JOIN updated
|
|
243
221
|
ON existing._id = updated._id;`;
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
UPDATE ${
|
|
222
|
+
},
|
|
223
|
+
updateMany: (filter, update) => {
|
|
224
|
+
const filterQuery = isSQL(filter) ? filter : constructFilterQuery(filter, serializer);
|
|
225
|
+
const updateQuery = isSQL(update) ? update : buildUpdateQuery(update, serializer);
|
|
226
|
+
return SQL`
|
|
227
|
+
UPDATE ${SQL.identifier(collectionName)}
|
|
250
228
|
SET
|
|
251
229
|
data = ${updateQuery} || jsonb_build_object('_version', (_version + 1)::text),
|
|
252
230
|
_version = _version + 1
|
|
253
231
|
${where(filterQuery)};`;
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
return SQL4`
|
|
232
|
+
},
|
|
233
|
+
deleteOne: (filter, options) => {
|
|
234
|
+
const expectedVersionUpdate = versionCheckClause(collectionName, options?.expectedVersion);
|
|
235
|
+
const filterQuery = isSQL(filter) ? filter : constructFilterQuery(filter, serializer);
|
|
236
|
+
return SQL`
|
|
260
237
|
WITH existing AS (
|
|
261
238
|
SELECT _id
|
|
262
|
-
FROM ${
|
|
239
|
+
FROM ${SQL.identifier(collectionName)} ${where(filterQuery)}
|
|
263
240
|
LIMIT 1
|
|
264
241
|
),
|
|
265
242
|
deleted AS (
|
|
266
|
-
DELETE FROM ${
|
|
243
|
+
DELETE FROM ${SQL.identifier(collectionName)}
|
|
267
244
|
USING existing
|
|
268
|
-
WHERE ${
|
|
269
|
-
RETURNING ${
|
|
245
|
+
WHERE ${SQL.identifier(collectionName)}._id = existing._id ${expectedVersionUpdate}
|
|
246
|
+
RETURNING ${SQL.identifier(collectionName)}._id
|
|
270
247
|
)
|
|
271
248
|
SELECT
|
|
272
249
|
existing._id,
|
|
@@ -275,88 +252,136 @@ var postgresSQLBuilder = (collectionName) => ({
|
|
|
275
252
|
FROM existing
|
|
276
253
|
LEFT JOIN deleted
|
|
277
254
|
ON existing._id = deleted._id;`;
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
255
|
+
},
|
|
256
|
+
deleteMany: (filter) => {
|
|
257
|
+
const filterQuery = isSQL(filter) ? filter : constructFilterQuery(filter, serializer);
|
|
258
|
+
return SQL`DELETE FROM ${SQL.identifier(collectionName)} ${where(filterQuery)}`;
|
|
259
|
+
},
|
|
260
|
+
replaceMany: (documents) => {
|
|
261
|
+
if (documents.some((d) => "_version" in d && d._version !== void 0)) return SQL`
|
|
262
|
+
WITH replacements(_id, data, expected_version) AS (
|
|
263
|
+
VALUES ${SQL.merge(documents.map((d) => {
|
|
264
|
+
const expectedVersion = d._version;
|
|
265
|
+
return expectedVersion !== void 0 ? SQL`(${d._id}::text, ${serializer.serialize(d)}::jsonb, ${expectedVersion}::bigint)` : SQL`(${d._id}::text, ${serializer.serialize(d)}::jsonb, NULL::bigint)`;
|
|
266
|
+
}), ",")}
|
|
267
|
+
)
|
|
268
|
+
UPDATE ${SQL.identifier(collectionName)} t
|
|
269
|
+
SET
|
|
270
|
+
data = r.data
|
|
271
|
+
|| jsonb_build_object('_id', t._id)
|
|
272
|
+
|| jsonb_build_object('_version', (t._version + 1)::text),
|
|
273
|
+
_version = t._version + 1
|
|
274
|
+
FROM replacements r
|
|
275
|
+
WHERE t._id = r._id AND (r.expected_version IS NULL OR t._version = r.expected_version)
|
|
276
|
+
RETURNING t._id, t._version AS version;`;
|
|
277
|
+
return SQL`
|
|
278
|
+
WITH replacements(_id, data) AS (
|
|
279
|
+
VALUES ${SQL.merge(documents.map((d) => SQL`(${d._id}::text, ${serializer.serialize(d)}::jsonb)`), ",")}
|
|
280
|
+
)
|
|
281
|
+
UPDATE ${SQL.identifier(collectionName)} t
|
|
282
|
+
SET
|
|
283
|
+
data = r.data
|
|
284
|
+
|| jsonb_build_object('_id', t._id)
|
|
285
|
+
|| jsonb_build_object('_version', (t._version + 1)::text),
|
|
286
|
+
_version = t._version + 1
|
|
287
|
+
FROM replacements r
|
|
288
|
+
WHERE t._id = r._id
|
|
289
|
+
RETURNING t._id, t._version AS version;`;
|
|
290
|
+
},
|
|
291
|
+
deleteManyByIds: (ids) => {
|
|
292
|
+
if (ids.some((d) => d._version !== void 0)) return SQL`
|
|
293
|
+
WITH targets(_id, expected_version) AS (
|
|
294
|
+
VALUES ${SQL.merge(ids.map((d) => SQL`(${d._id}::text, ${d._version ?? 0n}::bigint)`), ",")}
|
|
295
|
+
),
|
|
296
|
+
deleted AS (
|
|
297
|
+
DELETE FROM ${SQL.identifier(collectionName)} t
|
|
298
|
+
USING targets r
|
|
299
|
+
WHERE t._id = r._id AND t._version = r.expected_version
|
|
300
|
+
RETURNING t._id
|
|
301
|
+
)
|
|
302
|
+
SELECT r._id,
|
|
303
|
+
CASE WHEN d._id IS NOT NULL THEN 1 ELSE 0 END as deleted
|
|
304
|
+
FROM targets r
|
|
305
|
+
LEFT JOIN deleted d ON r._id = d._id;`;
|
|
306
|
+
return SQL`
|
|
307
|
+
WITH targets(_id) AS (
|
|
308
|
+
VALUES ${SQL.merge(ids.map((d) => SQL`(${d._id}::text)`), ",")}
|
|
309
|
+
),
|
|
310
|
+
deleted AS (
|
|
311
|
+
DELETE FROM ${SQL.identifier(collectionName)} t
|
|
312
|
+
USING targets r
|
|
313
|
+
WHERE t._id = r._id
|
|
314
|
+
RETURNING t._id
|
|
315
|
+
)
|
|
316
|
+
SELECT r._id,
|
|
317
|
+
CASE WHEN d._id IS NOT NULL THEN 1 ELSE 0 END as deleted
|
|
318
|
+
FROM targets r
|
|
319
|
+
LEFT JOIN deleted d ON r._id = d._id;`;
|
|
320
|
+
},
|
|
321
|
+
findOne: (filter) => {
|
|
322
|
+
const filterQuery = isSQL(filter) ? filter : constructFilterQuery(filter, serializer);
|
|
323
|
+
return SQL`SELECT data, _id, _version FROM ${SQL.identifier(collectionName)} ${where(filterQuery)} LIMIT 1;`;
|
|
324
|
+
},
|
|
325
|
+
find: (filter, options) => {
|
|
326
|
+
const filterQuery = isSQL(filter) ? filter : constructFilterQuery(filter, serializer);
|
|
327
|
+
const query = [];
|
|
328
|
+
query.push(SQL`SELECT data, _id, _version FROM ${SQL.identifier(collectionName)}`);
|
|
329
|
+
query.push(where(filterQuery));
|
|
330
|
+
if (options?.sort && Object.keys(options.sort).length > 0) {
|
|
331
|
+
const clauses = Object.entries(options.sort).map(([field, dir]) => {
|
|
332
|
+
const isMetadata = field === "_id" || field === "_version";
|
|
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)}'`;
|
|
335
|
+
return dir === 1 ? SQL`${accessor} ASC NULLS FIRST` : SQL`${accessor} DESC NULLS LAST`;
|
|
336
|
+
});
|
|
337
|
+
query.push(SQL`ORDER BY ${SQL.merge(clauses, ",")}`);
|
|
338
|
+
}
|
|
339
|
+
if (options?.limit) query.push(SQL`LIMIT ${options.limit}`);
|
|
340
|
+
if (options?.skip) query.push(SQL`OFFSET ${options.skip}`);
|
|
341
|
+
return SQL.merge([...query, SQL`;`]);
|
|
342
|
+
},
|
|
343
|
+
countDocuments: (filter) => {
|
|
344
|
+
const filterQuery = SQL.check.isSQL(filter) ? filter : constructFilterQuery(filter, serializer);
|
|
345
|
+
return SQL`SELECT COUNT(1) as count FROM ${SQL.identifier(collectionName)} ${where(filterQuery)};`;
|
|
346
|
+
},
|
|
347
|
+
rename: (newName) => SQL`ALTER TABLE ${SQL.identifier(collectionName)} RENAME TO ${SQL.identifier(newName)};`,
|
|
348
|
+
drop: (targetName = collectionName) => SQL`DROP TABLE IF EXISTS ${SQL.identifier(targetName)}`
|
|
306
349
|
});
|
|
307
|
-
|
|
350
|
+
const where = (filterQuery) => SQL.check.isEmpty(filterQuery) ? SQL.EMPTY : SQL.merge([SQL`WHERE `, filterQuery]);
|
|
308
351
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
sqlBuilder: postgresSQLBuilder(schema.name)
|
|
337
|
-
}),
|
|
338
|
-
definition: options.schema?.definition ?? pongoSchema.db(databaseName, {})
|
|
339
|
-
}),
|
|
340
|
-
databaseName
|
|
341
|
-
});
|
|
342
|
-
},
|
|
343
|
-
getDatabaseNameOrDefault: (options) => {
|
|
344
|
-
return options.databaseName ?? getDatabaseNameOrDefault(options.connectionString);
|
|
345
|
-
},
|
|
346
|
-
defaultConnectionString: "postgresql://localhost:5432/postgres"
|
|
352
|
+
//#endregion
|
|
353
|
+
//#region src/storage/postgresql/pg/index.ts
|
|
354
|
+
const pgPongoDriver = {
|
|
355
|
+
driverType: PgDriverType,
|
|
356
|
+
databaseFactory: (options) => {
|
|
357
|
+
const databaseName = options.databaseName ?? postgreSQLMetadata.parseDatabaseName(options.connectionString) ?? postgreSQLMetadata.defaultDatabaseName;
|
|
358
|
+
return PongoDatabase({
|
|
359
|
+
...options,
|
|
360
|
+
pool: dumbo({
|
|
361
|
+
connectionString: options.connectionString,
|
|
362
|
+
driver: pgDumboDriver,
|
|
363
|
+
...options.connectionOptions,
|
|
364
|
+
serialization: { serializer: options.serializer }
|
|
365
|
+
}),
|
|
366
|
+
schemaComponent: PongoDatabaseSchemaComponent({
|
|
367
|
+
driverType: PgDriverType,
|
|
368
|
+
collectionFactory: (schema) => PongoCollectionSchemaComponent({
|
|
369
|
+
driverType: PgDriverType,
|
|
370
|
+
definition: schema,
|
|
371
|
+
migrationsOrSchemaComponents: { migrations: pongoCollectionPostgreSQLMigrations(schema.name) },
|
|
372
|
+
sqlBuilder: postgresSQLBuilder(schema.name, options.serialization?.serializer ?? JSONSerializer)
|
|
373
|
+
}),
|
|
374
|
+
definition: options.schema?.definition ?? pongoSchema.db(databaseName, {})
|
|
375
|
+
}),
|
|
376
|
+
databaseName
|
|
377
|
+
});
|
|
378
|
+
}
|
|
347
379
|
};
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
NodePostgresDriverType,
|
|
351
|
-
pgDatabaseDriver
|
|
352
|
-
);
|
|
353
|
-
};
|
|
354
|
-
usePgDatabaseDriver();
|
|
355
|
-
export {
|
|
356
|
-
pgDatabaseDriver as databaseDriver,
|
|
357
|
-
pgDatabaseDriver as pgDriver,
|
|
358
|
-
pongoCollectionPostgreSQLMigrations,
|
|
359
|
-
postgresSQLBuilder,
|
|
360
|
-
usePgDatabaseDriver
|
|
380
|
+
const usePgPongoDriver = () => {
|
|
381
|
+
pongoDriverRegistry.register(PgDriverType, pgPongoDriver);
|
|
361
382
|
};
|
|
383
|
+
usePgPongoDriver();
|
|
384
|
+
|
|
385
|
+
//#endregion
|
|
386
|
+
export { pgPongoDriver as pgDriver, pgPongoDriver as pongoDriver, pongoCollectionPostgreSQLMigrations, postgresSQLBuilder, usePgPongoDriver };
|
|
362
387
|
//# sourceMappingURL=pg.js.map
|