imodel-pg 0.19.2 → 0.19.3

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 +146 -11
  3. package/package.json +1 -1
package/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * imodel v0.19.2
2
+ * imodel v0.19.3
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.2
2
+ * imodel v0.19.3
3
3
  * (c) 2019-2026 undefined
4
4
  * @license undefined
5
5
  */
@@ -1734,6 +1734,144 @@ async function syncTables(env, query, tables, schema) {
1734
1734
  }
1735
1735
  }
1736
1736
 
1737
+ /** @import { Environment } from 'imodel' */
1738
+ /** @import { PgEnvTrans } from './index.mjs' */
1739
+ /**
1740
+ *
1741
+ * @param {string?} [detail]
1742
+ * @returns
1743
+ */
1744
+ function parseUniqueViolationErrorColumns(detail) {
1745
+ const match = /^[^"]*"(.*)"[^"]*$/.exec(detail || '');
1746
+ const colsStr = match?.[1];
1747
+ if (!colsStr) {
1748
+ return [];
1749
+ }
1750
+ const cols = [];
1751
+ let i = 1;
1752
+ for (; i < colsStr.length; i++) {
1753
+ const char = colsStr[i];
1754
+ if (char === ' ' || char === ',') {
1755
+ continue;
1756
+ }
1757
+ if (char === ')') {
1758
+ break;
1759
+ }
1760
+ const list = [];
1761
+ if (char === '"') {
1762
+ i++;
1763
+ for (; i < colsStr.length; i++) {
1764
+ const char = colsStr[i];
1765
+ if (char === '"') {
1766
+ if (colsStr[i + 1] !== '"') {
1767
+ break;
1768
+ }
1769
+ i++;
1770
+ }
1771
+ list.push(char);
1772
+ }
1773
+ } else {
1774
+ for (; i < colsStr.length; i++) {
1775
+ const char = colsStr[i];
1776
+ if (char === ' ') {
1777
+ continue;
1778
+ }
1779
+ if (char === ')' || char === ',') {
1780
+ i--;
1781
+ break;
1782
+ }
1783
+ list.push(char);
1784
+ }
1785
+ }
1786
+ cols.push(list.join(''));
1787
+ continue;
1788
+ }
1789
+ return cols;
1790
+ }
1791
+ /** @type {Record<string, (e: pg.DatabaseError, env: Environment<PgEnvTrans>) => any>} */
1792
+ const errors = {
1793
+ '22P02'(error, {
1794
+ errors
1795
+ }) {
1796
+ return new errors.InvalidInputSyntaxError(error.message);
1797
+ },
1798
+ 23502(error, {
1799
+ errors
1800
+ }) {
1801
+ const {
1802
+ table,
1803
+ column
1804
+ } = error;
1805
+ if (!table || !column) {
1806
+ return;
1807
+ }
1808
+ return new errors.NotNullViolationError(table, column);
1809
+ },
1810
+ 23505(error, {
1811
+ errors
1812
+ }) {
1813
+ const {
1814
+ table,
1815
+ detail
1816
+ } = error;
1817
+ if (!table) {
1818
+ return;
1819
+ }
1820
+ return new errors.UniqueViolationError(table, parseUniqueViolationErrorColumns(detail));
1821
+ },
1822
+ 23503(error, {
1823
+ errors
1824
+ }) {
1825
+ const {
1826
+ table,
1827
+ column,
1828
+ constraint
1829
+ } = error;
1830
+ if (!table || !column) {
1831
+ return;
1832
+ }
1833
+ return new errors.ForeignKeyViolationError(table, column, constraint);
1834
+ },
1835
+ 42883(error, {
1836
+ errors
1837
+ }) {
1838
+ return new errors.OperatorMismatchError(error.message);
1839
+ }
1840
+ };
1841
+ const errorGroup = {
1842
+ 22: 'data',
1843
+ 23: 'constraint',
1844
+ 24: 'cursor',
1845
+ 25: 'transaction'
1846
+ };
1847
+ /**
1848
+ *
1849
+ * @param {pg.DatabaseError} error
1850
+ * @param {Environment<PgEnvTrans>} env
1851
+ */
1852
+ function errorConvert(error, env) {
1853
+ if (!(error instanceof pg.DatabaseError)) {
1854
+ return error;
1855
+ }
1856
+ const {
1857
+ code
1858
+ } = error;
1859
+ if (!code) {
1860
+ throw error;
1861
+ }
1862
+ const convert = Object.hasOwn(errors, code) ? errors[code] : null;
1863
+ const converted = convert?.(error, env);
1864
+ if (converted) {
1865
+ return converted;
1866
+ }
1867
+ if (typeof code !== 'string' || code.length !== 5) {
1868
+ return error;
1869
+ }
1870
+ const group = code.slice(0, 2);
1871
+ const groupCode = Object.hasOwn(errorGroup, group) && errorGroup[group];
1872
+ return new env.errors.ConnectionError(groupCode ? `${groupCode}::pg:${code}` : `:pg:${code}`, error.message);
1873
+ }
1874
+
1737
1875
  /** @import { Environment, IConnection } from 'imodel' */
1738
1876
  const {
1739
1877
  types
@@ -1862,22 +2000,19 @@ function index (pool, version) {
1862
2000
  const {
1863
2001
  transaction
1864
2002
  } = env;
1865
- const transactionClient = transaction?.client;
1866
- if (transactionClient) {
1867
- const client = await Promise.resolve(transactionClient);
1868
- return client.query({
1869
- text,
1870
- values: [...values]
1871
- });
1872
- }
1873
- const client = await connect();
2003
+ const transactionClient = await Promise.resolve(transaction?.client);
2004
+ const client = transactionClient || (await connect());
1874
2005
  try {
1875
2006
  return await client.query({
1876
2007
  text,
1877
2008
  values: [...values]
1878
2009
  });
2010
+ } catch (error) {
2011
+ throw errorConvert(error, env) || error;
1879
2012
  } finally {
1880
- client.release();
2013
+ if (!transactionClient) {
2014
+ client.release();
2015
+ }
1881
2016
  }
1882
2017
  }
1883
2018
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "imodel-pg",
3
- "version": "0.19.2",
3
+ "version": "0.19.3",
4
4
  "dependencies": {
5
5
  "pg": "^8.13.3",
6
6
  "tagged-sql": "^0.9.0"