@technicity/data-service-generator 0.23.0-next.4 → 0.23.0-next.6
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/dist/generation/generate.js +41 -25
- package/package.json +1 -1
|
@@ -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
|
|
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);
|
|
@@ -1704,7 +1705,7 @@ const getRelationsManyToOne = (0, memoize_1.default)(async function getRelations
|
|
|
1704
1705
|
nullable: tableMeta.find((m) => m.Field === v.t1Field)?.Null === "YES"
|
|
1705
1706
|
};
|
|
1706
1707
|
})));
|
|
1707
|
-
return _.sortBy((x) => x.referencedTable, xs);
|
|
1708
|
+
return _.sortBy([(x) => x.referencedTable, (x) => x.referencedKey, (x) => x.foreignKey], xs);
|
|
1708
1709
|
}, (table) => getCtx().runId + ":" + table);
|
|
1709
1710
|
// `to` relations
|
|
1710
1711
|
const getRelationsOneToMany = (0, memoize_1.default)(async function getRelationsOneToMany(table) {
|
|
@@ -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
|
|
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);
|
|
@@ -1747,7 +1749,7 @@ const getRelationsOneToMany = (0, memoize_1.default)(async function getRelations
|
|
|
1747
1749
|
nullable: false
|
|
1748
1750
|
};
|
|
1749
1751
|
})));
|
|
1750
|
-
return _.sortBy((x) => x.referencedKey,
|
|
1752
|
+
return _.sortBy([(x) => x.referencedTable, (x) => x.referencedKey, (x) => x.foreignKey], xs);
|
|
1751
1753
|
}, (table) => getCtx().runId + ":" + table);
|
|
1752
1754
|
async function getPrimaryColumn(table) {
|
|
1753
1755
|
const tableMeta = await getTableMeta(table);
|
|
@@ -1786,27 +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 = $
|
|
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);
|
|
1804
|
+
}, (udtSchema, udtName) => getCtx().runId + ":" + udtSchema + ":" + udtName);
|
|
1803
1805
|
const getTableMeta = (0, memoize_1.default)(async function getTableMeta(table) {
|
|
1804
1806
|
const { dialect, query } = getCtx();
|
|
1805
1807
|
if (dialect === "mysql") {
|
|
1806
1808
|
return query("DESCRIBE ??", [table]).then((xs) => _.sortBy((x) => x.Field, xs));
|
|
1807
1809
|
}
|
|
1808
1810
|
if (dialect === "postgresql") {
|
|
1809
|
-
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"
|
|
1810
1812
|
FROM information_schema.columns
|
|
1811
1813
|
WHERE table_schema = 'public' AND table_name = $1
|
|
1812
1814
|
ORDER BY ordinal_position`, [table]);
|
|
@@ -1831,17 +1833,26 @@ const getTableMeta = (0, memoize_1.default)(async function getTableMeta(table) {
|
|
|
1831
1833
|
if (!keyMap.has(k.col) || k.key_type === "PRI")
|
|
1832
1834
|
keyMap.set(k.col, k.key_type);
|
|
1833
1835
|
}
|
|
1834
|
-
const
|
|
1835
|
-
...new
|
|
1836
|
-
.filter((c) => c.data_type === "USER-DEFINED" &&
|
|
1837
|
-
.
|
|
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()
|
|
1838
1842
|
];
|
|
1839
|
-
const
|
|
1840
|
-
|
|
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)"]));
|
|
1841
1849
|
const cols = columns.map((c) => {
|
|
1842
1850
|
let type;
|
|
1843
|
-
if (c.data_type === "USER-DEFINED" &&
|
|
1844
|
-
|
|
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)";
|
|
1845
1856
|
}
|
|
1846
1857
|
else {
|
|
1847
1858
|
type = c.data_type;
|
|
@@ -1855,8 +1866,13 @@ const getTableMeta = (0, memoize_1.default)(async function getTableMeta(table) {
|
|
|
1855
1866
|
Type: type,
|
|
1856
1867
|
Null: c.is_nullable === "YES" ? "YES" : "NO",
|
|
1857
1868
|
Key: keyMap.get(c.Field) ?? "",
|
|
1858
|
-
|
|
1859
|
-
|
|
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
|
|
1860
1876
|
? { PgType: c.udt_name }
|
|
1861
1877
|
: {})
|
|
1862
1878
|
};
|
|
@@ -2077,18 +2093,18 @@ function getPropertyFormat(sqlType) {
|
|
|
2077
2093
|
}
|
|
2078
2094
|
return undefined;
|
|
2079
2095
|
}
|
|
2080
|
-
async function getTableNames() {
|
|
2096
|
+
const getTableNames = (0, memoize_1.default)(async function getTableNames() {
|
|
2081
2097
|
const { dialect, query } = getCtx();
|
|
2082
2098
|
if (dialect === "mysql") {
|
|
2083
2099
|
return query("SHOW TABLES").then((xs) => xs.flatMap((x) => Object.values(x)).sort());
|
|
2084
2100
|
}
|
|
2085
2101
|
if (dialect === "postgresql") {
|
|
2086
2102
|
return query(`SELECT table_name FROM information_schema.tables
|
|
2087
|
-
|
|
2088
|
-
|
|
2103
|
+
WHERE table_schema = 'public' AND table_type = 'BASE TABLE'
|
|
2104
|
+
ORDER BY table_name`).then((rows) => rows.map((r) => r.table_name));
|
|
2089
2105
|
}
|
|
2090
2106
|
throw new Error("Unsupported dialect: " + dialect);
|
|
2091
|
-
}
|
|
2107
|
+
}, () => getCtx().runId);
|
|
2092
2108
|
function getMysql2sqliteSrc() {
|
|
2093
2109
|
return `#!/usr/bin/awk -f
|
|
2094
2110
|
|