@technicity/data-service-generator 0.23.0-next.3 → 0.23.0-next.5

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.
@@ -1645,7 +1645,7 @@ function getRelationManyToOneFieldName(x) {
1645
1645
  return changeCase.camelCase(x.foreignKey.replace(new RegExp(x.referencedKey + "$", "i"), ""));
1646
1646
  }
1647
1647
  // TODO: not sure if this logic is correct
1648
- async function getJunctionTables() {
1648
+ const getJunctionTables = (0, memoize_1.default)(async function getJunctionTables() {
1649
1649
  const tables = await getTableNames();
1650
1650
  return (await Promise.all(tables.map(async (table) => {
1651
1651
  const relations = await getRelationsManyToOne(table);
@@ -1660,7 +1660,7 @@ async function getJunctionTables() {
1660
1660
  }
1661
1661
  return null;
1662
1662
  }))).filter(isNotNullOrUndefined_1.isNotNullOrUndefined);
1663
- }
1663
+ }, () => getCtx().runId);
1664
1664
  // `from` relations
1665
1665
  // https://stackoverflow.com/a/54732547
1666
1666
  const getRelationsManyToOne = (0, memoize_1.default)(async function getRelationsManyToOne(table) {
@@ -1690,7 +1690,8 @@ const getRelationsManyToOne = (0, memoize_1.default)(async function getRelations
1690
1690
  FROM information_schema.key_column_usage kcu
1691
1691
  JOIN information_schema.referential_constraints rc ON kcu.constraint_name = rc.constraint_name AND kcu.table_schema = rc.constraint_schema
1692
1692
  JOIN information_schema.constraint_column_usage ccu ON rc.unique_constraint_name = ccu.constraint_name AND rc.unique_constraint_schema = ccu.table_schema
1693
- WHERE kcu.table_schema = 'public' AND kcu.table_name = $1`, [table]);
1693
+ WHERE kcu.table_schema = 'public' AND kcu.table_name = $1
1694
+ ORDER BY ccu.table_name, ccu.column_name`, [table]);
1694
1695
  }
1695
1696
  else {
1696
1697
  throw new Error("Unsupported dialect: " + dialect);
@@ -1733,7 +1734,8 @@ const getRelationsOneToMany = (0, memoize_1.default)(async function getRelations
1733
1734
  FROM information_schema.key_column_usage kcu
1734
1735
  JOIN information_schema.referential_constraints rc ON kcu.constraint_name = rc.constraint_name AND kcu.table_schema = rc.constraint_schema
1735
1736
  JOIN information_schema.constraint_column_usage ccu ON rc.unique_constraint_name = ccu.constraint_name AND rc.unique_constraint_schema = ccu.table_schema
1736
- WHERE kcu.table_schema = 'public' AND ccu.table_name = $1`, [table]);
1737
+ WHERE kcu.table_schema = 'public' AND ccu.table_name = $1
1738
+ ORDER BY kcu.table_name, kcu.column_name`, [table]);
1737
1739
  }
1738
1740
  else {
1739
1741
  throw new Error("Unsupported dialect: " + dialect);
@@ -1786,53 +1788,27 @@ async function getUuidColumn(table) {
1786
1788
  nullable: column.Null === "YES"
1787
1789
  };
1788
1790
  }
1789
- const getPgEnumDefinition = (0, memoize_1.default)(async function getPgEnumDefinition(udtName) {
1791
+ const getPgEnumDefinition = (0, memoize_1.default)(async function getPgEnumDefinition(udtSchema, udtName) {
1790
1792
  const { dialect, query } = getCtx();
1791
1793
  if (dialect !== "postgresql")
1792
1794
  return null;
1793
1795
  const rows = await query(`SELECT e.enumlabel FROM pg_enum e
1794
1796
  JOIN pg_type t ON e.enumtypid = t.oid
1795
1797
  JOIN pg_catalog.pg_namespace n ON t.typnamespace = n.oid
1796
- WHERE t.typname = $1 AND n.nspname = 'public'
1797
- ORDER BY e.enumsortorder`, [udtName]);
1798
+ WHERE t.typname = $2 AND n.nspname = $1
1799
+ ORDER BY e.enumsortorder`, [udtSchema, udtName]);
1798
1800
  if (rows.length === 0)
1799
1801
  return null;
1800
1802
  const labels = rows.map((r) => String(r.enumlabel).replace(/'/g, "''"));
1801
1803
  return "enum('" + labels.join("', '") + "')";
1802
- }, (udtName) => getCtx().runId + ":" + udtName);
1803
- /** List enum type names in the public schema (for building CREATE TYPE DDL). */
1804
- async function getPublicEnumTypeNames() {
1805
- const { dialect, query } = getCtx();
1806
- if (dialect !== "postgresql")
1807
- return [];
1808
- const rows = await query(`SELECT t.typname FROM pg_type t
1809
- JOIN pg_catalog.pg_namespace n ON t.typnamespace = n.oid
1810
- WHERE n.nspname = 'public' AND t.typtype = 'e'
1811
- ORDER BY t.typname`);
1812
- return rows.map((r) => String(r.typname));
1813
- }
1814
- const getPgCreateTypeEnumStatement = (0, memoize_1.default)(async function getPgCreateTypeEnumStatement(typname) {
1815
- const { dialect, query } = getCtx();
1816
- if (dialect !== "postgresql")
1817
- return null;
1818
- const rows = await query(`SELECT e.enumlabel FROM pg_enum e
1819
- JOIN pg_type t ON e.enumtypid = t.oid
1820
- JOIN pg_catalog.pg_namespace n ON t.typnamespace = n.oid
1821
- WHERE t.typname = $1 AND n.nspname = 'public'
1822
- ORDER BY e.enumsortorder`, [typname]);
1823
- if (rows.length === 0)
1824
- return null;
1825
- const quoted = typname.replace(/"/g, '""');
1826
- const labels = rows.map((r) => "'" + String(r.enumlabel).replace(/'/g, "''") + "'");
1827
- return `CREATE TYPE "${quoted}" AS ENUM (${labels.join(", ")});`;
1828
- }, (typname) => getCtx().runId + ":" + typname);
1804
+ }, (udtSchema, udtName) => getCtx().runId + ":" + udtSchema + ":" + udtName);
1829
1805
  const getTableMeta = (0, memoize_1.default)(async function getTableMeta(table) {
1830
1806
  const { dialect, query } = getCtx();
1831
1807
  if (dialect === "mysql") {
1832
1808
  return query("DESCRIBE ??", [table]).then((xs) => _.sortBy((x) => x.Field, xs));
1833
1809
  }
1834
1810
  if (dialect === "postgresql") {
1835
- const columns = await query(`SELECT column_name AS "Field", data_type, udt_name, character_maximum_length AS char_max, is_nullable, column_default AS "Default"
1811
+ const columns = await query(`SELECT column_name AS "Field", data_type, udt_schema, udt_name, character_maximum_length AS char_max, is_nullable, column_default AS "Default"
1836
1812
  FROM information_schema.columns
1837
1813
  WHERE table_schema = 'public' AND table_name = $1
1838
1814
  ORDER BY ordinal_position`, [table]);
@@ -1857,17 +1833,26 @@ const getTableMeta = (0, memoize_1.default)(async function getTableMeta(table) {
1857
1833
  if (!keyMap.has(k.col) || k.key_type === "PRI")
1858
1834
  keyMap.set(k.col, k.key_type);
1859
1835
  }
1860
- const udtNames = [
1861
- ...new Set(columns
1862
- .filter((c) => c.data_type === "USER-DEFINED" && c.udt_name != null)
1863
- .map((c) => c.udt_name))
1836
+ const udtKeys = [
1837
+ ...new Map(columns
1838
+ .filter((c) => c.data_type === "USER-DEFINED" &&
1839
+ c.udt_schema != null &&
1840
+ c.udt_name != null)
1841
+ .map((c) => [`${c.udt_schema}.${c.udt_name}`, c])).keys()
1864
1842
  ];
1865
- const enumDefs = await Promise.all(udtNames.map((udt) => getPgEnumDefinition(udt)));
1866
- const enumMap = new Map(udtNames.map((udt, i) => [udt, enumDefs[i] ?? "varchar(255)"]));
1867
- return columns.map((c) => {
1843
+ const udtPairs = udtKeys.map((k) => {
1844
+ const [s, n] = k.split(".", 2);
1845
+ return [s, n];
1846
+ });
1847
+ const enumDefs = await Promise.all(udtPairs.map(([schema, name]) => getPgEnumDefinition(schema, name)));
1848
+ const enumMap = new Map(udtKeys.map((k, i) => [k, enumDefs[i] ?? "varchar(255)"]));
1849
+ const cols = columns.map((c) => {
1868
1850
  let type;
1869
- if (c.data_type === "USER-DEFINED" && c.udt_name != null) {
1870
- type = enumMap.get(c.udt_name) ?? "character varying(255)";
1851
+ if (c.data_type === "USER-DEFINED" &&
1852
+ c.udt_schema != null &&
1853
+ c.udt_name != null) {
1854
+ const enumKey = `${c.udt_schema}.${c.udt_name}`;
1855
+ type = enumMap.get(enumKey) ?? "character varying(255)";
1871
1856
  }
1872
1857
  else {
1873
1858
  type = c.data_type;
@@ -1881,12 +1866,18 @@ const getTableMeta = (0, memoize_1.default)(async function getTableMeta(table) {
1881
1866
  Type: type,
1882
1867
  Null: c.is_nullable === "YES" ? "YES" : "NO",
1883
1868
  Key: keyMap.get(c.Field) ?? "",
1884
- Default: c.Default ?? "",
1885
- ...(c.data_type === "USER-DEFINED" && c.udt_name != null
1869
+ // Preserve `null` when there is no default so that
1870
+ // required-field detection (via `hasDefault`) works
1871
+ // consistently with the MySQL `DESCRIBE` output.
1872
+ Default: c.Default,
1873
+ ...(c.data_type === "USER-DEFINED" &&
1874
+ c.udt_schema != null &&
1875
+ c.udt_name != null
1886
1876
  ? { PgType: c.udt_name }
1887
1877
  : {})
1888
1878
  };
1889
1879
  });
1880
+ return _.sortBy((c) => c.Field, cols);
1890
1881
  }
1891
1882
  throw new Error("Unsupported dialect: " + dialect);
1892
1883
  }, (table) => getCtx().runId + ":" + table);
@@ -2102,18 +2093,18 @@ function getPropertyFormat(sqlType) {
2102
2093
  }
2103
2094
  return undefined;
2104
2095
  }
2105
- async function getTableNames() {
2096
+ const getTableNames = (0, memoize_1.default)(async function getTableNames() {
2106
2097
  const { dialect, query } = getCtx();
2107
2098
  if (dialect === "mysql") {
2108
2099
  return query("SHOW TABLES").then((xs) => xs.flatMap((x) => Object.values(x)).sort());
2109
2100
  }
2110
2101
  if (dialect === "postgresql") {
2111
2102
  return query(`SELECT table_name FROM information_schema.tables
2112
- WHERE table_schema = 'public' AND table_type = 'BASE TABLE'
2113
- ORDER BY table_name`).then((rows) => rows.map((r) => r.table_name));
2103
+ WHERE table_schema = 'public' AND table_type = 'BASE TABLE'
2104
+ ORDER BY table_name`).then((rows) => rows.map((r) => r.table_name));
2114
2105
  }
2115
2106
  throw new Error("Unsupported dialect: " + dialect);
2116
- }
2107
+ }, () => getCtx().runId);
2117
2108
  function getMysql2sqliteSrc() {
2118
2109
  return `#!/usr/bin/awk -f
2119
2110
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@technicity/data-service-generator",
3
- "version": "0.23.0-next.3",
3
+ "version": "0.23.0-next.5",
4
4
  "main": "./dist/index.js",
5
5
  "files": [
6
6
  "dist"