imodel 0.16.2 → 0.17.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.
package/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * imodel v0.16.2
2
+ * imodel v0.17.1
3
3
  * (c) 2019-2026 undefined
4
4
  * @license undefined
5
5
  */
@@ -13,6 +13,15 @@ function setDevelopment(d) {
13
13
  isDevelopment = Boolean(d);
14
14
  }
15
15
 
16
+ /** @import { SelectItem } from './types' */
17
+ class Subquery {
18
+ /** @returns {SelectItem[]} */
19
+ toSubquery() {
20
+ throw new Error('toSubquery 方法未在子类中实现');
21
+ }
22
+ }
23
+
24
+ /** @import { SelectItem } from './types' */
16
25
  /** @typedef {{toWhereValue(): WhereValue[][]}} WhereLike */
17
26
  /** @typedef {WhereLike | Record<string, any> | (WhereLike | Record<string, any>)[]} Wheres */
18
27
  /**
@@ -21,6 +30,7 @@ function setDevelopment(d) {
21
30
  * @prop {null} [or]
22
31
  * @prop {string | {table?: string; field: string} | (string | {table?: string; field: string})[]} field
23
32
  * @prop {any} value
33
+ * @prop {SelectItem[]?} [subquery]
24
34
  * @prop {boolean} [not]
25
35
  * @prop {string?} [operator]
26
36
  */
@@ -111,12 +121,14 @@ function parse(items) {
111
121
  return null;
112
122
  }
113
123
  const [field, operator, value, not] = items;
124
+ const subquery = value instanceof Subquery ? value.toSubquery() : null;
114
125
  // @ts-ignore
115
126
  return [{
116
127
  field,
117
128
  operator,
118
129
  value,
119
- not: Boolean(not)
130
+ not: Boolean(not),
131
+ subquery
120
132
  }];
121
133
  }
122
134
  /**
@@ -658,9 +670,9 @@ function isPseudo(model) {
658
670
  }
659
671
 
660
672
  const now = Symbol();
661
- /** @type {typeof now} now */
673
+ /** @typeof {typeof now} now */
662
674
  const uuid = Symbol();
663
- /** @type {typeof uuid} uuid */
675
+ /** @typeof {typeof uuid} uuid */
664
676
  const increment$1 = Symbol();
665
677
  const decrement$1 = Symbol();
666
678
  const multiply$1 = Symbol();
@@ -929,7 +941,7 @@ function toFieldList(list, fieldColumns) {
929
941
  return list.map(it => Object.fromEntries(map.map(([k, v]) => [k, it[v]])));
930
942
  }
931
943
 
932
- /** @import { Environment, FieldDefine, Fields, IConnection, Skip, TableDefine } from '../types' */
944
+ /** @import { Environment, FieldDefine, Fields, Skip, TableConnection, TableDefine } from '../types' */
933
945
  /**
934
946
  *
935
947
  * @param {any} p
@@ -960,7 +972,7 @@ function defaultMap(value, others) {
960
972
  }
961
973
  /**
962
974
  *
963
- * @param {IConnection} conn
975
+ * @param {TableConnection} conn
964
976
  * @param {Environment} env
965
977
  * @param {[string, FieldDefine<TableDefine>][]} fields
966
978
  * @param {Record<string, any>[]} newList
@@ -1062,7 +1074,7 @@ async function createSub(conn, env, fields, newList, list, skip) {
1062
1074
  // TODO: 嵌套
1063
1075
  /**
1064
1076
  *
1065
- * @param {IConnection} conn
1077
+ * @param {TableConnection} conn
1066
1078
  * @param {Environment} env
1067
1079
  * @param {TableDefine} model
1068
1080
  * @param {any} p
@@ -1320,10 +1332,10 @@ function* getFixedValueWhere(columns, ignore) {
1320
1332
  }
1321
1333
  }
1322
1334
 
1323
- /** @import { Environment, FieldDefine, IConnection, Queryable, TableDefine } from '../types' */
1335
+ /** @import { Environment, FieldDefine, Queryable, TableConnection, TableDefine } from '../types' */
1324
1336
  /**
1325
1337
  *
1326
- * @param {IConnection} conn
1338
+ * @param {TableConnection} conn
1327
1339
  * @param {any[]} list
1328
1340
  * @param {[string, FieldDefine<TableDefine>][]} fields
1329
1341
  * @param {Set<string>} baseFieldSet
@@ -1381,7 +1393,7 @@ async function deleteSub(conn, list, fields, baseFieldSet, env, hasResult) {
1381
1393
  }
1382
1394
  // TODO: 嵌套
1383
1395
  /**
1384
- * @param {IConnection} conn
1396
+ * @param {TableConnection} conn
1385
1397
  * @param {Queryable} queryable
1386
1398
  * @param {Environment} env
1387
1399
  * @returns {Promise<number>}
@@ -1486,7 +1498,7 @@ async function getSetValue$1(columns, fieldColumns, update, skip) {
1486
1498
 
1487
1499
  /* eslint-disable max-lines */
1488
1500
  /* eslint-disable no-labels */
