imodel-pg 0.19.0 → 0.19.2

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 (3) hide show
  1. package/index.d.mts +1 -1
  2. package/index.mjs +64 -6
  3. package/package.json +1 -1
package/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * imodel v0.19.0
2
+ * imodel v0.19.2
3
3
  * (c) 2019-2026 undefined
4
4
  * @license undefined
5
5
  */
package/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * imodel v0.19.0
2
+ * imodel v0.19.2
3
3
  * (c) 2019-2026 undefined
4
4
  * @license undefined
5
5
  */
@@ -80,6 +80,7 @@ function getBaseType(s, {
80
80
  case 'json':
81
81
  return 'json';
82
82
  }
83
+ return s;
83
84
  }
84
85
  /**
85
86
  *
@@ -522,14 +523,17 @@ function buildSelect(env, selectList) {
522
523
  offset,
523
524
  limit,
524
525
  group,
525
- having
526
+ having,
527
+ lock
526
528
  } of selectList) {
527
529
  const Table = Sql.Table(table);
528
530
  const selectSql = getSelect(Table, select);
529
531
  const orderSql = getOrder(sort);
530
532
  const limitSql = limit && limit > 0 ? Sql('LIMIT', limit) : undefined;
531
533
  const offsetSql = offset && offset > 0 ? Sql('OFFSET', offset) : undefined;
532
- list.push(Sql(Sql`SELECT`, distinct ? Sql`DISTINCT` : undefined, Sql`${selectSql}`, Sql`FROM ${Table}`, getWhere(env, where), orderSql, limitSql, offsetSql, group?.length ? Sql`GROUP BY ${Sql`,`.glue(group.map(v => Sql.Field(v)))}` : undefined, getWhere(env, having, 'HAVING')));
534
+ list.push(Sql(Sql`SELECT`, distinct ? Sql`DISTINCT` : undefined, Sql`${selectSql}`, Sql`FROM ${Table}`, getWhere(env, where), orderSql, limitSql, offsetSql, group?.length ? Sql`GROUP BY ${Sql`,`.glue(group.map(v => Sql.Field(v)))}` : undefined, getWhere(env, having, 'HAVING'),
535
+ // eslint-disable-next-line no-nested-ternary
536
+ lock === 'X' ? Sql`FOR UPDATE` : lock === 'S' ? Sql`FOR SHARE` : undefined));
533
537
  }
534
538
  if (!list.length) {
535
539
  return null;
@@ -600,6 +604,17 @@ function buildWhere(env, wheres) {
600
604
  }
601
605
  return Sql`(${Sql` OR `.glue(...orList)})`;
602
606
  }
607
+ if (where.exists) {
608
+ const {
609
+ subquery,
610
+ not
611
+ } = where;
612
+ const select = buildSelect(env, subquery);
613
+ if (!select) {
614
+ return null;
615
+ }
616
+ return not ? Sql`NOT EXISTS(${select})` : Sql`EXISTS(${select})`;
617
+ }
603
618
  const {
604
619
  field: k,
605
620
  operator: o,
@@ -650,6 +665,11 @@ function buildWhere(env, wheres) {
650
665
  not = !not;
651
666
  operator = 'IN';
652
667
  break;
668
+ case 'NOTANY':
669
+ not = !not;
670
+ case 'ANY':
671
+ operator = 'ANY';
672
+ break;
653
673
  case 'NOTLIKE':
654
674
  not = !not;
655
675
  operator = 'LIKE';
@@ -716,6 +736,12 @@ function buildWhere(env, wheres) {
716
736
  if (!subquery?.length && Array.isArray(v) && (operator === 'IN' || operator === 'NOT IN') && v.length) {
717
737
  values = Sql(['(', ...Array(v.length - 1).fill(','), ')'], ...v.map(v => v ?? null));
718
738
  }
739
+ if (operator === 'ANY') {
740
+ if (!not) {
741
+ return Sql`${values} = ANY(${toField(k)})`;
742
+ }
743
+ return Sql`not(${values} = ANY(${toField(k)}))`;
744
+ }
719
745
  if (!not) {
720
746
  return Sql`${toField(k)} ${Sql(operator)} ${values}`;
721
747
  }
@@ -1294,6 +1320,35 @@ async function loadTables(env, query, tables, schema) {
1294
1320
  return dbTables;
1295
1321
  }
1296
1322
 
1323
+ /**
1324
+ * 生成 PostgreSQL ALTER TABLE 语句中强制类型转换的 USING 子句
1325
+ * @param {Sql} COLUMN - 列名
1326
+ * @param {boolean?} [array]
1327
+ * @param {boolean?} [nullable]
1328
+ * @param {boolean?} [oldArray]
1329
+ * @param {Sql?} [def]
1330
+ * @returns {Sql}
1331
+ */
1332
+ function generateUsingClause(COLUMN, array, nullable, oldArray, def) {
1333
+ if (array && !oldArray) {
1334
+ if (nullable) {
1335
+ return Sql`(CASE
1336
+ WHEN ${COLUMN} IS NULL THEN NULL
1337
+ ELSE ARRAY[${COLUMN}]
1338
+ END)`;
1339
+ }
1340
+ return Sql`(CASE
1341
+ WHEN ${COLUMN} IS NULL THEN ARRAY[]
1342
+ ELSE ARRAY[${COLUMN}]
1343
+ END)`;
1344
+ }
1345
+ const val = oldArray && !array ? Sql`${COLUMN}[1]` : Sql`${COLUMN}`;
1346
+ if (nullable || !def) {
1347
+ return val;
1348
+ }
1349
+ return Sql`COALESCE(${val}, ${def})`;
1350
+ }
1351
+
1297
1352
  /** @import { Environment, IConnection } from 'imodel' */
1298
1353
  /** @import { PgEnvTrans } from '../index.mjs' */
1299
1354
  /** @import { DBIndex, DBTable, DBColumn } from 'imodel' */
@@ -1617,15 +1672,18 @@ WHERE table_name = ${table} AND constraint_type = 'PRIMARY KEY'
1617
1672
  size
1618
1673
  }, array);
1619
1674
  const oldType = getType(old.type, old, old.array);
1620
- if (newType !== oldType) {
1621
- COLUMNs.push(Sql`${COLUMN} TYPE ${Sql(newType)}`);
1675
+ const def = getDefault(env, defaultValue, type, array);
1676
+ if (newType !== oldType || !nullable && old.nullable) {
1677
+ console.log(newType, oldType);
1678
+ const usingClause = generateUsingClause(Sql.Field(fieldName), array, nullable, old.array, def);
1679
+ const type = Sql(newType);
1680
+ COLUMNs.push(Sql`${COLUMN} TYPE ${type} USING ${usingClause}::${type}`);
1622
1681
  // TODO: USING "description"::int2
1623
1682
  }
1624
1683
  if (Boolean(nullable) !== Boolean(old.nullable)) {
1625
1684
  COLUMNs.push(nullable ? Sql`${COLUMN} DROP NOT NULL` : Sql`${COLUMN} SET NOT NULL`);
1626
1685
  }
1627
1686
  if (!defaultIsQe(defaultValue, old.default)) {
1628
- const def = getDefault(env, defaultValue, type, array);
1629
1687
  COLUMNs.push(def ? Sql`${COLUMN} SET DEFAULT ${def}` : Sql`${COLUMN} DROP DEFAULT`);
1630
1688
  }
1631
1689
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "imodel-pg",
3
- "version": "0.19.0",
3
+ "version": "0.19.2",
4
4
  "dependencies": {
5
5
  "pg": "^8.13.3",
6
6
  "tagged-sql": "^0.9.0"