@travetto/model-sql 8.0.0-alpha.23 → 8.0.0-alpha.25

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.
@@ -1,14 +1,21 @@
1
- /* eslint-disable @stylistic/indent */
2
- import { DataUtil, type SchemaFieldConfig, SchemaRegistryIndex, type Point } from '@travetto/schema';
3
- import { type Class, RuntimeError, TypedObject, TimeUtil, castTo, castKey, toConcrete, JSONUtil } from '@travetto/runtime';
4
- import { type SelectClause, type Query, type SortClause, type WhereClause, type RetainQueryPrimitiveFields, ModelQueryUtil, isModelQueryIndex } from '@travetto/model-query';
5
- import { IndexNotSupported, type BulkResponse, type IndexConfig, type ModelType } from '@travetto/model';
1
+ import { type BulkResponse, type IndexConfig, IndexNotSupported, type ModelType } from '@travetto/model';
6
2
  import { isModelIndexedIndex } from '@travetto/model-indexed';
3
+ import {
4
+ isModelQueryIndex,
5
+ ModelQueryUtil,
6
+ type Query,
7
+ type RetainQueryPrimitiveFields,
8
+ type SelectClause,
9
+ type SortClause,
10
+ type WhereClause
11
+ } from '@travetto/model-query';
12
+ import { type Class, castKey, castTo, JSONUtil, RuntimeError, TimeUtil, TypedObject, toConcrete } from '@travetto/runtime';
13
+ import { DataUtil, type Point, type SchemaFieldConfig, SchemaRegistryIndex } from '@travetto/schema';
7
14
 
8
- import { SQLModelUtil } from '../util.ts';
9
- import type { DeleteWrapper, InsertWrapper, DialectState } from '../internal/types.ts';
10
15
  import type { Connection } from '../connection/base.ts';
16
+ import type { DeleteWrapper, DialectState, InsertWrapper } from '../internal/types.ts';
11
17
  import type { VisitStack } from '../types.ts';
18
+ import { SQLModelUtil } from '../util.ts';
12
19
 
13
20
  const PointConcrete = toConcrete<Point>();
14
21
 
@@ -18,9 +25,9 @@ interface Alias {
18
25
  }
19
26
 
20
27
  export type SQLTableDescription = {
21
- columns: { name: string, type: string, is_not_null: boolean }[];
22
- foreignKeys: { name: string, from_column: string, to_column: string, to_table: string }[];
23
- indices: { name: string, columns: { name: string, desc: boolean }[], is_unique: boolean }[];
28
+ columns: { name: string; type: string; is_not_null: boolean }[];
29
+ foreignKeys: { name: string; from_column: string; to_column: string; to_table: string }[];
30
+ indices: { name: string; columns: { name: string; desc: boolean }[]; is_unique: boolean }[];
24
31
  };
25
32
 
