remult 0.18.1-exp.2 → 0.18.1-exp.21

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.
Files changed (154) hide show
  1. package/README.md +28 -5
  2. package/esm/index.d.ts +4 -3
  3. package/esm/index.js +4 -2
  4. package/esm/live-query/ably.d.ts +6 -6
  5. package/esm/live-query/ably.js +5 -5
  6. package/esm/postgres/postgres-data-provider.d.ts +3 -1
  7. package/esm/postgres/postgres-data-provider.js +11 -1
  8. package/esm/postgres/schema-builder.d.ts +1 -1
  9. package/esm/postgres/schema-builder.js +43 -27
  10. package/esm/remult-express.d.ts +4 -22
  11. package/esm/remult-express.js +30 -28
  12. package/esm/remult-fastify.js +1 -1
  13. package/esm/remult-fresh.js +2 -2
  14. package/esm/remult-knex/index.d.ts +7 -31
  15. package/esm/remult-knex/index.js +71 -42
  16. package/esm/remult-mongo.d.ts +9 -2
  17. package/esm/remult-mongo.js +24 -8
  18. package/esm/remult-next.d.ts +11 -0
  19. package/esm/remult-next.js +27 -0
  20. package/esm/server/expressBridge.d.ts +20 -52
  21. package/esm/server/expressBridge.js +55 -29
  22. package/esm/server/index.d.ts +3 -1
  23. package/esm/server/index.js +6 -1
  24. package/esm/src/column-interfaces.d.ts +44 -8
  25. package/esm/src/context.d.ts +31 -19
  26. package/esm/src/context.js +35 -42
  27. package/esm/src/data-api.js +17 -4
  28. package/esm/src/data-interfaces.d.ts +1 -1
  29. package/esm/src/data-providers/array-entity-data-provider.d.ts +1 -1
  30. package/esm/src/data-providers/array-entity-data-provider.js +1 -1
  31. package/esm/src/data-providers/rest-data-provider.d.ts +4 -15
  32. package/esm/src/data-providers/rest-data-provider.js +38 -23
  33. package/esm/src/data-providers/sql-database.d.ts +6 -3
  34. package/esm/src/data-providers/sql-database.js +57 -16
  35. package/esm/src/data-providers/web-sql-data-provider.d.ts +2 -0
  36. package/esm/src/data-providers/web-sql-data-provider.js +17 -8
  37. package/esm/src/entity.d.ts +2 -2
  38. package/esm/src/filter/filter-consumer-bridge-to-sql-request.d.ts +16 -16
  39. package/esm/src/filter/filter-consumer-bridge-to-sql-request.js +29 -21
  40. package/esm/src/filter/filter-interfaces.d.ts +5 -5
  41. package/esm/src/filter/filter-interfaces.js +31 -26
  42. package/esm/src/live-query/LiveQueryClient.d.ts +1 -19
  43. package/esm/src/live-query/LiveQueryClient.js +81 -50
  44. package/esm/src/live-query/SseSubscriptionClient.d.ts +4 -0
  45. package/esm/src/live-query/{EventSourceLiveQueryProvider.js → SseSubscriptionClient.js} +7 -6
  46. package/esm/src/live-query/SubscriptionChannel.d.ts +41 -0
  47. package/esm/src/live-query/{LiveQuerySubscriber.js → SubscriptionChannel.js} +40 -22
  48. package/esm/src/live-query/SubscriptionServer.d.ts +38 -0
  49. package/esm/src/live-query/{LiveQueryPublisher.js → SubscriptionServer.js} +60 -73
  50. package/esm/src/remult-proxy.js +44 -1
  51. package/esm/src/remult3/RepositoryImplementation.d.ts +8 -2
  52. package/esm/src/remult3/RepositoryImplementation.js +94 -30
  53. package/esm/src/remult3/remult3.d.ts +59 -6
  54. package/esm/src/remult3/remult3.js +1 -0
  55. package/esm/src/server-action.d.ts +1 -1
  56. package/esm/src/shared-tests/db-tests-setup.d.ts +1 -1
  57. package/esm/src/shared-tests/db-tests-setup.js +4 -3
  58. package/esm/src/shared-tests/db-tests.db-tests.js +55 -9
  59. package/esm/src/sql-command.d.ts +4 -2
  60. package/esm/src/tests/entityForCustomFilter.d.ts +6 -6
  61. package/esm/src/tests/entityForCustomFilter.js +20 -21
  62. package/esm/src/tests/frontend-database-tests-setup.spec.js +1 -2
  63. package/esm/src/tests/testHelper.spec.d.ts +2 -2
  64. package/esm/src/tests/testHelper.spec.js +1 -2
  65. package/esm/src/valueConverters.js +17 -7
  66. package/index.d.ts +4 -3
  67. package/index.js +7 -3
  68. package/live-query/ably.d.ts +6 -6
  69. package/live-query/ably.js +12 -12
  70. package/package.json +18 -9
  71. package/postgres/postgres-data-provider.d.ts +3 -1
  72. package/postgres/postgres-data-provider.js +13 -3
  73. package/postgres/schema-builder.d.ts +1 -1
  74. package/postgres/schema-builder.js +64 -50
  75. package/remult-express.d.ts +4 -22
  76. package/remult-express.js +39 -47
  77. package/remult-fastify.js +2 -2
  78. package/remult-fresh.js +1 -1
  79. package/remult-knex/index.d.ts +7 -31
  80. package/remult-knex/index.js +100 -53
  81. package/remult-mongo.d.ts +9 -2
  82. package/remult-mongo.js +39 -7
  83. package/remult-next.d.ts +11 -0
  84. package/remult-next.js +73 -0
  85. package/server/JsonEntityFileStorage.js +2 -2
  86. package/server/expressBridge.d.ts +20 -52
  87. package/server/expressBridge.js +68 -41
  88. package/server/index.d.ts +3 -1
  89. package/server/index.js +7 -2
  90. package/src/column-interfaces.d.ts +44 -8
  91. package/src/context.d.ts +31 -19
  92. package/src/context.js +39 -50
  93. package/src/data-api.js +18 -5
  94. package/src/data-interfaces.d.ts +1 -1
  95. package/src/data-providers/array-entity-data-provider.d.ts +1 -1
  96. package/src/data-providers/array-entity-data-provider.js +1 -1
  97. package/src/data-providers/rest-data-provider.d.ts +4 -15
  98. package/src/data-providers/rest-data-provider.js +48 -24
  99. package/src/data-providers/sql-database.d.ts +6 -3
  100. package/src/data-providers/sql-database.js +75 -15
  101. package/src/data-providers/web-sql-data-provider.d.ts +2 -0
  102. package/src/data-providers/web-sql-data-provider.js +16 -7
  103. package/src/entity.d.ts +2 -2
  104. package/src/filter/filter-consumer-bridge-to-sql-request.d.ts +16 -16
  105. package/src/filter/filter-consumer-bridge-to-sql-request.js +59 -50
  106. package/src/filter/filter-interfaces.d.ts +5 -5
  107. package/src/filter/filter-interfaces.js +31 -26
  108. package/src/live-query/LiveQueryClient.d.ts +1 -19
  109. package/src/live-query/LiveQueryClient.js +117 -64
  110. package/src/live-query/SseSubscriptionClient.d.ts +4 -0
  111. package/src/live-query/{EventSourceLiveQueryProvider.js → SseSubscriptionClient.js} +13 -12
  112. package/src/live-query/SubscriptionChannel.d.ts +41 -0
  113. package/src/live-query/{LiveQuerySubscriber.js → SubscriptionChannel.js} +51 -47
  114. package/src/live-query/SubscriptionServer.d.ts +38 -0
  115. package/src/live-query/SubscriptionServer.js +237 -0
  116. package/src/remult-proxy.js +137 -2
  117. package/src/remult3/RepositoryImplementation.d.ts +8 -2
  118. package/src/remult3/RepositoryImplementation.js +121 -34
  119. package/src/remult3/remult3.d.ts +59 -6
  120. package/src/remult3/remult3.js +1 -0
  121. package/src/server-action.d.ts +1 -1
  122. package/src/shared-tests/db-tests-setup.d.ts +1 -1
  123. package/src/shared-tests/db-tests-setup.js +5 -4
  124. package/src/shared-tests/db-tests.db-tests.js +101 -8
  125. package/src/sql-command.d.ts +4 -2
  126. package/src/tests/entityForCustomFilter.d.ts +6 -6
  127. package/src/tests/entityForCustomFilter.js +30 -31
  128. package/src/tests/frontend-database-tests-setup.spec.js +4 -5
  129. package/src/tests/testHelper.spec.d.ts +2 -2
  130. package/src/tests/testHelper.spec.js +4 -5
  131. package/src/valueConverters.js +17 -7
  132. package/esm/live-query/index.d.ts +0 -3
  133. package/esm/live-query/index.js +0 -3
  134. package/esm/src/backend-tests/backend-database-test-setup.backend-spec.d.ts +0 -5
  135. package/esm/src/backend-tests/backend-database-test-setup.backend-spec.js +0 -113
  136. package/esm/src/backend-tests/my-test.backend-spec.d.ts +0 -1
  137. package/esm/src/backend-tests/my-test.backend-spec.js +0 -59
  138. package/esm/src/backend-tests/test-http-server.backend-spec.d.ts +0 -6
  139. package/esm/src/backend-tests/test-http-server.backend-spec.js +0 -171
  140. package/esm/src/live-query/EventSourceLiveQueryProvider.d.ts +0 -4
  141. package/esm/src/live-query/LiveQueryPublisher.d.ts +0 -49
  142. package/esm/src/live-query/LiveQuerySubscriber.d.ts +0 -67
  143. package/live-query/index.d.ts +0 -3
  144. package/live-query/index.js +0 -10
  145. package/src/backend-tests/backend-database-test-setup.backend-spec.d.ts +0 -5
  146. package/src/backend-tests/backend-database-test-setup.backend-spec.js +0 -231
  147. package/src/backend-tests/my-test.backend-spec.d.ts +0 -1
  148. package/src/backend-tests/my-test.backend-spec.js +0 -160
  149. package/src/backend-tests/test-http-server.backend-spec.d.ts +0 -6
  150. package/src/backend-tests/test-http-server.backend-spec.js +0 -342
  151. package/src/live-query/EventSourceLiveQueryProvider.d.ts +0 -4
  152. package/src/live-query/LiveQueryPublisher.d.ts +0 -49
  153. package/src/live-query/LiveQueryPublisher.js +0 -248
  154. package/src/live-query/LiveQuerySubscriber.d.ts +0 -67