1489
- /** @import { Constraint, Environment, FieldDefine, IConnection, Skip, TableDefine } from '../types' */
1501
+ /** @import { Constraint, Environment, FieldDefine, Skip, TableConnection, TableDefine } from '../types' */
1490
1502
  /** @import { WhereValue } from '../Where.mjs' */
1491
1503
  /**
1492
1504
  *
@@ -1604,7 +1616,7 @@ function separation(newList, oldList, primaryKeys, commonFilterKeys, noField) {
1604
1616
  }
1605
1617
  /**
1606
1618
  *
1607
- * @param {IConnection} conn
1619
+ * @param {TableConnection} conn
1608
1620
  * @param {Environment} env
1609
1621
  * @param {[Record<string, any>, Record<string, any>, Record<string, any>][]} updatedOldNewList
1610
1622
  * @param {string} key
@@ -1810,7 +1822,7 @@ async function updateItem(conn, env, updatedOldNewList, key, type, array, constr
1810
1822
  }
1811
1823
  /**
1812
1824
  *
1813
- * @param {IConnection} conn
1825
+ * @param {TableConnection} conn
1814
1826
  * @param {[string, FieldDefine<TableDefine>][]} fields
1815
1827
  * @param {[Record<string, any>, Record<string, any>, Record<string, any>][]} list
1816
1828
  * @param {Environment} env
@@ -1838,7 +1850,7 @@ async function updateSub(conn, fields, list, env, skip) {
1838
1850
  }
1839
1851
  /**
1840
1852
  *
1841
- * @param {IConnection} conn
1853
+ * @param {TableConnection} conn
1842
1854
  * @param {TableDefine} model
1843
1855
  * @param {Record<string, any>} data
1844
1856
  * @param {Record<string, any>} newData
@@ -1920,10 +1932,10 @@ async function setDeleteTimestamp(columns, update) {
1920
1932
 
1921
1933
  /** @import { WhereValue } from '../Where.mjs' */
1922
1934
  /** @import { SetValue } from '../set.mjs' */
1923
- /** @import { Environment, IConnection, TableDefine } from '../types' */
1935
+ /** @import { Environment, TableDefine, TableConnection } from '../types' */
1924
1936
  /**
1925
1937
  *
1926
- * @param {IConnection} conn
1938
+ * @param {TableConnection} conn
1927
1939
  * @param {TableDefine} tableDef
1928
1940
  * @param {any} data
1929
1941
  * @param {Record<string, SetValue>} update
@@ -1961,10 +1973,10 @@ async function pseudoDestroy (conn, tableDef, data, update, env) {
1961
1973
  return toFieldList(dataUpdated, fieldColumns)[0] || null;
1962
1974
  }
1963
1975
 
1964
- /** @import { IConnection, TableDefine, Environment } from '../types' */
1976
+ /** @import { TableDefine, Environment, TableConnection } from '../types' */
1965
1977
  /**
1966
1978
  *
1967
- * @param {IConnection} conn
1979
+ * @param {TableConnection} conn
1968
1980
  * @param {TableDefine} tableDef
1969
1981
  * @param {any} data
1970
1982
  * @param {Environment} env
@@ -2068,7 +2080,7 @@ function sort2column(sort, fieldColumns) {
2068
2080
  }
2069
2081
 
2070
2082
  /** @import Connection from './index.mjs' */
2071
- /** @import { Environment, FieldDefine, Fields, IConnection, Skip, TableDefine, FieldType } from '../types' */
2083
+ /** @import { Environment, FieldDefine, Fields, Skip, TableDefine, FieldType, TableConnection, SelectItem } from '../types' */
2072
2084
  /**
2073
2085
  * @param {string[] | boolean | null} [items]
2074
2086
  */
@@ -2121,15 +2133,15 @@ function getSelectFields(select, columns, tableFields, baseFieldSet) {
2121
2133
  }
2122
2134
  /**
2123
2135
  *
2124
- * @param {IConnection} conn
2136
+ * @param {TableConnection} conn
2125
2137
  * @param {any[]} list
2126
2138
  * @param {[string, FieldDefine<TableDefine>][]} fields
2127
- * @param {Set<string>} baseFieldSet
2139
+ * @param {Set<string>} baseParentFieldSet
2128
2140
  * @param {Environment} env
2129
2141
  * @param {Record<string, string[] | undefined>?} [returnFields]
2130
2142
  * @returns {Promise<any[]>}
2131
2143
  */