26
33
  function makeField(name: string, type: Class, required: boolean, extra: Partial<SchemaFieldConfig>): SchemaFieldConfig {
@@ -163,7 +170,7 @@ export abstract class SQLDialect implements DialectState {
163
170
  */
164
171
  abstract describeTable(table: string): Promise<SQLTableDescription | undefined>;
165
172
 
166
- executeSQL<T>(sql: string): Promise<{ records: T[], count: number }> {
173
+ executeSQL<T>(sql: string): Promise<{ records: T[]; count: number }> {
167
174
  return this.connection.execute<T>(this.connection.active, sql);
168
175
  }
169
176
 
@@ -174,7 +181,7 @@ export abstract class SQLDialect implements DialectState {
174
181
  if (field === '*') {
175
182
  return field;
176
183
  } else {
177
- const name = (typeof field === 'string') ? field : field.name;
184
+ const name = typeof field === 'string' ? field : field.name;
178
185
  return `${this.ID_AFFIX}${name}${this.ID_AFFIX}`;
179
186
  }
180
187
  }
@@ -300,9 +307,7 @@ export abstract class SQLDialect implements DialectState {
300
307
  */
301
308
  async getCountForQuery<T extends ModelType>(cls: Class<T>, query: Query<T>): Promise<number> {
302
309
  const { records } = await this.executeSQL<{ total: number }>(
303
- this.getQueryCountSQL(cls,
304
- ModelQueryUtil.getWhereClause(cls, query.where)
305
- )
310
+ this.getQueryCountSQL(cls, ModelQueryUtil.getWhereClause(cls, query.where))
306
311
  );
307
312
  return DataUtil.coerceType(records[0].total, Number);
308
313
  }
@@ -451,14 +456,18 @@ export abstract class SQLDialect implements DialectState {
451
456
  const resolve = this.resolveValue.bind(this, field);
452
457
 
453
458
  switch (subKey) {
454
- case '$nin': case '$in': {
459
+ case '$nin':
460
+ case '$in': {
455
461
  const arr = (Array.isArray(value) ? value : [value]).map(resolve);
456
462
  items.push(`${sPath} ${SQL_OPS[subKey]} (${arr.join(',')})`);
457
463
  break;
458
464
  }
459
465
  case '$all': {
460
466
  const set = new Set();
461
- const arr = [value].flat().filter(item => !set.has(item) && !!set.add(item)).map(resolve);
467
+ const arr = [value]
468
+ .flat()
469
+ .filter(item => !set.has(item) && !!set.add(item))
470
+ .map(resolve);
462
471
  const valueTable = this.parentTable(sStack);
463
472
  const alias = `_all_${sStack.length}`;
464
473
  const pPath = this.identifier(this.parentPathField.name);
@@ -475,7 +484,7 @@ export abstract class SQLDialect implements DialectState {
475
484
  case '$regex': {
476
485
  const regex = DataUtil.toRegex(castTo(value));
477
486
  const regexSource = regex.source;
478
- const ins = regex.flags && regex.flags.includes('i');
487
+ const ins = regex.flags?.includes('i');
479
488
 
480
489
  if (/^[\^]\S+[.][*][$]?$/.test(regexSource)) {
481
490
  const inner = regexSource.substring(1, regexSource.length - 2);
@@ -512,7 +521,8 @@ export abstract class SQLDialect implements DialectState {
512
521
  }
513
522
  break;
514
523
  }
515
- case '$ne': case '$eq': {
524
+ case '$ne':
525
+ case '$eq': {
516
526
  if (value === null || value === undefined) {
517
527
  items.push(`${sPath} ${subKey === '$ne' ? SQL_OPS.$isNot : SQL_OPS.$is} NULL`);
518
528
  } else {
@@ -521,9 +531,13 @@ export abstract class SQLDialect implements DialectState {
521
531
  }
522
532
  break;
523
533
  }
524
- case '$lt': case '$gt': case '$gte': case '$lte': {
525
- const subItems = TypedObject.keys(castTo<typeof SQL_OPS>(top))
526
- .map(subSubKey => `${sPath} ${SQL_OPS[subSubKey]} ${resolve(top[subSubKey])}`);
534
+ case '$lt':
535
+ case '$gt':
536
+ case '$gte':
537
+ case '$lte': {
538
+ const subItems = TypedObject.keys(castTo<typeof SQL_OPS>(top)).map(
539
+ subSubKey => `${sPath} ${SQL_OPS[subSubKey]} ${resolve(top[subSubKey])}`
540
+ );
527
541
  items.push(subItems.length > 1 ? `(${subItems.join(` ${SQL_OPS.$and} `)})` : subItems[0]);
528
542
  break;
529
543
  }
@@ -569,20 +583,18 @@ export abstract class SQLDialect implements DialectState {
569
583
  * Generate WHERE clause
570
584
  */
571
585
  getWhereSQL<T>(cls: Class<T>, where?: WhereClause<T>): string {
572
- return !where || !Object.keys(where).length ?
573
- '' :
574
- `WHERE ${this.getWhereGroupingSQL(cls, castTo(where))}`;
586
+ return !where || !Object.keys(where).length ? '' : `WHERE ${this.getWhereGroupingSQL(cls, castTo(where))}`;
575
587
  }
576
588
 
577
589
  /**
578
590
  * Generate ORDER BY clause
579
591
  */
580
592
  getOrderBySQL<T>(cls: Class<T>, sortBy?: SortClause<T>[]): string {
581
- return !sortBy ?
582
- '' :
583
- `ORDER BY ${SQLModelUtil.orderBy(cls, sortBy).map((item) =>
584
- `${this.resolveName(item.stack)} ${item.asc ? 'ASC' : 'DESC'}`
585
- ).join(', ')}`;
593
+ return !sortBy
594
+ ? ''
595
+ : `ORDER BY ${SQLModelUtil.orderBy(cls, sortBy)
596
+ .map(item => `${this.resolveName(item.stack)} ${item.asc ? 'ASC' : 'DESC'}`)
597
+ .join(', ')}`;
586
598
  }
587
599
 
588
600
  /**
@@ -590,13 +602,11 @@ export abstract class SQLDialect implements DialectState {
590
602
  */
591
603
  getSelectSQL<T>(cls: Class<T>, select?: SelectClause<T>): string {
592
604
  const stack = SQLModelUtil.classToStack(cls);
593
- const columns = select && SQLModelUtil.select(cls, select).map((sel) => this.resolveName([...stack, sel]));
605
+ const columns = select && SQLModelUtil.select(cls, select).map(sel => this.resolveName([...stack, sel]));
594
606
  if (columns) {
595
607
  columns.unshift(this.alias(this.pathField));
596
608
  }
597
- return !columns ?
598
- `SELECT ${this.rootAlias}.* ` :
599
- `SELECT ${columns.join(', ')}`;
609
+ return !columns ? `SELECT ${this.rootAlias}.* ` : `SELECT ${columns.join(', ')}`;
600
610
  }
601
611
 
602
612
  /**
@@ -606,39 +616,39 @@ export abstract class SQLDialect implements DialectState {
606
616
  const stack = SQLModelUtil.classToStack(cls);
607
617
  const aliases = this.getAliasCache(stack, this.namespace);
608
618
  const tables = [...aliases.keys()].toSorted((a, b) => a.length - b.length); // Shortest first
609
- return `FROM ${tables.map((table) => {
610
- const { alias, path } = aliases.get(table)!;
611
- let from = `${this.identifier(table)} ${alias}`;
612
- if (path.length > 1) {
613
- const key = this.namespaceParent(path);
614
- const { alias: parentAlias } = aliases.get(key)!;
615
- from = `
619
+ return `FROM ${tables
620
+ .map(table => {
621
+ const { alias, path } = aliases.get(table)!;
622
+ let from = `${this.identifier(table)} ${alias}`;
623
+ if (path.length > 1) {
624
+ const key = this.namespaceParent(path);
625
+ const { alias: parentAlias } = aliases.get(key)!;
626
+ from = `
616
627
  LEFT OUTER JOIN ${from} ON
617
628
  ${this.alias(this.parentPathField, alias)} = ${this.alias(this.pathField, parentAlias)}
618
629
  `;
619
- }
620
- return from;
621
- }).join('\n')}`;
630
+ }
631
+ return from;
632
+ })
633
+ .join('\n')}`;
622
634
  }
623
635
 
624
636
  /**
625
637
  * Generate LIMIT clause
626
638
  */
627
639
  getLimitSQL<T>(cls: Class<T>, query?: Query<T>): string {
628
- return !query || (!query.limit && !query.offset) ?
629
- '' :
630
- `LIMIT ${query.limit ?? 200} OFFSET ${query.offset ?? 0}`;
640
+ return !query || (!query.limit && !query.offset) ? '' : `LIMIT ${query.limit ?? 200} OFFSET ${query.offset ?? 0}`;
631
641
  }
632
642
 
633
643
  /**
634
644
  * Generate GROUP BY clause
635
645
  */
636
646
  getGroupBySQL<T>(cls: Class<T>, query: Query<T>): string {
637
- const sortFields = !query.sort ?
638
- '' :
639
- SQLModelUtil.orderBy(cls, query.sort)
640
- .map(item => this.resolveName(item.stack))
641
- .join(', ');
647
+ const sortFields = !query.sort
648
+ ? ''
649
+ : SQLModelUtil.orderBy(cls, query.sort)
650
+ .map(item => this.resolveName(item.stack))
651
+ .join(', ');
642
652
 
643
653
  return `GROUP BY ${this.alias(this.idField)}${sortFields ? `, ${sortFields}` : ''}`;
644
654
  }
@@ -660,9 +670,11 @@ ${this.getLimitSQL(cls, query)}`;
660
670
  const config = stack.at(-1)!;
661
671
  const parent = stack.length > 1;
662
672
  const array = parent && config.array;
663
- const fields = SchemaRegistryIndex.has(config.type) ?
664
- [...SQLModelUtil.getFieldsByLocation(stack).local] :
665
- (array ? [castTo<SchemaFieldConfig>(config)] : []);
673
+ const fields = SchemaRegistryIndex.has(config.type)
674
+ ? [...SQLModelUtil.getFieldsByLocation(stack).local]
675
+ : array
676
+ ? [castTo<SchemaFieldConfig>(config)]
677
+ : [];
666
678
 
667
679
  if (!parent) {
668
680
  const idField = fields.find(field => field.name === this.idField.name);
@@ -680,12 +692,14 @@ ${this.getLimitSQL(cls, query)}`;
680
692
  CREATE TABLE IF NOT EXISTS ${this.table(stack)} (
681
693
  ${fieldSql}${fieldSql.length ? ',' : ''}
682
694
  ${this.getColumnDefinition(this.pathField)} UNIQUE,
683
- ${!parent ?
684
- `PRIMARY KEY (${this.identifier(this.idField)})` :
685
- `${this.getColumnDefinition(this.parentPathField)},
695
+ ${
696
+ !parent
697
+ ? `PRIMARY KEY (${this.identifier(this.idField)})`
698
+ : `${this.getColumnDefinition(this.parentPathField)},
686
699
  ${array ? `${this.getColumnDefinition(this.idxField)},` : ''}
687
700
  PRIMARY KEY (${this.identifier(this.pathField)}),
688
- FOREIGN KEY (${this.identifier(this.parentPathField)}) REFERENCES ${this.parentTable(stack)}(${this.identifier(this.pathField)}) ON DELETE CASCADE`}
701
+ FOREIGN KEY (${this.identifier(this.parentPathField)}) REFERENCES ${this.parentTable(stack)}(${this.identifier(this.pathField)}) ON DELETE CASCADE`
702
+ }
689
703
  );`;
690
704
  return out;
691
705
  }
@@ -710,8 +724,14 @@ CREATE TABLE IF NOT EXISTS ${this.table(stack)} (
710
724
  getCreateAllTablesSQL(cls: Class): string[] {
711
725
  const out: string[] = [];
712
726
  SQLModelUtil.visitSchemaSync(SchemaRegistryIndex.getConfig(cls), {
713
- onRoot: ({ path, descend }) => { out.push(this.getCreateTableSQL(path)); descend(); },
714
- onSub: ({ path, descend }) => { out.push(this.getCreateTableSQL(path)); descend(); },
727
+ onRoot: ({ path, descend }) => {
728
+ out.push(this.getCreateTableSQL(path));
729
+ descend();
730
+ },
731
+ onSub: ({ path, descend }) => {
732
+ out.push(this.getCreateTableSQL(path));
733
+ descend();
734
+ },
715
735
  onSimple: ({ path }) => out.push(this.getCreateTableSQL(path))
716
736
  });
717
737
  return out;
@@ -746,7 +766,7 @@ CREATE TABLE IF NOT EXISTS ${this.table(stack)} (
746
766
  if (DataUtil.isPlainObject(value)) {
747
767
  throw new IndexNotSupported(cls, idx, 'Only indexed and query indices are supported in SQL');
748
768
  }
749
- return [castTo(key), typeof value === 'number' ? value === 1 : (!!value)];
769
+ return [castTo(key), typeof value === 'number' ? value === 1 : !!value];
750
770
  });
751
771
  return `CREATE ${idx.unique ? 'UNIQUE ' : ''}INDEX ${constraint} ON ${this.identifier(table)} (${fields
752
772
  .map(([name, sel]) => `${this.identifier(name)} ${sel ? 'ASC' : 'DESC'}`)
@@ -757,12 +777,12 @@ CREATE TABLE IF NOT EXISTS ${this.table(stack)} (
757
777
  console.debug('Nested fields are not supported in ModelIndexed indices SQL', { index: idx.name });
758
778
  return;
759
779
  }
760
- const fields = all
761
- .map(({ path, value }) => `${this.identifier(path.join('_'))} ${value === -1 ? 'DESC' : 'ASC'}`)
762
- .join(', ');
780
+ const fields = all.map(({ path, value }) => `${this.identifier(path.join('_'))} ${value === -1 ? 'DESC' : 'ASC'}`).join(', ');
763
781
  switch (idx.type) {
764
- case 'indexed:keyed': return `CREATE ${idx.unique ? 'UNIQUE ' : ''}INDEX ${constraint} ON ${this.identifier(table)} (${fields});`;
765
- case 'indexed:sorted': return `CREATE INDEX ${constraint} ON ${this.identifier(table)} (${fields});`;
782
+ case 'indexed:keyed':
783
+ return `CREATE ${idx.unique ? 'UNIQUE ' : ''}INDEX ${constraint} ON ${this.identifier(table)} (${fields});`;
784
+ case 'indexed:sorted':
785
+ return `CREATE INDEX ${constraint} ON ${this.identifier(table)} (${fields});`;
766
786
  }
767
787
  } else {
768
788
  throw new IndexNotSupported(cls, idx, 'Only indexed and query indices are supported in SQL');
@@ -783,8 +803,14 @@ CREATE TABLE IF NOT EXISTS ${this.table(stack)} (
783
803
  getDropAllTablesSQL<T extends ModelType>(cls: Class<T>): string[] {
784
804
  const out: string[] = [];
785
805
  SQLModelUtil.visitSchemaSync(SchemaRegistryIndex.getConfig(cls), {
786
- onRoot: ({ path, descend }) => { descend(); out.push(this.getDropTableSQL(path)); },
787
- onSub: ({ path, descend }) => { descend(); out.push(this.getDropTableSQL(path)); },
806
+ onRoot: ({ path, descend }) => {
807
+ descend();
808
+ out.push(this.getDropTableSQL(path));
809
+ },
810
+ onSub: ({ path, descend }) => {
811
+ descend();
812
+ out.push(this.getDropTableSQL(path));
813
+ },
788
814
  onSimple: ({ path }) => out.push(this.getDropTableSQL(path))
789
815
  });
790
816
  return out;
@@ -796,8 +822,14 @@ CREATE TABLE IF NOT EXISTS ${this.table(stack)} (
796
822
  getTruncateAllTablesSQL<T extends ModelType>(cls: Class<T>): string[] {
797
823
  const out: string[] = [];
798
824
  SQLModelUtil.visitSchemaSync(SchemaRegistryIndex.getConfig(cls), {
799
- onRoot: ({ path, descend }) => { descend(); out.push(this.getTruncateTableSQL(path)); },
800
- onSub: ({ path, descend }) => { descend(); out.push(this.getTruncateTableSQL(path)); },
825
+ onRoot: ({ path, descend }) => {
826
+ descend();
827
+ out.push(this.getTruncateTableSQL(path));
828
+ },
829
+ onSub: ({ path, descend }) => {
830
+ descend();
831
+ out.push(this.getTruncateTableSQL(path));
832
+ },
801
833
  onSimple: ({ path }) => out.push(this.getTruncateTableSQL(path))
802
834
  });
803
835
  return out;
@@ -808,8 +840,8 @@ CREATE TABLE IF NOT EXISTS ${this.table(stack)} (
808
840
  */
809
841
  getInsertSQL(stack: VisitStack[], instances: InsertWrapper['records']): string | undefined {
810
842
  const config = stack.at(-1)!;
811
- const columns = SQLModelUtil.getFieldsByLocation(stack).local
812
- .filter(field => !SchemaRegistryIndex.has(field.type))
843
+ const columns = SQLModelUtil.getFieldsByLocation(stack)
844
+ .local.filter(field => !SchemaRegistryIndex.has(field.type))
813
845
  .toSorted((a, b) => a.name.localeCompare(b.name));
814
846
  const columnNames = columns.map(column => column.name);
815
847
 
@@ -820,7 +852,7 @@ CREATE TABLE IF NOT EXISTS ${this.table(stack)} (
820
852
  const newInstances: typeof instances = [];
821
853
  for (const instance of instances) {
822
854
  if (instance.value === null || instance.value === undefined) {
823
- continue;
855
+ // Continue
824
856
  } else if (Array.isArray(instance.value)) {
825
857
  const name = instance.stack.at(-1)!.name;
826
858
  for (const sel of instance.value) {
@@ -842,8 +874,9 @@ CREATE TABLE IF NOT EXISTS ${this.table(stack)} (
842
874
  return;
843
875
  }
844
876
 
845
- const matrix = instances.map(inst => columns.map(column =>
846
- this.resolveValue(column, castTo<Record<string, unknown>>(inst.value)[column.name])));
877
+ const matrix = instances.map(inst =>
878
+ columns.map(column => this.resolveValue(column, castTo<Record<string, unknown>>(inst.value)[column.name]))
879
+ );
847
880
 
848
881
  columnNames.push(this.pathField.name);
849
882
  if (hasParent) {
@@ -879,7 +912,9 @@ ${matrix.map(row => `(${row.join(', ')})`).join(',\n')};`;
879
912
  */
880
913
  getAllInsertSQL<T extends ModelType>(cls: Class<T>, instance: T): string[] {
881
914
  const out: string[] = [];
882
- const add = (text?: string): void => { text && out.push(text); };
915
+ const add = (text?: string): void => {
916
+ text && out.push(text);
917
+ };
883
918
  SQLModelUtil.visitSchemaInstance(cls, instance, {
884
919
  onRoot: ({ value, path }) => add(this.getInsertSQL(path, [{ stack: path, value }])),
885
920
  onSub: ({ value, path }) => add(this.getInsertSQL(path, [{ stack: path, value }])),
@@ -897,10 +932,10 @@ ${matrix.map(row => `(${row.join(', ')})`).join(',\n')};`;
897
932
  return `
898
933
  UPDATE ${this.table(stack)} ${this.rootAlias}
899
934
  SET
900
- ${Object
901
- .entries(data)
902
- .filter(([key]) => key in localMap)
903
- .map(([key, value]) => `${this.identifier(key)}=${this.resolveValue(localMap[key], value)}`).join(', ')}
935
+ ${Object.entries(data)
936
+ .filter(([key]) => key in localMap)
937
+ .map(([key, value]) => `${this.identifier(key)}=${this.resolveValue(localMap[key], value)}`)
938
+ .join(', ')}
904
939
  ${this.getWhereSQL(type, where)};`;
905
940
  }
906
941
 
@@ -917,11 +952,9 @@ ${this.getWhereSQL(type, where)};`;
917
952
  */
918
953
  getSelectRowsByIdsSQL(stack: VisitStack[], ids: string[], select: SchemaFieldConfig[] = []): string {
919
954
  const config = stack.at(-1)!;
920
- const orderBy = !config.array ?
921
- '' :
922
- `ORDER BY ${this.rootAlias}.${this.idxField.name} ASC`;
955
+ const orderBy = !config.array ? '' : `ORDER BY ${this.rootAlias}.${this.idxField.name} ASC`;
923
956
 
924
- const idField = (stack.length > 1 ? this.parentPathField : this.idField);
957
+ const idField = stack.length > 1 ? this.parentPathField : this.idField;
925
958
 
926
959
  return `
927
960
  SELECT ${select.length ? select.map(field => this.alias(field)).join(',') : '*'}
@@ -948,7 +981,7 @@ ${this.getWhereSQL(cls, where!)}`;
948
981
  SQLModelUtil.collectDependents(this, stack.at(-1)!, children, field);
949
982
 
950
983
  await SQLModelUtil.visitSchema(SchemaRegistryIndex.getConfig(cls), {
951
- onRoot: async (config) => {
984
+ onRoot: async config => {
952
985
  const fieldSet = buildSet(items); // Already filtered by initial select query
953
986
  selectStack.push(select);
954
987
  stack.push(fieldSet);
@@ -962,8 +995,8 @@ ${this.getWhereSQL(cls, where!)}`;
962
995
  const subSelectTop: SelectClause<T> | undefined = castTo(selectTop?.[fieldKey]);
963
996
 
964
997
  // See if a selection exists at all
965
- const selected: SchemaFieldConfig[] = subSelectTop ? fields
966
- .filter(field => typeof subSelectTop === 'object' && subSelectTop[castTo<typeof fieldKey>(field.name)] === 1)
998
+ const selected: SchemaFieldConfig[] = subSelectTop
999
+ ? fields.filter(field => typeof subSelectTop === 'object' && subSelectTop[castTo<typeof fieldKey>(field.name)] === 1)
967
1000
  : [];
968
1001
 
969
1002
  if (selected.length) {
@@ -975,11 +1008,7 @@ ${this.getWhereSQL(cls, where!)}`;
975
1008
 
976
1009
  // If children and selection exists
977
1010
  if (ids.length && (!subSelectTop || selected)) {
978
- const { records: children } = await this.executeSQL<unknown[]>(this.getSelectRowsByIdsSQL(
979
- path,
980
- ids,
981
- selected
982
- ));
1011
+ const { records: children } = await this.executeSQL<unknown[]>(this.getSelectRowsByIdsSQL(path, ids, selected));
983
1012
 
984
1013
  const fieldSet = buildSet(children, config);
985
1014
  try {
@@ -996,10 +1025,7 @@ ${this.getWhereSQL(cls, where!)}`;
996
1025
  const top = stack.at(-1)!;
997
1026
  const ids = Object.keys(top);
998
1027
  if (ids.length) {
999
- const { records: matching } = await this.executeSQL(this.getSelectRowsByIdsSQL(
1000
- path,
1001
- ids
1002
- ));
1028
+ const { records: matching } = await this.executeSQL(this.getSelectRowsByIdsSQL(path, ids));
1003
1029
  buildSet(matching, config);
1004
1030
  }
1005
1031
  }
@@ -1024,7 +1050,12 @@ ${this.getWhereSQL(cls, where!)}`;
1024
1050
  /**
1025
1051
  * Do bulk process
1026
1052
  */
1027
- async bulkProcess(deletes: DeleteWrapper[], inserts: InsertWrapper[], upserts: InsertWrapper[], updates: InsertWrapper[]): Promise<BulkResponse> {
1053
+ async bulkProcess(
1054
+ deletes: DeleteWrapper[],
1055
+ inserts: InsertWrapper[],
1056
+ upserts: InsertWrapper[],
1057
+ updates: InsertWrapper[]
1058
+ ): Promise<BulkResponse> {
1028
1059
  const out = {
1029
1060
  counts: {
1030
1061
  delete: deletes.reduce((count, item) => count + item.ids.length, 0),
@@ -1048,13 +1079,19 @@ ${this.getWhereSQL(cls, where!)}`;
1048
1079
  ...upserts
1049
1080
  .filter(item => item.stack.length === 1)
1050
1081
  .map(item =>
1051
- this.deleteByIds(item.stack, item.records.map(value => castTo<Record<string, string>>(value.value)[idx]))
1082
+ this.deleteByIds(
1083
+ item.stack,
1084
+ item.records.map(value => castTo<Record<string, string>>(value.value)[idx])
1085
+ )
1052
1086
  ),
1053
1087
  ...updates
1054
1088
  .filter(item => item.stack.length === 1)
1055
1089
  .map(item =>
1056
- this.deleteByIds(item.stack, item.records.map(value => castTo<Record<string, string>>(value.value)[idx]))
1057
- ),
1090
+ this.deleteByIds(
1091
+ item.stack,
1092
+ item.records.map(value => castTo<Record<string, string>>(value.value)[idx])
1093
+ )
1094
+ )
1058
1095
  ]);
1059
1096
  }
1060
1097
 
@@ -1064,15 +1101,18 @@ ${this.getWhereSQL(cls, where!)}`;
1064
1101
  continue;
1065
1102
  }
1066
1103
  let level = 1; // Add by level
1067
- for (; ;) { // Loop until done
1104
+ for (;;) {
1105
+ // Loop until done
1068
1106
  const leveled = items.filter(insertWrapper => insertWrapper.stack.length === level);
1069
1107
  if (!leveled.length) {
1070
1108
  break;
1071
1109
  }
1072
- await Promise.all(leveled
1073
- .map(inserted => this.getInsertSQL(inserted.stack, inserted.records))
1074
- .filter(sql => !!sql)
1075
- .map(sql => this.executeSQL(sql!)));
1110
+ await Promise.all(
1111
+ leveled
1112
+ .map(inserted => this.getInsertSQL(inserted.stack, inserted.records))
1113
+ .filter(sql => !!sql)
1114
+ .map(sql => this.executeSQL(sql!))
1115
+ );
1076
1116
  level += 1;
1077
1117
  }
1078
1118
  }
@@ -1083,11 +1123,11 @@ ${this.getWhereSQL(cls, where!)}`;
1083
1123
  /**
1084
1124
  * Determine if a column has changed
1085
1125
  */
1086
- isColumnChanged(requested: SchemaFieldConfig, existing: SQLTableDescription['columns'][number],): boolean {
1126
+ isColumnChanged(requested: SchemaFieldConfig, existing: SQLTableDescription['columns'][number]): boolean {
1087
1127
  const requestedColumnType = this.getColumnType(requested);
1088
1128
  const result =
1089
- (requested.name !== this.idField.name && !!requested.required?.active !== !!existing.is_not_null)
1090
- || (requestedColumnType.toUpperCase() !== existing.type.toUpperCase());
1129
+ (requested.name !== this.idField.name && !!requested.required?.active !== !!existing.is_not_null) ||
1130
+ requestedColumnType.toUpperCase() !== existing.type.toUpperCase();
1091
1131
 
1092
1132
  return result;
1093
1133
  }
@@ -1097,7 +1137,7 @@ ${this.getWhereSQL(cls, where!)}`;
1097
1137
  */
1098
1138
  isIndexChanged(requested: IndexConfig, existing: SQLTableDescription['indices'][number]): boolean {
1099
1139
  if (isModelQueryIndex(requested)) {
1100
- const uniqueChanged = (existing.is_unique && !requested.unique);
1140
+ const uniqueChanged = existing.is_unique && !requested.unique;
1101
1141
  const columnSizeChanged = requested.fields.length !== existing.columns.length;
1102
1142
  let result = uniqueChanged || columnSizeChanged;
1103
1143
  for (let i = 0; i < requested.fields.length && !result; i++) {
@@ -1112,7 +1152,7 @@ ${this.getWhereSQL(cls, where!)}`;
1112
1152
  const sort = Object.entries(requested.sort);
1113
1153
  const all = [...keys, ...sort];
1114
1154
 
1115
- const uniqueChanged = (requested.type === 'indexed:keyed' && existing.is_unique && !requested.unique);
1155
+ const uniqueChanged = requested.type === 'indexed:keyed' && existing.is_unique && !requested.unique;
1116
1156
  const columnSizeChanged = all.length !== existing.columns.length;
1117
1157
  let result = uniqueChanged || columnSizeChanged;
1118
1158
 
@@ -1139,4 +1179,4 @@ ${this.getWhereSQL(cls, where!)}`;
1139
1179
  idField.minlength = { limit: this.ID_LENGTH };
1140
1180
  }
1141
1181
  }
1142
- }
1182
+ }
@@ -1,4 +1,4 @@
1
- import type { SchemaFieldConfig, SchemaClassConfig } from '@travetto/schema';
1
+ import type { SchemaClassConfig, SchemaFieldConfig } from '@travetto/schema';
2
2
 
3
3
  import type { VisitStack } from '../types.ts';
4
4
 
@@ -7,7 +7,7 @@ import type { VisitStack } from '../types.ts';
7
7
  */
8
8
  export interface InsertWrapper {
9
9
  stack: VisitStack[];
10
- records: { stack: VisitStack[], value: unknown }[];
10
+ records: { stack: VisitStack[]; value: unknown }[];
11
11
  }
12
12
 
13
13
  /**