remult 0.26.18 → 0.26.19-next.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/esm/remult-knex/index.js +3 -3
- package/esm/remult-mongo.js +2 -2
- package/esm/src/data-providers/sql-database.js +56 -6
- package/esm/src/filter/filter-consumer-bridge-to-sql-request.js +16 -7
- package/esm/src/remult3/remult3.js +2 -0
- package/package.json +1 -1
- package/remult-knex/index.js +2 -2
- package/remult-mongo.js +1 -1
- package/src/data-providers/sql-database.d.ts +50 -0
- package/src/data-providers/sql-database.js +65 -16
- package/src/filter/filter-consumer-bridge-to-sql-request.d.ts +2 -1
- package/src/filter/filter-consumer-bridge-to-sql-request.js +32 -11
- package/src/remult3/remult3.d.ts +29 -1
- package/src/remult3/remult3.js +2 -0
package/esm/remult-knex/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CustomSqlFilterBuilder, } from '../src/filter/filter-consumer-bridge-to-sql-request.js';
|
|
1
|
+
import { CustomSqlFilterBuilder, dbNamesOfWithForceSqlExpression, } from '../src/filter/filter-consumer-bridge-to-sql-request.js';
|
|
2
2
|
import { dbNamesOf, isDbReadonly, shouldCreateEntity, shouldNotCreateField, } from '../src/filter/filter-consumer-bridge-to-sql-request.js';
|
|
3
3
|
import { customDatabaseFilterToken, Filter, } from '../src/filter/filter-interfaces.js';
|
|
4
4
|
import { remult as remultContext } from '../src/remult-proxy.js';
|
|
@@ -92,7 +92,7 @@ export class KnexDataProvider {
|
|
|
92
92
|
}
|
|
93
93
|
static async filterToRaw(entity, condition, wrapIdentifier) {
|
|
94
94
|
const repo = getRepository(entity);
|
|
95
|
-
var b = new FilterConsumerBridgeToKnexRequest(await
|
|
95
|
+
var b = new FilterConsumerBridgeToKnexRequest(await dbNamesOfWithForceSqlExpression(repo.metadata, (x) => x), wrapIdentifier);
|
|
96
96
|
b._addWhere = false;
|
|
97
97
|
await (await getRepositoryInternals(repo)._translateWhereToFilter(condition)).__applyToConsumer(b);
|
|
98
98
|
let r = await b.resolveWhere();
|
|
@@ -183,7 +183,7 @@ class KnexEntityDataProvider {
|
|
|
183
183
|
});
|
|
184
184
|
}
|
|
185
185
|
async init() {
|
|
186
|
-
const r = (await
|
|
186
|
+
const r = (await dbNamesOfWithForceSqlExpression(this.entity, (x) => x));
|
|
187
187
|
return {
|
|
188
188
|
$dbNameOf: (f) => {
|
|
189
189
|
let fm = f;
|
package/esm/remult-mongo.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ObjectId, } from 'mongodb';
|
|
2
2
|
import { Filter } from './index.js';
|
|
3
|
-
import { dbNamesOf } from './src/filter/filter-consumer-bridge-to-sql-request.js';
|
|
3
|
+
import { dbNamesOf, dbNamesOfWithForceSqlExpression, } from './src/filter/filter-consumer-bridge-to-sql-request.js';
|
|
4
4
|
import { remult as remultContext } from './src/remult-proxy.js';
|
|
5
5
|
import { getRepository } from './src/remult3/RepositoryImplementation.js';
|
|
6
6
|
import { getRepositoryInternals } from './src/remult3/repository-internals.js';
|
|
@@ -50,7 +50,7 @@ export class MongoDataProvider {
|
|
|
50
50
|
}
|
|
51
51
|
static async filterToRaw(entity, condition) {
|
|
52
52
|
const repo = getRepository(entity);
|
|
53
|
-
var b = new FilterConsumerBridgeToMongo(await
|
|
53
|
+
var b = new FilterConsumerBridgeToMongo(await dbNamesOfWithForceSqlExpression(repo.metadata));
|
|
54
54
|
b._addWhere = false;
|
|
55
55
|
await (await getRepositoryInternals(repo)._translateWhereToFilter(condition)).__applyToConsumer(b);
|
|
56
56
|
let r = await b.resolveWhere();
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { FilterConsumerBridgeToSqlRequest,
|
|
1
|
+
import { FilterConsumerBridgeToSqlRequest, dbNamesOfWithForceSqlExpression, isDbReadonly, } from '../filter/filter-consumer-bridge-to-sql-request.js';
|
|
2
2
|
import { Filter, customDatabaseFilterToken, } from '../filter/filter-interfaces.js';
|
|
3
3
|
import { remult as defaultRemult } from '../remult-proxy.js';
|
|
4
4
|
import { getRepository, isAutoIncrement, } from '../remult3/RepositoryImplementation.js';
|
|
@@ -6,9 +6,21 @@ import { Sort } from '../sort.js';
|
|
|
6
6
|
import { ValueConverters } from '../valueConverters.js';
|
|
7
7
|
import { getRepositoryInternals } from '../remult3/repository-internals.js';
|
|
8
8
|
import { isOfType } from '../isOfType.js';
|
|
9
|
-
|
|
9
|
+
/**
|
|
10
|
+
* A DataProvider for Sql Databases
|
|
11
|
+
* @example
|
|
12
|
+
* const db = new SqlDatabase(new PostgresDataProvider(pgPool))
|
|
13
|
+
* @see [Connecting a Database](https://remult.dev/docs/quickstart#connecting-a-database)
|
|
14
|
+
|
|
15
|
+
*/
|
|
10
16
|
export class SqlDatabase {
|
|
11
17
|
sql;
|
|
18
|
+
/**
|
|
19
|
+
* Gets the SQL database from the data provider.
|
|
20
|
+
* @param dataProvider - The data provider.
|
|
21
|
+
* @returns The SQL database.
|
|
22
|
+
* @see [Direct Database Access](https://remult.dev/docs/running-sql-on-the-server)
|
|
23
|
+
*/
|
|
12
24
|
static getDb(dataProvider) {
|
|
13
25
|
const r = (dataProvider || defaultRemult.dataProvider);
|
|
14
26
|
if (isOfType(r, 'createCommand'))
|
|
@@ -16,12 +28,26 @@ export class SqlDatabase {
|
|
|
16
28
|
else
|
|
17
29
|
throw 'the data provider is not an SqlCommandFactory';
|
|
18
30
|
}
|
|
31
|
+
/**
|
|
32
|
+
* Creates a new SQL command.
|
|
33
|
+
* @returns The SQL command.
|
|
34
|
+
* @see [Direct Database Access](https://remult.dev/docs/running-sql-on-the-server)
|
|
35
|
+
*/
|
|
19
36
|
createCommand() {
|
|
20
37
|
return new LogSQLCommand(this.sql.createCommand(), SqlDatabase.LogToConsole);
|
|
21
38
|
}
|
|
39
|
+
/**
|
|
40
|
+
* Executes a SQL command.
|
|
41
|
+
* @param sql - The SQL command.
|
|
42
|
+
* @returns The SQL result.
|
|
43
|
+
* @see [Direct Database Access](https://remult.dev/docs/running-sql-on-the-server)
|
|
44
|
+
*/
|
|
22
45
|
async execute(sql) {
|
|
23
46
|
return await this.createCommand().execute(sql);
|
|
24
47
|
}
|
|
48
|
+
/**
|
|
49
|
+
* Wraps an identifier with the database's identifier syntax.
|
|
50
|
+
*/
|
|
25
51
|
wrapIdentifier = (x) => x;
|
|
26
52
|
/* @internal*/
|
|
27
53
|
_getSourceSql() {
|
|
@@ -31,6 +57,11 @@ export class SqlDatabase {
|
|
|
31
57
|
if (this.sql.ensureSchema)
|
|
32
58
|
await this.sql.ensureSchema(entities);
|
|
33
59
|
}
|
|
60
|
+
/**
|
|
61
|
+
* Gets the entity data provider.
|
|
62
|
+
* @param entity - The entity metadata.
|
|
63
|
+
* @returns The entity data provider.
|
|
64
|
+
*/
|
|
34
65
|
getEntityDataProvider(entity) {
|
|
35
66
|
if (!this.sql.supportsJsonColumnType) {
|
|
36
67
|
for (const f of entity.fields.toArray()) {
|
|
@@ -44,13 +75,18 @@ export class SqlDatabase {
|
|
|
44
75
|
}
|
|
45
76
|
}
|
|
46
77
|
}
|
|
47
|
-
return new
|
|
78
|
+
return new ActualSQLEntityDataProvider(entity, this, async (dbName) => {
|
|
48
79
|
if (this.createdEntities.indexOf(dbName.$entityName) < 0) {
|
|
49
80
|
this.createdEntities.push(dbName.$entityName);
|
|
50
81
|
await this.sql.entityIsUsedForTheFirstTime(entity);
|
|
51
82
|
}
|
|
52
83
|
}, this.sql);
|
|
53
84
|
}
|
|
85
|
+
/**
|
|
86
|
+
* Runs a transaction. Used internally by remult when transactions are required
|
|
87
|
+
* @param action - The action to run in the transaction.
|
|
88
|
+
* @returns The promise of the transaction.
|
|
89
|
+
*/
|
|
54
90
|
transaction(action) {
|
|
55
91
|
return this.sql.transaction(async (x) => {
|
|
56
92
|
let completed = false;
|
|
@@ -103,12 +139,18 @@ export class SqlDatabase {
|
|
|
103
139
|
},
|
|
104
140
|
};
|
|
105
141
|
}
|
|
142
|
+
/**
|
|
143
|
+
* Converts a filter to a raw SQL string.
|
|
144
|
+
* @see [Leveraging Database Capabilities with Raw SQL in Custom Filters](https://remult.dev/docs/running-sql-on-the-server#leveraging-entityfilter-for-sql-databases)
|
|
145
|
+
|
|
146
|
+
*/
|
|
106
147
|
static async filterToRaw(repo, condition, sqlCommand, dbNames, wrapIdentifier) {
|
|
107
148
|
if (!sqlCommand) {
|
|
108
149
|
sqlCommand = new myDummySQLCommand();
|
|
109
150
|
}
|
|
110
151
|
const r = getRepository(repo);
|
|
111
|
-
var b = new FilterConsumerBridgeToSqlRequest(sqlCommand, dbNames ||
|
|
152
|
+
var b = new FilterConsumerBridgeToSqlRequest(sqlCommand, dbNames ||
|
|
153
|
+
(await dbNamesOfWithForceSqlExpression(r.metadata, wrapIdentifier)));
|
|
112
154
|
b._addWhere = false;
|
|
113
155
|
await (await getRepositoryInternals(r)._translateWhereToFilter(condition)).__applyToConsumer(b);
|
|
114
156
|
return await b.resolveWhere();
|
|
@@ -121,12 +163,20 @@ export class SqlDatabase {
|
|
|
121
163
|
* `oneLiner` - to log all queries to the console as one line
|
|
122
164
|
*
|
|
123
165
|
* a `function` - to log all queries to the console as a custom format
|
|
166
|
+
* @example
|
|
167
|
+
* SqlDatabase.LogToConsole = (duration, query, args) => { console.log("be crazy ;)") }
|
|
124
168
|
*/
|
|
125
169
|
static LogToConsole = false;
|
|
126
170
|
/**
|
|
127
171
|
* Threshold in milliseconds for logging queries to the console.
|
|
128
172
|
*/
|
|
129
173
|
static durationThreshold = 0;
|
|
174
|
+
/**
|
|
175
|
+
* Creates a new SQL database.
|
|
176
|
+
* @param sql - The SQL implementation.
|
|
177
|
+
* @example
|
|
178
|
+
* const db = new SqlDatabase(new PostgresDataProvider(pgPool))
|
|
179
|
+
*/
|
|
130
180
|
constructor(sql) {
|
|
131
181
|
this.sql = sql;
|
|
132
182
|
if (sql.wrapIdentifier)
|
|
@@ -206,7 +256,7 @@ class LogSQLCommand {
|
|
|
206
256
|
}
|
|
207
257
|
}
|
|
208
258
|
}
|
|
209
|
-
class
|
|
259
|
+
class ActualSQLEntityDataProvider {
|
|
210
260
|
entity;
|
|
211
261
|
sql;
|
|
212
262
|
iAmUsed;
|
|
@@ -219,7 +269,7 @@ class ActualSQLServerDataProvider {
|
|
|
219
269
|
this.strategy = strategy;
|
|
220
270
|
}
|
|
221
271
|
async init() {
|
|
222
|
-
let dbNameProvider = await
|
|
272
|
+
let dbNameProvider = await dbNamesOfWithForceSqlExpression(this.entity, (x) => this.sql.wrapIdentifier(x));
|
|
223
273
|
await this.iAmUsed(dbNameProvider);
|
|
224
274
|
return dbNameProvider;
|
|
225
275
|
}
|
|
@@ -190,6 +190,12 @@ export function shouldCreateEntity(entity, e) {
|
|
|
190
190
|
e.$entityName.toLowerCase().indexOf('from ') < 0);
|
|
191
191
|
}
|
|
192
192
|
export async function dbNamesOf(repo, wrapIdentifierOrOptions) {
|
|
193
|
+
return internalDbNamesOf(repo, wrapIdentifierOrOptions);
|
|
194
|
+
}
|
|
195
|
+
export async function dbNamesOfWithForceSqlExpression(repo, wrapIdentifierOrOptions) {
|
|
196
|
+
return internalDbNamesOf(repo, wrapIdentifierOrOptions, true);
|
|
197
|
+
}
|
|
198
|
+
async function internalDbNamesOf(repo, wrapIdentifierOrOptions, forceSqlExpression = false) {
|
|
193
199
|
let options = typeof wrapIdentifierOrOptions === 'function'
|
|
194
200
|
? { wrapIdentifier: wrapIdentifierOrOptions }
|
|
195
201
|
: wrapIdentifierOrOptions || {};
|
|
@@ -213,7 +219,7 @@ export async function dbNamesOf(repo, wrapIdentifierOrOptions) {
|
|
|
213
219
|
wrapIdentifier: options.wrapIdentifier,
|
|
214
220
|
};
|
|
215
221
|
for (const field of meta.fields) {
|
|
216
|
-
let r = await fieldDbName(field, meta, options.wrapIdentifier);
|
|
222
|
+
let r = await fieldDbName(field, meta, options.wrapIdentifier, forceSqlExpression);
|
|
217
223
|
if (!field.options.sqlExpression)
|
|
218
224
|
if (typeof options.tableName === 'string')
|
|
219
225
|
r = options.wrapIdentifier(options.tableName) + '.' + r;
|
|
@@ -242,19 +248,22 @@ export async function entityDbName(metadata, wrapIdentifier = (x) => x) {
|
|
|
242
248
|
}
|
|
243
249
|
return wrapIdentifier(metadata.dbName);
|
|
244
250
|
}
|
|
245
|
-
|
|
251
|
+
const sqlExpressionInProgressKey = Symbol.for(`sqlExpressionInProgressKey`);
|
|
252
|
+
export async function fieldDbName(f, meta, wrapIdentifier = (x) => x, forceSqlExpression = false) {
|
|
246
253
|
try {
|
|
247
254
|
if (f.options.sqlExpression) {
|
|
248
255
|
let result;
|
|
249
256
|
if (typeof f.options.sqlExpression === 'function') {
|
|
250
|
-
|
|
257
|
+
if (f[sqlExpressionInProgressKey] && !forceSqlExpression) {
|
|
258
|
+
return "recursive sqlExpression call for field '" + f.key + "'. ";
|
|
259
|
+
}
|
|
251
260
|
try {
|
|
252
|
-
f
|
|
253
|
-
|
|
254
|
-
result = await prev(meta);
|
|
261
|
+
f[sqlExpressionInProgressKey] = true;
|
|
262
|
+
result = await f.options.sqlExpression(meta);
|
|
255
263
|
f.options.sqlExpression = () => result;
|
|
256
264
|
}
|
|
257
265
|
finally {
|
|
266
|
+
delete f[sqlExpressionInProgressKey];
|
|
258
267
|
}
|
|
259
268
|
}
|
|
260
269
|
else
|
|
@@ -269,7 +278,7 @@ export async function fieldDbName(f, meta, wrapIdentifier = (x) => x) {
|
|
|
269
278
|
if (field) {
|
|
270
279
|
let fInfo = meta.fields.find(field);
|
|
271
280
|
if (fInfo)
|
|
272
|
-
return fieldDbName(fInfo, meta, wrapIdentifier);
|
|
281
|
+
return fieldDbName(fInfo, meta, wrapIdentifier, forceSqlExpression);
|
|
273
282
|
}
|
|
274
283
|
return wrapIdentifier(f.dbName);
|
|
275
284
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export const flags = {
|
|
2
2
|
error500RetryCount: 4,
|
|
3
3
|
};
|
|
4
|
+
//p1 - fix query docs to also explain how it can be used for infinite scroll and pagination.
|
|
4
5
|
//y1 - 'test expression columns without aliases'
|
|
5
6
|
//p1 - see if I can fix the no alias problem in selects
|
|
6
7
|
//p1 - add luid - it's cool for order by.
|
|
@@ -8,6 +9,7 @@ export const flags = {
|
|
|
8
9
|
//p1 - add nanoid
|
|
9
10
|
//p1 - add id and use luid by default, but allow changes with Fields.id.defaultIdProvider
|
|
10
11
|
//p1 - explain the benefits of changing the default provider for testing in docs.
|
|
12
|
+
//p1 - fix sqlite to support alter table when adding a column with ensure schema = on
|
|
11
13
|
//p1 - fix app custom filters example for multiple filters.
|
|
12
14
|
//p1 - add not!!!!
|
|
13
15
|
//p1 - add LifecycleEvent to documentation
|
package/package.json
CHANGED
package/remult-knex/index.js
CHANGED
|
@@ -157,7 +157,7 @@ var KnexDataProvider = /** @class */ (function () {
|
|
|
157
157
|
case 0:
|
|
158
158
|
repo = (0, RepositoryImplementation_js_1.getRepository)(entity);
|
|
159
159
|
_a = FilterConsumerBridgeToKnexRequest.bind;
|
|
160
|
-
return [4 /*yield*/, (0,
|
|
160
|
+
return [4 /*yield*/, (0, filter_consumer_bridge_to_sql_request_js_1.dbNamesOfWithForceSqlExpression)(repo.metadata, function (x) { return x; })];
|
|
161
161
|
case 1:
|
|
162
162
|
b = new (_a.apply(FilterConsumerBridgeToKnexRequest, [void 0, _b.sent(), wrapIdentifier]))();
|
|
163
163
|
b._addWhere = false;
|
|
@@ -310,7 +310,7 @@ var KnexEntityDataProvider = /** @class */ (function () {
|
|
|
310
310
|
var _this = this;
|
|
311
311
|
return tslib_1.__generator(this, function (_a) {
|
|
312
312
|
switch (_a.label) {
|
|
313
|
-
case 0: return [4 /*yield*/, (0,
|
|
313
|
+
case 0: return [4 /*yield*/, (0, filter_consumer_bridge_to_sql_request_js_1.dbNamesOfWithForceSqlExpression)(this.entity, function (x) { return x; })];
|
|
314
314
|
case 1:
|
|
315
315
|
r = (_a.sent());
|
|
316
316
|
return [2 /*return*/, {
|
package/remult-mongo.js
CHANGED
|
@@ -78,7 +78,7 @@ var MongoDataProvider = /** @class */ (function () {
|
|
|
78
78
|
case 0:
|
|
79
79
|
repo = (0, RepositoryImplementation_js_1.getRepository)(entity);
|
|
80
80
|
_a = FilterConsumerBridgeToMongo.bind;
|
|
81
|
-
return [4 /*yield*/, (0, filter_consumer_bridge_to_sql_request_js_1.
|
|
81
|
+
return [4 /*yield*/, (0, filter_consumer_bridge_to_sql_request_js_1.dbNamesOfWithForceSqlExpression)(repo.metadata)];
|
|
82
82
|
case 1:
|
|
83
83
|
b = new (_a.apply(FilterConsumerBridgeToMongo, [void 0, _b.sent()]))();
|
|
84
84
|
b._addWhere = false;
|
|
@@ -4,14 +4,51 @@ import type { CustomSqlFilterBuilderFunction, EntityDbNamesBase } from '../filte
|
|
|
4
4
|
import type { EntityFilter, EntityMetadata } from '../remult3/remult3.js';
|
|
5
5
|
import type { RepositoryOverloads } from '../remult3/RepositoryImplementation.js';
|
|
6
6
|
import type { CanBuildMigrations, MigrationBuilder, MigrationCode } from '../../migrations/migration-types.js';
|
|
7
|
+
/**
|
|
8
|
+
* A DataProvider for Sql Databases
|
|
9
|
+
* @example
|
|
10
|
+
* const db = new SqlDatabase(new PostgresDataProvider(pgPool))
|
|
11
|
+
* @see [Connecting a Database](https://remult.dev/docs/quickstart#connecting-a-database)
|
|
12
|
+
|
|
13
|
+
*/
|
|
7
14
|
export declare class SqlDatabase implements DataProvider, HasWrapIdentifier, CanBuildMigrations, SqlCommandFactory {
|
|
8
15
|
private sql;
|
|
16
|
+
/**
|
|
17
|
+
* Gets the SQL database from the data provider.
|
|
18
|
+
* @param dataProvider - The data provider.
|
|
19
|
+
* @returns The SQL database.
|
|
20
|
+
* @see [Direct Database Access](https://remult.dev/docs/running-sql-on-the-server)
|
|
21
|
+
*/
|
|
9
22
|
static getDb(dataProvider?: DataProvider): SqlDatabase;
|
|
23
|
+
/**
|
|
24
|
+
* Creates a new SQL command.
|
|
25
|
+
* @returns The SQL command.
|
|
26
|
+
* @see [Direct Database Access](https://remult.dev/docs/running-sql-on-the-server)
|
|
27
|
+
*/
|
|
10
28
|
createCommand(): SqlCommand;
|
|
29
|
+
/**
|
|
30
|
+
* Executes a SQL command.
|
|
31
|
+
* @param sql - The SQL command.
|
|
32
|
+
* @returns The SQL result.
|
|
33
|
+
* @see [Direct Database Access](https://remult.dev/docs/running-sql-on-the-server)
|
|
34
|
+
*/
|
|
11
35
|
execute(sql: string): Promise<SqlResult>;
|
|
36
|
+
/**
|
|
37
|
+
* Wraps an identifier with the database's identifier syntax.
|
|
38
|
+
*/
|
|
12
39
|
wrapIdentifier: (name: string) => string;
|
|
13
40
|
ensureSchema(entities: EntityMetadata<any>[]): Promise<void>;
|
|
41
|
+
/**
|
|
42
|
+
* Gets the entity data provider.
|
|
43
|
+
* @param entity - The entity metadata.
|
|
44
|
+
* @returns The entity data provider.
|
|
45
|
+
*/
|
|
14
46
|
getEntityDataProvider(entity: EntityMetadata): EntityDataProvider;
|
|
47
|
+
/**
|
|
48
|
+
* Runs a transaction. Used internally by remult when transactions are required
|
|
49
|
+
* @param action - The action to run in the transaction.
|
|
50
|
+
* @returns The promise of the transaction.
|
|
51
|
+
*/
|
|
15
52
|
transaction(action: (dataProvider: DataProvider) => Promise<void>): Promise<void>;
|
|
16
53
|
/**
|
|
17
54
|
* Creates a raw filter for entity filtering.
|
|
@@ -24,6 +61,11 @@ export declare class SqlDatabase implements DataProvider, HasWrapIdentifier, Can
|
|
|
24
61
|
* @see [Leveraging Database Capabilities with Raw SQL in Custom Filters](https://remult.dev/docs/custom-filter.html#leveraging-database-capabilities-with-raw-sql-in-custom-filters)
|
|
25
62
|
*/
|
|
26
63
|
static rawFilter(build: CustomSqlFilterBuilderFunction): EntityFilter<any>;
|
|
64
|
+
/**
|
|
65
|
+
* Converts a filter to a raw SQL string.
|
|
66
|
+
* @see [Leveraging Database Capabilities with Raw SQL in Custom Filters](https://remult.dev/docs/running-sql-on-the-server#leveraging-entityfilter-for-sql-databases)
|
|
67
|
+
|
|
68
|
+
*/
|
|
27
69
|
static filterToRaw<entityType>(repo: RepositoryOverloads<entityType>, condition: EntityFilter<entityType>, sqlCommand?: SqlCommandWithParameters, dbNames?: EntityDbNamesBase, wrapIdentifier?: (name: string) => string): Promise<string>;
|
|
28
70
|
/**
|
|
29
71
|
* `false` _(default)_ - No logging
|
|
@@ -33,12 +75,20 @@ export declare class SqlDatabase implements DataProvider, HasWrapIdentifier, Can
|
|
|
33
75
|
* `oneLiner` - to log all queries to the console as one line
|
|
34
76
|
*
|
|
35
77
|
* a `function` - to log all queries to the console as a custom format
|
|
78
|
+
* @example
|
|
79
|
+
* SqlDatabase.LogToConsole = (duration, query, args) => { console.log("be crazy ;)") }
|
|
36
80
|
*/
|
|
37
81
|
static LogToConsole: boolean | 'oneLiner' | ((duration: number, query: string, args: Record<string, any>) => void);
|
|
38
82
|
/**
|
|
39
83
|
* Threshold in milliseconds for logging queries to the console.
|
|
40
84
|
*/
|
|
41
85
|
static durationThreshold: number;
|
|
86
|
+
/**
|
|
87
|
+
* Creates a new SQL database.
|
|
88
|
+
* @param sql - The SQL implementation.
|
|
89
|
+
* @example
|
|
90
|
+
* const db = new SqlDatabase(new PostgresDataProvider(pgPool))
|
|
91
|
+
*/
|
|
42
92
|
constructor(sql: SqlImplementation);
|
|
43
93
|
provideMigrationBuilder: (builder: MigrationCode) => MigrationBuilder;
|
|
44
94
|
private createdEntities;
|
|
@@ -10,10 +10,25 @@ var sort_js_1 = require("../sort.js");
|
|
|
10
10
|
var valueConverters_js_1 = require("../valueConverters.js");
|
|
11
11
|
var repository_internals_js_1 = require("../remult3/repository-internals.js");
|
|
12
12
|
var isOfType_js_1 = require("../isOfType.js");
|
|
13
|
-
|
|
13
|
+
/**
|
|
14
|
+
* A DataProvider for Sql Databases
|
|
15
|
+
* @example
|
|
16
|
+
* const db = new SqlDatabase(new PostgresDataProvider(pgPool))
|
|
17
|
+
* @see [Connecting a Database](https://remult.dev/docs/quickstart#connecting-a-database)
|
|
18
|
+
|
|
19
|
+
*/
|
|
14
20
|
var SqlDatabase = /** @class */ (function () {
|
|
21
|
+
/**
|
|
22
|
+
* Creates a new SQL database.
|
|
23
|
+
* @param sql - The SQL implementation.
|
|
24
|
+
* @example
|
|
25
|
+
* const db = new SqlDatabase(new PostgresDataProvider(pgPool))
|
|
26
|
+
*/
|
|
15
27
|
function SqlDatabase(sql) {
|
|
16
28
|
this.sql = sql;
|
|
29
|
+
/**
|
|
30
|
+
* Wraps an identifier with the database's identifier syntax.
|
|
31
|
+
*/
|
|
17
32
|
this.wrapIdentifier = function (x) { return x; };
|
|
18
33
|
this.createdEntities = [];
|
|
19
34
|
if (sql.wrapIdentifier)
|
|
@@ -24,6 +39,12 @@ var SqlDatabase = /** @class */ (function () {
|
|
|
24
39
|
if ((0, isOfType_js_1.isOfType)(sql, 'end'))
|
|
25
40
|
this.end = function () { return sql.end(); };
|
|
26
41
|
}
|
|
42
|
+
/**
|
|
43
|
+
* Gets the SQL database from the data provider.
|
|
44
|
+
* @param dataProvider - The data provider.
|
|
45
|
+
* @returns The SQL database.
|
|
46
|
+
* @see [Direct Database Access](https://remult.dev/docs/running-sql-on-the-server)
|
|
47
|
+
*/
|
|
27
48
|
SqlDatabase.getDb = function (dataProvider) {
|
|
28
49
|
var r = (dataProvider || remult_proxy_js_1.remult.dataProvider);
|
|
29
50
|
if ((0, isOfType_js_1.isOfType)(r, 'createCommand'))
|
|
@@ -31,9 +52,20 @@ var SqlDatabase = /** @class */ (function () {
|
|
|
31
52
|
else
|
|
32
53
|
throw 'the data provider is not an SqlCommandFactory';
|
|
33
54
|
};
|
|
55
|
+
/**
|
|
56
|
+
* Creates a new SQL command.
|
|
57
|
+
* @returns The SQL command.
|
|
58
|
+
* @see [Direct Database Access](https://remult.dev/docs/running-sql-on-the-server)
|
|
59
|
+
*/
|
|
34
60
|
SqlDatabase.prototype.createCommand = function () {
|
|
35
61
|
return new LogSQLCommand(this.sql.createCommand(), SqlDatabase.LogToConsole);
|
|
36
62
|
};
|
|
63
|
+
/**
|
|
64
|
+
* Executes a SQL command.
|
|
65
|
+
* @param sql - The SQL command.
|
|
66
|
+
* @returns The SQL result.
|
|
67
|
+
* @see [Direct Database Access](https://remult.dev/docs/running-sql-on-the-server)
|
|
68
|
+
*/
|
|
37
69
|
SqlDatabase.prototype.execute = function (sql) {
|
|
38
70
|
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
39
71
|
return tslib_1.__generator(this, function (_a) {
|
|
@@ -63,6 +95,11 @@ var SqlDatabase = /** @class */ (function () {
|
|
|
63
95
|
});
|
|
64
96
|
});
|
|
65
97
|
};
|
|
98
|
+
/**
|
|
99
|
+
* Gets the entity data provider.
|
|
100
|
+
* @param entity - The entity metadata.
|
|
101
|
+
* @returns The entity data provider.
|
|
102
|
+
*/
|
|
66
103
|
SqlDatabase.prototype.getEntityDataProvider = function (entity) {
|
|
67
104
|
var e_1, _a;
|
|
68
105
|
var _this = this;
|
|
@@ -84,7 +121,7 @@ var SqlDatabase = /** @class */ (function () {
|
|
|
84
121
|
finally { if (e_1) throw e_1.error; }
|
|
85
122
|
}
|
|
86
123
|
}
|
|
87
|
-
return new
|
|
124
|
+
return new ActualSQLEntityDataProvider(entity, this, function (dbName) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
|
88
125
|
return tslib_1.__generator(this, function (_a) {
|
|
89
126
|
switch (_a.label) {
|
|
90
127
|
case 0:
|
|
@@ -99,6 +136,11 @@ var SqlDatabase = /** @class */ (function () {
|
|
|
99
136
|
});
|
|
100
137
|
}); }, this.sql);
|
|
101
138
|
};
|
|
139
|
+
/**
|
|
140
|
+
* Runs a transaction. Used internally by remult when transactions are required
|
|
141
|
+
* @param action - The action to run in the transaction.
|
|
142
|
+
* @returns The promise of the transaction.
|
|
143
|
+
*/
|
|
102
144
|
SqlDatabase.prototype.transaction = function (action) {
|
|
103
145
|
var _this = this;
|
|
104
146
|
return this.sql.transaction(function (x) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
|
@@ -169,6 +211,11 @@ var SqlDatabase = /** @class */ (function () {
|
|
|
169
211
|
},
|
|
170
212
|
_a;
|
|
171
213
|
};
|
|
214
|
+
/**
|
|
215
|
+
* Converts a filter to a raw SQL string.
|
|
216
|
+
* @see [Leveraging Database Capabilities with Raw SQL in Custom Filters](https://remult.dev/docs/running-sql-on-the-server#leveraging-entityfilter-for-sql-databases)
|
|
217
|
+
|
|
218
|
+
*/
|
|
172
219
|
SqlDatabase.filterToRaw = function (repo, condition, sqlCommand, dbNames, wrapIdentifier) {
|
|
173
220
|
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
174
221
|
var r, b, _a, _b, _c;
|
|
@@ -183,7 +230,7 @@ var SqlDatabase = /** @class */ (function () {
|
|
|
183
230
|
_b = [void 0, sqlCommand];
|
|
184
231
|
_c = dbNames;
|
|
185
232
|
if (_c) return [3 /*break*/, 2];
|
|
186
|
-
return [4 /*yield*/, (0, filter_consumer_bridge_to_sql_request_js_1.
|
|
233
|
+
return [4 /*yield*/, (0, filter_consumer_bridge_to_sql_request_js_1.dbNamesOfWithForceSqlExpression)(r.metadata, wrapIdentifier)];
|
|
187
234
|
case 1:
|
|
188
235
|
_c = (_d.sent());
|
|
189
236
|
_d.label = 2;
|
|
@@ -208,6 +255,8 @@ var SqlDatabase = /** @class */ (function () {
|
|
|
208
255
|
* `oneLiner` - to log all queries to the console as one line
|
|
209
256
|
*
|
|
210
257
|
* a `function` - to log all queries to the console as a custom format
|
|
258
|
+
* @example
|
|
259
|
+
* SqlDatabase.LogToConsole = (duration, query, args) => { console.log("be crazy ;)") }
|
|
211
260
|
*/
|
|
212
261
|
SqlDatabase.LogToConsole = false;
|
|
213
262
|
/**
|
|
@@ -291,20 +340,20 @@ var LogSQLCommand = /** @class */ (function () {
|
|
|
291
340
|
};
|
|
292
341
|
return LogSQLCommand;
|
|
293
342
|
}());
|
|
294
|
-
var
|
|
295
|
-
function
|
|
343
|
+
var ActualSQLEntityDataProvider = /** @class */ (function () {
|
|
344
|
+
function ActualSQLEntityDataProvider(entity, sql, iAmUsed, strategy) {
|
|
296
345
|
this.entity = entity;
|
|
297
346
|
this.sql = sql;
|
|
298
347
|
this.iAmUsed = iAmUsed;
|
|
299
348
|
this.strategy = strategy;
|
|
300
349
|
}
|
|
301
|
-
|
|
350
|
+
ActualSQLEntityDataProvider.prototype.init = function () {
|
|
302
351
|
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
303
352
|
var dbNameProvider;
|
|
304
353
|
var _this = this;
|
|
305
354
|
return tslib_1.__generator(this, function (_a) {
|
|
306
355
|
switch (_a.label) {
|
|
307
|
-
case 0: return [4 /*yield*/, (0, filter_consumer_bridge_to_sql_request_js_1.
|
|
356
|
+
case 0: return [4 /*yield*/, (0, filter_consumer_bridge_to_sql_request_js_1.dbNamesOfWithForceSqlExpression)(this.entity, function (x) {
|
|
308
357
|
return _this.sql.wrapIdentifier(x);
|
|
309
358
|
})];
|
|
310
359
|
case 1:
|
|
@@ -317,7 +366,7 @@ var ActualSQLServerDataProvider = /** @class */ (function () {
|
|
|
317
366
|
});
|
|
318
367
|
});
|
|
319
368
|
};
|
|
320
|
-
|
|
369
|
+
ActualSQLEntityDataProvider.prototype.count = function (where) {
|
|
321
370
|
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
322
371
|
var e, select, r, wc, _a;
|
|
323
372
|
return tslib_1.__generator(this, function (_b) {
|
|
@@ -342,7 +391,7 @@ var ActualSQLServerDataProvider = /** @class */ (function () {
|
|
|
342
391
|
});
|
|
343
392
|
});
|
|
344
393
|
};
|
|
345
|
-
|
|
394
|
+
ActualSQLEntityDataProvider.prototype.find = function (options) {
|
|
346
395
|
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
347
396
|
var e, _a, colKeys, select, r, where, _b, first, segs, _c, _d, s, segs_1, segs_1_1, c, page;
|
|
348
397
|
var e_2, _e, e_3, _f;
|
|
@@ -436,7 +485,7 @@ var ActualSQLServerDataProvider = /** @class */ (function () {
|
|
|
436
485
|
});
|
|
437
486
|
});
|
|
438
487
|
};
|
|
439
|
-
|
|
488
|
+
ActualSQLEntityDataProvider.prototype.buildResultRow = function (colKeys, y, r) {
|
|
440
489
|
var result = {};
|
|
441
490
|
for (var index = 0; index < colKeys.length; index++) {
|
|
442
491
|
var col = colKeys[index];
|
|
@@ -449,7 +498,7 @@ var ActualSQLServerDataProvider = /** @class */ (function () {
|
|
|
449
498
|
}
|
|
450
499
|
return result;
|
|
451
500
|
};
|
|
452
|
-
|
|
501
|
+
ActualSQLEntityDataProvider.prototype.buildSelect = function (e) {
|
|
453
502
|
var e_4, _a;
|
|
454
503
|
var select = '';
|
|
455
504
|
var colKeys = [];
|
|
@@ -477,7 +526,7 @@ var ActualSQLServerDataProvider = /** @class */ (function () {
|
|
|
477
526
|
}
|
|
478
527
|
return { colKeys: colKeys, select: select };
|
|
479
528
|
};
|
|
480
|
-
|
|
529
|
+
ActualSQLEntityDataProvider.prototype.update = function (id, data) {
|
|
481
530
|
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
482
531
|
var e, r, statement, added, _a, _b, x, v, idFilter, f, _c, _d, colKeys, select, returning;
|
|
483
532
|
var e_5, _e;
|
|
@@ -547,7 +596,7 @@ var ActualSQLServerDataProvider = /** @class */ (function () {
|
|
|
547
596
|
});
|
|
548
597
|
});
|
|
549
598
|
};
|
|
550
|
-
|
|
599
|
+
ActualSQLEntityDataProvider.prototype.delete = function (id) {
|
|
551
600
|
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
552
601
|
var e, r, f, statement, _a;
|
|
553
602
|
var _this = this;
|
|
@@ -572,7 +621,7 @@ var ActualSQLServerDataProvider = /** @class */ (function () {
|
|
|
572
621
|
});
|
|
573
622
|
});
|
|
574
623
|
};
|
|
575
|
-
|
|
624
|
+
ActualSQLEntityDataProvider.prototype.insert = function (data) {
|
|
576
625
|
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
577
626
|
var e, r, cols, vals, added, _a, _b, x, v, statement, _c, colKeys, select;
|
|
578
627
|
var e_6, _d;
|
|
@@ -643,8 +692,8 @@ var ActualSQLServerDataProvider = /** @class */ (function () {
|
|
|
643
692
|
});
|
|
644
693
|
});
|
|
645
694
|
};
|
|
646
|
-
|
|
647
|
-
return
|
|
695
|
+
ActualSQLEntityDataProvider.LogToConsole = false;
|
|
696
|
+
return ActualSQLEntityDataProvider;
|
|
648
697
|
}());
|
|
649
698
|
var myDummySQLCommand = /** @class */ (function () {
|
|
650
699
|
function myDummySQLCommand() {
|
|
@@ -80,5 +80,6 @@ export interface dbNamesOfOptions {
|
|
|
80
80
|
tableName?: boolean | string;
|
|
81
81
|
}
|
|
82
82
|
export declare function dbNamesOf<entityType>(repo: EntityMetadataOverloads<entityType>, wrapIdentifierOrOptions?: ((name: string) => string) | dbNamesOfOptions): Promise<EntityDbNames<entityType>>;
|
|
83
|
+
export declare function dbNamesOfWithForceSqlExpression<entityType>(repo: EntityMetadataOverloads<entityType>, wrapIdentifierOrOptions?: ((name: string) => string) | dbNamesOfOptions): Promise<EntityDbNames<entityType>>;
|
|
83
84
|
export declare function entityDbName(metadata: EntityMetadata, wrapIdentifier?: (name: string) => string): Promise<string>;
|
|
84
|
-
export declare function fieldDbName(f: FieldMetadata, meta: EntityMetadata, wrapIdentifier?: (name: string) => string): Promise<string>;
|
|
85
|
+
export declare function fieldDbName(f: FieldMetadata, meta: EntityMetadata, wrapIdentifier?: (name: string) => string, forceSqlExpression?: boolean): Promise<string>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.fieldDbName = exports.entityDbName = exports.dbNamesOf = exports.shouldCreateEntity = exports.shouldNotCreateField = exports.isDbReadonly = exports.CustomSqlFilterBuilder = exports.FilterConsumerBridgeToSqlRequest = void 0;
|
|
3
|
+
exports.fieldDbName = exports.entityDbName = exports.dbNamesOfWithForceSqlExpression = exports.dbNamesOf = exports.shouldCreateEntity = exports.shouldNotCreateField = exports.isDbReadonly = exports.CustomSqlFilterBuilder = exports.FilterConsumerBridgeToSqlRequest = void 0;
|
|
4
4
|
var tslib_1 = require("tslib");
|
|
5
5
|
var sql_database_js_1 = require("../data-providers/sql-database.js");
|
|
6
6
|
var remult_proxy_js_1 = require("../remult-proxy.js");
|
|
@@ -297,6 +297,23 @@ function shouldCreateEntity(entity, e) {
|
|
|
297
297
|
}
|
|
298
298
|
exports.shouldCreateEntity = shouldCreateEntity;
|
|
299
299
|
function dbNamesOf(repo, wrapIdentifierOrOptions) {
|
|
300
|
+
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
301
|
+
return tslib_1.__generator(this, function (_a) {
|
|
302
|
+
return [2 /*return*/, internalDbNamesOf(repo, wrapIdentifierOrOptions)];
|
|
303
|
+
});
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
exports.dbNamesOf = dbNamesOf;
|
|
307
|
+
function dbNamesOfWithForceSqlExpression(repo, wrapIdentifierOrOptions) {
|
|
308
|
+
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
309
|
+
return tslib_1.__generator(this, function (_a) {
|
|
310
|
+
return [2 /*return*/, internalDbNamesOf(repo, wrapIdentifierOrOptions, true)];
|
|
311
|
+
});
|
|
312
|
+
});
|
|
313
|
+
}
|
|
314
|
+
exports.dbNamesOfWithForceSqlExpression = dbNamesOfWithForceSqlExpression;
|
|
315
|
+
function internalDbNamesOf(repo, wrapIdentifierOrOptions, forceSqlExpression) {
|
|
316
|
+
if (forceSqlExpression === void 0) { forceSqlExpression = false; }
|
|
300
317
|
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
301
318
|
var options, meta, result, _a, _b, field, r, e_3_1;
|
|
302
319
|
var _c, e_3, _d;
|
|
@@ -335,7 +352,7 @@ function dbNamesOf(repo, wrapIdentifierOrOptions) {
|
|
|
335
352
|
case 3:
|
|
336
353
|
if (!!_b.done) return [3 /*break*/, 6];
|
|
337
354
|
field = _b.value;
|
|
338
|
-
return [4 /*yield*/, fieldDbName(field, meta, options.wrapIdentifier)];
|
|
355
|
+
return [4 /*yield*/, fieldDbName(field, meta, options.wrapIdentifier, forceSqlExpression)];
|
|
339
356
|
case 4:
|
|
340
357
|
r = _e.sent();
|
|
341
358
|
if (!field.options.sqlExpression)
|
|
@@ -365,7 +382,6 @@ function dbNamesOf(repo, wrapIdentifierOrOptions) {
|
|
|
365
382
|
});
|
|
366
383
|
});
|
|
367
384
|
}
|
|
368
|
-
exports.dbNamesOf = dbNamesOf;
|
|
369
385
|
function entityDbName(metadata, wrapIdentifier) {
|
|
370
386
|
if (wrapIdentifier === void 0) { wrapIdentifier = function (x) { return x; }; }
|
|
371
387
|
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
@@ -395,28 +411,33 @@ function entityDbName(metadata, wrapIdentifier) {
|
|
|
395
411
|
});
|
|
396
412
|
}
|
|
397
413
|
exports.entityDbName = entityDbName;
|
|
398
|
-
|
|
414
|
+
var sqlExpressionInProgressKey = Symbol.for("sqlExpressionInProgressKey");
|
|
415
|
+
function fieldDbName(f, meta, wrapIdentifier, forceSqlExpression) {
|
|
399
416
|
if (wrapIdentifier === void 0) { wrapIdentifier = function (x) { return x; }; }
|
|
417
|
+
if (forceSqlExpression === void 0) { forceSqlExpression = false; }
|
|
400
418
|
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
401
|
-
var result_1,
|
|
419
|
+
var result_1, rel, field, fInfo;
|
|
402
420
|
return tslib_1.__generator(this, function (_a) {
|
|
403
421
|
switch (_a.label) {
|
|
404
422
|
case 0:
|
|
405
423
|
_a.trys.push([0, , 8, 9]);
|
|
406
424
|
if (!f.options.sqlExpression) return [3 /*break*/, 7];
|
|
407
425
|
if (!(typeof f.options.sqlExpression === 'function')) return [3 /*break*/, 5];
|
|
408
|
-
|
|
426
|
+
if (f[sqlExpressionInProgressKey] && !forceSqlExpression) {
|
|
427
|
+
return [2 /*return*/, "recursive sqlExpression call for field '" + f.key + "'. "];
|
|
428
|
+
}
|
|
409
429
|
_a.label = 1;
|
|
410
430
|
case 1:
|
|
411
431
|
_a.trys.push([1, , 3, 4]);
|
|
412
|
-
f
|
|
413
|
-
|
|
414
|
-
return [4 /*yield*/, prev(meta)];
|
|
432
|
+
f[sqlExpressionInProgressKey] = true;
|
|
433
|
+
return [4 /*yield*/, f.options.sqlExpression(meta)];
|
|
415
434
|
case 2:
|
|
416
435
|
result_1 = _a.sent();
|
|
417
436
|
f.options.sqlExpression = function () { return result_1; };
|
|
418
437
|
return [3 /*break*/, 4];
|
|
419
|
-
case 3:
|
|
438
|
+
case 3:
|
|
439
|
+
delete f[sqlExpressionInProgressKey];
|
|
440
|
+
return [7 /*endfinally*/];
|
|
420
441
|
case 4: return [3 /*break*/, 6];
|
|
421
442
|
case 5:
|
|
422
443
|
result_1 = f.options.sqlExpression;
|
|
@@ -432,7 +453,7 @@ function fieldDbName(f, meta, wrapIdentifier) {
|
|
|
432
453
|
if (field) {
|
|
433
454
|
fInfo = meta.fields.find(field);
|
|
434
455
|
if (fInfo)
|
|
435
|
-
return [2 /*return*/, fieldDbName(fInfo, meta, wrapIdentifier)];
|
|
456
|
+
return [2 /*return*/, fieldDbName(fInfo, meta, wrapIdentifier, forceSqlExpression)];
|
|
436
457
|
}
|
|
437
458
|
return [2 /*return*/, wrapIdentifier(f.dbName)];
|
|
438
459
|
case 8: return [7 /*endfinally*/];
|
package/src/remult3/remult3.d.ts
CHANGED
|
@@ -285,6 +285,19 @@ export interface Repository<entityType> {
|
|
|
285
285
|
* for await (const task of taskRepo.query()) {
|
|
286
286
|
* // do something.
|
|
287
287
|
* }
|
|
288
|
+
* @example
|
|
289
|
+
* const query = taskRepo.query({
|
|
290
|
+
* where: { completed: false },
|
|
291
|
+
* pageSize: 100,
|
|
292
|
+
* })
|
|
293
|
+
* const count = await query.count()
|
|
294
|
+
* console.log('Paged: ' + count / 100)
|
|
295
|
+
* let paginator = await query.paginator()
|
|
296
|
+
* console.log(paginator.items.length)
|
|
297
|
+
* if (paginator.hasNextPage) {
|
|
298
|
+
* paginator = await paginator.nextPage()
|
|
299
|
+
* console.log(paginator.items.length)
|
|
300
|
+
* }
|
|
288
301
|
* */
|
|
289
302
|
query(options?: QueryOptions<entityType>): QueryResult<entityType>;
|
|
290
303
|
/** Returns a count of the items matching the criteria.
|
|
@@ -596,7 +609,22 @@ export interface QueryResult<entityType> {
|
|
|
596
609
|
/** Performs an operation on all the items matching the query criteria */
|
|
597
610
|
forEach(what: (item: entityType) => Promise<any>): Promise<number>;
|
|
598
611
|
}
|
|
599
|
-
/** An interface used to paginating using the `query` method in the `Repository` object
|
|
612
|
+
/** An interface used to paginating using the `query` method in the `Repository` object
|
|
613
|
+
* @example
|
|
614
|
+
* @example
|
|
615
|
+
* const query = taskRepo.query({
|
|
616
|
+
* where: { completed: false },
|
|
617
|
+
* pageSize: 100,
|
|
618
|
+
* })
|
|
619
|
+
* const count = await query.count()
|
|
620
|
+
* console.log('Paged: ' + count / 100)
|
|
621
|
+
* let paginator = await query.paginator()
|
|
622
|
+
* console.log(paginator.items.length)
|
|
623
|
+
* if (paginator.hasNextPage) {
|
|
624
|
+
* paginator = await paginator.nextPage()
|
|
625
|
+
* console.log(paginator.items.length)
|
|
626
|
+
* }
|
|
627
|
+
*/
|
|
600
628
|
export interface Paginator<entityType> {
|
|
601
629
|
/** the items in the current page */
|
|
602
630
|
items: entityType[];
|
package/src/remult3/remult3.js
CHANGED
|
@@ -4,6 +4,7 @@ exports.flags = void 0;
|
|
|
4
4
|
exports.flags = {
|
|
5
5
|
error500RetryCount: 4,
|
|
6
6
|
};
|
|
7
|
+
//p1 - fix query docs to also explain how it can be used for infinite scroll and pagination.
|
|
7
8
|
//y1 - 'test expression columns without aliases'
|
|
8
9
|
//p1 - see if I can fix the no alias problem in selects
|
|
9
10
|
//p1 - add luid - it's cool for order by.
|
|
@@ -11,6 +12,7 @@ exports.flags = {
|
|
|
11
12
|
//p1 - add nanoid
|
|
12
13
|
//p1 - add id and use luid by default, but allow changes with Fields.id.defaultIdProvider
|
|
13
14
|
//p1 - explain the benefits of changing the default provider for testing in docs.
|
|
15
|
+
//p1 - fix sqlite to support alter table when adding a column with ensure schema = on
|
|
14
16
|
//p1 - fix app custom filters example for multiple filters.
|
|
15
17
|
//p1 - add not!!!!
|
|
16
18
|
//p1 - add LifecycleEvent to documentation
|