@andymic/pigeon 1.4.2 → 1.6.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@andymic/pigeon",
3
- "version": "1.4.2",
3
+ "version": "1.6.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": [
@@ -32,8 +32,8 @@
32
32
  },
33
33
  "dependencies": {
34
34
  "meow": "^13.2.0",
35
- "pg": "^8.15.6",
35
+ "pg": "^8.16.0",
36
36
  "prompt-sync": "^4.2.0"
37
37
  },
38
- "gitHead": "04b72fd9eb0dde3a4005146b38d899b9655f0d83"
38
+ "gitHead": "6562b7ff32a6a9dd9f0ef108026c198db32b0aa9"
39
39
  }
package/src/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { arrayMaker, consoleMessage, getCombinations, getType, nameBeautifier, queryMaker, runQuery, singularize, sleep, tabsInserter } from "./utils.js";
1
+ import { arrayMaker, getCombinations, getJSType, getPGType, nameBeautifier, queryMaker, runQuery, singularize, sleep, tabsInserter } from "./utils.js";
2
2
  import prompt from "prompt-sync";
3
3
  import fs from "node:fs";
4
4
  import * as path from "node:path";
@@ -27,20 +27,46 @@ export class Database {
27
27
  this.pass = pass;
28
28
  }
29
29
  }
