@expo/entity-database-adapter-knex 0.54.0 → 0.57.0
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/build/src/AuthorizationResultBasedKnexEntityLoader.d.ts +279 -0
- package/build/src/AuthorizationResultBasedKnexEntityLoader.js +127 -0
- package/build/src/AuthorizationResultBasedKnexEntityLoader.js.map +1 -0
- package/build/src/BasePostgresEntityDatabaseAdapter.d.ts +150 -0
- package/build/src/BasePostgresEntityDatabaseAdapter.js +119 -0
- package/build/src/BasePostgresEntityDatabaseAdapter.js.map +1 -0
- package/build/src/BaseSQLQueryBuilder.d.ts +61 -0
- package/build/src/BaseSQLQueryBuilder.js +87 -0
- package/build/src/BaseSQLQueryBuilder.js.map +1 -0
- package/build/src/EnforcingKnexEntityLoader.d.ts +124 -0
- package/build/src/EnforcingKnexEntityLoader.js +166 -0
- package/build/src/EnforcingKnexEntityLoader.js.map +1 -0
- package/build/src/KnexEntityLoaderFactory.d.ts +25 -0
- package/build/src/KnexEntityLoaderFactory.js +39 -0
- package/build/src/KnexEntityLoaderFactory.js.map +1 -0
- package/build/src/PaginationStrategy.d.ts +30 -0
- package/build/src/PaginationStrategy.js +35 -0
- package/build/src/PaginationStrategy.js.map +1 -0
- package/build/src/PostgresEntity.d.ts +25 -0
- package/build/src/PostgresEntity.js +39 -0
- package/build/src/PostgresEntity.js.map +1 -0
- package/build/src/PostgresEntityDatabaseAdapter.d.ts +12 -5
- package/build/src/PostgresEntityDatabaseAdapter.js +32 -11
- package/build/src/PostgresEntityDatabaseAdapter.js.map +1 -1
- package/build/src/PostgresEntityDatabaseAdapterProvider.d.ts +9 -0
- package/build/src/PostgresEntityDatabaseAdapterProvider.js +5 -1
- package/build/src/PostgresEntityDatabaseAdapterProvider.js.map +1 -1
- package/build/src/ReadonlyPostgresEntity.d.ts +25 -0
- package/build/src/ReadonlyPostgresEntity.js +39 -0
- package/build/src/ReadonlyPostgresEntity.js.map +1 -0
- package/build/src/SQLOperator.d.ts +261 -0
- package/build/src/SQLOperator.js +464 -0
- package/build/src/SQLOperator.js.map +1 -0
- package/build/src/index.d.ts +15 -0
- package/build/src/index.js +15 -0
- package/build/src/index.js.map +1 -1
- package/build/src/internal/EntityKnexDataManager.d.ts +147 -0
- package/build/src/internal/EntityKnexDataManager.js +453 -0
- package/build/src/internal/EntityKnexDataManager.js.map +1 -0
- package/build/src/internal/getKnexDataManager.d.ts +3 -0
- package/build/src/internal/getKnexDataManager.js +19 -0
- package/build/src/internal/getKnexDataManager.js.map +1 -0
- package/build/src/internal/getKnexEntityLoaderFactory.d.ts +3 -0
- package/build/src/internal/getKnexEntityLoaderFactory.js +11 -0
- package/build/src/internal/getKnexEntityLoaderFactory.js.map +1 -0
- package/build/src/internal/utilityTypes.d.ts +5 -0
- package/build/src/internal/utilityTypes.js +5 -0
- package/build/src/internal/utilityTypes.js.map +1 -0
- package/build/src/internal/weakMaps.d.ts +9 -0
- package/build/src/internal/weakMaps.js +20 -0
- package/build/src/internal/weakMaps.js.map +1 -0
- package/build/src/knexLoader.d.ts +18 -0
- package/build/src/knexLoader.js +31 -0
- package/build/src/knexLoader.js.map +1 -0
- package/package.json +6 -5
- package/src/AuthorizationResultBasedKnexEntityLoader.ts +538 -0
- package/src/BasePostgresEntityDatabaseAdapter.ts +317 -0
- package/src/BaseSQLQueryBuilder.ts +114 -0
- package/src/EnforcingKnexEntityLoader.ts +271 -0
- package/src/KnexEntityLoaderFactory.ts +130 -0
- package/src/PaginationStrategy.ts +32 -0
- package/src/PostgresEntity.ts +118 -0
- package/src/PostgresEntityDatabaseAdapter.ts +78 -24
- package/src/PostgresEntityDatabaseAdapterProvider.ts +11 -1
- package/src/ReadonlyPostgresEntity.ts +115 -0
- package/src/SQLOperator.ts +603 -0
- package/src/__integration-tests__/EntityCreationUtils-test.ts +25 -31
- package/src/__integration-tests__/PostgresEntityIntegration-test.ts +3192 -330
- package/src/__integration-tests__/PostgresEntityQueryContextProvider-test.ts +7 -7
- package/src/__testfixtures__/PostgresTestEntity.ts +17 -3
- package/src/__tests__/AuthorizationResultBasedKnexEntityLoader-test.ts +1167 -0
- package/src/__tests__/BasePostgresEntityDatabaseAdapter-test.ts +160 -0
- package/src/__tests__/EnforcingKnexEntityLoader-test.ts +384 -0
- package/src/__tests__/EntityFields-test.ts +1 -1
- package/src/__tests__/PostgresEntity-test.ts +172 -0
- package/src/__tests__/ReadonlyEntity-test.ts +32 -0
- package/src/__tests__/SQLOperator-test.ts +831 -0
- package/src/__tests__/fixtures/StubPostgresDatabaseAdapter.ts +302 -0
- package/src/__tests__/fixtures/StubPostgresDatabaseAdapterProvider.ts +17 -0
- package/src/__tests__/fixtures/TestEntity.ts +131 -0
- package/src/__tests__/fixtures/TestPaginationEntity.ts +107 -0
- package/src/__tests__/fixtures/createUnitTestPostgresEntityCompanionProvider.ts +42 -0
- package/src/index.ts +15 -0
- package/src/internal/EntityKnexDataManager.ts +832 -0
- package/src/internal/__tests__/EntityKnexDataManager-test.ts +378 -0
- package/src/internal/__tests__/weakMaps-test.ts +25 -0
- package/src/internal/getKnexDataManager.ts +43 -0
- package/src/internal/getKnexEntityLoaderFactory.ts +60 -0
- package/src/internal/utilityTypes.ts +11 -0
- package/src/internal/weakMaps.ts +19 -0
- package/src/knexLoader.ts +110 -0
|
@@ -0,0 +1,464 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SQLFragmentHelpers = exports.SQLUnsafeRaw = exports.SQLEntityField = exports.SQLIdentifier = exports.SQLFragment = void 0;
|
|
4
|
+
exports.identifier = identifier;
|
|
5
|
+
exports.entityField = entityField;
|
|
6
|
+
exports.unsafeRaw = unsafeRaw;
|
|
7
|
+
exports.sql = sql;
|
|
8
|
+
/**
|
|
9
|
+
* SQL Fragment class that safely handles parameterized queries.
|
|
10
|
+
*/
|
|
11
|
+
class SQLFragment {
|
|
12
|
+
sql;
|
|
13
|
+
bindings;
|
|
14
|
+
constructor(sql, bindings) {
|
|
15
|
+
this.sql = sql;
|
|
16
|
+
this.bindings = bindings;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Get bindings in the format expected by Knex.
|
|
20
|
+
* Knex expects a flat array where both identifiers and values are mixed in order.
|
|
21
|
+
*
|
|
22
|
+
* @param getColumnForField - function that resolves an entity field name to its database column name
|
|
23
|
+
*/
|
|
24
|
+
getKnexBindings(getColumnForField) {
|
|
25
|
+
return this.bindings.map((b) => {
|
|
26
|
+
switch (b.type) {
|
|
27
|
+
case 'entityField':
|
|
28
|
+
return getColumnForField(b.fieldName);
|
|
29
|
+
case 'identifier':
|
|
30
|
+
return b.name;
|
|
31
|
+
case 'value':
|
|
32
|
+
return b.value;
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Combine SQL fragments
|
|
38
|
+
*/
|
|
39
|
+
append(other) {
|
|
40
|
+
return joinSQLFragments([this, other], ' ');
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Join multiple SQL fragments with a comma separator.
|
|
44
|
+
* Useful for combining column lists, value lists, etc.
|
|
45
|
+
*
|
|
46
|
+
* @param fragments - Array of SQL fragments to join
|
|
47
|
+
* @returns - A new SQLFragment with the fragments joined by a comma and space
|
|
48
|
+
*/
|
|
49
|
+
static joinWithCommaSeparator(...fragments) {
|
|
50
|
+
return joinSQLFragments(fragments, ', ');
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Concatenate multiple SQL fragments with space separator.
|
|
54
|
+
* Useful for combining SQL clauses like WHERE, ORDER BY, etc.
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* ```ts
|
|
58
|
+
* const where = sql`WHERE age > ${18}`;
|
|
59
|
+
* const orderBy = sql`ORDER BY name`;
|
|
60
|
+
* const query = SQLFragment.concat(sql`SELECT * FROM users`, where, orderBy);
|
|
61
|
+
* // Generates: "SELECT * FROM users WHERE age > ? ORDER BY name"
|
|
62
|
+
* ```
|
|
63
|
+
*/
|
|
64
|
+
static concat(...fragments) {
|
|
65
|
+
return joinSQLFragments(fragments, ' ');
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Get a debug representation of the query with values inline
|
|
69
|
+
* WARNING: This is for debugging only. Never execute the returned string directly.
|
|
70
|
+
*/
|
|
71
|
+
getDebugString() {
|
|
72
|
+
let debugString = this.sql;
|
|
73
|
+
let bindingIndex = 0;
|
|
74
|
+
// Replace ?? and ? placeholders with actual values for debugging
|
|
75
|
+
debugString = debugString.replace(/\?\?|\?/g, (match) => {
|
|
76
|
+
if (bindingIndex >= this.bindings.length) {
|
|
77
|
+
return match;
|
|
78
|
+
}
|
|
79
|
+
const binding = this.bindings[bindingIndex];
|
|
80
|
+
if (!binding) {
|
|
81
|
+
return match;
|
|
82
|
+
}
|
|
83
|
+
bindingIndex++;
|
|
84
|
+
if (match === '??' && binding.type === 'identifier') {
|
|
85
|
+
// For identifiers, show them quoted as they would appear
|
|
86
|
+
return `"${binding.name.replace(/"/g, '""')}"`;
|
|
87
|
+
}
|
|
88
|
+
else if (match === '??' && binding.type === 'entityField') {
|
|
89
|
+
// For entity fields, show the entity field name as the identifier for debugging
|
|
90
|
+
return `"${binding.fieldName.toString()}"`;
|
|
91
|
+
}
|
|
92
|
+
else if (match === '?' && binding.type === 'value') {
|
|
93
|
+
return SQLFragment.formatDebugValue(binding.value);
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
// Mismatch between placeholder type and binding type
|
|
97
|
+
return match;
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
return debugString;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Format a value for debug output based on its type.
|
|
104
|
+
* Handles all SupportedSQLValue types.
|
|
105
|
+
*/
|
|
106
|
+
static formatDebugValue(value) {
|
|
107
|
+
// Handle null and undefined
|
|
108
|
+
if (value === null || value === undefined) {
|
|
109
|
+
return 'NULL';
|
|
110
|
+
}
|
|
111
|
+
// Handle primitives
|
|
112
|
+
if (typeof value === 'string') {
|
|
113
|
+
return `'${value.replace(/'/g, "''")}'`;
|
|
114
|
+
}
|
|
115
|
+
if (typeof value === 'number' || typeof value === 'bigint') {
|
|
116
|
+
return String(value);
|
|
117
|
+
}
|
|
118
|
+
if (typeof value === 'boolean') {
|
|
119
|
+
return value ? 'TRUE' : 'FALSE';
|
|
120
|
+
}
|
|
121
|
+
// Handle Date
|
|
122
|
+
if (value instanceof Date) {
|
|
123
|
+
return `'${value.toISOString()}'`;
|
|
124
|
+
}
|
|
125
|
+
// Handle Buffer
|
|
126
|
+
if (Buffer.isBuffer(value)) {
|
|
127
|
+
return `'\\x${value.toString('hex')}'`;
|
|
128
|
+
}
|
|
129
|
+
// Handle arrays (for IN clauses or array columns)
|
|
130
|
+
if (Array.isArray(value)) {
|
|
131
|
+
return `ARRAY[${value.map((v) => this.formatDebugValue(v)).join(', ')}]`;
|
|
132
|
+
}
|
|
133
|
+
// Handle objects (for JSON/JSONB columns)
|
|
134
|
+
if (typeof value === 'object' && SQLFragment.isPlainObjectForDebug(value)) {
|
|
135
|
+
return `'${JSON.stringify(value).replace(/'/g, "''")}'::jsonb`;
|
|
136
|
+
}
|
|
137
|
+
// Fallback (should never reach here with SupportedSQLValue but because this is used
|
|
138
|
+
// for debugging, there might be other values that we want to know about)
|
|
139
|
+
return `UnsupportedSQLValue[${String(value)}]`;
|
|
140
|
+
}
|
|
141
|
+
static isPlainObjectForDebug(obj) {
|
|
142
|
+
const proto = Object.getPrototypeOf(obj);
|
|
143
|
+
// Ensure it doesn't have a custom prototype (like a class would)
|
|
144
|
+
if (proto === null) {
|
|
145
|
+
return true; // Created via Object.create(null)
|
|
146
|
+
}
|
|
147
|
+
// Check if constructor is the base Object function
|
|
148
|
+
return proto.constructor === Object;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
exports.SQLFragment = SQLFragment;
|
|
152
|
+
/**
|
|
153
|
+
* Helper for SQL identifiers (table/column names).
|
|
154
|
+
* Stores the raw identifier name to be escaped by Knex using ?? placeholder.
|
|
155
|
+
*/
|
|
156
|
+
class SQLIdentifier {
|
|
157
|
+
name;
|
|
158
|
+
constructor(name) {
|
|
159
|
+
this.name = name;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
exports.SQLIdentifier = SQLIdentifier;
|
|
163
|
+
/**
|
|
164
|
+
* Helper for referencing entity fields that can be used in SQL queries. This allows for type-safe references to fields of an entity
|
|
165
|
+
* and does automatic translation to DB field names.
|
|
166
|
+
*/
|
|
167
|
+
class SQLEntityField {
|
|
168
|
+
fieldName;
|
|
169
|
+
constructor(fieldName) {
|
|
170
|
+
this.fieldName = fieldName;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
exports.SQLEntityField = SQLEntityField;
|
|
174
|
+
/**
|
|
175
|
+
* Helper for raw SQL that should not be parameterized
|
|
176
|
+
* WARNING: Only use this with trusted input to avoid SQL injection
|
|
177
|
+
*/
|
|
178
|
+
class SQLUnsafeRaw {
|
|
179
|
+
rawSql;
|
|
180
|
+
constructor(rawSql) {
|
|
181
|
+
this.rawSql = rawSql;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
exports.SQLUnsafeRaw = SQLUnsafeRaw;
|
|
185
|
+
/**
|
|
186
|
+
* Create a SQL identifier (table/column name) that will be escaped by Knex using ??.
|
|
187
|
+
*
|
|
188
|
+
* @example
|
|
189
|
+
* ```ts
|
|
190
|
+
* identifier('users') // Will be escaped as "users" in PostgreSQL
|
|
191
|
+
* identifier('my"table') // Will be escaped as "my""table" in PostgreSQL
|
|
192
|
+
* identifier('column"; DROP TABLE users; --') // Will be safely escaped
|
|
193
|
+
* ```
|
|
194
|
+
*/
|
|
195
|
+
function identifier(name) {
|
|
196
|
+
return new SQLIdentifier(name);
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Create a reference to an entity field that can be used in SQL queries. This allows for type-safe references to fields of an entity
|
|
200
|
+
* and does automatic translation to DB field names and will be escaped by Knex using ??.
|
|
201
|
+
*
|
|
202
|
+
* @param fieldName - The entity field name to reference.
|
|
203
|
+
*/
|
|
204
|
+
function entityField(fieldName) {
|
|
205
|
+
return new SQLEntityField(fieldName);
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Insert raw SQL that will not be parameterized
|
|
209
|
+
* WARNING: This bypasses SQL injection protection. Only use with trusted input.
|
|
210
|
+
*
|
|
211
|
+
* @example
|
|
212
|
+
* ```ts
|
|
213
|
+
* // Dynamic column names
|
|
214
|
+
* const sortColumn = 'created_at';
|
|
215
|
+
* const query = sql`ORDER BY ${unsafeRaw(sortColumn)} DESC`;
|
|
216
|
+
*
|
|
217
|
+
* // Dynamic SQL expressions
|
|
218
|
+
* const query = sql`WHERE ${unsafeRaw('EXTRACT(year FROM created_at)')} = ${2024}`;
|
|
219
|
+
* ```
|
|
220
|
+
*/
|
|
221
|
+
function unsafeRaw(sqlString) {
|
|
222
|
+
return new SQLUnsafeRaw(sqlString);
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Tagged template literal function for SQL queries
|
|
226
|
+
*
|
|
227
|
+
* @example
|
|
228
|
+
* ```ts
|
|
229
|
+
* const age = 18;
|
|
230
|
+
* const query = sql`age >= ${age} AND status = ${'active'}`;
|
|
231
|
+
* ```
|
|
232
|
+
*/
|
|
233
|
+
function sql(strings, ...values) {
|
|
234
|
+
let sqlString = '';
|
|
235
|
+
const bindings = [];
|
|
236
|
+
strings.forEach((string, i) => {
|
|
237
|
+
sqlString += string;
|
|
238
|
+
if (i < values.length) {
|
|
239
|
+
const value = values[i];
|
|
240
|
+
if (value instanceof SQLFragment) {
|
|
241
|
+
// Handle nested SQL fragments
|
|
242
|
+
sqlString += value.sql;
|
|
243
|
+
bindings.push(...value.bindings);
|
|
244
|
+
}
|
|
245
|
+
else if (value instanceof SQLIdentifier) {
|
|
246
|
+
// Handle identifiers (table/column names) with ?? placeholder
|
|
247
|
+
sqlString += '??';
|
|
248
|
+
bindings.push({ type: 'identifier', name: value.name });
|
|
249
|
+
}
|
|
250
|
+
else if (value instanceof SQLEntityField) {
|
|
251
|
+
// Handle entity field references by treating them as identifiers
|
|
252
|
+
sqlString += '??';
|
|
253
|
+
bindings.push({ type: 'entityField', fieldName: value.fieldName });
|
|
254
|
+
}
|
|
255
|
+
else if (value instanceof SQLUnsafeRaw) {
|
|
256
|
+
// Handle raw SQL (WARNING: no parameterization)
|
|
257
|
+
sqlString += value.rawSql;
|
|
258
|
+
}
|
|
259
|
+
else if (Array.isArray(value)) {
|
|
260
|
+
// Handle IN clauses
|
|
261
|
+
sqlString += `(${value.map(() => '?').join(', ')})`;
|
|
262
|
+
bindings.push(...value.map((v) => ({ type: 'value', value: v })));
|
|
263
|
+
}
|
|
264
|
+
else {
|
|
265
|
+
// Regular value binding
|
|
266
|
+
sqlString += '?';
|
|
267
|
+
bindings.push({ type: 'value', value });
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
});
|
|
271
|
+
return new SQLFragment(sqlString, bindings);
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Common SQL helper functions for building queries
|
|
275
|
+
*/
|
|
276
|
+
exports.SQLFragmentHelpers = {
|
|
277
|
+
/**
|
|
278
|
+
* IN clause helper
|
|
279
|
+
*
|
|
280
|
+
* @example
|
|
281
|
+
* ```ts
|
|
282
|
+
* const query = SQLFragmentHelpers.inArray<MyFields, 'id'>('status', ['active', 'pending']);
|
|
283
|
+
* // Generates: ?? IN (?, ?) with entityField binding for 'status' and value bindings
|
|
284
|
+
* ```
|
|
285
|
+
*/
|
|
286
|
+
inArray(fieldName, values) {
|
|
287
|
+
if (values.length === 0) {
|
|
288
|
+
// Handle empty array case - always false
|
|
289
|
+
return sql `1 = 0`;
|
|
290
|
+
}
|
|
291
|
+
return sql `${entityField(fieldName)} IN ${values}`;
|
|
292
|
+
},
|
|
293
|
+
/**
|
|
294
|
+
* NOT IN clause helper
|
|
295
|
+
*/
|
|
296
|
+
notInArray(fieldName, values) {
|
|
297
|
+
if (values.length === 0) {
|
|
298
|
+
// Handle empty array case - always true
|
|
299
|
+
return sql `1 = 1`;
|
|
300
|
+
}
|
|
301
|
+
return sql `${entityField(fieldName)} NOT IN ${values}`;
|
|
302
|
+
},
|
|
303
|
+
/**
|
|
304
|
+
* BETWEEN helper
|
|
305
|
+
*
|
|
306
|
+
* @example
|
|
307
|
+
* ```ts
|
|
308
|
+
* const query = SQLFragmentHelpers.between<MyFields, 'id'>('age', 18, 65);
|
|
309
|
+
* // Generates: ?? BETWEEN ? AND ? with entityField binding for 'age' and value bindings
|
|
310
|
+
* ```
|
|
311
|
+
*/
|
|
312
|
+
between(fieldName, min, max) {
|
|
313
|
+
return sql `${entityField(fieldName)} BETWEEN ${min} AND ${max}`;
|
|
314
|
+
},
|
|
315
|
+
/**
|
|
316
|
+
* NOT BETWEEN helper
|
|
317
|
+
*/
|
|
318
|
+
notBetween(fieldName, min, max) {
|
|
319
|
+
return sql `${entityField(fieldName)} NOT BETWEEN ${min} AND ${max}`;
|
|
320
|
+
},
|
|
321
|
+
/**
|
|
322
|
+
* LIKE helper with automatic escaping
|
|
323
|
+
*
|
|
324
|
+
* @example
|
|
325
|
+
* ```ts
|
|
326
|
+
* const query = SQLFragmentHelpers.like<MyFields, 'id'>('name', '%John%');
|
|
327
|
+
* // Generates: ?? LIKE ? with entityField binding for 'name' and value binding
|
|
328
|
+
* ```
|
|
329
|
+
*/
|
|
330
|
+
like(fieldName, pattern) {
|
|
331
|
+
return sql `${entityField(fieldName)} LIKE ${pattern}`;
|
|
332
|
+
},
|
|
333
|
+
/**
|
|
334
|
+
* NOT LIKE helper
|
|
335
|
+
*/
|
|
336
|
+
notLike(fieldName, pattern) {
|
|
337
|
+
return sql `${entityField(fieldName)} NOT LIKE ${pattern}`;
|
|
338
|
+
},
|
|
339
|
+
/**
|
|
340
|
+
* ILIKE helper for case-insensitive matching
|
|
341
|
+
*/
|
|
342
|
+
ilike(fieldName, pattern) {
|
|
343
|
+
return sql `${entityField(fieldName)} ILIKE ${pattern}`;
|
|
344
|
+
},
|
|
345
|
+
/**
|
|
346
|
+
* NOT ILIKE helper for case-insensitive non-matching
|
|
347
|
+
*/
|
|
348
|
+
notIlike(fieldName, pattern) {
|
|
349
|
+
return sql `${entityField(fieldName)} NOT ILIKE ${pattern}`;
|
|
350
|
+
},
|
|
351
|
+
/**
|
|
352
|
+
* NULL check helper
|
|
353
|
+
*/
|
|
354
|
+
isNull(fieldName) {
|
|
355
|
+
return sql `${entityField(fieldName)} IS NULL`;
|
|
356
|
+
},
|
|
357
|
+
/**
|
|
358
|
+
* NOT NULL check helper
|
|
359
|
+
*/
|
|
360
|
+
isNotNull(fieldName) {
|
|
361
|
+
return sql `${entityField(fieldName)} IS NOT NULL`;
|
|
362
|
+
},
|
|
363
|
+
/**
|
|
364
|
+
* Single-equals-equality operator
|
|
365
|
+
*/
|
|
366
|
+
eq(fieldName, value) {
|
|
367
|
+
if (value === null || value === undefined) {
|
|
368
|
+
return exports.SQLFragmentHelpers.isNull(fieldName);
|
|
369
|
+
}
|
|
370
|
+
return sql `${entityField(fieldName)} = ${value}`;
|
|
371
|
+
},
|
|
372
|
+
/**
|
|
373
|
+
* Single-equals-inequality operator
|
|
374
|
+
*/
|
|
375
|
+
neq(fieldName, value) {
|
|
376
|
+
if (value === null || value === undefined) {
|
|
377
|
+
return exports.SQLFragmentHelpers.isNotNull(fieldName);
|
|
378
|
+
}
|
|
379
|
+
return sql `${entityField(fieldName)} != ${value}`;
|
|
380
|
+
},
|
|
381
|
+
/**
|
|
382
|
+
* Greater-than comparison operator
|
|
383
|
+
*/
|
|
384
|
+
gt(fieldName, value) {
|
|
385
|
+
return sql `${entityField(fieldName)} > ${value}`;
|
|
386
|
+
},
|
|
387
|
+
/**
|
|
388
|
+
* Greater-than-or-equal-to comparison operator
|
|
389
|
+
*/
|
|
390
|
+
gte(fieldName, value) {
|
|
391
|
+
return sql `${entityField(fieldName)} >= ${value}`;
|
|
392
|
+
},
|
|
393
|
+
/**
|
|
394
|
+
* Less-than comparison operator
|
|
395
|
+
*/
|
|
396
|
+
lt(fieldName, value) {
|
|
397
|
+
return sql `${entityField(fieldName)} < ${value}`;
|
|
398
|
+
},
|
|
399
|
+
/**
|
|
400
|
+
* Less-than-or-equal-to comparison operator
|
|
401
|
+
*/
|
|
402
|
+
lte(fieldName, value) {
|
|
403
|
+
return sql `${entityField(fieldName)} <= ${value}`;
|
|
404
|
+
},
|
|
405
|
+
/**
|
|
406
|
+
* JSON contains operator (\@\>)
|
|
407
|
+
*/
|
|
408
|
+
jsonContains(fieldName, value) {
|
|
409
|
+
return sql `${entityField(fieldName)} @> ${JSON.stringify(value)}::jsonb`;
|
|
410
|
+
},
|
|
411
|
+
/**
|
|
412
|
+
* JSON contained by operator (\<\@\)
|
|
413
|
+
*/
|
|
414
|
+
jsonContainedBy(fieldName, value) {
|
|
415
|
+
return sql `${entityField(fieldName)} <@ ${JSON.stringify(value)}::jsonb`;
|
|
416
|
+
},
|
|
417
|
+
/**
|
|
418
|
+
* JSON path extraction helper (-\>)
|
|
419
|
+
*/
|
|
420
|
+
jsonPath(fieldName, path) {
|
|
421
|
+
return sql `${entityField(fieldName)}->${path}`;
|
|
422
|
+
},
|
|
423
|
+
/**
|
|
424
|
+
* JSON path text extraction helper (-\>\>)
|
|
425
|
+
*/
|
|
426
|
+
jsonPathText(fieldName, path) {
|
|
427
|
+
return sql `${entityField(fieldName)}->>${path}`;
|
|
428
|
+
},
|
|
429
|
+
/**
|
|
430
|
+
* Logical AND of multiple fragments
|
|
431
|
+
*/
|
|
432
|
+
and(...conditions) {
|
|
433
|
+
if (conditions.length === 0) {
|
|
434
|
+
return sql `1 = 1`;
|
|
435
|
+
}
|
|
436
|
+
return joinSQLFragments(conditions.map((c) => exports.SQLFragmentHelpers.group(c)), ' AND ');
|
|
437
|
+
},
|
|
438
|
+
/**
|
|
439
|
+
* Logical OR of multiple fragments
|
|
440
|
+
*/
|
|
441
|
+
or(...conditions) {
|
|
442
|
+
if (conditions.length === 0) {
|
|
443
|
+
return sql `1 = 0`;
|
|
444
|
+
}
|
|
445
|
+
return joinSQLFragments(conditions.map((c) => exports.SQLFragmentHelpers.group(c)), ' OR ');
|
|
446
|
+
},
|
|
447
|
+
/**
|
|
448
|
+
* Logical NOT of a fragment
|
|
449
|
+
*/
|
|
450
|
+
not(condition) {
|
|
451
|
+
return new SQLFragment('NOT (' + condition.sql + ')', condition.bindings);
|
|
452
|
+
},
|
|
453
|
+
/**
|
|
454
|
+
* Parentheses helper for grouping conditions
|
|
455
|
+
*/
|
|
456
|
+
group(condition) {
|
|
457
|
+
return new SQLFragment('(' + condition.sql + ')', condition.bindings);
|
|
458
|
+
},
|
|
459
|
+
};
|
|
460
|
+
// Internal helper function to join SQL fragments with a specified separator
|
|
461
|
+
function joinSQLFragments(fragments, separator) {
|
|
462
|
+
return new SQLFragment(fragments.map((f) => f.sql).join(separator), fragments.flatMap((f) => f.bindings));
|
|
463
|
+
}
|
|
464
|
+
//# sourceMappingURL=SQLOperator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SQLOperator.js","sourceRoot":"","sources":["../../src/SQLOperator.ts"],"names":[],"mappings":";;;AA2NA,gCAEC;AAQD,kCAIC;AAgBD,8BAEC;AAWD,kBA8CC;AA5RD;;GAEG;AACH,MAAa,WAAW;IAEJ;IACA;IAFlB,YACkB,GAAW,EACX,QAAwC;QADxC,QAAG,GAAH,GAAG,CAAQ;QACX,aAAQ,GAAR,QAAQ,CAAgC;IACvD,CAAC;IAEJ;;;;;OAKG;IACH,eAAe,CACb,iBAAuD;QAEvD,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;YAC7B,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC;gBACf,KAAK,aAAa;oBAChB,OAAO,iBAAiB,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;gBACxC,KAAK,YAAY;oBACf,OAAO,CAAC,CAAC,IAAI,CAAC;gBAChB,KAAK,OAAO;oBACV,OAAO,CAAC,CAAC,KAAK,CAAC;YACnB,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,KAA2B;QAChC,OAAO,gBAAgB,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC;IAC9C,CAAC;IAED;;;;;;OAMG;IACH,MAAM,CAAC,sBAAsB,CAC3B,GAAG,SAA0C;QAE7C,OAAO,gBAAgB,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IAC3C,CAAC;IAED;;;;;;;;;;;OAWG;IACH,MAAM,CAAC,MAAM,CACX,GAAG,SAA0C;QAE7C,OAAO,gBAAgB,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;IAC1C,CAAC;IAED;;;OAGG;IACH,cAAc;QACZ,IAAI,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC;QAC3B,IAAI,YAAY,GAAG,CAAC,CAAC;QAErB,iEAAiE;QACjE,WAAW,GAAG,WAAW,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC,KAAK,EAAE,EAAE;YACtD,IAAI,YAAY,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;gBACzC,OAAO,KAAK,CAAC;YACf,CAAC;YACD,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;YAC5C,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,OAAO,KAAK,CAAC;YACf,CAAC;YACD,YAAY,EAAE,CAAC;YAEf,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;gBACpD,yDAAyD;gBACzD,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC;YACjD,CAAC;iBAAM,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;gBAC5D,gFAAgF;gBAChF,OAAO,IAAI,OAAO,CAAC,SAAS,CAAC,QAAQ,EAAE,GAAG,CAAC;YAC7C,CAAC;iBAAM,IAAI,KAAK,KAAK,GAAG,IAAI,OAAO,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;gBACrD,OAAO,WAAW,CAAC,gBAAgB,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YACrD,CAAC;iBAAM,CAAC;gBACN,qDAAqD;gBACrD,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,OAAO,WAAW,CAAC;IACrB,CAAC;IAED;;;OAGG;IACK,MAAM,CAAC,gBAAgB,CAAC,KAAwB;QACtD,4BAA4B;QAC5B,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YAC1C,OAAO,MAAM,CAAC;QAChB,CAAC;QAED,oBAAoB;QACpB,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC9B,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC;QAC1C,CAAC;QACD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC3D,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;QACvB,CAAC;QACD,IAAI,OAAO,KAAK,KAAK,SAAS,EAAE,CAAC;YAC/B,OAAO,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC;QAClC,CAAC;QAED,cAAc;QACd,IAAI,KAAK,YAAY,IAAI,EAAE,CAAC;YAC1B,OAAO,IAAI,KAAK,CAAC,WAAW,EAAE,GAAG,CAAC;QACpC,CAAC;QAED,gBAAgB;QAChB,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YAC3B,OAAO,OAAO,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC;QACzC,CAAC;QAED,kDAAkD;QAClD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACzB,OAAO,SAAS,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;QAC3E,CAAC;QAED,0CAA0C;QAC1C,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,WAAW,CAAC,qBAAqB,CAAC,KAAK,CAAC,EAAE,CAAC;YAC1E,OAAO,IAAI,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,UAAU,CAAC;QACjE,CAAC;QAED,oFAAoF;QACpF,yEAAyE;QACzE,OAAO,uBAAuB,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC;IACjD,CAAC;IAEO,MAAM,CAAC,qBAAqB,CAAC,GAAW;QAC9C,MAAM,KAAK,GAAG,MAAM,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;QACzC,iEAAiE;QACjE,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YACnB,OAAO,IAAI,CAAC,CAAC,kCAAkC;QACjD,CAAC;QACD,mDAAmD;QACnD,OAAO,KAAK,CAAC,WAAW,KAAK,MAAM,CAAC;IACtC,CAAC;CACF;AA5JD,kCA4JC;AAED;;;GAGG;AACH,MAAa,aAAa;IACI;IAA5B,YAA4B,IAAY;QAAZ,SAAI,GAAJ,IAAI,CAAQ;IAAG,CAAC;CAC7C;AAFD,sCAEC;AAED;;;GAGG;AACH,MAAa,cAAc;IACG;IAA5B,YAA4B,SAAwB;QAAxB,cAAS,GAAT,SAAS,CAAe;IAAG,CAAC;CACzD;AAFD,wCAEC;AAED;;;GAGG;AACH,MAAa,YAAY;IACK;IAA5B,YAA4B,MAAc;QAAd,WAAM,GAAN,MAAM,CAAQ;IAAG,CAAC;CAC/C;AAFD,oCAEC;AAED;;;;;;;;;GASG;AACH,SAAgB,UAAU,CAAC,IAAY;IACrC,OAAO,IAAI,aAAa,CAAC,IAAI,CAAC,CAAC;AACjC,CAAC;AAED;;;;;GAKG;AACH,SAAgB,WAAW,CACzB,SAAwB;IAExB,OAAO,IAAI,cAAc,CAAC,SAAS,CAAC,CAAC;AACvC,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,SAAgB,SAAS,CAAC,SAAiB;IACzC,OAAO,IAAI,YAAY,CAAC,SAAS,CAAC,CAAC;AACrC,CAAC;AAED;;;;;;;;GAQG;AACH,SAAgB,GAAG,CACjB,OAA6B,EAC7B,GAAG,MAMA;IAEH,IAAI,SAAS,GAAG,EAAE,CAAC;IACnB,MAAM,QAAQ,GAA0B,EAAE,CAAC;IAE3C,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;QAC5B,SAAS,IAAI,MAAM,CAAC;QACpB,IAAI,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC;YACtB,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;YAExB,IAAI,KAAK,YAAY,WAAW,EAAE,CAAC;gBACjC,8BAA8B;gBAC9B,SAAS,IAAI,KAAK,CAAC,GAAG,CAAC;gBACvB,QAAQ,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC;YACnC,CAAC;iBAAM,IAAI,KAAK,YAAY,aAAa,EAAE,CAAC;gBAC1C,8DAA8D;gBAC9D,SAAS,IAAI,IAAI,CAAC;gBAClB,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;YAC1D,CAAC;iBAAM,IAAI,KAAK,YAAY,cAAc,EAAE,CAAC;gBAC3C,iEAAiE;gBACjE,SAAS,IAAI,IAAI,CAAC;gBAClB,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC;YACrE,CAAC;iBAAM,IAAI,KAAK,YAAY,YAAY,EAAE,CAAC;gBACzC,gDAAgD;gBAChD,SAAS,IAAI,KAAK,CAAC,MAAM,CAAC;YAC5B,CAAC;iBAAM,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;gBAChC,oBAAoB;gBACpB,SAAS,IAAI,IAAI,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;gBACpD,QAAQ,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAuB,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YACzF,CAAC;iBAAM,CAAC;gBACN,wBAAwB;gBACxB,SAAS,IAAI,GAAG,CAAC;gBACjB,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;YAC1C,CAAC;QACH,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,IAAI,WAAW,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;AAC9C,CAAC;AAMD;;GAEG;AACU,QAAA,kBAAkB,GAAG;IAChC;;;;;;;;OAQG;IACH,OAAO,CACL,SAAY,EACZ,MAA6B;QAE7B,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,yCAAyC;YACzC,OAAO,GAAG,CAAA,OAAO,CAAC;QACpB,CAAC;QACD,OAAO,GAAG,CAAA,GAAG,WAAW,CAAC,SAAS,CAAC,OAAO,MAAM,EAAE,CAAC;IACrD,CAAC;IAED;;OAEG;IACH,UAAU,CACR,SAAY,EACZ,MAA6B;QAE7B,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,wCAAwC;YACxC,OAAO,GAAG,CAAA,OAAO,CAAC;QACpB,CAAC;QACD,OAAO,GAAG,CAAA,GAAG,WAAW,CAAC,SAAS,CAAC,WAAW,MAAM,EAAE,CAAC;IACzD,CAAC;IAED;;;;;;;;OAQG;IACH,OAAO,CACL,SAAY,EACZ,GAAe,EACf,GAAe;QAEf,OAAO,GAAG,CAAA,GAAG,WAAW,CAAC,SAAS,CAAC,YAAY,GAAG,QAAQ,GAAG,EAAE,CAAC;IAClE,CAAC;IAED;;OAEG;IACH,UAAU,CACR,SAAY,EACZ,GAAe,EACf,GAAe;QAEf,OAAO,GAAG,CAAA,GAAG,WAAW,CAAC,SAAS,CAAC,gBAAgB,GAAG,QAAQ,GAAG,EAAE,CAAC;IACtE,CAAC;IAED;;;;;;;;OAQG;IACH,IAAI,CACF,SAAwB,EACxB,OAAe;QAEf,OAAO,GAAG,CAAA,GAAG,WAAW,CAAC,SAAS,CAAC,SAAS,OAAO,EAAE,CAAC;IACxD,CAAC;IAED;;OAEG;IACH,OAAO,CACL,SAAwB,EACxB,OAAe;QAEf,OAAO,GAAG,CAAA,GAAG,WAAW,CAAC,SAAS,CAAC,aAAa,OAAO,EAAE,CAAC;IAC5D,CAAC;IAED;;OAEG;IACH,KAAK,CACH,SAAwB,EACxB,OAAe;QAEf,OAAO,GAAG,CAAA,GAAG,WAAW,CAAC,SAAS,CAAC,UAAU,OAAO,EAAE,CAAC;IACzD,CAAC;IAED;;OAEG;IACH,QAAQ,CACN,SAAwB,EACxB,OAAe;QAEf,OAAO,GAAG,CAAA,GAAG,WAAW,CAAC,SAAS,CAAC,cAAc,OAAO,EAAE,CAAC;IAC7D,CAAC;IAED;;OAEG;IACH,MAAM,CAAsC,SAAwB;QAClE,OAAO,GAAG,CAAA,GAAG,WAAW,CAAC,SAAS,CAAC,UAAU,CAAC;IAChD,CAAC;IAED;;OAEG;IACH,SAAS,CAAsC,SAAwB;QACrE,OAAO,GAAG,CAAA,GAAG,WAAW,CAAC,SAAS,CAAC,cAAc,CAAC;IACpD,CAAC;IAED;;OAEG;IACH,EAAE,CACA,SAAY,EACZ,KAAiB;QAEjB,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YAC1C,OAAO,0BAAkB,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAC9C,CAAC;QACD,OAAO,GAAG,CAAA,GAAG,WAAW,CAAC,SAAS,CAAC,MAAM,KAAK,EAAE,CAAC;IACnD,CAAC;IAED;;OAEG;IACH,GAAG,CACD,SAAY,EACZ,KAAiB;QAEjB,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YAC1C,OAAO,0BAAkB,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QACjD,CAAC;QACD,OAAO,GAAG,CAAA,GAAG,WAAW,CAAC,SAAS,CAAC,OAAO,KAAK,EAAE,CAAC;IACpD,CAAC;IAED;;OAEG;IACH,EAAE,CACA,SAAY,EACZ,KAAiB;QAEjB,OAAO,GAAG,CAAA,GAAG,WAAW,CAAC,SAAS,CAAC,MAAM,KAAK,EAAE,CAAC;IACnD,CAAC;IAED;;OAEG;IACH,GAAG,CACD,SAAY,EACZ,KAAiB;QAEjB,OAAO,GAAG,CAAA,GAAG,WAAW,CAAC,SAAS,CAAC,OAAO,KAAK,EAAE,CAAC;IACpD,CAAC;IAED;;OAEG;IACH,EAAE,CACA,SAAY,EACZ,KAAiB;QAEjB,OAAO,GAAG,CAAA,GAAG,WAAW,CAAC,SAAS,CAAC,MAAM,KAAK,EAAE,CAAC;IACnD,CAAC;IAED;;OAEG;IACH,GAAG,CACD,SAAY,EACZ,KAAiB;QAEjB,OAAO,GAAG,CAAA,GAAG,WAAW,CAAC,SAAS,CAAC,OAAO,KAAK,EAAE,CAAC;IACpD,CAAC;IAED;;OAEG;IACH,YAAY,CACV,SAAwB,EACxB,KAAc;QAEd,OAAO,GAAG,CAAA,GAAG,WAAW,CAAC,SAAS,CAAC,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,SAAS,CAAC;IAC3E,CAAC;IAED;;OAEG;IACH,eAAe,CACb,SAAwB,EACxB,KAAc;QAEd,OAAO,GAAG,CAAA,GAAG,WAAW,CAAC,SAAS,CAAC,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,SAAS,CAAC;IAC3E,CAAC;IAED;;OAEG;IACH,QAAQ,CACN,SAAwB,EACxB,IAAY;QAEZ,OAAO,GAAG,CAAA,GAAG,WAAW,CAAC,SAAS,CAAC,KAAK,IAAI,EAAE,CAAC;IACjD,CAAC;IAED;;OAEG;IACH,YAAY,CACV,SAAwB,EACxB,IAAY;QAEZ,OAAO,GAAG,CAAA,GAAG,WAAW,CAAC,SAAS,CAAC,MAAM,IAAI,EAAE,CAAC;IAClD,CAAC;IAED;;OAEG;IACH,GAAG,CACD,GAAG,UAA2C;QAE9C,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC5B,OAAO,GAAG,CAAA,OAAO,CAAC;QACpB,CAAC;QACD,OAAO,gBAAgB,CACrB,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,0BAAkB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAClD,OAAO,CACR,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,EAAE,CACA,GAAG,UAA2C;QAE9C,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC5B,OAAO,GAAG,CAAA,OAAO,CAAC;QACpB,CAAC;QACD,OAAO,gBAAgB,CACrB,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,0BAAkB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAClD,MAAM,CACP,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,GAAG,CAAsC,SAA+B;QACtE,OAAO,IAAI,WAAW,CAAC,OAAO,GAAG,SAAS,CAAC,GAAG,GAAG,GAAG,EAAE,SAAS,CAAC,QAAQ,CAAC,CAAC;IAC5E,CAAC;IAED;;OAEG;IACH,KAAK,CACH,SAA+B;QAE/B,OAAO,IAAI,WAAW,CAAC,GAAG,GAAG,SAAS,CAAC,GAAG,GAAG,GAAG,EAAE,SAAS,CAAC,QAAQ,CAAC,CAAC;IACxE,CAAC;CACF,CAAC;AAEF,4EAA4E;AAC5E,SAAS,gBAAgB,CACvB,SAA0C,EAC1C,SAAiB;IAEjB,OAAO,IAAI,WAAW,CACpB,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,EAC3C,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CACrC,CAAC;AACJ,CAAC"}
|
package/build/src/index.d.ts
CHANGED
|
@@ -2,8 +2,23 @@
|
|
|
2
2
|
* @packageDocumentation
|
|
3
3
|
* @module @expo/entity-database-adapter-knex
|
|
4
4
|
*/
|
|
5
|
+
export * from './AuthorizationResultBasedKnexEntityLoader';
|
|
6
|
+
export * from './BasePostgresEntityDatabaseAdapter';
|
|
7
|
+
export * from './BaseSQLQueryBuilder';
|
|
8
|
+
export * from './EnforcingKnexEntityLoader';
|
|
5
9
|
export * from './EntityFields';
|
|
10
|
+
export * from './KnexEntityLoaderFactory';
|
|
11
|
+
export * from './knexLoader';
|
|
12
|
+
export * from './PaginationStrategy';
|
|
13
|
+
export * from './PostgresEntity';
|
|
6
14
|
export * from './PostgresEntityDatabaseAdapter';
|
|
7
15
|
export * from './PostgresEntityDatabaseAdapterProvider';
|
|
8
16
|
export * from './PostgresEntityQueryContextProvider';
|
|
17
|
+
export * from './ReadonlyPostgresEntity';
|
|
18
|
+
export * from './SQLOperator';
|
|
9
19
|
export * from './errors/wrapNativePostgresCallAsync';
|
|
20
|
+
export * from './internal/EntityKnexDataManager';
|
|
21
|
+
export * from './internal/getKnexDataManager';
|
|
22
|
+
export * from './internal/getKnexEntityLoaderFactory';
|
|
23
|
+
export * from './internal/utilityTypes';
|
|
24
|
+
export * from './internal/weakMaps';
|
package/build/src/index.js
CHANGED
|
@@ -19,9 +19,24 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
19
19
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
20
20
|
};
|
|
21
21
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
+
__exportStar(require("./AuthorizationResultBasedKnexEntityLoader"), exports);
|
|
23
|
+
__exportStar(require("./BasePostgresEntityDatabaseAdapter"), exports);
|
|
24
|
+
__exportStar(require("./BaseSQLQueryBuilder"), exports);
|
|
25
|
+
__exportStar(require("./EnforcingKnexEntityLoader"), exports);
|
|
22
26
|
__exportStar(require("./EntityFields"), exports);
|
|
27
|
+
__exportStar(require("./KnexEntityLoaderFactory"), exports);
|
|
28
|
+
__exportStar(require("./knexLoader"), exports);
|
|
29
|
+
__exportStar(require("./PaginationStrategy"), exports);
|
|
30
|
+
__exportStar(require("./PostgresEntity"), exports);
|
|
23
31
|
__exportStar(require("./PostgresEntityDatabaseAdapter"), exports);
|
|
24
32
|
__exportStar(require("./PostgresEntityDatabaseAdapterProvider"), exports);
|
|
25
33
|
__exportStar(require("./PostgresEntityQueryContextProvider"), exports);
|
|
34
|
+
__exportStar(require("./ReadonlyPostgresEntity"), exports);
|
|
35
|
+
__exportStar(require("./SQLOperator"), exports);
|
|
26
36
|
__exportStar(require("./errors/wrapNativePostgresCallAsync"), exports);
|
|
37
|
+
__exportStar(require("./internal/EntityKnexDataManager"), exports);
|
|
38
|
+
__exportStar(require("./internal/getKnexDataManager"), exports);
|
|
39
|
+
__exportStar(require("./internal/getKnexEntityLoaderFactory"), exports);
|
|
40
|
+
__exportStar(require("./internal/utilityTypes"), exports);
|
|
41
|
+
__exportStar(require("./internal/weakMaps"), exports);
|
|
27
42
|
//# sourceMappingURL=index.js.map
|
package/build/src/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AAAA,iCAAiC;AACjC;;;GAGG;;;;;;;;;;;;;;;;AAEH,iDAA+B;AAC/B,kEAAgD;AAChD,0EAAwD;AACxD,uEAAqD;AACrD,uEAAqD"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AAAA,iCAAiC;AACjC;;;GAGG;;;;;;;;;;;;;;;;AAEH,6EAA2D;AAC3D,sEAAoD;AACpD,wDAAsC;AACtC,8DAA4C;AAC5C,iDAA+B;AAC/B,4DAA0C;AAC1C,+CAA6B;AAC7B,uDAAqC;AACrC,mDAAiC;AACjC,kEAAgD;AAChD,0EAAwD;AACxD,uEAAqD;AACrD,2DAAyC;AACzC,gDAA8B;AAC9B,uEAAqD;AACrD,mEAAiD;AACjD,gEAA8C;AAC9C,wEAAsD;AACtD,0DAAwC;AACxC,sDAAoC"}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { EntityQueryContext, IEntityMetricsAdapter, EntityConfiguration } from '@expo/entity';
|
|
2
|
+
import { BasePostgresEntityDatabaseAdapter, FieldEqualityCondition, PostgresOrderByClause, PostgresQuerySelectionModifiers } from '../BasePostgresEntityDatabaseAdapter';
|
|
3
|
+
import { PaginationStrategy } from '../PaginationStrategy';
|
|
4
|
+
import { SQLFragment } from '../SQLOperator';
|
|
5
|
+
import { NonNullableKeys } from './utilityTypes';
|
|
6
|
+
interface DataManagerStandardSpecification<TFields extends Record<string, any>> {
|
|
7
|
+
strategy: PaginationStrategy.STANDARD;
|
|
8
|
+
orderBy: readonly PostgresOrderByClause<TFields>[];
|
|
9
|
+
}
|
|
10
|
+
type DataManagerFieldNameConstructorFn<TFields extends Record<string, any>> = (fieldName: keyof TFields) => SQLFragment<TFields>;
|
|
11
|
+
type DataManagerSearchFieldSQLFragmentFnSpecification<TFields extends Record<string, any>> = {
|
|
12
|
+
fieldConstructor: (getFragmentForFieldName: DataManagerFieldNameConstructorFn<TFields>) => SQLFragment<TFields>;
|
|
13
|
+
};
|
|
14
|
+
type DataManagerSearchFieldSpecification<TFields extends Record<string, any>> = NonNullableKeys<TFields> | DataManagerSearchFieldSQLFragmentFnSpecification<TFields>;
|
|
15
|
+
interface DataManagerSearchSpecificationBase<TFields extends Record<string, any>> {
|
|
16
|
+
term: string;
|
|
17
|
+
fields: readonly DataManagerSearchFieldSpecification<TFields>[];
|
|
18
|
+
}
|
|
19
|
+
interface DataManagerILikeSearchSpecification<TFields extends Record<string, any>> extends DataManagerSearchSpecificationBase<TFields> {
|
|
20
|
+
strategy: PaginationStrategy.ILIKE_SEARCH;
|
|
21
|
+
}
|
|
22
|
+
interface DataManagerTrigramSearchSpecification<TFields extends Record<string, any>> extends DataManagerSearchSpecificationBase<TFields> {
|
|
23
|
+
strategy: PaginationStrategy.TRIGRAM_SEARCH;
|
|
24
|
+
threshold: number;
|
|
25
|
+
extraOrderByFields?: readonly DataManagerSearchFieldSpecification<TFields>[];
|
|
26
|
+
}
|
|
27
|
+
type DataManagerSearchSpecification<TFields extends Record<string, any>> = DataManagerILikeSearchSpecification<TFields> | DataManagerTrigramSearchSpecification<TFields>;
|
|
28
|
+
type DataManagerPaginationSpecification<TFields extends Record<string, any>> = DataManagerStandardSpecification<TFields> | DataManagerSearchSpecification<TFields>;
|
|
29
|
+
interface BaseUnifiedPaginationArgs<TFields extends Record<string, any>> {
|
|
30
|
+
where?: SQLFragment<TFields>;
|
|
31
|
+
pagination: DataManagerPaginationSpecification<TFields>;
|
|
32
|
+
}
|
|
33
|
+
interface ForwardUnifiedPaginationArgs<TFields extends Record<string, any>> extends BaseUnifiedPaginationArgs<TFields> {
|
|
34
|
+
first: number;
|
|
35
|
+
last?: never;
|
|
36
|
+
before?: never;
|
|
37
|
+
after?: string;
|
|
38
|
+
}
|
|
39
|
+
interface BackwardUnifiedPaginationArgs<TFields extends Record<string, any>> extends BaseUnifiedPaginationArgs<TFields> {
|
|
40
|
+
first?: never;
|
|
41
|
+
last: number;
|
|
42
|
+
before?: string;
|
|
43
|
+
after?: never;
|
|
44
|
+
}
|
|
45
|
+
type LoadPageArgs<TFields extends Record<string, any>> = ForwardUnifiedPaginationArgs<TFields> | BackwardUnifiedPaginationArgs<TFields>;
|
|
46
|
+
/**
|
|
47
|
+
* Edge in a connection
|
|
48
|
+
*/
|
|
49
|
+
export interface Edge<TNode> {
|
|
50
|
+
cursor: string;
|
|
51
|
+
node: TNode;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Page information for pagination
|
|
55
|
+
*/
|
|
56
|
+
export interface PageInfo {
|
|
57
|
+
hasNextPage: boolean;
|
|
58
|
+
hasPreviousPage: boolean;
|
|
59
|
+
startCursor: string | null;
|
|
60
|
+
endCursor: string | null;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Relay-style Connection type
|
|
64
|
+
*/
|
|
65
|
+
export interface Connection<TNode> {
|
|
66
|
+
edges: readonly Edge<TNode>[];
|
|
67
|
+
pageInfo: PageInfo;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* A knex data manager is responsible for handling non-dataloader-based
|
|
71
|
+
* database operations.
|
|
72
|
+
*
|
|
73
|
+
* @internal
|
|
74
|
+
*/
|
|
75
|
+
export declare class EntityKnexDataManager<TFields extends Record<string, any>, TIDField extends keyof TFields> {
|
|
76
|
+
private readonly entityConfiguration;
|
|
77
|
+
private readonly databaseAdapter;
|
|
78
|
+
private readonly metricsAdapter;
|
|
79
|
+
private readonly entityClassName;
|
|
80
|
+
constructor(entityConfiguration: EntityConfiguration<TFields, TIDField>, databaseAdapter: BasePostgresEntityDatabaseAdapter<TFields, TIDField>, metricsAdapter: IEntityMetricsAdapter, entityClassName: string);
|
|
81
|
+
/**
|
|
82
|
+
* Loads many objects matching the conjunction of where clauses constructed from
|
|
83
|
+
* specified field equality operands.
|
|
84
|
+
*
|
|
85
|
+
* @param queryContext - query context in which to perform the load
|
|
86
|
+
* @param fieldEqualityOperands - list of field equality where clause operand specifications
|
|
87
|
+
* @param querySelectionModifiers - limit, offset, and orderBy for the query
|
|
88
|
+
* @returns array of objects matching the query
|
|
89
|
+
*/
|
|
90
|
+
loadManyByFieldEqualityConjunctionAsync<N extends keyof TFields>(queryContext: EntityQueryContext, fieldEqualityOperands: readonly FieldEqualityCondition<TFields, N>[], querySelectionModifiers: PostgresQuerySelectionModifiers<TFields>): Promise<readonly Readonly<TFields>[]>;
|
|
91
|
+
/**
|
|
92
|
+
* Loads many objects matching the raw WHERE clause.
|
|
93
|
+
*
|
|
94
|
+
* @param queryContext - query context in which to perform the load
|
|
95
|
+
* @param rawWhereClause - parameterized SQL WHERE clause with positional binding placeholders or named binding placeholders
|
|
96
|
+
* @param bindings - array of positional bindings or object of named bindings
|
|
97
|
+
* @param querySelectionModifiers - limit, offset, orderBy, and orderByRaw for the query
|
|
98
|
+
* @returns array of objects matching the query
|
|
99
|
+
*/
|
|
100
|
+
loadManyByRawWhereClauseAsync(queryContext: EntityQueryContext, rawWhereClause: string, bindings: readonly any[] | object, querySelectionModifiers: PostgresQuerySelectionModifiers<TFields>): Promise<readonly Readonly<TFields>[]>;
|
|
101
|
+
loadManyBySQLFragmentAsync(queryContext: EntityQueryContext, sqlFragment: SQLFragment<TFields>, querySelectionModifiers: PostgresQuerySelectionModifiers<TFields>): Promise<readonly Readonly<TFields>[]>;
|
|
102
|
+
/**
|
|
103
|
+
* Load a page of objects using cursor-based pagination with unified pagination specification.
|
|
104
|
+
*
|
|
105
|
+
* @remarks
|
|
106
|
+
*
|
|
107
|
+
* This method implements cursor-based pagination using the seek method for efficient pagination even on large datasets
|
|
108
|
+
* given appropriate indexes. Cursors are opaque and encode the necessary information to fetch the next page based on the
|
|
109
|
+
* specified pagination strategy (standard, ILIKE search, or trigram search). For this implementation in particular,
|
|
110
|
+
* the cursor encodes the ID of the last entity in the page to ensure correct pagination for all strategies, even in cases
|
|
111
|
+
* where multiple rows have the same value for all fields other than the ID. If the entity referenced by a cursor has been
|
|
112
|
+
* deleted, the load will return an empty page with `hasNextPage: false`.
|
|
113
|
+
*
|
|
114
|
+
* @param queryContext - query context in which to perform the load
|
|
115
|
+
* @param args - pagination arguments including pagination and first/after or last/before
|
|
116
|
+
* @returns connection with edges containing field objects and page info
|
|
117
|
+
*/
|
|
118
|
+
loadPageAsync(queryContext: EntityQueryContext, args: LoadPageArgs<TFields>): Promise<Connection<Readonly<TFields>>>;
|
|
119
|
+
getCursorForEntityID(entityID: TFields[TIDField]): string;
|
|
120
|
+
/**
|
|
121
|
+
* Internal method for loading a page with cursor-based pagination.
|
|
122
|
+
* Shared logic for both regular and search pagination.
|
|
123
|
+
*/
|
|
124
|
+
private loadPageInternalAsync;
|
|
125
|
+
private combineWhereConditions;
|
|
126
|
+
private augmentOrderByIfNecessary;
|
|
127
|
+
private static flipNullsOrderingSpread;
|
|
128
|
+
private static validateOrderByClauses;
|
|
129
|
+
/**
|
|
130
|
+
* Cursor-based pagination uses Postgres tuple comparison (e.g., (a, b) \> (x, y)) which
|
|
131
|
+
* applies a single comparison direction to all columns. Mixed ordering directions would
|
|
132
|
+
* produce incorrect pagination results.
|
|
133
|
+
*/
|
|
134
|
+
private static validateOrderByClausesHaveConsistentDirection;
|
|
135
|
+
private encodeOpaqueCursor;
|
|
136
|
+
private decodeOpaqueCursor;
|
|
137
|
+
private resolveSearchFieldToSQLFragment;
|
|
138
|
+
private buildCursorCondition;
|
|
139
|
+
private buildILikeConditions;
|
|
140
|
+
private buildTrigramSimilarityExpressions;
|
|
141
|
+
private buildTrigramExactMatchCaseExpression;
|
|
142
|
+
private buildTrigramSimilarityGreatestExpression;
|
|
143
|
+
private buildTrigramCursorCondition;
|
|
144
|
+
private buildSearchConditionAndOrderBy;
|
|
145
|
+
private static escapeILikePattern;
|
|
146
|
+
}
|
|
147
|
+
export {};
|