@andymic/pigeon 1.3.0 → 1.4.0
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/bin/pigeon.js +0 -4
- package/package.json +2 -2
- package/src/cli.js +42 -5
- package/src/config.js +0 -4
- package/src/index.js +26 -22
- package/src/maps.js +60 -5
- package/src/pgAdmin.js +117 -0
- package/src/utils.js +2 -6
package/bin/pigeon.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@andymic/pigeon",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"author": "Andreas Michael <ateasm03@gmail.com>",
|
|
5
5
|
"description": "Pigeon is a TypeScript-based tool for generating TypeScript classes and methods from PostgreSQL database schemas.",
|
|
6
6
|
"keywords": [
|
|
@@ -35,5 +35,5 @@
|
|
|
35
35
|
"pg": "^8.15.6",
|
|
36
36
|
"prompt-sync": "^4.2.0"
|
|
37
37
|
},
|
|
38
|
-
"gitHead": "
|
|
38
|
+
"gitHead": "ec33791a735792a340bfa41c1f66e9a08534ffa6"
|
|
39
39
|
}
|
package/src/cli.js
CHANGED
|
@@ -1,12 +1,9 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright (c) 2025 Andreas Michael
|
|
3
|
-
* This software is under the Apache 2.0 License
|
|
4
|
-
*/
|
|
5
1
|
import meow from "meow";
|
|
6
2
|
import { createConfig } from "./config.js";
|
|
7
|
-
import { Database, deleteDir, guided, PigeonError, queryDB, runGeneration } from "./index.js";
|
|
3
|
+
import { Database, deleteDir, enumsQuery, guided, PigeonError, queryDB, runGeneration } from "./index.js";
|
|
8
4
|
import * as path from "node:path";
|
|
9
5
|
import fs from "node:fs";
|
|
6
|
+
import { getRelationshipsAndTables, tableProcessing } from "./pgAdmin.js";
|
|
10
7
|
export const cli = meow(`
|
|
11
8
|
Usage
|
|
12
9
|
$ pigeon [options]
|
|
@@ -17,12 +14,15 @@ export const cli = meow(`
|
|
|
17
14
|
--force overwrites already existing files
|
|
18
15
|
--output [path:String] output directory for the generated files.
|
|
19
16
|
--config [path:String] path to .pigeon.json config file.
|
|
17
|
+
--pgAdmin [path:String] path to the pgAdmin ERD file.
|
|
18
|
+
--offline (only with pgAdmin) does not contact the database
|
|
20
19
|
|
|
21
20
|
Examples
|
|
22
21
|
$ pigeon --init
|
|
23
22
|
$ pigeon --output C:/Users/User/Documents/Project
|
|
24
23
|
$ pigeon --output ./generatedFiles --force
|
|
25
24
|
$ pigeon --config ./customPigeonConfig.json
|
|
25
|
+
$ pigeon --pgAdmin C:/Users/User/Documents/Project/ERD.json --offline
|
|
26
26
|
|
|
27
27
|
Exit Status
|
|
28
28
|
Pigeon returns the following codes:
|
|
@@ -57,6 +57,13 @@ export const cli = meow(`
|
|
|
57
57
|
type: "string",
|
|
58
58
|
default: process.cwd(),
|
|
59
59
|
},
|
|
60
|
+
pgAdmin: {
|
|
61
|
+
type: "string",
|
|
62
|
+
},
|
|
63
|
+
offline: {
|
|
64
|
+
type: "boolean",
|
|
65
|
+
default: false,
|
|
66
|
+
}
|
|
60
67
|
},
|
|
61
68
|
autoHelp: true,
|
|
62
69
|
autoVersion: true,
|
|
@@ -67,6 +74,36 @@ export async function run(flags) {
|
|
|
67
74
|
return createConfig(flags.cwd);
|
|
68
75
|
if (flags.force)
|
|
69
76
|
deleteDir(flags.output);
|
|
77
|
+
if (flags.pgAdmin) {
|
|
78
|
+
let enums;
|
|
79
|
+
let database;
|
|
80
|
+
if (!flags.offline) {
|
|
81
|
+
if (!fs.existsSync(path.join(process.cwd(), ".pigeon.json")))
|
|
82
|
+
return new PigeonError(1, "", new Error("The configuration file does not exist. Generate one using the \"pigeon --init\" command"));
|
|
83
|
+
const params = JSON.parse(fs.readFileSync(flags.config).toString());
|
|
84
|
+
database = new Database(params.host, params.port, params.database, params.username, params.password);
|
|
85
|
+
enums = await enumsQuery(database);
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
enums = [];
|
|
89
|
+
database = new Database("localhost", "5432", "database", "username", "password");
|
|
90
|
+
}
|
|
91
|
+
if (enums instanceof PigeonError)
|
|
92
|
+
return enums;
|
|
93
|
+
if (!fs.existsSync(flags.pgAdmin))
|
|
94
|
+
return new PigeonError(1, "", new Error("The pgAdmin ERD file specified does not exist."));
|
|
95
|
+
const file = fs.readFileSync(flags.pgAdmin).toString();
|
|
96
|
+
let tables;
|
|
97
|
+
try {
|
|
98
|
+
tables = getRelationshipsAndTables(file).tables;
|
|
99
|
+
}
|
|
100
|
+
catch (e) {
|
|
101
|
+
return e;
|
|
102
|
+
}
|
|
103
|
+
const generationResult = runGeneration(flags.output, database, tableProcessing(tables), enums);
|
|
104
|
+
if (generationResult instanceof PigeonError)
|
|
105
|
+
return generationResult;
|
|
106
|
+
}
|
|
70
107
|
if (flags.guided) {
|
|
71
108
|
const params = guided();
|
|
72
109
|
const database = new Database(params.host, String(params.port), params.db, params.user, params.pass);
|
package/src/config.js
CHANGED
package/src/index.js
CHANGED
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright (c) 2025 Andreas Michael
|
|
3
|
-
* This software is under the Apache 2.0 License
|
|
4
|
-
*/
|
|
5
1
|
import { arrayMaker, consoleMessage, getCombinations, getType, nameBeautifier, queryMaker, runQuery, singularize, sleep, tabsInserter } from "./utils.js";
|
|
6
2
|
import prompt from "prompt-sync";
|
|
7
3
|
import fs from "node:fs";
|
|
@@ -30,7 +26,7 @@ export class Database {
|
|
|
30
26
|
this.pass = pass;
|
|
31
27
|
}
|
|
32
28
|
}
|
|
33
|
-
class Table {
|
|
29
|
+
export class Table {
|
|
34
30
|
table_schema;
|
|
35
31
|
table_name;
|
|
36
32
|
columns = [];
|
|
@@ -46,7 +42,7 @@ class Table {
|
|
|
46
42
|
this.unique = unique;
|
|
47
43
|
}
|
|
48
44
|
}
|
|
49
|
-
class Enum {
|
|
45
|
+
export class Enum {
|
|
50
46
|
name;
|
|
51
47
|
labels;
|
|
52
48
|
constructor(name, labels) {
|
|
@@ -54,7 +50,7 @@ class Enum {
|
|
|
54
50
|
this.labels = labels;
|
|
55
51
|
}
|
|
56
52
|
}
|
|
57
|
-
class ColumnQueryRow {
|
|
53
|
+
export class ColumnQueryRow {
|
|
58
54
|
column_name;
|
|
59
55
|
ordinal_position;
|
|
60
56
|
column_default;
|
|
@@ -74,19 +70,21 @@ class ColumnQueryRow {
|
|
|
74
70
|
this.identity_generation = identity_generation;
|
|
75
71
|
}
|
|
76
72
|
}
|
|
77
|
-
class PrimaryKeyQueryRow {
|
|
73
|
+
export class PrimaryKeyQueryRow {
|
|
78
74
|
column_name;
|
|
79
75
|
constructor(column_name) {
|
|
80
76
|
this.column_name = column_name;
|
|
81
77
|
}
|
|
82
78
|
}
|
|
83
|
-
class ForeignKeyQueryRow {
|
|
79
|
+
export class ForeignKeyQueryRow {
|
|
80
|
+
local_schema;
|
|
84
81
|
local_table;
|
|
85
82
|
local_column;
|
|
86
83
|
foreign_schema;
|
|
87
84
|
foreign_table;
|
|
88
85
|
foreign_column;
|
|
89
|
-
constructor(local_table, local_column, foreign_schema, foreign_table, foreign_column) {
|
|
86
|
+
constructor(local_schema, local_table, local_column, foreign_schema, foreign_table, foreign_column) {
|
|
87
|
+
this.local_schema = local_schema;
|
|
90
88
|
this.local_table = local_table;
|
|
91
89
|
this.local_column = local_column;
|
|
92
90
|
this.foreign_schema = foreign_schema;
|
|
@@ -94,7 +92,7 @@ class ForeignKeyQueryRow {
|
|
|
94
92
|
this.foreign_column = foreign_column;
|
|
95
93
|
}
|
|
96
94
|
}
|
|
97
|
-
class UniqueQueryRow {
|
|
95
|
+
export class UniqueQueryRow {
|
|
98
96
|
columns;
|
|
99
97
|
constructor(columns) {
|
|
100
98
|
this.columns = columns;
|
|
@@ -152,14 +150,7 @@ export function guided() {
|
|
|
152
150
|
const pass = input("Database Password: ");
|
|
153
151
|
return { host, port, db, user, pass };
|
|
154
152
|
}
|
|
155
|
-
export async function
|
|
156
|
-
const tableQuery = await runQuery(`SELECT table_schema, table_name
|
|
157
|
-
FROM information_schema.tables
|
|
158
|
-
WHERE table_type = 'BASE TABLE'
|
|
159
|
-
AND table_schema NOT IN
|
|
160
|
-
('pg_catalog', 'information_schema');`, [], db);
|
|
161
|
-
if (typeof tableQuery === "undefined")
|
|
162
|
-
return new PigeonError(1, "", new Error("An SQL error has occurred."));
|
|
153
|
+
export async function enumsQuery(db) {
|
|
163
154
|
const customTypeQuery = await runQuery(`SELECT t.oid, t.typname
|
|
164
155
|
FROM pg_type t
|
|
165
156
|
WHERE (t.typrelid = 0 OR t.typrelid IN (SELECT oid FROM pg_class WHERE relkind = 'c'))
|
|
@@ -181,6 +172,19 @@ export async function queryDB(db) {
|
|
|
181
172
|
labels.push(enumLabel.enumlabel);
|
|
182
173
|
enums.push(new Enum(type.typname, labels));
|
|
183
174
|
}
|
|
175
|
+
return enums;
|
|
176
|
+
}
|
|
177
|
+
export async function queryDB(db) {
|
|
178
|
+
const tableQuery = await runQuery(`SELECT table_schema, table_name
|
|
179
|
+
FROM information_schema.tables
|
|
180
|
+
WHERE table_type = 'BASE TABLE'
|
|
181
|
+
AND table_schema NOT IN
|
|
182
|
+
('pg_catalog', 'information_schema');`, [], db);
|
|
183
|
+
if (typeof tableQuery === "undefined")
|
|
184
|
+
return new PigeonError(1, "", new Error("An SQL error has occurred."));
|
|
185
|
+
const enums = await enumsQuery(db);
|
|
186
|
+
if (enums instanceof PigeonError)
|
|
187
|
+
return enums;
|
|
184
188
|
const tables = [];
|
|
185
189
|
for (const table of tableQuery.rows) {
|
|
186
190
|
const columnQuery = await runQuery(`SELECT column_name,
|
|
@@ -383,7 +387,7 @@ function createClass(tableName, columns, primaryKey, foreignKeys) {
|
|
|
383
387
|
text += "\t * A primary key representing the " + nameBeautifier(column.column_name) + " for the " + nameBeautifier(tableName) + " table.\n";
|
|
384
388
|
else if (foreignKeys && foreignKeyIndex)
|
|
385
389
|
text += "\t * A foreign key representing the " + nameBeautifier(column.column_name) + " for the " + nameBeautifier(tableName) + " table and referencing the " + nameBeautifier(foreignKeys[foreignKeyIndex].foreign_column) + " in the " + nameBeautifier(foreignKeys[foreignKeyIndex].foreign_table) + " table in the " + nameBeautifier(foreignKeys[foreignKeyIndex].foreign_schema) + " schema.\n";
|
|
386
|
-
else if (column.column_name.toLowerCase().startsWith(
|
|
390
|
+
else if (column.column_name.toLowerCase().startsWith("is_"))
|
|
387
391
|
text += "\t * Indicates whether this record in the table " + nameBeautifier(tableName) + " is currently " + nameBeautifier(column.column_name.slice(3)).toLowerCase() + ".\n";
|
|
388
392
|
else
|
|
389
393
|
text += "\t * The " + nameBeautifier(column.column_name) + " for the " + nameBeautifier(tableName) + " table.\n";
|
|
@@ -396,7 +400,7 @@ function createClass(tableName, columns, primaryKey, foreignKeys) {
|
|
|
396
400
|
if (column.column_default)
|
|
397
401
|
text += " = new Date()";
|
|
398
402
|
else
|
|
399
|
-
text += " = new Date(" + column.column_default.replace(
|
|
403
|
+
text += " = new Date(" + column.column_default.replace(" ", "T") + ")";
|
|
400
404
|
}
|
|
401
405
|
else if (dataType === "number" || dataType === "boolean")
|
|
402
406
|
text += " = " + column.column_default;
|
|
@@ -417,7 +421,7 @@ function createClass(tableName, columns, primaryKey, foreignKeys) {
|
|
|
417
421
|
if (column.is_nullable === "YES")
|
|
418
422
|
text += " | undefined";
|
|
419
423
|
text += "} " + column.column_name;
|
|
420
|
-
if (!column.column_name.toLowerCase().startsWith(
|
|
424
|
+
if (!column.column_name.toLowerCase().startsWith("is_"))
|
|
421
425
|
text += " - The " + nameBeautifier(column.column_name) + " of the " + nameBeautifier(tableName) + " table. \n";
|
|
422
426
|
else
|
|
423
427
|
text += " - Indicates whether this record in the table " + nameBeautifier(tableName) + " is currently " + nameBeautifier(column.column_name.slice(3)).toLowerCase() + ".\n";
|
package/src/maps.js
CHANGED
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
* Copyright (c) 2024 Andreas Michael
|
|
3
|
-
* This software is under the Apache 2.0 License
|
|
4
|
-
*/
|
|
5
|
-
export const types = new Map([
|
|
1
|
+
export const jsTypes = new Map([
|
|
6
2
|
["bigint", "number"],
|
|
7
3
|
["int8", "number"],
|
|
8
4
|
["bigserial", "number"],
|
|
@@ -65,3 +61,62 @@ export const types = new Map([
|
|
|
65
61
|
["uuid", "string"],
|
|
66
62
|
["xml", "string"],
|
|
67
63
|
]);
|
|
64
|
+
export const udtTypes = new Map([
|
|
65
|
+
["smallint", "int2"],
|
|
66
|
+
["int2", "int2"],
|
|
67
|
+
["integer", "int4"],
|
|
68
|
+
["int", "int4"],
|
|
69
|
+
["bigint", "int8"],
|
|
70
|
+
["int8", "int8"],
|
|
71
|
+
["real", "float4"],
|
|
72
|
+
["float4", "float4"],
|
|
73
|
+
["double precision", "float8"],
|
|
74
|
+
["float8", "float8"],
|
|
75
|
+
["numeric", "numeric"],
|
|
76
|
+
["decimal", "numeric"],
|
|
77
|
+
["money", "money"],
|
|
78
|
+
["smallserial", "int2"],
|
|
79
|
+
["serial", "int4"],
|
|
80
|
+
["bigserial", "int8"],
|
|
81
|
+
["character", "bpchar"],
|
|
82
|
+
["char", "bpchar"],
|
|
83
|
+
["character varying", "varchar"],
|
|
84
|
+
["varchar", "varchar"],
|
|
85
|
+
["text", "text"],
|
|
86
|
+
["bytea", "bytea"],
|
|
87
|
+
["bit", "bit"],
|
|
88
|
+
["bit varying", "varbit"],
|
|
89
|
+
["varbit", "varbit"],
|
|
90
|
+
["boolean", "bool"],
|
|
91
|
+
["bool", "bool"],
|
|
92
|
+
["date", "date"],
|
|
93
|
+
["time without time zone", "time"],
|
|
94
|
+
["time", "time"],
|
|
95
|
+
["time with time zone", "timetz"],
|
|
96
|
+
["timetz", "timetz"],
|
|
97
|
+
["timestamp without time zone", "timestamp"],
|
|
98
|
+
["timestamp", "timestamp"],
|
|
99
|
+
["timestamp with time zone", "timestamptz"],
|
|
100
|
+
["timestamptz", "timestamptz"],
|
|
101
|
+
["interval", "interval"],
|
|
102
|
+
["box", "box"],
|
|
103
|
+
["circle", "circle"],
|
|
104
|
+
["line", "line"],
|
|
105
|
+
["lseg", "lseg"],
|
|
106
|
+
["path", "path"],
|
|
107
|
+
["point", "point"],
|
|
108
|
+
["polygon", "polygon"],
|
|
109
|
+
["cidr", "cidr"],
|
|
110
|
+
["inet", "inet"],
|
|
111
|
+
["macaddr", "macaddr"],
|
|
112
|
+
["macaddr8", "macaddr8"],
|
|
113
|
+
["json", "json"],
|
|
114
|
+
["jsonb", "jsonb"],
|
|
115
|
+
["uuid", "uuid"],
|
|
116
|
+
["tsquery", "tsquery"],
|
|
117
|
+
["tsvector", "tsvector"],
|
|
118
|
+
["pg_lsn", "pg_lsn"],
|
|
119
|
+
["pg_snapshot", "pg_snapshot"],
|
|
120
|
+
["txid_snapshot", "txid_snapshot"],
|
|
121
|
+
["xml", "xml"],
|
|
122
|
+
]);
|
package/src/pgAdmin.js
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { ColumnQueryRow, ForeignKeyQueryRow, PigeonError, PrimaryKeyQueryRow, Table, UniqueQueryRow } from "./index.js";
|
|
2
|
+
import { udtTypes } from "./maps.js";
|
|
3
|
+
function objectToArray(json) {
|
|
4
|
+
let arrayJSON = "";
|
|
5
|
+
let enteredObject = false;
|
|
6
|
+
let brackets = 0;
|
|
7
|
+
for (let i = 0; i < json.length; i++) {
|
|
8
|
+
if (json[i] === "{") {
|
|
9
|
+
if (!enteredObject) {
|
|
10
|
+
enteredObject = true;
|
|
11
|
+
arrayJSON += "[";
|
|
12
|
+
brackets++;
|
|
13
|
+
continue;
|
|
14
|
+
}
|
|
15
|
+
brackets++;
|
|
16
|
+
arrayJSON += json[i];
|
|
17
|
+
continue;
|
|
18
|
+
}
|
|
19
|
+
else if (json[i] === "}") {
|
|
20
|
+
brackets--;
|
|
21
|
+
if (brackets === 0)
|
|
22
|
+
return JSON.parse(arrayJSON.slice(0, -1) + "]");
|
|
23
|
+
arrayJSON += json[i];
|
|
24
|
+
if (brackets === 1)
|
|
25
|
+
arrayJSON += ",";
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
if (enteredObject && brackets !== 1)
|
|
29
|
+
arrayJSON += json[i];
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
export function getRelationshipsAndTables(json) {
|
|
33
|
+
if (!json.startsWith("{\"version\":"))
|
|
34
|
+
throw new PigeonError(1, "", new Error("The file specified is not an pgAdmin ERD file."));
|
|
35
|
+
let relationships = [];
|
|
36
|
+
let tables = [];
|
|
37
|
+
const relationshipsIndex = json.match(/"type":"diagram-links"/)?.index;
|
|
38
|
+
if (relationshipsIndex)
|
|
39
|
+
relationships = objectToArray(json.slice(relationshipsIndex));
|
|
40
|
+
const tablesIndex = json.match(/"type":"diagram-nodes"/)?.index;
|
|
41
|
+
if (tablesIndex)
|
|
42
|
+
tables = objectToArray(json.slice(tablesIndex));
|
|
43
|
+
return {
|
|
44
|
+
relationships: relationships,
|
|
45
|
+
tables: tables,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
export function tableProcessing(tables) {
|
|
49
|
+
const pigeonTables = [];
|
|
50
|
+
for (const table of tables) {
|
|
51
|
+
const data = table.otherInfo.data;
|
|
52
|
+
const columns = [];
|
|
53
|
+
let ordinalPossition = 1;
|
|
54
|
+
for (const column of data.columns) {
|
|
55
|
+
let dataType = column.cltype;
|
|
56
|
+
let udtType;
|
|
57
|
+
udtType = udtTypes.get(dataType);
|
|
58
|
+
if (!udtType) {
|
|
59
|
+
if (dataType.endsWith("[]")) {
|
|
60
|
+
udtType = "_" + udtTypes.get(dataType.slice(0, -2));
|
|
61
|
+
dataType = "ARRAY";
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
udtType = dataType;
|
|
65
|
+
dataType = "USER-DEFINED";
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
if (dataType === "smallserial" || dataType === "serial" || dataType === "bigserial") {
|
|
69
|
+
dataType = dataType.replace("serial", "int");
|
|
70
|
+
if (dataType === "int")
|
|
71
|
+
dataType = "integer";
|
|
72
|
+
column.defval = "nextval('" + data.name + "_" + column.name + "_seq'::regclass)";
|
|
73
|
+
}
|
|
74
|
+
let isNullable;
|
|
75
|
+
if (column.attnotnull)
|
|
76
|
+
isNullable = "NO";
|
|
77
|
+
else
|
|
78
|
+
isNullable = "YES";
|
|
79
|
+
let columnDefault;
|
|
80
|
+
if (column.defval !== "" && column.defval !== undefined)
|
|
81
|
+
columnDefault = column.defval;
|
|
82
|
+
else
|
|
83
|
+
columnDefault = null;
|
|
84
|
+
let identity;
|
|
85
|
+
if (column.colconstype === "i")
|
|
86
|
+
identity = "YES";
|
|
87
|
+
else
|
|
88
|
+
identity = "NO";
|
|
89
|
+
let identityGeneration = null;
|
|
90
|
+
if (identity === "YES") {
|
|
91
|
+
if (column.attidentity === "a")
|
|
92
|
+
identityGeneration = "ALWAYS";
|
|
93
|
+
if (column.attidentity === "b")
|
|
94
|
+
identityGeneration = "BY DEFAULT";
|
|
95
|
+
}
|
|
96
|
+
columns.push(new ColumnQueryRow(column.name, ordinalPossition, columnDefault, isNullable, dataType, udtType, identity, identityGeneration));
|
|
97
|
+
ordinalPossition++;
|
|
98
|
+
}
|
|
99
|
+
let primaryKey = undefined;
|
|
100
|
+
if (data.primary_key[0]?.columns[0]?.column)
|
|
101
|
+
primaryKey = new PrimaryKeyQueryRow(data.primary_key[0].columns[0].column);
|
|
102
|
+
const foreignKeys = [];
|
|
103
|
+
for (const foreignKey of data.foreign_key) {
|
|
104
|
+
for (const column of foreignKey.columns) {
|
|
105
|
+
const match = column.references_table_name.match(/(?:\((.*?)\))? ?(.*)/);
|
|
106
|
+
foreignKeys.push(new ForeignKeyQueryRow(data.schema, data.name, column.local_column, match[1] || data.schema, match[2], column.referenced));
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
const uniqueConstraints = [];
|
|
110
|
+
if (data.unique_constraint)
|
|
111
|
+
for (const uniqueConstraint of data.unique_constraint)
|
|
112
|
+
for (const column of uniqueConstraint.columns)
|
|
113
|
+
uniqueConstraints.push(column.column);
|
|
114
|
+
pigeonTables.push(new Table(data.schema, data.name, columns, primaryKey, foreignKeys, new UniqueQueryRow(uniqueConstraints)));
|
|
115
|
+
}
|
|
116
|
+
return pigeonTables;
|
|
117
|
+
}
|
package/src/utils.js
CHANGED
|
@@ -1,9 +1,5 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright (c) 2025 Andreas Michael
|
|
3
|
-
* This software is under the Apache 2.0 License
|
|
4
|
-
*/
|
|
5
1
|
import pg from "pg";
|
|
6
|
-
import {
|
|
2
|
+
import { jsTypes } from "./maps.js";
|
|
7
3
|
const { Client } = pg;
|
|
8
4
|
export async function runQuery(command, parameters, db) {
|
|
9
5
|
const client = new Client({
|
|
@@ -156,7 +152,7 @@ export function getType(dataType, udtName) {
|
|
|
156
152
|
dataType = udtName.slice(1);
|
|
157
153
|
isArray = true;
|
|
158
154
|
}
|
|
159
|
-
let foundDataType =
|
|
155
|
+
let foundDataType = jsTypes.get(dataType);
|
|
160
156
|
if (foundDataType === undefined)
|
|
161
157
|
foundDataType = nameBeautifier(udtName).replaceAll(" ", "");
|
|
162
158
|
if (isArray)
|