@subsquid/openreader 0.0.0 → 0.3.1

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.
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.getFtsQuery = exports.getEntity = exports.propTypeEquals = exports.validateUnionTypes = exports.validateNames = exports.validateModel = exports.buildUnionProps = exports.getUnionProps = void 0;
6
+ exports.getFtsQuery = exports.getObject = exports.getEntity = exports.propTypeEquals = exports.validateLookups = exports.validateUnionTypes = exports.validateNames = exports.validateModel = exports.buildUnionProps = exports.getUnionProps = void 0;
7
7
  const assert_1 = __importDefault(require("assert"));
8
8
  const UNION_MAPS = new WeakMap();
9
9
  function getUnionProps(model, unionName) {
@@ -35,8 +35,10 @@ function buildUnionProps(model, unionName) {
35
35
  }
36
36
  exports.buildUnionProps = buildUnionProps;
37
37
  function validateModel(model) {
38
+ // TODO: check all invariants we assume
38
39
  validateNames(model);
39
40
  validateUnionTypes(model);
41
+ validateLookups(model);
40
42
  }
41
43
  exports.validateModel = validateModel;
42
44
  const TYPE_NAME_REGEX = /^[A-Z][a-zA-Z0-9]*$/;
@@ -90,6 +92,44 @@ function validateUnionTypes(model) {
90
92
  }
91
93
  }
92
94
  exports.validateUnionTypes = validateUnionTypes;