2132
- async function findSub(conn, list, fields, baseFieldSet, env, returnFields) {
2144
+ async function findSub(conn, list, fields, baseParentFieldSet, env, returnFields) {
2133
2145
  if (!list.length) {
2134
2146
  return list;
2135
2147
  }
@@ -2151,7 +2163,7 @@ async function findSub(conn, list, fields, baseFieldSet, env, returnFields) {
2151
2163
  if (returnFields && !fieldMap) {
2152
2164
  continue;
2153
2165
  }
2154
- const mapList = getMapList(fields, baseFieldSet, constraints);
2166
+ const mapList = getMapList(fields, baseParentFieldSet, constraints);
2155
2167
  if (!mapList) {
2156
2168
  continue;
2157
2169
  }
@@ -2160,19 +2172,22 @@ async function findSub(conn, list, fields, baseFieldSet, env, returnFields) {
2160
2172
  const [columns, fieldColumns, tableFields] = toColumns(fields);
2161
2173
  const noColumn = noField && fieldColumns ? fieldColumns[noField] : noField;
2162
2174
  const where = [subList2where(list, mapList, fieldColumns), ...getValueWhere(constraints, columns, fieldColumns)];
2175
+ const baseFieldSet = new Set(Object.keys(fieldColumns || columns));
2163
2176
  const selected = fieldMap && getSelectFields(fieldMap[''] || [], columns, tableFields, baseFieldSet) || null;
2164
2177
  const select = select2column(columns, fieldColumns, selected && [...selected, ...mapList.map(v => v[0])]);
2165
- /** @type {PromiseLike<object[]>} */
2166
- const result = table && typeof table === 'object' ? table.find(env, conn, columns, {
2167
- where,
2168
- sort: getDefaultSort(columns, noColumn),
2169
- select
2170
- }) : conn.find(env, table, columns, {
2178
+ /** @type {SelectItem[]} */
2179
+ const selects = [{
2180
+ table: typeof table === 'string' ? table : '',
2181
+ columns,
2182
+ select,
2171
2183
  where,
2172
- sort: getDefaultSort(columns, noColumn),
2173
- select
2174
- });
2175
- let promise = result.then(list => findSub(conn, list, tableFields, new Set(Object.keys(fieldColumns || columns)), env, fieldMap));
2184
+ sort: getDefaultSort(columns, noColumn) || [],
2185
+ group: [],
2186
+ having: []
2187
+ }];
2188
+ /** @type {PromiseLike<object[]>} */
2189
+ const result = table && typeof table === 'object' ? table.select(env, conn, selects) : conn.select(env, selects);
2190
+ let promise = result.then(list => findSub(conn, list, tableFields, baseFieldSet, env, fieldMap));
2176
2191
  promises.push(array ? promise.then(subList => {
2177
2192
  for (const item of list) {
2178
2193
  item[key] = subList.filter(createFilter(item, mapList));
@@ -2188,7 +2203,7 @@ async function findSub(conn, list, fields, baseFieldSet, env, returnFields) {
2188
2203
  /**
2189
2204
  *
2190
2205
  * @template {TableDefine} T
2191
- * @param {IConnection} conn
2206
+ * @param {TableConnection} conn
2192
2207
  * @param {Connection} that
2193
2208
  * @param {T} p
2194
2209
  * @param {Environment} env
@@ -2220,19 +2235,19 @@ async function search(conn, that, p, env, returnFields, skip) {
2220
2235
  const selected = fieldMap && getSelectFields(fieldMap[''] || [], columns, tableFields, baseFieldSet) || null;
2221
2236
  const select = select2column(columns, fieldColumns, selected);
2222
2237
  const sorted = sort?.length ? sort2column(sort, fieldColumns) : getDefaultSort(columns);
2223
- const list = table && typeof table === 'object' ? await table.find(env, conn, columns, {
2224
- where,
2225
- offset,
2226
- limit,
2238
+ /** @type {SelectItem[]} */
2239
+ const selects = [{
2240
+ table: typeof table === 'string' ? table : '',
2241
+ columns,
2227
2242
  select,
2228
- sort: sorted
2229
- }) : await conn.find(env, table || '', columns, {
2230
2243
  where,
2231
2244
  offset,
2232
2245
  limit,
2233
- select,
2234
- sort: sorted
2235
- });
2246
+ sort: sorted || [],
2247
+ group: [],
2248
+ having: []
2249
+ }];
2250
+ const list = table && typeof table === 'object' ? await table.select(env, conn, selects) : await conn.select(env, selects);
2236
2251
  if (!list.length) {
2237
2252
  return [];
2238
2253
  }
@@ -2243,11 +2258,11 @@ async function search(conn, that, p, env, returnFields, skip) {
2243
2258
  }
2244
2259
 
2245
2260
  /** @import Connection from './index.mjs' */
2246
- /** @import { Environment, TableDefine, IConnection, Skip } from '../types' */
2261
+ /** @import { Environment, TableDefine, Skip, TableConnection, SelectItem } from '../types' */
2247
2262
  /**
2248
2263
  *
2249
2264
  * @template {TableDefine} T
2250
- * @param {IConnection} conn
2265
+ * @param {TableConnection} conn
2251
2266
  * @param {Connection} that
2252
2267
  * @param {T} p
2253
2268
  * @param {Environment} env
@@ -2271,17 +2286,18 @@ async function first(conn, that, p, env, skip) {
2271
2286
  if (whereHook) {
2272
2287
  where.push(...where2column(Where.parse(whereHook), fieldColumns));
2273
2288
  }
2274
- const list = table && typeof table === 'object' ? await table.find(env, conn, columns, {
2289
+ /** @type {SelectItem[]} */
2290
+ const selects = [{
2291
+ table: typeof table === 'string' ? table : '',
2292
+ columns,
2275
2293
  where,
2276
2294
  limit: 1,
2277
- sort: sort?.length ? sort2column(sort, fieldColumns) : getDefaultSort(columns),
2278
- select: select2column(columns, fieldColumns)
2279
- }) : await conn.find(env, table || '', columns, {
2280
- where,
2281
- limit: 1,
2282
- sort: sort?.length ? sort2column(sort, fieldColumns) : getDefaultSort(columns),
2283
- select: select2column(columns, fieldColumns)
2284
- });
2295
+ sort: sort?.length ? sort2column(sort, fieldColumns) || [] : getDefaultSort(columns) || [],
2296
+ select: select2column(columns, fieldColumns),
2297
+ group: [],
2298
+ having: []
2299
+ }];
2300
+ const list = table && typeof table === 'object' ? await table.select(env, conn, selects) : await conn.select(env, selects);
2285
2301
  const baseFieldSet = new Set(Object.keys(fieldColumns || columns));
2286
2302
  const [item] = await findSub(conn, list, tableFields, baseFieldSet, env);
2287
2303
  if (!item) {
@@ -2293,9 +2309,9 @@ async function first(conn, that, p, env, skip) {
2293
2309
  return p[Build](item, true, env);
2294
2310
  }
2295
2311
 
2296
- /** @import { Environment, IConnection, Queryable } from '../types' */
2312
+ /** @import { Environment, Queryable, TableConnection } from '../types' */
2297
2313
  /**
2298
- * @param {IConnection} conn
2314
+ * @param {TableConnection} conn
2299
2315
  * @param {Queryable} queryable
2300
2316
  * @param {Record<string, any> | boolean | undefined} update
2301
2317
  * @param {Environment} env
@@ -2451,6 +2467,43 @@ function table2db(tables) {
2451
2467
  return allTables;
2452
2468
  }
2453
2469
 
2470
+ /** @import { Fields, Queryable, SelectItem } from '../types' */
2471
+ /**
2472
+ * @template {Fields} T
2473
+ * @param {Queryable<T>} queryable
2474
+ * @returns {SelectItem[]}
2475
+ */
2476
+ function toSelect(queryable) {
2477
+ const [columns, fieldColumns, tableFields] = toColumns(queryable.fields);
2478
+ const {
2479
+ table
2480
+ } = queryable;
2481
+ const options = getOptions(queryable);
2482
+ const {
2483
+ offset,
2484
+ limit
2485
+ } = options;
2486
+ const where = where2column(options.where, fieldColumns);
2487
+ where.push(...getFixedValueWhere(columns));
2488
+ const select = select2column(columns, fieldColumns, options.select);
2489
+ const {
2490
+ sort
2491
+ } = options;
2492
+ /** @type {SelectItem[]} */
2493
+ const result = [{
2494
+ table: typeof table === 'string' ? table : '',
2495
+ columns,
2496
+ offset,
2497
+ limit,
2498
+ where,
2499
+ select,
2500
+ sort: sort?.length ? sort2column(sort, fieldColumns) : getDefaultSort(columns),
2501
+ group: options.group || [],
2502
+ having: []
2503
+ }];
2504
+ return result;
2505
+ }
2506
+
2454
2507
  /* eslint-disable max-lines */
2455
2508
  /* eslint-disable max-len */
2456
2509
  /**
@@ -2495,6 +2548,8 @@ class Connection {
2495
2548
  #env;
2496
2549
  /** @type {() => Promise<IConnection<E>>} */
2497
2550
  #getConnection;
2551
+ /** @type {(t: TableConnect<E> | null | undefined) => Promise<TableConnection<E>>} */
2552
+ #getTableConnection;
2498
2553
  /** @type {E?} */
2499
2554
  #baseTransaction;
2500
2555
  /**
@@ -2505,6 +2560,7 @@ class Connection {
2505
2560
  constructor(connection, transaction = null) {
2506
2561
  this.#baseTransaction = transaction;
2507
2562
  this.#getConnection = async () => connection;
2563
+ this.#getTableConnection = async t => typeof t === 'function' ? t(await connection) : connection;
2508
2564
  this.#env = {
2509
2565
  isDevelopment,
2510
2566
  values,
@@ -2635,7 +2691,7 @@ class Connection {
2635
2691
  if (list.length !== 1) {
2636
2692
  const modelBuild = model[Build];
2637
2693
  const md = typeof modelBuild === 'function' ? modelBuild.bind(model) : undefined;
2638
- const conn = await this.#getConnection();
2694
+ const conn = await this.#getTableConnection(model.connect);
2639
2695
  let setData = list;
2640
2696
  if (typeof beforeCreateMany === 'function') {
2641
2697
  // @ts-ignore
@@ -2651,7 +2707,7 @@ class Connection {
2651
2707
  if (typeof model[Create] !== 'function') {
2652
2708
  const modelBuild = model[Build];
2653
2709
  const md = typeof modelBuild === 'function' ? modelBuild.bind(model) : undefined;
2654
- const conn = await this.#getConnection();
2710
+ const conn = await this.#getTableConnection(model.connect);
2655
2711
  let setData = data;
2656
2712
  if (typeof beforeCreate === 'function') {
2657
2713
  setData = (await beforeCreate.call(setData, this, model, setData)) || setData;
@@ -2666,7 +2722,7 @@ class Connection {
2666
2722
  const m = /** @type {Create} */model;
2667
2723
  const result = m[Create](this, data, async (data, that) => {
2668
2724
  let setData = data;
2669
- const conn = await this.#getConnection();
2725
+ const conn = await this.#getTableConnection(model.connect);
2670
2726
  if (typeof beforeCreate === 'function') {
2671
2727
  setData = (await beforeCreate.call(that ?? setData, this, model, setData)) || setData;
2672
2728
  }
@@ -2688,9 +2744,10 @@ class Connection {
2688
2744
  */
2689
2745
  async search(sql, fields, skip) {
2690
2746
  const returnFields = Array.isArray(fields) ? fields : [];
2691
- const conn = await this.#getConnection();
2747
+ const conn = await this.#getTableConnection(sql.connect);
2748
+ const result = search(conn, this, sql, this.#env, returnFields, skip);
2692
2749
  // @ts-ignore
2693
- return search(conn, this, sql, this.#env, returnFields, skip);
2750
+ return result;
2694
2751
  }
2695
2752
  /**
2696
2753
  *
@@ -2700,7 +2757,7 @@ class Connection {
2700
2757
  * @returns {Promise<T extends Build<infer R > ? R[] : T extends TableDefine<infer F> ? FieldValue<F>[] : never>}
2701
2758
  */
2702
2759
  async find(sql, skip) {
2703
- const conn = await this.#getConnection();
2760
+ const conn = await this.#getTableConnection(sql.connect);
2704
2761
  const env = this.#env;
2705
2762
  /** @type {any} */
2706
2763
  const result = await search(conn, this, sql, env, true, skip);
@@ -2719,7 +2776,7 @@ class Connection {
2719
2776
  * @returns {Promise<T extends Build<infer R > ? R : T extends TableDefine<infer F> ? FieldValue<F> : never>}
2720
2777
  */
2721
2778
  async first(sql, skip) {
2722
- const conn = await this.#getConnection();
2779
+ const conn = await this.#getTableConnection(sql.connect);
2723
2780
  return first(conn, this, sql, this.#env, skip);
2724
2781
  }
2725
2782
  /**
@@ -2738,12 +2795,13 @@ class Connection {
2738
2795
  afterUpdate
2739
2796
  } = model.hooks || {};
2740
2797
  if (typeof data[Save] !== 'function') {
2741
- const conn = await this.#getConnection();
2798
+ const conn = await this.#getTableConnection(model.connect);
2742
2799
  if (newData) {
2743
2800
  let setData = newData;
2744
2801
  if (typeof beforeUpdate === 'function') {
2802
+ const result = (await beforeUpdate.call(data, this, model, data, setData)) || setData;
2745
2803
  // @ts-ignore
2746
- setData = (await beforeUpdate.call(data, this, model, data, setData)) || setData;
2804
+ setData = result;
2747
2805
  }
2748
2806
  // @ts-ignore
2749
2807
  const r = await updateData(conn, model, data, setData, this.#env, skip);
@@ -2771,7 +2829,7 @@ class Connection {
2771
2829
  const that = /** @type {Save}*/data;
2772
2830
  // @ts-ignore
2773
2831
  return that[Save](this, async (data, newData) => {
2774
- const conn = await this.#getConnection();
2832
+ const conn = await this.#getTableConnection(model.connect);
2775
2833
  if (newData) {
2776
2834
  let setData = newData;
2777
2835
  if (typeof beforeUpdate === 'function') {
@@ -2809,7 +2867,7 @@ class Connection {
2809
2867
  afterDelete
2810
2868
  } = tableDef.hooks || {};
2811
2869
  if (typeof data[Destroy] !== 'function') {
2812
- const conn = await this.#getConnection();
2870
+ const conn = await this.#getTableConnection(tableDef.connect);
2813
2871
  if (typeof beforeDelete === 'function') {
2814
2872
  // @ts-ignore
2815
2873
  await beforeDelete.call(data, this, tableDef, data, null);
@@ -2824,7 +2882,7 @@ class Connection {
2824
2882
  const that = /** @type {Destroy} */data;
2825
2883
  // @ts-ignore
2826
2884
  return that[Destroy](this, async data => {
2827
- const conn = await this.#getConnection();
2885
+ const conn = await this.#getTableConnection(tableDef.connect);
2828
2886
  if (typeof beforeDelete === 'function') {
2829
2887
  await beforeDelete.call(that, this, tableDef, data, null);
2830
2888
  }
@@ -2855,7 +2913,7 @@ class Connection {
2855
2913
  ...value
2856
2914
  };
2857
2915
  if (typeof data[PseudoDestroy] !== 'function') {
2858
- const conn = await this.#getConnection();
2916
+ const conn = await this.#getTableConnection(tableDef.connect);
2859
2917
  if (typeof beforeDelete === 'function') {
2860
2918
  // @ts-ignore
2861
2919
  await beforeDelete.call(data, this, tableDef, data, update);
@@ -2871,7 +2929,7 @@ class Connection {
2871
2929
  const that = /** @type {PseudoDestroy} */data;
2872
2930
  // @ts-ignore
2873
2931
  return that[PseudoDestroy](this, update, async data => {
2874
- const conn = await this.#getConnection();
2932
+ const conn = await this.#getTableConnection(tableDef.connect);
2875
2933
  if (typeof beforeDelete === 'function') {
2876
2934
  await beforeDelete.call(that, this, tableDef, data, update);
2877
2935
  }
@@ -2927,7 +2985,7 @@ class Connection {
2927
2985
  * @returns {Promise<number>}
2928
2986
  */
2929
2987
  async destroyMany(queryable, update) {
2930
- const conn = await this.#getConnection();
2988
+ const conn = await this.#getTableConnection(queryable.connect);
2931
2989
  if (update === false || !isPseudo(queryable)) {
2932
2990
  return deleteMany(conn, queryable, this.#env);
2933
2991
  }
@@ -3003,6 +3061,7 @@ class Connection {
3003
3061
  * @returns {Promise<T | T[]>}
3004
3062
  */
3005
3063
  async insert({
3064
+ connect,
3006
3065
  table,
3007
3066
  fields
3008
3067
  }, data, keys, ignoreConflict) {
@@ -3025,7 +3084,7 @@ class Connection {
3025
3084
  insertKeys = Object.entries(columns).map(v => v[0]);
3026
3085
  }
3027
3086
  const ignore = Boolean(Array.isArray(keys) ? ignoreConflict : keys);
3028
- const conn = await this.#getConnection();
3087
+ const conn = await this.#getTableConnection(connect);
3029
3088
  const result = table && typeof table === 'object' ? await table.insert(this.#env, conn, columns, insertValues, insertKeys, ignore) : await conn.insert(this.#env, table || '', columns, insertValues, insertKeys, ignore);
3030
3089
  const list = toFieldList(result, fieldColumns);
3031
3090
  // @ts-ignore
@@ -3125,6 +3184,7 @@ class Connection {
3125
3184
  * @returns {Promise<T | T[]>}
3126
3185
  */
3127
3186
  async upsert({
3187
+ connect,
3128
3188
  table,
3129
3189
  fields
3130
3190
  }, data, keys, conflictKeys, conflictSet) {
@@ -3148,7 +3208,7 @@ class Connection {
3148
3208
  insertKeys = Object.entries(columns).map(v => v[0]);
3149
3209
  }
3150
3210
  const conflict = Array.isArray(conflictKeys) || conflictKeys === true ? conflictKeys : baseFields.filter(([, v]) => v.primary).sort(([, a], [, b]) => Number(a.primary) - Number(b.primary)).map(([v]) => v);
3151
- const conn = await this.#getConnection();
3211
+ const conn = await this.#getTableConnection(connect);
3152
3212
  const result = table && typeof table === 'object' ? await table.upsert(this.#env, conn, columns, insertValues, insertKeys, conflict, set) : await conn.upsert(this.#env, table || '', columns, insertValues, insertKeys, conflict, set);
3153
3213
  const list = toFieldList(result, fieldColumns);
3154
3214
  // @ts-ignore
@@ -3162,11 +3222,12 @@ class Connection {
3162
3222
  * @returns {Promise<number>}
3163
3223
  */
3164
3224
  async update({
3225
+ connect,
3165
3226
  table,
3166
3227
  fields
3167
3228
  }, update, where, skip) {
3168
3229
  const [columns, fieldColumns, tableFields] = toColumns(fields);
3169
- const conn = await this.#getConnection();
3230
+ const conn = await this.#getTableConnection(connect);
3170
3231
  const whereColumns = where2column(where ? Where.parse(where) : [], fieldColumns);
3171
3232
  whereColumns.push(...getFixedValueWhere(columns));
3172
3233
  return table && typeof table === 'object' ? table.update(this.#env, conn, columns, await getSetValue$1(columns, fieldColumns, update, skip), whereColumns) : conn.update(this.#env, table || '', columns, await getSetValue$1(columns, fieldColumns, update, skip), whereColumns);
@@ -3181,11 +3242,12 @@ class Connection {
3181
3242
  * @returns {Promise<any[]>}
3182
3243
  */
3183
3244
  async updateReturn({
3245
+ connect,
3184
3246
  table,
3185
3247
  fields
3186
3248
  }, update, returning, where, skip) {
3187
3249
  const [columns, fieldColumns, tableFields] = toColumns(fields);
3188
- const conn = await this.#getConnection();
3250
+ const conn = await this.#getTableConnection(connect);
3189
3251
  const whereColumns = where2column(where ? Where.parse(where) : [], fieldColumns);
3190
3252
  whereColumns.push(...getFixedValueWhere(columns));
3191
3253
  const result = table && typeof table === 'object' ? await table.updateReturn(this.#env, conn, returning?.length ? field2column(returning, fieldColumns) : Object.keys(columns), columns, await getSetValue$1(columns, fieldColumns, update, skip), whereColumns) : await conn.updateReturn(this.#env, returning?.length ? field2column(returning, fieldColumns) : Object.keys(columns), table || '', columns, await getSetValue$1(columns, fieldColumns, update, skip), whereColumns);
@@ -3200,13 +3262,14 @@ class Connection {
3200
3262
  * @returns {Promise<number>}
3201
3263
  */
3202
3264
  async updateMany({
3265
+ connect,
3203
3266
  table,
3204
3267
  fields
3205
3268
  }, pKeys, setKeys, list, skip) {
3206
3269
  const [columns, fieldColumns, tableFields] = toColumns(fields);
3207
3270
  const update = await getSetValue$1(columns, fieldColumns, null, skip);
3208
3271
  const [whereColumns, setColumns] = getKeys(columns, update, field2column(pKeys, fieldColumns), field2column(setKeys, fieldColumns));
3209
- const conn = await this.#getConnection();
3272
+ const conn = await this.#getTableConnection(connect);
3210
3273
  return table && typeof table === 'object' ? table.updateMany(this.#env, conn, columns, update, whereColumns, setColumns, toColumnList(list, fieldColumns), []) : conn.updateMany(this.#env, table || '', columns, update, whereColumns, setColumns, list, []);
3211
3274
  }
3212
3275
  /**
@@ -3220,13 +3283,14 @@ class Connection {
3220
3283
  * @returns {Promise<any[]>}
3221
3284
  */
3222
3285
  async updateManyReturn({
3286
+ connect,
3223
3287
  table,
3224
3288
  fields
3225
3289
  }, pKeys, setKeys, list, returning, skip) {
3226
3290
  const [columns, fieldColumns, tableFields] = toColumns(fields);
3227
3291
  const update = getSetValue$1(columns, fieldColumns, null, skip);
3228
3292
  const [whereColumns, setColumns] = getKeys(columns, update, field2column(pKeys, fieldColumns), field2column(setKeys, fieldColumns));
3229
- const conn = await this.#getConnection();
3293
+ const conn = await this.#getTableConnection(connect);
3230
3294
  const result = table && typeof table === 'object' ? await table.updateManyReturn(this.#env, conn, columns, update, whereColumns, setColumns, toColumnList(list, fieldColumns), [], returning?.length ? field2column(returning, fieldColumns) : Object.keys(columns)) : await conn.updateManyReturn(this.#env, table || '', columns, update, whereColumns, setColumns, toColumnList(list, fieldColumns), [], returning?.length ? field2column(returning, fieldColumns) : Object.keys(columns));
3231
3295
  return toFieldList(result, fieldColumns);
3232
3296
  }
@@ -3236,11 +3300,12 @@ class Connection {
3236
3300
  * @returns {Promise<number>}
3237
3301
  */
3238
3302
  async delete({
3303
+ connect,
3239
3304
  table,
3240
3305
  fields
3241
3306
  }, where) {
3242
3307
  const [columns, fieldColumns, tableFields] = toColumns(fields);
3243
- const conn = await this.#getConnection();
3308
+ const conn = await this.#getTableConnection(connect);
3244
3309
  const whereColumns = where2column(where ? Where.parse(where) : [], fieldColumns);
3245
3310
  whereColumns.push(...getFixedValueWhere(columns));
3246
3311
  return table && typeof table === 'object' ? table.delete(this.#env, conn, columns, whereColumns) : conn.delete(this.#env, table || '', columns, whereColumns);
@@ -3253,11 +3318,12 @@ class Connection {
3253
3318
  * @returns {Promise<any[]>}
3254
3319
  */
3255
3320
  async deleteReturn({
3321
+ connect,
3256
3322
  table,
3257
3323
  fields
3258
3324
  }, returning, where) {
3259
3325
  const [columns, fieldColumns, tableFields] = toColumns(fields);
3260
- const conn = await this.#getConnection();
3326
+ const conn = await this.#getTableConnection(connect);
3261
3327
  const whereColumns = where2column(where ? Where.parse(where) : [], fieldColumns);
3262
3328
  whereColumns.push(...getFixedValueWhere(columns));
3263
3329
  const result = table && typeof table === 'object' ? await table.deleteReturn(this.#env, conn, returning?.length ? field2column(returning, fieldColumns) : Object.keys(columns), columns, whereColumns) : await conn.deleteReturn(this.#env, returning?.length ? field2column(returning, fieldColumns) : Object.keys(columns), table || '', columns, whereColumns);
@@ -3271,12 +3337,13 @@ class Connection {
3271
3337
  async count(queryable) {
3272
3338
  const [columns, fieldColumns, tableFields] = toColumns(queryable.fields);
3273
3339
  const {
3340
+ connect,
3274
3341
  table
3275
3342
  } = queryable;
3276
3343
  const options = getOptions(queryable);
3277
3344
  const where = where2column(options.where, fieldColumns);
3278
3345
  where.push(...getFixedValueWhere(columns));
3279
- const conn = await this.#getConnection();
3346
+ const conn = await this.#getTableConnection(connect);
3280
3347
  return table && typeof table === 'object' ? table.count(this.#env, conn, columns, where) : conn.count(this.#env, table || '', columns, where);
3281
3348
  }
3282
3349
  /**
@@ -3284,43 +3351,12 @@ class Connection {
3284
3351
  * @returns {Promise<any[]>}
3285
3352
  */
3286
3353
  async select(queryable) {
3287
- const [columns, fieldColumns, tableFields] = toColumns(queryable.fields);
3288
3354
  const {
3289
3355
  table
3290
3356
  } = queryable;
3291
- const options = getOptions(queryable);
3292
- const {
3293
- offset,
3294
- limit
3295
- } = options;
3296
- const where = where2column(options.where, fieldColumns);
3297
- where.push(...getFixedValueWhere(columns));
3298
- const conn = await this.#getConnection();
3299
- const select = select2column(columns, fieldColumns, options.select);
3300
- const {
3301
- sort
3302
- } = options;
3303
- const result = table && typeof table === 'object' ? await table.select(this.#env, conn, [{
3304
- table: '',
3305
- columns,
3306
- offset,
3307
- limit,
3308
- where,
3309
- select,
3310
- sort: sort?.length ? sort2column(sort, fieldColumns) : getDefaultSort(columns),
3311
- group: options.group || [],
3312
- having: []
3313
- }]) : await conn.select(this.#env, [{
3314
- table: table || '',
3315
- columns,
3316
- offset,
3317
- limit,
3318
- where,
3319
- select,
3320
- sort: sort?.length ? sort2column(sort, fieldColumns) : getDefaultSort(columns),
3321
- group: options.group || [],
3322
- having: []
3323
- }]);
3357
+ const conn = await this.#getTableConnection(queryable.connect);
3358
+ const selects = toSelect(queryable);
3359
+ const result = table && typeof table === 'object' ? await table.select(this.#env, conn, selects) : await conn.select(this.#env, selects);
3324
3360
  return result;
3325
3361
  }
3326
3362
  /**
@@ -4747,7 +4783,7 @@ function coefficient(...value) {
4747
4783
  };
4748
4784
  }
4749
4785
 
4750
- /** @import { Fields, Options, Queryable, Select, VirtualTable } from './types' */
4786
+ /** @import { Fields, Options, Queryable, Select, TableConnect, VirtualTable } from './types' */
4751
4787
  /** @import { WhereValue, Wheres } from './Where.mjs' */
4752
4788
  /**
4753
4789
  *
@@ -4802,6 +4838,7 @@ function selectFn(fn, select, newSelect) {
4802
4838
  * @template {Fields} T
4803
4839
  * @template {object} [TB=object]
4804
4840
  * @typedef {object} QueryOptions
4841
+ * @property {TableConnect<any>?} [connect]
4805
4842
  * @property {string | VirtualTable} [table]
4806
4843
  * @property {T} fields
4807
4844
  * @property {string} [pseudo]
@@ -4812,7 +4849,7 @@ function selectFn(fn, select, newSelect) {
4812
4849
  * @template {object} [TB=object]
4813
4850
  * @implements {Queryable<T>}
4814
4851
  */
4815
- class Query {
4852
+ class Query extends Subquery {
4816
4853
  /**
4817
4854
  * @template {Fields} F
4818
4855
  * @template {new (o: QueryOptions<F>) => Query<F>} T
@@ -4830,6 +4867,8 @@ class Query {
4830
4867
  pseudo
4831
4868
  });
4832
4869
  }
4870
+ /** @readonly @type {TableConnect | null | undefined} */
4871
+
4833
4872
  /** @readonly @type {string | VirtualTable | undefined} */
4834
4873
 
4835
4874
  /** @readonly @type {T} */
@@ -4847,12 +4886,17 @@ class Query {
4847
4886
  get options() {
4848
4887
  return this.#options;
4849
4888
  }
4889
+ toSubquery() {
4890
+ return toSelect(this);
4891
+ }
4850
4892
  /**
4851
4893
  * @param {QueryOptions<T, TB> | Query<T, TB>} options
4852
4894
  * @param {boolean} [noBuild]
4853
4895
  */
4854
4896
  constructor(options, noBuild) {
4897
+ super();
4855
4898
  if (options instanceof Query) {
4899
+ this.connect = options.connect;
4856
4900
  this.table = options.table;
4857
4901
  this.fields = options.fields;
4858
4902
  this.pseudo = options.pseudo;
@@ -4864,11 +4908,13 @@ class Query {
4864
4908
  this.#primary = options.#primary;
4865
4909
  } else {
4866
4910
  const {
4911
+ connect,
4867
4912
  table,
4868
4913
  fields,
4869
4914
  pseudo,
4870
4915
  build
4871
4916
  } = options;
4917
+ this.connect = connect;
4872
4918
  this.table = table;
4873
4919
  this.fields = fields;
4874
4920
  this.pseudo = typeof pseudo === 'string' ? pseudo : '';