@@ -1,10 +1,11 @@
1
1
  import { UrlBuilder } from '../../urlBuilder';
2
2
  import { customUrlToken, Filter } from '../filter/filter-interfaces';
3
3
  import { buildRestDataProvider, retry } from "../buildRestDataProvider";
4
+ import { actionInfo } from '../server-action';
4
5
  export class RestDataProvider {
5
6
  constructor(apiProvider) {
6
7
  this.apiProvider = apiProvider;
7
- this.supportsCustomFilter = true;
8
+ this.supportsrawFilter = true;
8
9
  }
9
10
  getEntityDataProvider(entity) {
10
11
  return new RestEntityDataProvider(() => {
@@ -20,6 +21,7 @@ export class RestDataProvider {
20
21
  throw new Error("Method not implemented.");
21
22
  }
22
23
  }
24
+ //@internal
23
25
  export function findOptionsToJson(options, meta) {
24
26
  return {
25
27
  limit: options.limit,
@@ -28,6 +30,7 @@ export function findOptionsToJson(options, meta) {
28
30
  orderBy: options.orderBy
29
31
  };
30
32
  }
33
+ //@internal
31
34
  export function findOptionsFromJson(json, meta) {
32
35
  let r = {};
33
36
  for (const key of ["limit", "page", "where", "orderBy"]) {
@@ -62,29 +65,14 @@ export class RestEntityDataProvider {
62
65
  return result;
63
66
  }
64
67
  async count(where) {
65
- let url = new UrlBuilder(this.url());
66
- url.add("__action", "count");
67
- let filterObject;
68
- if (where) {
69
- filterObject = where.toJson();
70
- if (addFilterToUrlAndReturnTrueIfSuccessful(filterObject, url))
71
- filterObject = undefined;
72
- }
73
- if (filterObject)
74
- return this.http().post(url.url, filterObject).then(r => +(r.count));
75
- else
76
- return this.http().get(url.url).then(r => +(r.count));
68
+ const { run } = this.buildFindRequest({ where });
69
+ return run("count").then(r => +r.count);
77
70
  }
78
71
  find(options) {
79
- let { filterObject, url } = this.buildFindRequest(options);
80
- if (filterObject) {
81
- url.add("__action", "get");
82
- return this.http().post(url.url, filterObject).then(x => x.map(y => this.translateFromJson(y)));
83
- }
84
- else
85
- return this.http().get(url.url).then(x => x.map(y => this.translateFromJson(y)));
86
- ;
72
+ let { run } = this.buildFindRequest(options);
73
+ return run().then(x => x.map(y => this.translateFromJson(y)));
87
74
  }
75
+ //@internal
88
76
  buildFindRequest(options) {
89
77
  let url = new UrlBuilder(this.url());
90
78
  let filterObject;
@@ -113,7 +101,34 @@ export class RestEntityDataProvider {
113
101
  if (options.page)
114
102
  url.add('_page', options.page);
115
103
  }
116
- return { filterObject, url };
104
+ const run = (action) => {
105
+ let u = new UrlBuilder(url.url);
106
+ if (!action && filterObject) {
107
+ action = "get";
108
+ }
109
+ if (action)
110
+ u.add("__action", action);
111
+ if (filterObject) {
112
+ return this.http().post(u.url, filterObject);
113
+ }
114
+ else
115
+ return this.http().get(u.url);
116
+ };
117
+ return {
118
+ createKey: () => JSON.stringify({ url, filterObject }),
119
+ run,
120
+ subscribe: async () => {
121
+ const result = await run("liveQuery");
122
+ return {
123
+ ...result,
124
+ unsubscribe: async () => {
125
+ return actionInfo.runActionWithoutBlockingUI(() => this.http().post(this.url() + "?__action=endLiveQuery", {
126
+ id: result.queryChannel
127
+ }));
128
+ }
129
+ };
130
+ }
131
+ };
117
132
  }
118
133
  update(id, data) {
119
134
  let result = {};
@@ -211,7 +226,7 @@ export function addFilterToUrlAndReturnTrueIfSuccessful(filter, url) {
211
226
  if (Object.prototype.hasOwnProperty.call(filter, key)) {
212
227
  const element = filter[key];
213
228
  if (Array.isArray(element)) {
214
- if (key.endsWith("_in"))
229
+ if (key.endsWith(".in"))
215
230
  url.add(key, JSON.stringify(element));
216
231
  else
217
232
  element.forEach(e => url.add(key, e));
@@ -1,14 +1,17 @@
1
1
  import { EntityDataProvider, DataProvider } from "../data-interfaces";
2
- import { SqlCommand, SqlImplementation, SqlResult } from "../sql-command";
2
+ import { SqlCommand, SqlCommandWithParameters, SqlImplementation, SqlResult } from "../sql-command";
3
3
  import { CustomSqlFilterBuilderFunction } from "../filter/filter-consumer-bridge-to-sql-request";
4
- import { EntityMetadata, EntityFilter } from "../remult3";
4
+ import { EntityMetadata, EntityFilter, RepositoryOverloads } from "../remult3";
5
+ import { Remult } from "../context";
5
6
  export declare class SqlDatabase implements DataProvider {
6
7
  private sql;
8
+ static getDb(remult?: Remult): SqlDatabase;
7
9
  createCommand(): SqlCommand;
8
10
  execute(sql: string): Promise<SqlResult>;
9
11
  getEntityDataProvider(entity: EntityMetadata): EntityDataProvider;
10
12
  transaction(action: (dataProvider: DataProvider) => Promise<void>): Promise<void>;
11
- static customFilter(build: CustomSqlFilterBuilderFunction): EntityFilter<any>;
13
+ static rawFilter(build: CustomSqlFilterBuilderFunction): EntityFilter<any>;
14
+ static filterToRaw<entityType>(repo: RepositoryOverloads<entityType>, condition: EntityFilter<entityType>, sqlCommand?: SqlCommandWithParameters): Promise<string>;
12
15
  static LogToConsole: boolean;
13
16
  static durationThreshold: number;
14
17
  constructor(sql: SqlImplementation);
@@ -1,23 +1,35 @@
1
1
  import { CompoundIdField } from "../column";
2
- import { FilterConsumerBridgeToSqlRequest, getDbNameProvider } from "../filter/filter-consumer-bridge-to-sql-request";
2
+ import { dbNamesOf, FilterConsumerBridgeToSqlRequest, isDbReadonly } from "../filter/filter-consumer-bridge-to-sql-request";
3
3
  import { customDatabaseFilterToken, Filter } from '../filter/filter-interfaces';
4
4
  import { Sort } from '../sort';
5
+ import { getRepository } from "../remult3";
6
+ import { RemultProxy } from "../remult-proxy";
5
7
  // @dynamic
6
8
  export class SqlDatabase {
7
9
  constructor(sql) {
8
10
  this.sql = sql;
9
11
  this.createdEntities = [];
10
12
  }
13
+ static getDb(remult) {
14
+ const r = (remult || RemultProxy.defaultRemult).dataProvider;
15
+ if (!r.createCommand)
16
+ throw "the data provider is not an SqlDatabase";
17
+ return r;
18
+ }
11
19
  createCommand() {
12
20
  return new LogSQLCommand(this.sql.createCommand(), SqlDatabase.LogToConsole);
13
21
  }
14
22
  async execute(sql) {
15
23
  return await this.createCommand().execute(sql);
16
24
  }
25
+ /* @internal*/
26
+ _getSourceSql() {
27
+ return this.sql;
28
+ }
17
29
  getEntityDataProvider(entity) {
18
30
  return new ActualSQLServerDataProvider(entity, this, async (dbName) => {
19
- if (this.createdEntities.indexOf(dbName.entityName) < 0) {
20
- this.createdEntities.push(dbName.entityName);
31
+ if (this.createdEntities.indexOf(dbName.$entityName) < 0) {
32
+ this.createdEntities.push(dbName.$entityName);
21
33
  await this.sql.entityIsUsedForTheFirstTime(entity);
22
34
  }
23
35
  }, this.sql);
@@ -48,13 +60,25 @@ export class SqlDatabase {
48
60
  }
49
61
  });
50
62
  }
51
- static customFilter(build) {
63
+ //TODO - change to "rawFilter" (in all databases and docs)
64
+ static rawFilter(build) {
52
65
  return {
53
66
  [customDatabaseFilterToken]: {
54
67
  buildSql: build
55
68
  }
56
69
  };
57
70
  }
71
+ //TODO - filter to raw
72
+ static async filterToRaw(repo, condition, sqlCommand) {
73
+ if (!sqlCommand) {
74
+ sqlCommand = new myDummySQLCommand();
75
+ }
76
+ const r = getRepository(repo);
77
+ var b = new FilterConsumerBridgeToSqlRequest(sqlCommand, await dbNamesOf(r.metadata));
78
+ b._addWhere = false;
79
+ await (await (r.translateWhereToFilter(condition))).__applyToConsumer(b);
80
+ return await b.resolveWhere();
81
+ }
58
82
  }
59
83
  SqlDatabase.LogToConsole = false;
60
84
  SqlDatabase.durationThreshold = 0;
@@ -95,13 +119,13 @@ class ActualSQLServerDataProvider {
95
119
  this.strategy = strategy;
96
120
  }
97
121
  async init() {
98
- let dbNameProvider = await getDbNameProvider(this.entity);
122
+ let dbNameProvider = await dbNamesOf(this.entity);
99
123
  await this.iAmUsed(dbNameProvider);
100
124
  return dbNameProvider;
101
125
  }
102
126
  async count(where) {
103
127
  let e = await this.init();
104
- let select = 'select count(*) count from ' + e.entityName;
128
+ let select = 'select count(*) count from ' + e.$entityName;
105
129
  let r = this.sql.createCommand();
106
130
  if (where) {
107
131
  let wc = new FilterConsumerBridgeToSqlRequest(r, e);
@@ -116,7 +140,7 @@ class ActualSQLServerDataProvider {
116
140
  let e = await this.init();
117
141
  let { colKeys, select } = this.buildSelect(e);
118
142
  select = 'select ' + select;
119
- select += '\n from ' + e.entityName;
143
+ select += '\n from ' + e.$entityName;
120
144
  let r = this.sql.createCommand();
121
145
  if (options) {
122
146
  if (options.where) {
@@ -147,7 +171,7 @@ class ActualSQLServerDataProvider {
147
171
  }
148
172
  else
149
173
  select += ', ';
150
- select += e.nameOf(c.field);
174
+ select += e.$dbNameOf(c.field);
151
175
  if (c.isDescending)
152
176
  select += ' desc';
153
177
  }
@@ -189,7 +213,7 @@ class ActualSQLServerDataProvider {
189
213
  else {
190
214
  if (colKeys.length > 0)
191
215
  select += ', ';
192
- select += e.nameOf(x);
216
+ select += e.$dbNameOf(x);
193
217
  colKeys.push(x);
194
218
  }
195
219
  }
@@ -200,12 +224,12 @@ class ActualSQLServerDataProvider {
200
224
  let r = this.sql.createCommand();
201
225
  let f = new FilterConsumerBridgeToSqlRequest(r, e);
202
226
  Filter.fromEntityFilter(this.entity, this.entity.idMetadata.getIdFilter(id)).__applyToConsumer(f);
203
- let statement = 'update ' + e.entityName + ' set ';
227
+ let statement = 'update ' + e.$entityName + ' set ';
204
228
  let added = false;
205
229
  for (const x of this.entity.fields) {
206
230
  if (x instanceof CompoundIdField) {
207
231
  }
208
- if (e.isDbReadonly(x)) { }
232
+ if (isDbReadonly(x, e)) { }
209
233
  else if (data[x.key] !== undefined) {
210
234
  let v = x.valueConverter.toDb(data[x.key]);
211
235
  if (v !== undefined) {
@@ -213,7 +237,7 @@ class ActualSQLServerDataProvider {
213
237
  added = true;
214
238
  else
215
239
  statement += ', ';
216
- statement += e.nameOf(x) + ' = ' + r.addParameterAndReturnSqlToken(v);
240
+ statement += e.$dbNameOf(x) + ' = ' + r.addParameterAndReturnSqlToken(v);
217
241
  }
218
242
  }
219
243
  }
@@ -229,7 +253,7 @@ class ActualSQLServerDataProvider {
229
253
  let r = this.sql.createCommand();
230
254
  let f = new FilterConsumerBridgeToSqlRequest(r, e);
231
255
  Filter.fromEntityFilter(this.entity, this.entity.idMetadata.getIdFilter(id)).__applyToConsumer(f);
232
- let statement = 'delete from ' + e.entityName;
256
+ let statement = 'delete from ' + e.$entityName;
233
257
  statement += await f.resolveWhere();
234
258
  return r.execute(statement).then(() => { });
235
259
  }
@@ -240,7 +264,7 @@ class ActualSQLServerDataProvider {
240
264
  let vals = '';
241
265
  let added = false;
242
266
  for (const x of this.entity.fields) {
243
- if (e.isDbReadonly(x)) { }
267
+ if (isDbReadonly(x, e)) { }
244
268
  else {
245
269
  let v = x.valueConverter.toDb(data[x.key]);
246
270
  if (v != undefined) {
@@ -250,15 +274,32 @@ class ActualSQLServerDataProvider {
250
274
  cols += ', ';
251
275
  vals += ', ';
252
276
  }
253
- cols += e.nameOf(x);
277
+ cols += e.$dbNameOf(x);
254
278
  vals += r.addParameterAndReturnSqlToken(v);
255
279
  }
256
280
  }
257
281
  }
258
- let statement = `insert into ${e.entityName} (${cols}) values (${vals})`;
282
+ let statement = `insert into ${e.$entityName} (${cols}) values (${vals})`;
259
283
  let { colKeys, select } = this.buildSelect(e);
260
284
  statement += ' returning ' + select;
261
285
  return await r.execute(statement).then(sql => this.buildResultRow(colKeys, sql.rows[0], sql));
262
286
  }
263
287
  }
264
288
  ActualSQLServerDataProvider.LogToConsole = false;
289
+ class myDummySQLCommand {
290
+ execute(sql) {
291
+ throw new Error("Method not implemented.");
292
+ }
293
+ addParameterAndReturnSqlToken(val) {
294
+ if (val === null)
295
+ return "null";
296
+ if (val instanceof Date)
297
+ val = val.toISOString();
298
+ if (typeof (val) == "string") {
299
+ if (val == undefined)
300
+ val = '';
301
+ return '\'' + val.replace(/'/g, '\'\'') + '\'';
302
+ }
303
+ return val.toString();
304
+ }
305
+ }
@@ -1,12 +1,14 @@
1
1
  import { __RowsOfDataForTesting } from "../__RowsOfDataForTesting";
2
2
  import { SqlCommand, SqlImplementation } from "../sql-command";
3
3
  import { EntityMetadata } from "../remult3";
4
+ import { Remult } from "../context";
4
5
  export declare class WebSqlDataProvider implements SqlImplementation, __RowsOfDataForTesting {
5
6
  private databaseName;
6
7
  rows: {
7
8
  [tableName: string]: any;
8
9
  };
9
10
  constructor(databaseName: string, databaseSize?: number);
11
+ static getDb(remult?: Remult): any;
10
12
  getLimitSqlSyntax(limit: number, offset: number): string;
11
13
  entityIsUsedForTheFirstTime(entity: EntityMetadata): Promise<void>;
12
14
  dropTable(entity: EntityMetadata): Promise<void>;
@@ -1,6 +1,6 @@
1
1
  import { isAutoIncrement } from "../remult3";
2
2
  import { SqlDatabase } from "./sql-database";
3
- import { getDbNameProvider } from "../filter/filter-consumer-bridge-to-sql-request";
3
+ import { dbNamesOf, isDbReadonly } from "../filter/filter-consumer-bridge-to-sql-request";
4
4
  //SqlDatabase.LogToConsole = true;
5
5
  export class WebSqlDataProvider {
6
6
  constructor(databaseName, databaseSize = 2 * 1024 * 1024) {
@@ -8,6 +8,15 @@ export class WebSqlDataProvider {
8
8
  //@ts-ignore
9
9
  this.db = window.openDatabase(databaseName, '1.0', databaseName, databaseSize);
10
10
  }
11
+ // return instance of websql.Database class - see @types/websql
12
+ static getDb(remult) {
13
+ const sql = SqlDatabase.getDb(remult);
14
+ const me = sql._getSourceSql();
15
+ if (!me.db) {
16
+ throw "the data provider is not a WebSqlDataProvider";
17
+ }
18
+ return me.db;
19
+ }
11
20
  getLimitSqlSyntax(limit, offset) {
12
21
  return ' limit ' + limit + ' offset ' + offset;
13
22
  }
@@ -15,34 +24,34 @@ export class WebSqlDataProvider {
15
24
  await this.createTable(entity);
16
25
  }
17
26
  async dropTable(entity) {
18
- let e = await getDbNameProvider(entity);
19
- let sql = 'drop table if exists ' + e.entityName;
27
+ let e = await dbNamesOf(entity);
28
+ let sql = 'drop table if exists ' + e.$entityName;
20
29
  if (SqlDatabase.LogToConsole)
21
30
  console.info(sql);
22
31
  await this.createCommand().execute(sql);
23
32
  }
24
33
  async createTable(entity) {
25
34
  let result = '';
26
- let e = await getDbNameProvider(entity);
35
+ let e = await dbNamesOf(entity);
27
36
  for (const x of entity.fields) {
28
- if (!e.isDbReadonly(x) || isAutoIncrement(x)) {
37
+ if (!isDbReadonly(x, e) || isAutoIncrement(x)) {
29
38
  if (result.length != 0)
30
39
  result += ',';
31
40
  result += '\r\n ';
32
41
  if (isAutoIncrement(x)) {
33
42
  if (x.key != entity.idMetadata.field.key)
34
43
  throw "in web sql, autoincrement is only allowed for primary key";
35
- result += e.nameOf(x) + ' integer primary key autoincrement';
44
+ result += e.$dbNameOf(x) + ' integer primary key autoincrement';
36
45
  }
37
46
  else {
38
- result += this.addColumnSqlSyntax(x, e.nameOf(x));
47
+ result += this.addColumnSqlSyntax(x, e.$dbNameOf(x));
39
48
  if (x.key == entity.idMetadata.field.key) {
40
49
  result += ' primary key';
41
50
  }
42
51
  }
43
52
  }
44
53
  }
45
- let sql = 'create table if not exists ' + e.entityName + ' (' + result + '\r\n)';
54
+ let sql = 'create table if not exists ' + e.$entityName + ' (' + result + '\r\n)';
46
55
  if (SqlDatabase.LogToConsole)
47
56
  console.log(sql);
48
57
  await this.createCommand().execute(sql);
@@ -1,6 +1,6 @@
1
1
  import { Allowed, AllowedForInstance } from "./context";
2
2
  import { FieldMetadata as FieldMetadata } from './column-interfaces';
3
- import { EntityOrderBy, FieldsMetadata, EntityFilter, EntityRef } from "./remult3";
3
+ import { EntityOrderBy, FieldsMetadata, EntityFilter, EntityRef, EntityMetadata } from "./remult3";
4
4
  export interface EntityOptions<entityType = any> {
5
5
  /**A human readable name for the entity */
6
6
  caption?: string;
@@ -67,7 +67,7 @@ export interface EntityOptions<entityType = any> {
67
67
  */
68
68
  dbName?: string;
69
69
  /** For entities that are based on SQL expressions instead of a physical table or view*/
70
- sqlExpression?: string | ((entity: FieldsMetadata<entityType>) => string | Promise<string>);
70
+ sqlExpression?: string | ((entity: EntityMetadata<entityType>) => string | Promise<string>);
71
71
  /** An arrow function that identifies the `id` column to use for this entity
72
72
  * @example
73
73
  * //Single column id
@@ -1,7 +1,8 @@
1
- import { SqlCommand } from "../sql-command";
1
+ import { SqlCommandWithParameters } from "../sql-command";
2
2
  import { Filter, FilterConsumer } from './filter-interfaces';
3
3
  import { FieldMetadata } from "../column-interfaces";
4
- import { EntityMetadata } from "../remult3/remult3";
4
+ import { EntityFilter, OmitEB } from "../remult3/remult3";
5
+ import { EntityMetadataOverloads, RepositoryOverloads } from "../remult3";
5
6
  export declare class FilterConsumerBridgeToSqlRequest implements FilterConsumer {
6
7
  private r;
7
8
  private nameProvider;
@@ -9,7 +10,7 @@ export declare class FilterConsumerBridgeToSqlRequest implements FilterConsumer
9
10
  _addWhere: boolean;
10
11
  promises: Promise<void>[];
11
12
  resolveWhere(): Promise<string>;
12
- constructor(r: SqlCommand, nameProvider: dbNameProvider);
13
+ constructor(r: SqlCommandWithParameters, nameProvider: EntityDbNamesBase);
13
14
  custom(key: string, customItem: any): void;
14
15
  or(orElements: Filter[]): void;
15
16
  isNull(col: FieldMetadata): void;
@@ -32,19 +33,18 @@ export interface CustomSqlFilterObject {
32
33
  }
33
34
  export declare class CustomSqlFilterBuilder {
34
35
  private r;
35
- constructor(r: SqlCommand);
36
+ constructor(r: SqlCommandWithParameters);
36
37
  sql: string;
37
38
  addParameterAndReturnSqlToken<valueType>(val: valueType, field?: FieldMetadata<valueType>): string;
39
+ filterToRaw<entityType>(repo: RepositoryOverloads<entityType>, condition: EntityFilter<entityType>): Promise<string>;
38
40
  }
39
- export declare function getDbNameProvider(meta: EntityMetadata): Promise<dbNameProvider>;
40
- export declare class dbNameProviderImpl {
41
- map: Map<string, string>;
42
- nameOf(field: FieldMetadata<any>): string;
43
- entityName: string;
44
- isDbReadonly(x: FieldMetadata): boolean;
45
- }
46
- export interface dbNameProvider {
47
- nameOf(field: FieldMetadata<any>): string;
48
- entityName: string;
49
- isDbReadonly(x: FieldMetadata): boolean;
50
- }
41
+ export declare function isDbReadonly<entityType>(field: FieldMetadata, dbNames: EntityDbNames<entityType>): boolean;
42
+ export declare type EntityDbNamesBase = {
43
+ $entityName: string;
44
+ $dbNameOf(field: FieldMetadata<any> | string): string;
45
+ toString(): string;
46
+ };
47
+ export declare type EntityDbNames<entityType> = {
48
+ [Properties in keyof Required<OmitEB<entityType>>]: string;
49
+ } & EntityDbNamesBase;
50
+ export declare function dbNamesOf<entityType>(repo: EntityMetadataOverloads<entityType>): Promise<EntityDbNames<entityType>>;
@@ -1,3 +1,5 @@
1
+ import { getEntityMetadata } from "../remult3";
2
+ import { SqlDatabase } from "../data-providers/sql-database";
1
3
  export class FilterConsumerBridgeToSqlRequest {
2
4
  constructor(r, nameProvider) {
3
5
  this.r = r;
@@ -44,15 +46,15 @@ export class FilterConsumerBridgeToSqlRequest {
44
46
  })());
45
47
  }
46
48
  isNull(col) {
47
- this.promises.push((async () => this.addToWhere(this.nameProvider.nameOf(col) + ' is null'))());
49
+ this.promises.push((async () => this.addToWhere(this.nameProvider.$dbNameOf(col) + ' is null'))());
48
50
  }
49
51
  isNotNull(col) {
50
- this.promises.push((async () => this.addToWhere(this.nameProvider.nameOf(col) + ' is not null'))());
52
+ this.promises.push((async () => this.addToWhere(this.nameProvider.$dbNameOf(col) + ' is not null'))());
51
53
  }
52
54
  isIn(col, val) {
53
55
  this.promises.push((async () => {
54
56
  if (val && val.length > 0)
55
- this.addToWhere(this.nameProvider.nameOf(col) + " in (" + val.map(x => this.r.addParameterAndReturnSqlToken(col.valueConverter.toDb(x))).join(",") + ")");
57
+ this.addToWhere(this.nameProvider.$dbNameOf(col) + " in (" + val.map(x => this.r.addParameterAndReturnSqlToken(col.valueConverter.toDb(x))).join(",") + ")");
56
58
  else
57
59
  this.addToWhere('1 = 0 /*isIn with no values*/');
58
60
  })());
@@ -77,12 +79,12 @@ export class FilterConsumerBridgeToSqlRequest {
77
79
  }
78
80
  containsCaseInsensitive(col, val) {
79
81
  this.promises.push((async () => {
80
- this.addToWhere('lower (' + this.nameProvider.nameOf(col) + ") like lower ('%" + val.replace(/'/g, '\'\'') + "%')");
82
+ this.addToWhere('lower (' + this.nameProvider.$dbNameOf(col) + ") like lower ('%" + val.replace(/'/g, '\'\'') + "%')");
81
83
  })());
82
84
  }
83
85
  add(col, val, operator) {
84
86
  this.promises.push((async () => {
85
- let x = this.nameProvider.nameOf(col) + ' ' + operator + ' ' + this.r.addParameterAndReturnSqlToken(col.valueConverter.toDb(val));
87
+ let x = this.nameProvider.$dbNameOf(col) + ' ' + operator + ' ' + this.r.addParameterAndReturnSqlToken(col.valueConverter.toDb(val));
86
88
  this.addToWhere(x);
87
89
  })());
88
90
  }
@@ -117,23 +119,29 @@ export class CustomSqlFilterBuilder {
117
119
  val = field.valueConverter.toDb(val);
118
120
  return this.r.addParameterAndReturnSqlToken(val);
119
121
  }
120
- }
121
- export async function getDbNameProvider(meta) {
122
- var result = new dbNameProviderImpl();
123
- for (const f of meta.fields) {
124
- result.map.set(f.key, await f.getDbName());
122
+ async filterToRaw(repo, condition) {
123
+ return SqlDatabase.filterToRaw(repo, condition, this);
125
124
  }
126
- result.entityName = await meta.getDbName();
127
- return result;
128
125
  }
129
- export class dbNameProviderImpl {
130
- constructor() {
131
- this.map = new Map();
132
- }
133
- nameOf(field) {
134
- return this.map.get(field.key);
135
- }
136
- isDbReadonly(x) {
137
- return (x.dbReadOnly || x.isServerExpression || this.nameOf(x) != x.options.dbName);
126
+ export function isDbReadonly(field, dbNames) {
127
+ return (field.dbReadOnly || field.isServerExpression || dbNames.$dbNameOf(field) != field.options.dbName);
128
+ }
129
+ export async function dbNamesOf(repo) {
130
+ var meta = getEntityMetadata(repo);
131
+ const result = {
132
+ $entityName: await meta.getDbName(),
133
+ toString: () => result.$entityName,
134
+ $dbNameOf: (field) => {
135
+ var key;
136
+ if (typeof field === "string")
137
+ key = field;
138
+ else
139
+ key = field.key;
140
+ return result[key];
141
+ }
142
+ };
143
+ for (const field of meta.fields) {
144
+ result[field.key] = await field.getDbName();
138
145
  }
146
+ return result;
139
147
  }
@@ -6,8 +6,8 @@ export declare class Filter {
6
6
  constructor(apply?: (add: FilterConsumer) => void);
7
7
  __applyToConsumer(add: FilterConsumer): void;
8
8
  static resolve<entityType>(filter: EntityFilter<entityType> | (() => EntityFilter<entityType> | Promise<EntityFilter<entityType>>)): Promise<EntityFilter<entityType>>;
9
- static createCustom<entityType>(customFilterTranslator: (r: Remult) => EntityFilter<entityType> | Promise<EntityFilter<entityType>>, key?: string): (() => EntityFilter<entityType>) & customFilterInfo<entityType>;
10
- static createCustom<entityType, argsType>(customFilterTranslator: (r: Remult, args: argsType) => EntityFilter<entityType> | Promise<EntityFilter<entityType>>, key?: string): ((y: argsType) => EntityFilter<entityType>) & customFilterInfo<entityType>;
9
+ static createCustom<entityType>(rawFilterTranslator: (unused: never, r: Remult) => EntityFilter<entityType> | Promise<EntityFilter<entityType>>, key?: string): (() => EntityFilter<entityType>) & rawFilterInfo<entityType>;
10
+ static createCustom<entityType, argsType>(rawFilterTranslator: (args: argsType, r: Remult) => EntityFilter<entityType> | Promise<EntityFilter<entityType>>, key?: string): ((y: argsType) => EntityFilter<entityType>) & rawFilterInfo<entityType>;
11
11
  static fromEntityFilter<T>(entity: EntityMetadata<T>, whereItem: EntityFilter<T>): Filter;
12
12
  toJson(): any;
13
13
  static entityFilterToJson<T>(entityDefs: EntityMetadata<T>, where: EntityFilter<T>): any;
@@ -77,9 +77,9 @@ export declare function entityFilterToJson<T>(entityDefs: EntityMetadata<T>, whe
77
77
  export declare function buildFilterFromRequestParameters(entity: EntityMetadata, filterInfo: {
78
78
  get: (key: string) => any;
79
79
  }): EntityFilter<any>;
80
- export interface customFilterInfo<entityType> {
81
- customFilterInfo: {
80
+ export interface rawFilterInfo<entityType> {
81
+ rawFilterInfo: {
82
82
  key: string;
83
- customFilterTranslator: (r: Remult, args: any) => (EntityFilter<entityType> | Promise<EntityFilter<entityType>>);
83
+ rawFilterTranslator: (args: any, r: Remult) => (EntityFilter<entityType> | Promise<EntityFilter<entityType>>);
84
84
  };
85
85
  }