30
+ export class Column {
31
+ name;
32
+ position;
33
+ defaultValue;
34
+ isNullable;
35
+ jsType;
36
+ pgType;
37
+ isIdentity;
38
+ identityGeneration;
39
+ isPrimary;
40
+ isUnique;
41
+ isForeign;
42
+ foreignSchema;
43
+ foreignTable;
44
+ foreignColumn;
45
+ constructor(name, position, defaultValue, isNullable, jsType, pgType, isIdentity, identityGeneration, isPrimary, isUnique, isForeign, foreignSchema, foreignTable, foreignColumn) {
46
+ this.name = name;
47
+ this.position = position;
48
+ this.defaultValue = defaultValue;
49
+ this.isNullable = isNullable;
50
+ this.jsType = jsType;
51
+ this.pgType = pgType;
52
+ this.isIdentity = isIdentity;
53
+ this.identityGeneration = identityGeneration;
54
+ this.isPrimary = isPrimary;
55
+ this.isUnique = isUnique;
56
+ this.isForeign = isForeign;
57
+ this.foreignSchema = foreignSchema;
58
+ this.foreignTable = foreignTable;
59
+ this.foreignColumn = foreignColumn;
60
+ }
61
+ }
30
62
  export class Table {
31
- table_schema;
32
- table_name;
63
+ name;
64
+ schema;
33
65
  columns = [];
34
- primaryKey;
35
- foreignKeys;
36
- unique;
37
- constructor(table_schema, table_name, columns, primaryKey, foreignKeys, unique) {
38
- this.table_schema = table_schema;
39
- this.table_name = table_name;
66
+ constructor(name, schema, columns) {
67
+ this.name = name;
68
+ this.schema = schema;
40
69
  this.columns = columns;
41
- this.primaryKey = primaryKey;
42
- this.foreignKeys = foreignKeys;
43
- this.unique = unique;
44
70
  }
45
71
  }
46
72
  export class Enum {
@@ -51,54 +77,6 @@ export class Enum {
51
77
  this.labels = labels;
52
78
  }
53
79
  }
54
- export class ColumnQueryRow {
55
- column_name;
56
- ordinal_position;
57
- column_default;
58
- is_nullable;
59
- data_type;
60
- udt_name;
61
- is_identity;
62
- identity_generation;
63
- constructor(column_name, ordinal_position, column_default, is_nullable, data_type, udt_name, is_identity, identity_generation) {
64
- this.column_name = column_name;
65
- this.ordinal_position = ordinal_position;
66
- this.column_default = column_default;
67
- this.is_nullable = is_nullable;
68
- this.data_type = data_type;
69
- this.udt_name = udt_name;
70
- this.is_identity = is_identity;
71
- this.identity_generation = identity_generation;
72
- }
73
- }
74
- export class PrimaryKeyQueryRow {
75
- column_name;
76
- constructor(column_name) {
77
- this.column_name = column_name;
78
- }
79
- }
80
- export class ForeignKeyQueryRow {
81
- local_schema;
82
- local_table;
83
- local_column;
84
- foreign_schema;
85
- foreign_table;
86
- foreign_column;
87
- constructor(local_schema, local_table, local_column, foreign_schema, foreign_table, foreign_column) {
88
- this.local_schema = local_schema;
89
- this.local_table = local_table;
90
- this.local_column = local_column;
91
- this.foreign_schema = foreign_schema;
92
- this.foreign_table = foreign_table;
93
- this.foreign_column = foreign_column;
94
- }
95
- }
96
- export class UniqueQueryRow {
97
- columns;
98
- constructor(columns) {
99
- this.columns = columns;
100
- }
101
- }
102
80
  function createDir(dirPath) {
103
81
  if (fs.existsSync(dirPath))
104
82
  return new PigeonError(1, "", new Error("Generation directory already exists. Add the --force flag if you want to overwrite it."));
@@ -210,6 +188,10 @@ export async function queryDB(db) {
210
188
  AND tc.table_name = $2::varchar;`, [table.table_schema, table.table_name], db);
211
189
  if (typeof pKeyQuery === "undefined")
212
190
  return new PigeonError(1, "", new Error("An SQL error has occurred."));
191
+ for (const pKey of pKeyQuery.rows)
192
+ for (const column of columnQuery.rows)
193
+ if (pKey.column_name === column.column_name)
194
+ column.isPrimary = true;
213
195
  const fKeyQuery = await runQuery(`SELECT kcu1.table_schema AS local_schema,
214
196
  kcu1.table_name AS local_table,
215
197
  kcu1.column_name AS local_column,
@@ -231,6 +213,16 @@ export async function queryDB(db) {
231
213
  AND kcu1.table_name = $2::varchar;`, [table.table_schema, table.table_name], db);
232
214
  if (typeof fKeyQuery === "undefined")
233
215
  return new PigeonError(1, "", new Error("An SQL error has occurred."));
216
+ for (const fKey of fKeyQuery.rows) {
217
+ for (const column of columnQuery.rows) {
218
+ if (fKey.local_schema === table.table_schema && fKey.local_table === table.table_name && fKey.local_column === column.column_name) {
219
+ column.isForeign = true;
220
+ column.foreignSchema = fKey.foreign_schema;
221
+ column.foreignTable = fKey.foreign_table;
222
+ column.foreignColumn = fKey.foreign_column;
223
+ }
224
+ }
225
+ }
234
226
  const uniqueQuery = await runQuery(`SELECT array_agg(a.attname) AS columns
235
227
  FROM pg_constraint AS c
236
228
  CROSS JOIN LATERAL unnest(c.conkey) AS k(c)
@@ -245,7 +237,15 @@ export async function queryDB(db) {
245
237
  let uniques = [];
246
238
  if (uniqueQuery.rowCount > 0)
247
239
  uniques = uniqueQuery.rows[0].columns.slice(1, -1).split(",");
248
- tables.push(new Table(table.table_schema, table.table_name, columnQuery.rows, pKeyQuery.rows[0], fKeyQuery.rows, { columns: uniques }));
240
+ for (const unique of uniques)
241
+ for (const column of columnQuery.rows)
242
+ if (unique === column.column_name)
243
+ column.isUnique = true;
244
+ const columns = [];
245
+ for (const column of columnQuery.rows) {
246
+ columns.push(new Column(column.column_name, column.ordinal_position, column.column_default, column.is_nullable === "YES", getJSType(column.data_type, column.udt_name, column.is_nullable === "YES"), getPGType(column.data_type, column.udt_name), column.is_identity === "YES", column.identity_generation, column.isPrimary || false, column.isUnique || false, column.isForeign || false, column.foreignSchema, column.foreignTable, column.foreignColumn));
247
+ }
248
+ tables.push(new Table(table.table_name, table.table_schema, columns));
249
249
  }
250
250
  return {
251
251
  tables: tables,
@@ -253,16 +253,16 @@ export async function queryDB(db) {
253
253
  };
254
254
  }
255
255
  export function runGeneration(dir, db, tables, enums) {
256
- if (!tables)
256
+ if (tables.length === 0)
257
257
  return new PigeonError(1, "", new Error("No tables were found."));
258
258
  const dirResult = createDir(dir);
259
259
  if (dirResult instanceof PigeonError)
260
260
  return dirResult;
261
261
  let schemas = [];
262
262
  for (const table of tables) {
263
- if (schemas.includes(table.table_schema))
263
+ if (schemas.includes(table.schema))
264
264
  continue;
265
- schemas.push(table.table_schema);
265
+ schemas.push(table.schema);
266
266
  }
267
267
  for (const schema of schemas) {
268
268
  const dirResult = createDir(path.join(dir, schema));
@@ -275,7 +275,7 @@ export function runGeneration(dir, db, tables, enums) {
275
275
  if (enums) {
276
276
  for (const cEnum of enums) {
277
277
  for (const column of table.columns) {
278
- if (cEnum.name === column.udt_name) {
278
+ if (column.pgType.includes(cEnum.name)) {
279
279
  const enumName = nameBeautifier(cEnum.name).replaceAll(" ", "");
280
280
  ts += "/**\n An Enum representing the " + nameBeautifier(cEnum.name).toLowerCase() + ".\n * @readonly\n * @enum {string}\n */\n";
281
281
  ts += "class " + enumName + " {\n";
@@ -290,37 +290,40 @@ export function runGeneration(dir, db, tables, enums) {
290
290
  }
291
291
  }
292
292
  }
293
- ts += createClass(table.table_name, table.columns, table.primaryKey?.column_name, table.foreignKeys);
293
+ ts += createClass(table.name, table.columns);
294
294
  ts += "\n\n";
295
- ts += createGetAll(table.table_schema, table.table_name, table.columns);
295
+ ts += createGetAll(table.schema, table.name, table.columns);
296
296
  ts += "\n\n";
297
297
  let keys = [];
298
- if (table.primaryKey)
299
- keys.push(table.primaryKey.column_name);
300
- if (table.foreignKeys)
301
- for (const fKey of table.foreignKeys)
302
- keys.push(fKey.local_column.replaceAll(" ", ""));
303
- if (table.unique)
304
- keys = keys.concat(table.unique.columns);
305
- keys = [...new Set(keys)];
298
+ for (const column of table.columns)
299
+ if (column.isPrimary || column.isForeign || column.isUnique)
300
+ keys.push(column);
306
301
  for (const keyCombination of getCombinations(keys)) {
307
- ts += createGet(table.table_schema, table.table_name, table.columns, keyCombination);
302
+ ts += createGet(table.schema, table.name, table.columns, keyCombination);
308
303
  ts += "\n\n";
309
304
  }
310
305
  let nonDefaults = [];
311
306
  let softDefaults = [];
312
307
  let hardDefaults = [];
313
308
  for (const column of table.columns) {
314
- if (column.column_default === null && column.is_identity === "NO")
309
+ if (column.defaultValue === null && !column.isIdentity)
315
310
  nonDefaults.push(column);
316
- else if ((column.column_default !== null && !column.column_default.includes("nextval")) || (column.is_identity === "YES" && column.identity_generation === "BY DEFAULT"))
311
+ else if ((column.defaultValue !== null && !column.defaultValue.includes("nextval")) || (column.isIdentity && column.identityGeneration === "BY DEFAULT"))
317
312
  softDefaults.push(column);
318
- else if ((column.column_default !== null && column.column_default.includes("nextval")) || (column.is_identity === "YES" && column.identity_generation === "ALWAYS"))
313
+ else if ((column.defaultValue !== null && column.defaultValue.includes("nextval")) || (column.isIdentity && column.identityGeneration === "ALWAYS"))
319
314
  hardDefaults.push(column);
320
315
  }
321
- ts += createAdd(table.table_schema, table.table_name, nonDefaults, [], hardDefaults.concat(softDefaults), table.foreignKeys) + "\n\n";
316
+ ts += createAdd(table.schema, table.name, nonDefaults, [], hardDefaults.concat(softDefaults)) + "\n\n";
322
317
  for (const softCombination of getCombinations(softDefaults))
323
- ts += createAdd(table.table_schema, table.table_name, nonDefaults, softCombination, hardDefaults.concat(softDefaults.filter(n => !getCombinations(softDefaults).includes([n]))), table.foreignKeys) + "\n\n";
318
+ ts += createAdd(table.schema, table.name, nonDefaults, softCombination, hardDefaults.concat(softDefaults.filter(n => !getCombinations(softDefaults).includes([n])))) + "\n\n";
319
+ for (const keyCombination of getCombinations(keys)) {
320
+ ts += createUpdate(table.schema, table.name, table.columns, keyCombination);
321
+ ts += "\n\n";
322
+ }
323
+ for (const column of table.columns) {
324
+ ts += createDelete(table.schema, table.name, column, table.columns);
325
+ ts += "\n\n";
326
+ }
324
327
  ts = ts.slice(0, -2);
325
328
  const regex = /import ({?.*?}?) from "(.*?)";\n/g;
326
329
  let importObjects = [];
@@ -365,47 +368,36 @@ export function runGeneration(dir, db, tables, enums) {
365
368
  importString += "import pg from \"pg\";\n\n";
366
369
  importString += "const {Client} = pg;\n\n";
367
370
  ts = importString + ts;
368
- fs.writeFileSync(path.join(dir, table.table_schema, table.table_name + ".ts"), ts);
371
+ fs.writeFileSync(path.join(dir, table.schema, table.name + ".ts"), ts);
369
372
  }
370
373
  }
371
- function createClass(tableName, columns, primaryKey, foreignKeys) {
374
+ function createClass(tableName, columns) {
372
375
  let text = "";
373
376
  text += "export class " + singularize(nameBeautifier(tableName)).replaceAll(" ", "") + " {\n";
374
377
  for (const column of columns) {
375
- let dataType = getType(column.data_type, column.udt_name).replaceAll(" ", "");
376
- if (column.is_nullable === "YES")
377
- dataType += " | undefined";
378
- let isPrimaryKey = false;
379
- if (column.column_name === primaryKey)
380
- isPrimaryKey = true;
381
- let foreignKeyIndex;
382
- if (foreignKeys)
383
- for (let i = 0; i < foreignKeys.length; i++)
384
- if (foreignKeys[i].local_column === column.column_name)
385
- foreignKeyIndex = i;
386
378
  text += "\t/**\n";
387
- if (isPrimaryKey)
388
- text += "\t * A primary key representing the " + nameBeautifier(column.column_name) + " for the " + nameBeautifier(tableName) + " table.\n";
389
- else if (foreignKeys && foreignKeyIndex)
390
- 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";
391
- else if (column.column_name.toLowerCase().startsWith("is_"))
392
- text += "\t * Indicates whether this record in the table " + nameBeautifier(tableName) + " is currently " + nameBeautifier(column.column_name.slice(3)).toLowerCase() + ".\n";
379
+ if (column.isPrimary)
380
+ text += "\t * A primary key representing the " + nameBeautifier(column.name) + " for the " + nameBeautifier(tableName) + " table.\n";
381
+ else if (column.isForeign && column.foreignColumn && column.foreignTable && column.foreignSchema)
382
+ text += "\t * A foreign key representing the " + nameBeautifier(column.name) + " for the " + nameBeautifier(tableName) + " table and referencing the " + nameBeautifier(column.foreignColumn) + " in the " + nameBeautifier(column.foreignTable) + " table in the " + nameBeautifier(column.foreignSchema) + " schema.\n";
383
+ else if (column.name.toLowerCase().startsWith("is_"))
384
+ text += "\t * Indicates whether this record in the table " + nameBeautifier(tableName) + " is currently " + nameBeautifier(column.name.slice(3)).toLowerCase() + ".\n";
393
385
  else
394
- text += "\t * The " + nameBeautifier(column.column_name) + " for the " + nameBeautifier(tableName) + " table.\n";
395
- text += "\t * @type {" + dataType + "}\n";
386
+ text += "\t * The " + nameBeautifier(column.name) + " for the " + nameBeautifier(tableName) + " table.\n";
387
+ text += "\t * @type {" + column.jsType + "}\n";
396
388
  text += "\t */\n";
397
- text += "\t" + column.column_name + ": " + dataType;
398
- if (column.column_default !== null) {
399
- let columnDefault = column.column_default.split("::")[0];
400
- let type = column.column_default.split("::")[1];
389
+ text += "\t" + column.name + ": " + column.jsType;
390
+ if (column.defaultValue !== null) {
391
+ let columnDefault = column.defaultValue.split("::")[0];
392
+ let type = column.defaultValue.split("::")[1];
401
393
  if (!columnDefault.includes("nextval")) {
402
- if (dataType === "Date") {
394
+ if (column.jsType === "Date") {
403
395
  if (columnDefault.toLowerCase() === "now()")
404
396
  text += " = new Date()";
405
397
  else
406
398
  text += " = new Date(" + columnDefault.replace(" ", "T") + ")";
407
399
  }
408
- else if (dataType === "number" || dataType === "boolean")
400
+ else if (column.jsType.includes("number") || column.jsType.includes("boolean"))
409
401
  text += " = " + columnDefault;
410
402
  else if (type) {
411
403
  if (jsTypes.get(type) === "string")
@@ -419,7 +411,7 @@ function createClass(tableName, columns, primaryKey, foreignKeys) {
419
411
  }
420
412
  }
421
413
  else
422
- text += " = \"" + column.column_default + "\"";
414
+ text += " = \"" + column.defaultValue + "\"";
423
415
  }
424
416
  }
425
417
  text += ";\n";
@@ -429,30 +421,20 @@ function createClass(tableName, columns, primaryKey, foreignKeys) {
429
421
  text += "\t * Creates a new object for the " + nameBeautifier(tableName) + " table.\n";
430
422
  text += "\t * \n";
431
423
  for (const column of columns) {
432
- let dataType = getType(column.data_type, column.udt_name).replaceAll(" ", "");
433
- text += "\t * ";
434
- text += "@param {" + dataType;
435
- if (column.is_nullable === "YES")
436
- text += " | undefined";
437
- text += "} " + column.column_name;
438
- if (!column.column_name.toLowerCase().startsWith("is_"))
439
- text += " - The " + nameBeautifier(column.column_name) + " of the " + nameBeautifier(tableName) + " table. \n";
424
+ text += "\t * @param {" + column.jsType + "} " + column.name;
425
+ if (!column.name.toLowerCase().startsWith("is_"))
426
+ text += " - The " + nameBeautifier(column.name) + " of the " + nameBeautifier(tableName) + " table. \n";
440
427
  else
441
- text += " - Indicates whether this record in the table " + nameBeautifier(tableName) + " is currently " + nameBeautifier(column.column_name.slice(3)).toLowerCase() + ".\n";
428
+ text += " - Indicates whether this record in the table " + nameBeautifier(tableName) + " is currently " + nameBeautifier(column.name.slice(3)).toLowerCase() + ".\n";
442
429
  }
443
430
  text += "\t */\n";
444
431
  text += "\tconstructor(";
445
- for (const column of columns) {
446
- let dataType = getType(column.data_type, column.udt_name).replaceAll(" ", "");
447
- text += column.column_name + ": " + dataType;
448
- if (column.is_nullable === "YES")
449
- text += " | undefined";
450
- text += ", ";
451
- }
432
+ for (const column of columns)
433
+ text += column.name + ": " + column.jsType + ", ";
452
434
  text = text.slice(0, -2);
453
435
  text += ") {\n";
454
436
  for (const column of columns)
455
- text += "\t\tthis." + column.column_name + " = " + column.column_name + ";\n";
437
+ text += "\t\tthis." + column.name + " = " + column.name + ";\n";
456
438
  text += "\t}\n";
457
439
  text += "}";
458
440
  return text;
@@ -492,53 +474,32 @@ function createGet(tableSchema, tableName, columns, keys) {
492
474
  text += "/**\n";
493
475
  text += " * Gets " + className + " objects from the database by ";
494
476
  for (const key of keys)
495
- text += key + " and ";
477
+ text += key.name + " and ";
496
478
  text = text.slice(0, -5) + ".\n";
497
479
  text += " *\n";
498
- for (const key of keys) {
499
- const column = columns.find(column => column.column_name === key);
500
- if (!column) {
501
- consoleMessage("WRN", `Key ${key} was not found in the columns of table ${tableName}.`);
502
- continue;
503
- }
504
- let dataType = getType(column.data_type, column.udt_name).replaceAll(" ", "");
505
- text += " * ";
506
- text += "@param {" + dataType;
507
- text += "} " + column.column_name;
508
- text += " - The " + nameBeautifier(column.column_name) + " of the " + nameBeautifier(tableName) + " table.\n";
509
- }
480
+ for (const key of keys)
481
+ text += " * @param {" + key.jsType + "} " + key.name + " - The " + nameBeautifier(key.name) + " of the " + nameBeautifier(tableName) + " table.\n";
510
482
  text += " * @returns {Promise<" + className + "[]>} - A Promise object returning an array of " + nameBeautifier(tableName) + ".\n";
511
483
  text += " */\n";
512
484
  text += "export async function get" + nameBeautifier(tableName).replaceAll(" ", "") + "By";
513
485
  for (const key of keys)
514
- text += nameBeautifier(key).replaceAll(" ", "") + "And";
486
+ text += nameBeautifier(key.name).replaceAll(" ", "") + "And";
515
487
  text = text.slice(0, -3);
516
488
  text += "(";
517
- for (const key of keys) {
518
- const column = columns.find(column => column.column_name === key);
519
- if (!column) {
520
- consoleMessage("WRN", `Key ${key} was not found in the columns of table ${tableName}.`);
521
- continue;
522
- }
523
- text += key + ": " + getType(column.data_type, column.udt_name) + ", ";
524
- }
489
+ for (const key of keys)
490
+ text += key.name + ": " + key.jsType + ", ";
525
491
  text = text.slice(0, -2);
526
492
  text += "): Promise<" + className + "[]> {\n";
527
493
  text += "\tif (";
528
494
  for (const key of keys)
529
- text += key + " === undefined || ";
495
+ text += key.name + " === undefined || ";
530
496
  text = text.slice(0, -4);
531
497
  text += ")\n" + "\t\tthrow \"Missing Parameters\";\n\n";
532
498
  let query = "SELECT * FROM " + tableSchema + "." + tableName + " WHERE ";
533
499
  let parameters = "";
534
500
  for (let i = 0; i < keys.length; i++) {
535
- const column = columns.find(column => column.column_name === keys[i]);
536
- if (!column) {
537
- consoleMessage("WRN", `Key ${keys[i]} was not found in the columns of table ${tableName}.`);
538
- continue;
539
- }
540
- query += keys[i] + " = " + "$" + (i + 1) + "::" + (column.data_type || column.udt_name) + " AND ";
541
- parameters += keys[i] + ", ";
501
+ query += keys[i].name + " = " + "$" + (i + 1) + "::" + keys[i].pgType + " AND ";
502
+ parameters += keys[i].name + ", ";
542
503
  }
543
504
  query = query.slice(0, -5) + ";";
544
505
  parameters = parameters.slice(0, -2);
@@ -549,38 +510,34 @@ function createGet(tableSchema, tableName, columns, keys) {
549
510
  text += "}";
550
511
  return text;
551
512
  }
552
- function createAdd(tableSchema, tableName, nonDefaults, softDefaults, hardDefaults, foreignKeys) {
513
+ function createAdd(tableSchema, tableName, nonDefaults, softDefaults, hardDefaults) {
553
514
  let text = "";
554
515
  const className = singularize(nameBeautifier(tableName)).replaceAll(" ", "");
555
- if (foreignKeys) {
556
- for (const foreignKey of foreignKeys) {
557
- if ((tableSchema === foreignKey.foreign_schema) && (tableName === foreignKey.foreign_table))
516
+ let hasForeign = false;
517
+ for (const column of nonDefaults.concat(softDefaults).concat(hardDefaults).sort((a, b) => a.position - b.position)) {
518
+ if (column.isForeign && column.foreignColumn && column.foreignTable && column.foreignSchema) {
519
+ hasForeign = true;
520
+ if ((tableSchema === column.foreignSchema) && (tableName === column.foreignTable))
558
521
  continue;
559
- text += "import {get" + nameBeautifier(foreignKey.foreign_table).replaceAll(" ", "") + "By" + nameBeautifier(foreignKey.foreign_column).replaceAll(" ", "") + "} from \".";
560
- if (tableSchema !== foreignKey.foreign_schema)
561
- text += "./" + foreignKey.foreign_schema;
562
- text += "/" + foreignKey.foreign_table + ".js\";\n";
522
+ text += "import {get" + nameBeautifier(column.foreignTable).replaceAll(" ", "") + "By" + nameBeautifier(column.foreignColumn).replaceAll(" ", "") + "} from \".";
523
+ if (tableSchema !== column.foreignSchema)
524
+ text += "./" + column.foreignSchema;
525
+ text += "/" + column.foreignTable + ".js\";\n";
563
526
  }
564
527
  }
565
528
  text += "/**\n";
566
529
  text += " * Adds the provided " + className + " object to the database.\n";
567
530
  text += " *\n";
568
531
  let columns = nonDefaults.concat(softDefaults);
569
- columns.sort((a, b) => a.ordinal_position - b.ordinal_position);
570
- for (const column of columns) {
571
- let dataType = getType(column.data_type, column.udt_name).replaceAll(" ", "");
572
- text += " * ";
573
- text += "@param {" + dataType;
574
- if (column.is_nullable === "YES")
575
- text += " | undefined";
576
- text += "} " + column.column_name;
577
- text += " - The " + nameBeautifier(column.column_name) + " to be inserted into the " + nameBeautifier(tableName) + " table.\n";
578
- }
532
+ columns.sort((a, b) => a.position - b.position);
533
+ for (const column of columns)
534
+ text += " * @param {" + column.jsType + "} " + column.name + " - The " + nameBeautifier(column.name) + " to be inserted into the " + nameBeautifier(tableName) + " table.\n";
579
535
  text += " * @returns {Promise<" + className + ">} - A Promise object returning the inserted " + nameBeautifier(tableName) + ".\n";
580
- if (foreignKeys && foreignKeys.length > 0) {
536
+ if (hasForeign) {
581
537
  text += " * @throws string An exception in the case of the ";
582
- for (const foreignKey of foreignKeys)
583
- text += nameBeautifier(foreignKey.local_column) + " or the ";
538
+ for (const column of columns)
539
+ if (column.isForeign)
540
+ text += nameBeautifier(column.name) + " or the ";
584
541
  text = text.slice(0, -8);
585
542
  text += " not existing in their table.\n";
586
543
  }
@@ -589,54 +546,42 @@ function createAdd(tableSchema, tableName, nonDefaults, softDefaults, hardDefaul
589
546
  if (softDefaults.length > 0) {
590
547
  text += "With";
591
548
  for (const softDefault of softDefaults)
592
- text += nameBeautifier(softDefault.column_name).replaceAll(" ", "") + "And";
549
+ text += nameBeautifier(softDefault.name).replaceAll(" ", "") + "And";
593
550
  text = text.slice(0, -3);
594
551
  }
595
552
  text += "(";
596
- for (const column of columns) {
597
- let dataType = getType(column.data_type, column.udt_name);
598
- text += column.column_name + ": " + dataType;
599
- if (column.is_nullable === "YES")
600
- text += " | undefined";
601
- text += ", ";
602
- }
553
+ for (const column of columns)
554
+ text += column.name + ": " + column.jsType + ", ";
603
555
  text = text.slice(0, -2);
604
556
  text += "): Promise<" + className + "> {\n";
605
- if (foreignKeys) {
606
- for (const foreignKey of foreignKeys) {
607
- const column = columns.find(column => column.column_name === foreignKey.local_column);
608
- if (!column) {
609
- consoleMessage("WRN", `Key ${foreignKey} was not found in the columns of table ${tableName}.`);
610
- continue;
611
- }
612
- if (column.is_nullable === "YES") {
613
- text += "\tif (" + foreignKey.local_column + ") {\n";
614
- text += "\t\tconst verify" + nameBeautifier(foreignKey.local_column).replaceAll(" ", "") + " = await get" + nameBeautifier(foreignKey.foreign_table).replaceAll(" ", "") + "By" + nameBeautifier(foreignKey.foreign_column).replaceAll(" ", "") + "(" + foreignKey.local_column + ");\n";
615
- text += "\t\tif (verify" + nameBeautifier(foreignKey.local_column).replaceAll(" ", "") + ".length === 0)\n";
616
- text += "\t\t\tthrow \"The " + nameBeautifier(foreignKey.local_column) + " provided does not exist.\";\n";
617
- text += "\t}\n\n";
618
- }
619
- else {
620
- text += "\tconst verify" + nameBeautifier(foreignKey.local_column).replaceAll(" ", "") + " = await get" + nameBeautifier(foreignKey.foreign_table).replaceAll(" ", "") + "By" + nameBeautifier(foreignKey.foreign_column).replaceAll(" ", "") + "(" + foreignKey.local_column + ");\n";
621
- text += "\tif (verify" + nameBeautifier(foreignKey.local_column).replaceAll(" ", "") + ".length === 0)\n";
622
- text += "\t\tthrow \"The " + nameBeautifier(foreignKey.local_column) + " provided does not exist.\";\n\n";
557
+ if (hasForeign) {
558
+ for (const column of columns) {
559
+ if (column.isForeign && column.foreignColumn && column.foreignTable && column.foreignSchema) {
560
+ const name = nameBeautifier(column.name).replaceAll(" ", "");
561
+ if (column.isNullable) {
562
+ text += "\tif (" + column.name + ") {\n";
563
+ text += "\t\tconst verify" + name + " = await get" + nameBeautifier(column.foreignTable).replaceAll(" ", "") + "By" + nameBeautifier(column.foreignColumn).replaceAll(" ", "") + "(" + column.name + ");\n";
564
+ text += "\t\tif (verify" + name + ".length === 0)\n";
565
+ text += "\t\t\tthrow \"The " + nameBeautifier(column.name) + " provided does not exist.\";\n";
566
+ text += "\t}\n\n";
567
+ }
568
+ else {
569
+ text += "\tconst verify" + name + " = await get" + nameBeautifier(column.foreignTable).replaceAll(" ", "") + "By" + nameBeautifier(column.foreignColumn).replaceAll(" ", "") + "(" + column.name + ");\n";
570
+ text += "\tif (verify" + name + ".length === 0)\n";
571
+ text += "\t\tthrow \"The " + nameBeautifier(column.name) + " provided does not exist.\";\n\n";
572
+ }
623
573
  }
624
574
  }
625
575
  }
626
576
  let query = "INSERT INTO " + tableSchema + "." + tableName + " (";
627
577
  for (const column of columns)
628
- query += column.column_name + ", ";
578
+ query += column.name + ", ";
629
579
  query = query.slice(0, -2);
630
580
  query += ") VALUES (";
631
581
  let parameters = "";
632
582
  for (let i = 0; i < columns.length; i++) {
633
- let dataType = columns[i].udt_name;
634
- if (dataType[0] === "_")
635
- dataType = dataType.slice(1) + "[]";
636
- else if (columns[i].data_type !== "USER-DEFINED")
637
- dataType = columns[i].data_type;
638
- query += "$" + (i + 1) + "::" + dataType + ", ";
639
- parameters += columns[i].column_name + ", ";
583
+ query += "$" + (i + 1) + "::" + columns[i].pgType + ", ";
584
+ parameters += columns[i].name + ", ";
640
585
  }
641
586
  query = query.slice(0, -2);
642
587
  parameters = parameters.slice(0, -2);
@@ -646,9 +591,122 @@ function createAdd(tableSchema, tableName, nonDefaults, softDefaults, hardDefaul
646
591
  text += "\treturn new " + className + "(\n";
647
592
  columns = columns.concat(hardDefaults);
648
593
  columns = [...new Set(columns)];
649
- columns.sort((a, b) => a.ordinal_position - b.ordinal_position);
594
+ columns.sort((a, b) => a.position - b.position);
595
+ for (const column of columns)
596
+ text += "\t\tinsertQuery.rows[0]." + column.name + ",\n";
597
+ text = text.slice(0, -2);
598
+ text += "\n";
599
+ text += "\t);\n";
600
+ text += "}";
601
+ return text;
602
+ }
603
+ function createUpdate(tableSchema, tableName, columns, keys) {
604
+ const optionals = columns.filter(column => !keys.includes(column));
605
+ let text = "";
606
+ const className = singularize(nameBeautifier(tableName)).replaceAll(" ", "");
607
+ let hasForeign = false;
608
+ for (const column of columns) {
609
+ if (column.isForeign && column.foreignColumn && column.foreignTable && column.foreignSchema) {
610
+ hasForeign = true;
611
+ if ((tableSchema === column.foreignSchema) && (tableName === column.foreignTable))
612
+ continue;
613
+ text += "import {get" + nameBeautifier(column.foreignTable).replaceAll(" ", "") + "By" + nameBeautifier(column.foreignColumn).replaceAll(" ", "") + "} from \".";
614
+ if (tableSchema !== column.foreignSchema)
615
+ text += "./" + column.foreignSchema;
616
+ text += "/" + column.foreignTable + ".js\";\n";
617
+ }
618
+ }
619
+ text += "/**\n";
620
+ text += " * Updates the " + className + " objects from the database by ";
621
+ for (const key of keys)
622
+ text += key.name + " and ";
623
+ text = text.slice(0, -5) + ".\n";
624
+ text += " *\n";
625
+ for (const key of keys)
626
+ text += " * @param {" + key.jsType.replace(" | null", "") + "} " + key.name + " - The " + nameBeautifier(key.name) + " of the " + nameBeautifier(tableName) + " table to be updated.\n";
627
+ for (const optional of optionals)
628
+ text += " * @param {" + optional.jsType + " | undefined} " + optional.name + " - The value of the" + nameBeautifier(optional.name) + " of the " + nameBeautifier(tableName) + " table to be updated.\n";
629
+ text += " * @returns {Promise<" + className + ">} - A Promise object returning the updated " + nameBeautifier(tableName) + ".\n";
630
+ if (hasForeign) {
631
+ text += " * @throws string An exception in the case of the ";
632
+ for (const column of columns)
633
+ if (column.isForeign)
634
+ text += nameBeautifier(column.name) + " or the ";
635
+ text = text.slice(0, -8);
636
+ text += " not existing in their table.\n";
637
+ }
638
+ text += " */\n";
639
+ text += "export async function update" + className + "By";
640
+ for (const key of keys)
641
+ text += nameBeautifier(key.name).replaceAll(" ", "") + "And";
642
+ text = text.slice(0, -3);
643
+ text += "(";
644
+ for (const key of keys)
645
+ text += key.name + ": " + key.jsType.replace(" | null", "") + ", ";
646
+ for (const optional of optionals)
647
+ text += optional.name + "?: " + optional.jsType + " | undefined, ";
648
+ text = text.slice(0, -2);
649
+ text += "): Promise<" + className + "> {\n";
650
+ if (hasForeign) {
651
+ for (const column of columns) {
652
+ if (column.isForeign && column.foreignColumn && column.foreignTable && column.foreignSchema) {
653
+ const name = nameBeautifier(column.name).replaceAll(" ", "");
654
+ if (!keys.includes(column)) {
655
+ text += "\tif (" + column.name + ") {\n";
656
+ text += "\t\tconst verify" + name + " = await get" + nameBeautifier(column.foreignTable).replaceAll(" ", "") + "By" + nameBeautifier(column.foreignColumn).replaceAll(" ", "") + "(" + column.name + ");\n";
657
+ text += "\t\tif (verify" + name + ".length === 0)\n";
658
+ text += "\t\t\tthrow \"The " + nameBeautifier(column.name) + " provided does not exist.\";\n";
659
+ text += "\t}\n\n";
660
+ }
661
+ else {
662
+ text += "\tconst verify" + name + " = await get" + nameBeautifier(column.foreignTable).replaceAll(" ", "") + "By" + nameBeautifier(column.foreignColumn).replaceAll(" ", "") + "(" + column.name + ");\n";
663
+ text += "\tif (verify" + name + ".length === 0)\n";
664
+ text += "\t\tthrow \"The " + nameBeautifier(column.name) + " provided does not exist.\";\n\n";
665
+ }
666
+ }
667
+ }
668
+ }
669
+ text += "\tlet set = \"\";\n";
670
+ for (let optional of optionals) {
671
+ text += "\tif (" + optional.name + " !== undefined)\n";
672
+ text += "\t\tset += \"" + optional.name + " = '\" + " + optional.name + " + \"', \";\n";
673
+ }
674
+ text += "\tset = set.slice(0, -2);\n";
675
+ let parameters = "";
676
+ let query = "UPDATE " + tableSchema + "." + tableName + ` SET \$\{set\} WHERE `;
677
+ for (let i = 0; i < keys.length; i++) {
678
+ query += keys[i].name + " = " + "$" + (i + 1) + "::" + keys[i].pgType + " AND ";
679
+ parameters += keys[i].name + ", ";
680
+ }
681
+ parameters = parameters.slice(0, -2);
682
+ query = query.slice(0, -5) + " RETURNING *;";
683
+ text += queryMaker(1, "update", query, parameters);
684
+ text += "\n\n";
685
+ text += "\treturn new " + className + "(\n";
686
+ for (const column of columns)
687
+ text += "\t\tupdateQuery.rows[0]." + column.name + ",\n";
688
+ text = text.slice(0, -2);
689
+ text += "\n";
690
+ text += "\t);\n";
691
+ text += "}";
692
+ return text;
693
+ }
694
+ function createDelete(tableSchema, tableName, column, columns) {
695
+ let text = "";
696
+ const className = singularize(nameBeautifier(tableName)).replaceAll(" ", "");
697
+ text += "/**\n";
698
+ text += " * Deletes the " + className + " objects from the database by the value of its " + nameBeautifier(column.name) + ".\n";
699
+ text += " *\n";
700
+ text += " * @param {" + column.jsType.replace(" | null", "") + "} " + column.name + " - The value of the" + nameBeautifier(column.name) + " of the " + nameBeautifier(tableName) + " table to be updated.\n";
701
+ text += " * @returns {Promise<" + className + ">} - A Promise object returning the deleted " + nameBeautifier(tableName) + ".\n";
702
+ text += " */\n";
703
+ text += "export async function delete" + className + "By" + nameBeautifier(column.name).replaceAll(" ", "") + "(" + column.name + ": " + column.jsType.replace(" | null", "") + "): Promise<" + className + "> {\n";
704
+ const query = "DELETE FROM " + tableSchema + "." + tableName + " WHERE " + column.name + " = $1::" + column.pgType + "RETURNING *;";
705
+ text += queryMaker(1, "delete", query, column.name);
706
+ text += "\n\n";
707
+ text += "\treturn new " + className + "(\n";
650
708
  for (const column of columns)
651
- text += "\t\tinsertQuery.rows[0]." + column.column_name + ",\n";
709
+ text += "\t\tdeleteQuery.rows[0]." + column.name + ",\n";
652
710
  text = text.slice(0, -2);
653
711
  text += "\n";
654
712
  text += "\t);\n";
package/src/maps.js CHANGED
@@ -1,64 +1,64 @@
1
1
  export const jsTypes = new Map([
2
- ["bigint", "number"],
3
- ["int8", "number"],
4
- ["bigserial", "number"],
5
- ["serial8", "number"],
6
- ["bit", "Array"],
7
- ["bit varying", "Array"],
8
- ["varbit", "Array"],
9
- ["boolean", "boolean"],
10
- ["bool", "boolean"],
11
- ["box", ""],
12
- ["bytea", "Array"],
13
- ["character", "string"],
14
- ["char", "string"],
15
- ["character varying", "string"],
16
- ["varchar", "string"],
17
- ["cidr", "string"],
18
- ["circle", ""],
19
- ["date", "Date"],
20
- ["double precision", "number"],
21
- ["float8", "number"],
22
- ["inet", "string"],
2
+ ["smallint", "number"],
3
+ ["int2", "number"],
23
4
  ["integer", "number"],
24
5
  ["int", "number"],
25
- ["int4", "number"],
26
- ["interval", ""],
27
- ["json", "string"],
28
- ["jsonb", "Array"],
29
- ["line", ""],
30
- ["lseg", ""],
31
- ["macaddr", "string"],
32
- ["macaddr8", "string"],
33
- ["money", "number"],
34
- ["numeric", "number"],
35
- ["decimal", "number"],
36
- ["path", ""],
37
- ["pg_lsn", "number"],
38
- ["pg_snapshot", ""],
39
- ["point", ""],
40
- ["polygon", ""],
6
+ ["bigint", "string"],
7
+ ["int8", "string"],
41
8
  ["real", "number"],
42
9
  ["float4", "number"],
43
- ["smallint", "number"],
44
- ["int2", "number"],
10
+ ["double precision", "number"],
11
+ ["float8", "string"],
12
+ ["numeric", "string"],
13
+ ["decimal", "string"],
14
+ ["money", "string"],
45
15
  ["smallserial", "number"],
46
16
  ["serial2", "number"],
47
17
  ["serial", "number"],
48
- ["string4", "number"],
18
+ ["serial4", "number"],
19
+ ["bigserial", "string"],
20
+ ["serial8", "string"],
21
+ ["character", "string"],
22
+ ["char", "string"],
23
+ ["character varying", "string"],
24
+ ["varchar", "string"],
49
25
  ["text", "string"],
50
- ["time", ""],
51
- ["time without time zone", ""],
52
- ["time with time zone", ""],
53
- ["timetz", ""],
54
- ["timestamp", "Date"],
26
+ ["name", "string"],
27
+ ["bytea", "Buffer"],
28
+ ["bit", "string"],
29
+ ["bit varying", "string"],
30
+ ["varbit", "string"],
31
+ ["boolean", "boolean"],
32
+ ["bool", "boolean"],
33
+ ["date", "Date"],
34
+ ["time without time zone", "string"],
35
+ ["time", "string"],
36
+ ["time with time zone", "string"],
37
+ ["timetz", "string"],
55
38
  ["timestamp without time zone", "Date"],
39
+ ["timestamp", "Date"],
56
40
  ["timestamp with time zone", "Date"],
57
41
  ["timestamptz", "Date"],
58
- ["tsquery", ""],
59
- ["tsvector", ""],
60
- ["txid_snapshot", ""],
42
+ ["interval", "object"],
43
+ ["box", "object"],
44
+ ["circle", "object"],
45
+ ["line", "object"],
46
+ ["lseg", "object"],
47
+ ["path", "object"],
48
+ ["point", "object"],
49
+ ["polygon", "object"],
50
+ ["cidr", "string"],
51
+ ["inet", "string"],
52
+ ["macaddr", "string"],
53
+ ["macaddr8", "string"],
54
+ ["json", "object"],
55
+ ["jsonb", "object"],
61
56
  ["uuid", "string"],
57
+ ["tsquery", "string"],
58
+ ["tsvector", "string"],
59
+ ["pg_lsn", "string"],
60
+ ["pg_snapshot", "string"],
61
+ ["txid_snapshot", "string"],
62
62
  ["xml", "string"],
63
63
  ]);
64
64
  export const udtTypes = new Map([
@@ -83,6 +83,7 @@ export const udtTypes = new Map([
83
83
  ["character varying", "varchar"],
84
84
  ["varchar", "varchar"],
85
85
  ["text", "text"],
86
+ ["name", "name"],
86
87
  ["bytea", "bytea"],
87
88
  ["bit", "bit"],
88
89
  ["bit varying", "varbit"],
package/src/pgAdmin.js CHANGED
@@ -1,5 +1,5 @@
1
- import { ColumnQueryRow, ForeignKeyQueryRow, PigeonError, PrimaryKeyQueryRow, Table, UniqueQueryRow } from "./index.js";
2
- import { udtTypes } from "./maps.js";
1
+ import { Column, PigeonError, Table, } from "./index.js";
2
+ import { getJSType, getPGType, getTypesByDataType } from "./utils.js";
3
3
  function objectToArray(json) {
4
4
  let arrayJSON = "";
5
5
  let enteredObject = false;
@@ -52,66 +52,57 @@ export function tableProcessing(tables) {
52
52
  const columns = [];
53
53
  let ordinalPossition = 1;
54
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;
55
+ const types = getTypesByDataType(column.cltype);
56
+ let isNullable = true;
75
57
  if (column.attnotnull)
76
- isNullable = "NO";
77
- else
78
- isNullable = "YES";
58
+ isNullable = false;
59
+ const jsType = getJSType(types.dataType, types.udtName, isNullable);
60
+ const pgType = getPGType(types.dataType);
61
+ if (column.cltype.includes("serial"))
62
+ column.defval = "nextval('" + data.name + "_" + column.name + "_seq'::regclass)";
79
63
  let columnDefault;
80
64
  if (column.defval !== "" && column.defval !== undefined)
81
65
  columnDefault = column.defval;
82
66
  else
83
67
  columnDefault = null;
84
- let identity;
68
+ let identity = false;
85
69
  if (column.colconstype === "i")
86
- identity = "YES";
87
- else
88
- identity = "NO";
70
+ identity = true;
89
71
  let identityGeneration = null;
90
- if (identity === "YES") {
72
+ if (identity) {
91
73
  if (column.attidentity === "a")
92
74
  identityGeneration = "ALWAYS";
93
75
  if (column.attidentity === "b")
94
76
  identityGeneration = "BY DEFAULT";
95
77
  }
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));
78
+ let isPrimary = false;
79
+ if (column.name === data.primary_key[0].columns[0].column)
80
+ isPrimary = true;
81
+ let isForeign = false;
82
+ let foreignSchema = undefined;
83
+ let foreignTable = undefined;
84
+ let foreignColumn = undefined;
85
+ for (const foreignKey of data.foreign_key) {
86
+ for (const foreignKeyColumn of foreignKey.columns) {
87
+ if (foreignKeyColumn.local_column === column.name) {
88
+ isForeign = true;
89
+ const match = foreignKeyColumn.references_table_name.match(/(?:\((.*?)\))? ?(.*)/);
90
+ foreignSchema = match[1] || data.schema;
91
+ foreignTable = match[2];
92
+ foreignColumn = foreignKeyColumn.referenced;
93
+ }
94
+ }
107
95
  }
96
+ let isUnique = false;
97
+ if (data.unique_constraint)
98
+ for (const uniqueConstraint of data.unique_constraint)
99
+ for (const uniqueColumn of uniqueConstraint.columns)
100
+ if (uniqueColumn.column === column.name)
101
+ isUnique = true;
102
+ columns.push(new Column(column.name, ordinalPossition, columnDefault, isNullable, jsType, pgType, identity, identityGeneration, isPrimary, isUnique, isForeign, foreignSchema, foreignTable, foreignColumn));
103
+ ordinalPossition++;
108
104
  }
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)));
105
+ pigeonTables.push(new Table(data.name, data.schema, columns));
115
106
  }
116
107
  return pigeonTables;
117
108
  }
package/src/utils.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import pg from "pg";
2
- import { jsTypes } from "./maps.js";
2
+ import { jsTypes, udtTypes } from "./maps.js";
3
3
  const { Client } = pg;
4
4
  export async function runQuery(command, parameters, db) {
5
5
  const client = new Client({
@@ -85,7 +85,7 @@ export function queryMaker(baseTabs, variableName, command, parameters) {
85
85
  return query;
86
86
  }
87
87
  function queryBeautifier(baseTabs, command) {
88
- const regex = /(?=((?:SELECT|INSERT|FROM|WHERE|AND|VALUES|RETURNING).*?)(?:FROM|WHERE|AND|VALUES|RETURNING|;))/g;
88
+ const regex = /(?=((?:SELECT|INSERT|UPDATE|DELETE|FROM|WHERE|AND|VALUES|RETURNING).*?)(?:FROM|WHERE|AND|VALUES|RETURNING|;))/g;
89
89
  let match;
90
90
  let lines = [];
91
91
  while ((match = regex.exec(command)) !== null) {
@@ -114,7 +114,7 @@ export function arrayMaker(baseTabs, variableName, className, columns) {
114
114
  array += tabsInserter(baseTabs) + "for (const row of " + variableName + "Query.rows)\n";
115
115
  array += tabsInserter(baseTabs + 1) + variableName + ".push(new " + className + "(\n";
116
116
  for (const column of columns)
117
- array += tabsInserter(baseTabs + 2) + "row." + column.column_name + ",\n";
117
+ array += tabsInserter(baseTabs + 2) + "row." + column.name + ",\n";
118
118
  array = array.slice(0, -2) + "\n";
119
119
  array += tabsInserter(baseTabs + 1) + "));";
120
120
  return array;
@@ -146,7 +146,10 @@ export function getCombinations(valuesArray) {
146
146
  combinations.sort((a, b) => a.length - b.length);
147
147
  return combinations;
148
148
  }
149
- export function getType(dataType, udtName) {
149
+ export function getJSType(dataType, udtName, isNullable) {
150
+ dataType = dataType.replace("serial", "int");
151
+ if (dataType === "int")
152
+ dataType = "integer";
150
153
  let isArray = false;
151
154
  if (dataType === "ARRAY") {
152
155
  dataType = udtName.slice(1);
@@ -157,5 +160,40 @@ export function getType(dataType, udtName) {
157
160
  foundDataType = nameBeautifier(udtName).replaceAll(" ", "");
158
161
  if (isArray)
159
162
  foundDataType += "[]";
163
+ if (isNullable)
164
+ foundDataType += " | null";
160
165
  return foundDataType;
161
166
  }
167
+ export function getTypesByDataType(dataType) {
168
+ let udtName;
169
+ udtName = udtTypes.get(dataType);
170
+ if (!udtName) {
171
+ if (dataType.endsWith("[]")) {
172
+ udtName = "_" + udtTypes.get(dataType.slice(0, -2));
173
+ dataType = "ARRAY";
174
+ }
175
+ else {
176
+ udtName = dataType;
177
+ dataType = "USER-DEFINED";
178
+ }
179
+ }
180
+ return {
181
+ dataType: dataType,
182
+ udtName: udtName
183
+ };
184
+ }
185
+ export function getPGType(dataType, udtName) {
186
+ if (!udtName) {
187
+ const types = getTypesByDataType(dataType);
188
+ udtName = types.udtName;
189
+ }
190
+ dataType = dataType.replace("serial", "int");
191
+ if (dataType === "int")
192
+ dataType = "integer";
193
+ let pgType = udtName;
194
+ if (dataType.endsWith("[]") || dataType === "ARRAY")
195
+ pgType = (udtTypes.get(pgType.slice(1)) || pgType.slice(1)) + "[]";
196
+ else if (dataType !== "USER-DEFINED")
197
+ pgType = dataType;
198
+ return pgType;
199
+ }