95
+ function validateLookups(model) {
96
+ for (let name in model) {
97
+ let item = model[name];
98
+ switch (item.kind) {
99
+ case 'object':
100
+ case 'interface':
101
+ for (let key in item.properties) {
102
+ let prop = item.properties[key];
103
+ if (prop.type.kind == 'lookup' || prop.type.kind == 'list-lookup') {
104
+ throw invalidProperty(name, key, `lookups are only supported on entity types`);
105
+ }
106
+ }
107
+ break;
108
+ case 'entity':
109
+ for (let key in item.properties) {
110
+ let prop = item.properties[key];
111
+ if (prop.type.kind == 'lookup' && !prop.nullable) {
112
+ throw invalidProperty(name, key, 'one-to-one lookups must be nullable');
113
+ }
114
+ if (prop.type.kind == 'lookup' || prop.type.kind == 'list-lookup') {
115
+ let lookupEntity = getEntity(model, prop.type.entity);
116
+ let lookupProperty = lookupEntity.properties[prop.type.field];
117
+ if (lookupProperty?.type.kind != 'fk' || lookupProperty.type.foreignEntity != name) {
118
+ throw invalidProperty(name, key, `${prop.type.entity}.${prop.type.field} is not a foreign key pointing to ${name}`);
119
+ }
120
+ if (prop.type.kind == 'lookup' && !lookupProperty.unique) {
121
+ throw invalidProperty(name, key, `${prop.type.entity}.${prop.type.field} is not @unique`);
122
+ }
123
+ }
124
+ }
125
+ break;
126
+ }
127
+ }
128
+ }
129
+ exports.validateLookups = validateLookups;
130
+ function invalidProperty(item, key, msg) {
131
+ return new Error(`Invalid property ${item}.${key}: ${msg}`);
132
+ }
93
133
  function propTypeEquals(a, b) {
94
134
  if (a.kind != b.kind)
95
135
  return false;
@@ -98,7 +138,8 @@ function propTypeEquals(a, b) {
98
138
  switch (a.kind) {
99
139
  case 'fk':
100
140
  return a.foreignEntity == b.foreignEntity;
101
- case 'list-relation':
141
+ case 'lookup':
142
+ case 'list-lookup':
102
143
  return a.entity == b.entity && a.field == b.field;
103
144
  default:
104
145
  return a.name == b.name;
@@ -107,13 +148,19 @@ function propTypeEquals(a, b) {
107
148
  exports.propTypeEquals = propTypeEquals;
108
149
  function getEntity(model, name) {
109
150
  let entity = model[name];
110
- (0, assert_1.default)(entity.kind == 'entity');
151
+ (0, assert_1.default)(entity.kind == 'entity', `${name} expected to be an entity`);
111
152
  return entity;
112
153
  }
113
154
  exports.getEntity = getEntity;
155
+ function getObject(model, name) {
156
+ let object = model[name];
157
+ (0, assert_1.default)(object.kind == 'object', `${name} expected to be an object`);
158
+ return object;
159
+ }
160
+ exports.getObject = getObject;
114
161
  function getFtsQuery(model, name) {
115
162
  let query = model[name];
116
- (0, assert_1.default)(query.kind == 'fts');
163
+ (0, assert_1.default)(query.kind == 'fts', `${name} expected to be FTS query`);
117
164
  return query;
118
165
  }
119
166
  exports.getFtsQuery = getFtsQuery;
@@ -1 +1 @@
1
- {"version":3,"file":"model.tools.js","sourceRoot":"","sources":["../src/model.tools.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"model.tools.js","sourceRoot":"","sources":["../src/model.tools.ts"],"names":[],"mappings":"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"}
package/dist/orderBy.js CHANGED
@@ -46,6 +46,11 @@ function buildOrderByMapping(model, typeName, depth) {
46
46
  m.set(key + '_' + name, { [key]: spec });
47
47
  }
48
48
  break;
49
+ case 'lookup':
50
+ for (let [name, spec] of buildOrderByMapping(model, propType.entity, depth - 1)) {
51
+ m.set(key + '_' + name, { [key]: spec });
52
+ }
53
+ break;
49
54
  }
50
55
  }
51
56
  return m;
@@ -1 +1 @@
1
- {"version":3,"file":"orderBy.js","sourceRoot":"","sources":["../src/orderBy.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"orderBy.js","sourceRoot":"","sources":["../src/orderBy.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,7 @@
1
+ import { Database } from "./db";
2
+ import type { Model } from "./model";
1
3
  import { OpenCrudOrderByValue } from "./orderBy";
2
4
  import type { FtsRequestedFields, RequestedFields } from "./requestedFields";
3
- import type { ResolverContext } from "./resolver";
4
5
  export interface ListArgs {
5
6
  offset?: number;
6
7
  limit?: number;
@@ -8,11 +9,11 @@ export interface ListArgs {
8
9
  where?: any;
9
10
  }
10
11
  export declare class QueryBuilder {
11
- params: any[];
12
- private aliases;
13
- private db;
14
12
  private model;
15
- constructor(ctx: ResolverContext);
13
+ private db;
14
+ private params;
15
+ private aliases;
16
+ constructor(model: Model, db: Database);
16
17
  private param;
17
18
  private ident;
18
19
  select(entityName: string, args: ListArgs, fields?: RequestedFields, variant?: SelectVariant): string;
@@ -4,18 +4,19 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.QueryBuilder = void 0;
7
+ const util_1 = require("@subsquid/util");
7
8
  const assert_1 = __importDefault(require("assert"));
8
9
  const model_tools_1 = require("./model.tools");
9
10
  const orderBy_1 = require("./orderBy");
10
11
  const scalars_1 = require("./scalars");
11
- const util_1 = require("./util");
12
+ const util_2 = require("./util");
12
13
  const where_1 = require("./where");
13
14
  class QueryBuilder {
14
- constructor(ctx) {
15
+ constructor(model, db) {
16
+ this.model = model;
17
+ this.db = db;
15
18
  this.params = [];
16
19
  this.aliases = new AliasSet();
17
- this.db = ctx.db;
18
- this.model = ctx.model;
19
20
  }
20
21
  param(value) {
21
22
  return '$' + this.params.push(value);
@@ -25,10 +26,10 @@ class QueryBuilder {
25
26
  }
26
27
  select(entityName, args, fields, variant) {
27
28
  let entity = (0, model_tools_1.getEntity)(this.model, entityName);
28
- let table = (0, util_1.toTable)(entityName);
29
+ let table = (0, util_2.toTable)(entityName);
29
30
  let alias = this.aliases.add(table);
30
- let join = new FkJoinSet(this.aliases);
31
- let cursor = new Cursor(this.model, this.ident.bind(this), this.aliases, join, entity, alias, '');
31
+ let join = new JoinSet(this.aliases);
32
+ let cursor = new Cursor(this.model, this.ident.bind(this), this.aliases, join, entityName, entity, alias, '');
32
33
  let whereExps = [];
33
34
  let orderByExps = [];
34
35
  let columns = new ColumnSet();
@@ -68,14 +69,16 @@ class QueryBuilder {
68
69
  if (variant?.kind == 'fts') {
69
70
  whereExps.push(`phraseto_tsquery('english', ${variant.textParam}) @@ ${cursor.tsv(variant.queryName)}`);
70
71
  }
71
- let orderByInput = args.orderBy && (0, util_1.ensureArray)(args.orderBy);
72
+ let orderByInput = args.orderBy && (0, util_2.ensureArray)(args.orderBy);
72
73
  if (orderByInput?.length) {
73
74
  let orderBy = (0, orderBy_1.parseOrderBy)(this.model, entityName, orderByInput);
74
75
  this.populateOrderBy(orderByExps, cursor, orderBy);
75
76
  }
76
- if (join.isNotEmpty()) {
77
- out += join.render(name => this.ident(name));
78
- }
77
+ join.forEach(j => {
78
+ let table = this.ident(j.table);
79
+ let alias = this.ident(j.alias);
80
+ out += `\nLEFT OUTER JOIN ${table} ${alias} ON ${alias}.${j.column} = ${j.rhs}`;
81
+ });
79
82
  if (whereExps.length) {
80
83
  out += '\nWHERE ' + whereExps.join(' AND ');
81
84
  }
@@ -106,11 +109,12 @@ class QueryBuilder {
106
109
  case 'object':
107
110
  case 'union':
108
111
  case 'fk':
112
+ case 'lookup':
109
113
  (0, assert_1.default)(typeof spec == 'object');
110
114
  this.populateOrderBy(exps, cursor.child(key), spec);
111
115
  break;
112
116
  default:
113
- throw (0, util_1.unsupportedCase)(propType.kind);
117
+ throw (0, util_2.unsupportedCase)(propType.kind);
114
118
  }
115
119
  }
116
120
  }
@@ -134,13 +138,14 @@ class QueryBuilder {
134
138
  req.index = columns.add(cu.transport('isTypeOf'));
135
139
  this.populateColumns(columns, cu, req.children);
136
140
  break;
137
- case 'fk': {
141
+ case 'fk':
142
+ case 'lookup': {
138
143
  let cu = cursor.child(fieldName);
139
144
  req.index = columns.add(cu.transport('id'));
140
145
  this.populateColumns(columns, cu, req.children);
141
146
  break;
142
147
  }
143
- case 'list-relation':
148
+ case 'list-lookup':
144
149
  req.index = columns.add('array(' + this.select(field.propType.entity, req.args, req.children, {
145
150
  kind: 'list-subquery',
146
151
  field: field.propType.field,
@@ -148,7 +153,7 @@ class QueryBuilder {
148
153
  }) + ')');
149
154
  break;
150
155
  default:
151
- throw (0, util_1.unsupportedCase)(field.propType.kind);
156
+ throw (0, util_2.unsupportedCase)(field.propType.kind);
152
157
  }
153
158
  }
154
159
  }
@@ -163,7 +168,7 @@ class QueryBuilder {
163
168
  case 'every':
164
169
  if ((0, where_1.hasConditions)(opArg)) {
165
170
  let rel = cursor.object.properties[f.field].type;
166
- (0, assert_1.default)(rel.kind == 'list-relation');
171
+ (0, assert_1.default)(rel.kind == 'list-lookup');
167
172
  let conditionedFrom = this.select(rel.entity, { where: opArg }, undefined, { kind: 'list-subquery', parent: cursor.native('id'), field: rel.field });
168
173
  let allFrom = this.select(rel.entity, {}, undefined, { kind: 'list-subquery', parent: cursor.native('id'), field: rel.field });
169
174
  exps.push(`(SELECT count(*) ${conditionedFrom}) = (SELECT count(*) ${allFrom})`);
@@ -172,7 +177,7 @@ class QueryBuilder {
172
177
  case 'some':
173
178
  case 'none':
174
179
  let rel = cursor.object.properties[f.field].type;
175
- (0, assert_1.default)(rel.kind == 'list-relation');
180
+ (0, assert_1.default)(rel.kind == 'list-lookup');
176
181
  let q = '(SELECT true ' + this.select(rel.entity, { where: opArg }, undefined, { kind: 'list-subquery', parent: cursor.native('id'), field: rel.field }) + ' LIMIT 1)';
177
182
  if (f.op == 'some') {
178
183
  exps.push(q);
@@ -190,7 +195,7 @@ class QueryBuilder {
190
195
  }
191
196
  if (AND) {
192
197
  // We are getting objects here, although we have array in schema
193
- (0, util_1.ensureArray)(AND).forEach((andWhere) => {
198
+ (0, util_2.ensureArray)(AND).forEach((andWhere) => {
194
199
  if ((0, where_1.hasConditions)(andWhere)) {
195
200
  exps.push(this.generateWhere(cursor, andWhere));
196
201
  }
@@ -202,7 +207,7 @@ class QueryBuilder {
202
207
  ors.push('(' + exps.join(' AND ') + ')');
203
208
  }
204
209
  // We are getting objects here, although we have array in schema
205
- (0, util_1.ensureArray)(OR).forEach((orWhere) => {
210
+ (0, util_2.ensureArray)(OR).forEach((orWhere) => {
206
211
  if ((0, where_1.hasConditions)(orWhere)) {
207
212
  ors.push('(' + this.generateWhere(cursor, orWhere) + ')');
208
213
  }
@@ -219,7 +224,6 @@ class QueryBuilder {
219
224
  case 'scalar':
220
225
  case 'enum': {
221
226
  let lhs = cursor.native(field);
222
- let typeName = propType.name;
223
227
  switch (op) {
224
228
  case 'in':
225
229
  case 'not_in': {
@@ -227,7 +231,7 @@ class QueryBuilder {
227
231
  // 1. use array parameter and do: WHERE col IN (SELECT * FROM unnest($array_param))
228
232
  // 2. use arg list
229
233
  // Let's try second option first.
230
- let list = (0, util_1.ensureArray)(arg).map(a => (0, scalars_1.fromTransportCast)(typeName, this.param(a)));
234
+ let list = (0, util_2.ensureArray)(arg).map(a => this.param(a));
231
235
  let param = `(${list.join(', ')})`;
232
236
  exps.push(`${lhs} ${(0, where_1.whereOpToSqlOperator)(op)} ${param}`);
233
237
  break;
@@ -255,8 +259,7 @@ class QueryBuilder {
255
259
  exps.push(`position(${this.param(arg)} in ${lhs}) = 0`);
256
260
  break;
257
261
  default: {
258
- let param = (0, scalars_1.fromTransportCast)(propType.name, this.param(arg));
259
- exps.push(`${lhs} ${(0, where_1.whereOpToSqlOperator)(op)} ${param}`);
262
+ exps.push(`${lhs} ${(0, where_1.whereOpToSqlOperator)(op)} ${this.param(arg)}`);
260
263
  }
261
264
  }
262
265
  break;
@@ -264,7 +267,7 @@ class QueryBuilder {
264
267
  case 'list': {
265
268
  let item = propType.item.type;
266
269
  (0, assert_1.default)(item.kind == 'scalar' || item.kind == 'enum');
267
- let param = (0, scalars_1.fromTransportArrayCast)(item.name, this.param(arg));
270
+ let param = this.param(arg);
268
271
  let lhs = cursor.native(field);
269
272
  switch (op) {
270
273
  case 'containsAll':
@@ -277,7 +280,7 @@ class QueryBuilder {
277
280
  exps.push(`NOT (${lhs} && ${param})`);
278
281
  break;
279
282
  default:
280
- throw (0, util_1.unsupportedCase)(op);
283
+ throw (0, util_2.unsupportedCase)(op);
281
284
  }
282
285
  break;
283
286
  }
@@ -291,7 +294,8 @@ class QueryBuilder {
291
294
  }
292
295
  break;
293
296
  }
294
- case 'fk': {
297
+ case 'fk':
298
+ case 'lookup': {
295
299
  (0, assert_1.default)(op == '-');
296
300
  if ((0, where_1.hasConditions)(arg)) {
297
301
  exps.push(this.generateWhere(cursor.child(field), arg));
@@ -299,7 +303,7 @@ class QueryBuilder {
299
303
  break;
300
304
  }
301
305
  default:
302
- throw (0, util_1.unsupportedCase)(propType.kind);
306
+ throw (0, util_2.unsupportedCase)(propType.kind);
303
307
  }
304
308
  }
305
309
  toResult(rows, fields) {
@@ -339,18 +343,19 @@ class QueryBuilder {
339
343
  }
340
344
  break;
341
345
  }
342
- case 'fk': {
346
+ case 'fk':
347
+ case 'lookup': {
343
348
  let id = row[req.index];
344
349
  if (id != null) {
345
350
  rec[req.alias] = this.mapRow(row, req.children);
346
351
  }
347
352
  break;
348
353
  }
349
- case 'list-relation':
354
+ case 'list-lookup':
350
355
  rec[req.alias] = this.toResult(row[req.index], req.children);
351
356
  break;
352
357
  default:
353
- throw (0, util_1.unsupportedCase)(f.propType.kind);
358
+ throw (0, util_2.unsupportedCase)(f.propType.kind);
354
359
  }
355
360
  }
356
361
  }
@@ -358,22 +363,21 @@ class QueryBuilder {
358
363
  }
359
364
  async executeSelect(entityName, args, fields$) {
360
365
  let sql = this.select(entityName, args, fields$);
361
- let result = await this.query(sql);
362
- return this.toResult(result.rows, fields$);
366
+ let rows = await this.query(sql);
367
+ return this.toResult(rows, fields$);
363
368
  }
364
369
  async executeSelectCount(entityName, where) {
365
370
  let sql = `SELECT count(*) ${this.select(entityName, { where })}`;
366
- let result = await this.query(sql);
367
- return (0, util_1.toInt)(result.rows[0][0]);
371
+ let rows = await this.query(sql);
372
+ return (0, util_2.toInt)(rows[0][0]);
368
373
  }
369
374
  async executeListCount(entityName, args) {
370
375
  let sql = `SELECT count(*) FROM (SELECT true ${this.select(entityName, args)}) AS ${this.aliases.add('list')}`;
371
- let result = await this.query(sql);
372
- return (0, util_1.toInt)(result.rows[0][0]);
376
+ let rows = await this.query(sql);
377
+ return (0, util_2.toInt)(rows[0][0]);
373
378
  }
374
379
  query(sql) {
375
- // console.log('\n' + sql)
376
- return this.db.query({ text: sql, rowMode: 'array' }, this.params);
380
+ return this.db.query(sql, this.params);
377
381
  }
378
382
  fulltextSearchSelect(queryName, args, $fields) {
379
383
  let query = (0, model_tools_1.getFtsQuery)(this.model, queryName);
@@ -433,17 +437,24 @@ class QueryBuilder {
433
437
  }
434
438
  async executeFulltextSearch(queryName, args, $fields) {
435
439
  let sql = this.fulltextSearchSelect(queryName, args, $fields);
436
- let result = await this.query(sql);
437
- return this.toFulltextSearchResult(result.rows, $fields);
440
+ let rows = await this.query(sql);
441
+ return this.toFulltextSearchResult(rows, $fields);
438
442
  }
439
443
  }
440
444
  exports.QueryBuilder = QueryBuilder;
445
+ /**
446
+ * A pointer to an entity or nested json object within SQL query.
447
+ *
448
+ * It has convenience methods for building various SQL expressions
449
+ * related to individual properties of an entity or an object it points to.
450
+ */
441
451
  class Cursor {
442
- constructor(model, ident, aliases, join, object, alias, prefix) {
452
+ constructor(model, ident, aliases, join, name, object, alias, prefix) {
443
453
  this.model = model;
444
454
  this.ident = ident;
445
455
  this.aliases = aliases;
446
456
  this.join = join;
457
+ this.name = name;
447
458
  this.object = object;
448
459
  this.alias = alias;
449
460
  this.prefix = prefix;
@@ -454,10 +465,10 @@ class Cursor {
454
465
  case 'scalar':
455
466
  case 'enum':
456
467
  if (this.object.kind == 'object') {
457
- return (0, scalars_1.fromJsonToTransportCast)(prop.type.name, this.prefix, propName);
468
+ return (0, scalars_1.fromJsonToOutputCast)(prop.type.name, this.prefix, propName);
458
469
  }
459
470
  else {
460
- return (0, scalars_1.toTransportCast)(prop.type.name, this.column(propName));
471
+ return (0, scalars_1.toOutputCast)(prop.type.name, this.column(propName));
461
472
  }
462
473
  case 'list':
463
474
  let itemType = prop.type.item.type;
@@ -466,10 +477,10 @@ class Cursor {
466
477
  return this.field(propName);
467
478
  }
468
479
  else {
469
- return (0, scalars_1.toTransportArrayCast)(itemType.name, this.column(propName));
480
+ return (0, scalars_1.toOutputArrayCast)(itemType.name, this.column(propName));
470
481
  }
471
482
  default:
472
- throw (0, util_1.unsupportedCase)(prop.type.kind);
483
+ throw (0, util_2.unsupportedCase)(prop.type.kind);
473
484
  }
474
485
  }
475
486
  native(propName) {
@@ -488,30 +499,40 @@ class Cursor {
488
499
  }
489
500
  }
490
501
  child(propName) {
502
+ let name;
491
503
  let object;
492
504
  let alias;
493
505
  let prefix;
494
506
  let prop = this.object.properties[propName];
495
507
  switch (prop.type.kind) {
496
508
  case 'object':
497
- object = this.model[prop.type.name];
509
+ name = prop.type.name;
510
+ object = (0, model_tools_1.getObject)(this.model, name);
498
511
  alias = this.alias;
499
512
  prefix = this.field(propName);
500
513
  break;
501
514
  case 'union':
502
- object = (0, model_tools_1.getUnionProps)(this.model, prop.type.name);
515
+ name = prop.type.name;
516
+ object = (0, model_tools_1.getUnionProps)(this.model, name);
503
517
  alias = this.alias;
504
518
  prefix = this.field(propName);
505
519
  break;
506
520
  case 'fk':
507
- object = this.model[prop.type.foreignEntity];
508
- alias = this.join.add((0, util_1.toTable)(prop.type.foreignEntity), this.fk(propName));
521
+ name = prop.type.foreignEntity;
522
+ object = (0, model_tools_1.getEntity)(this.model, name);
523
+ alias = this.join.add((0, util_2.toTable)(name), '"id"', this.fk(propName));
524
+ prefix = '';
525
+ break;
526
+ case 'lookup':
527
+ name = prop.type.entity;
528
+ object = (0, model_tools_1.getEntity)(this.model, name);
529
+ alias = this.join.add((0, util_2.toTable)(name), this.ident((0, util_2.toFkColumn)(prop.type.field)), this.field('id'));
509
530
  prefix = '';
510
531
  break;
511
532
  default:
512
- throw (0, util_1.unsupportedCase)(prop.type.kind);
533
+ throw (0, util_2.unsupportedCase)(prop.type.kind);
513
534
  }
514
- return new Cursor(this.model, this.ident, this.aliases, this.join, object, alias, prefix);
535
+ return new Cursor(this.model, this.ident, this.aliases, this.join, name, object, alias, prefix);
515
536
  }
516
537
  field(name) {
517
538
  if (this.object.kind == 'entity') {
@@ -523,20 +544,23 @@ class Cursor {
523
544
  }
524
545
  column(name) {
525
546
  (0, assert_1.default)(this.object.kind == 'entity');
526
- return this.ident(this.alias) + '.' + this.ident((0, util_1.toColumn)(name));
547
+ return this.ident(this.alias) + '.' + this.ident((0, util_2.toColumn)(name));
527
548
  }
528
549
  fk(propName) {
529
550
  return this.object.kind == 'entity'
530
- ? this.ident(this.alias) + '.' + this.ident((0, util_1.toFkColumn)(propName))
551
+ ? this.ident(this.alias) + '.' + this.ident((0, util_2.toFkColumn)(propName))
531
552
  : (0, scalars_1.fromJsonCast)('ID', this.prefix, propName);
532
553
  }
533
554
  tsv(queryName) {
534
555
  (0, assert_1.default)(this.object.kind == 'entity');
535
- return this.ident(this.alias) + '.' + this.ident((0, util_1.snakeCase)(queryName) + '_tsv');
556
+ return this.ident(this.alias) + '.' + this.ident((0, util_1.toSnakeCase)(queryName) + '_tsv');
536
557
  }
537
558
  doc(queryName) {
538
559
  (0, assert_1.default)(this.object.kind == 'entity');
539
- return this.ident(this.alias) + '.' + this.ident((0, util_1.snakeCase)(queryName) + '_doc');
560
+ let query = (0, model_tools_1.getFtsQuery)(this.model, queryName);
561
+ let src = query.sources.find(src => src.entity == this.name);
562
+ (0, assert_1.default)(src != null);
563
+ return src.fields.map(f => `coalesce(${this.field(f)}, '')`).join(` || E'\\n\\n' || `);
540
564
  }
541
565
  }
542
566
  class ColumnSet {
@@ -558,34 +582,27 @@ class ColumnSet {
558
582
  return this.columns.size;
559
583
  }
560
584
  }
561
- class FkJoinSet {
585
+ class JoinSet {
562
586
  constructor(aliases) {
563
587
  this.aliases = aliases;
564
588
  this.joins = new Map();
565
589
  }
566
- add(table, on) {
567
- let key = table + ' ' + on;
590
+ add(table, column, rhs) {
591
+ let key = `${table} ${column} ${rhs}`;
568
592
  let e = this.joins.get(key);
569
593
  if (!e) {
570
594
  e = {
571
595
  table,
572
596
  alias: this.aliases.add(table),
573
- on
597
+ column,
598
+ rhs
574
599
  };
575
600
  this.joins.set(key, e);
576
601
  }
577
602
  return e.alias;
578
603
  }
579
- isNotEmpty() {
580
- return this.joins.size > 0;
581
- }
582
- render(escapeIdentifier) {
583
- let e = escapeIdentifier;
584
- let out = '';
585
- this.joins.forEach(join => {
586
- out += `\nLEFT OUTER JOIN ${e(join.table)} ${e(join.alias)} ON ${e(join.alias)}."id" = ${join.on}`;
587
- });
588
- return out;
604
+ forEach(cb) {
605
+ this.joins.forEach(join => cb(join));
589
606
  }
590
607
  }
591
608
  class AliasSet {