@strapi/database 5.47.1 → 5.48.1

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 (44) hide show
  1. package/dist/dialects/mysql/schema-inspector.d.ts +3 -0
  2. package/dist/dialects/mysql/schema-inspector.d.ts.map +1 -1
  3. package/dist/dialects/mysql/schema-inspector.js +145 -85
  4. package/dist/dialects/mysql/schema-inspector.js.map +1 -1
  5. package/dist/dialects/mysql/schema-inspector.mjs +145 -85
  6. package/dist/dialects/mysql/schema-inspector.mjs.map +1 -1
  7. package/dist/dialects/postgresql/schema-inspector.d.ts +3 -1
  8. package/dist/dialects/postgresql/schema-inspector.d.ts.map +1 -1
  9. package/dist/dialects/postgresql/schema-inspector.js +150 -109
  10. package/dist/dialects/postgresql/schema-inspector.js.map +1 -1
  11. package/dist/dialects/postgresql/schema-inspector.mjs +150 -109
  12. package/dist/dialects/postgresql/schema-inspector.mjs.map +1 -1
  13. package/dist/fields/biginteger.d.ts +4 -2
  14. package/dist/fields/biginteger.d.ts.map +1 -1
  15. package/dist/fields/biginteger.js +41 -2
  16. package/dist/fields/biginteger.js.map +1 -1
  17. package/dist/fields/biginteger.mjs +41 -2
  18. package/dist/fields/biginteger.mjs.map +1 -1
  19. package/dist/fields/number.d.ts +1 -1
  20. package/dist/fields/number.d.ts.map +1 -1
  21. package/dist/fields/number.js +20 -4
  22. package/dist/fields/number.js.map +1 -1
  23. package/dist/fields/number.mjs +20 -4
  24. package/dist/fields/number.mjs.map +1 -1
  25. package/dist/index.d.ts +7 -0
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/index.js.map +1 -1
  28. package/dist/index.mjs.map +1 -1
  29. package/dist/migrations/internal-migrations/5.0.0-06-add-document-id-indexes.d.ts +5 -0
  30. package/dist/migrations/internal-migrations/5.0.0-06-add-document-id-indexes.d.ts.map +1 -1
  31. package/dist/migrations/internal-migrations/5.0.0-06-add-document-id-indexes.js +7 -58
  32. package/dist/migrations/internal-migrations/5.0.0-06-add-document-id-indexes.js.map +1 -1
  33. package/dist/migrations/internal-migrations/5.0.0-06-add-document-id-indexes.mjs +7 -58
  34. package/dist/migrations/internal-migrations/5.0.0-06-add-document-id-indexes.mjs.map +1 -1
  35. package/dist/query/helpers/populate/apply.js +1 -1
  36. package/dist/query/helpers/populate/apply.js.map +1 -1
  37. package/dist/query/helpers/populate/apply.mjs +1 -1
  38. package/dist/query/helpers/populate/apply.mjs.map +1 -1
  39. package/dist/transaction-context.d.ts.map +1 -1
  40. package/dist/transaction-context.js +22 -0
  41. package/dist/transaction-context.js.map +1 -1
  42. package/dist/transaction-context.mjs +22 -0
  43. package/dist/transaction-context.mjs.map +1 -1
  44. package/package.json +5 -5
@@ -10,13 +10,14 @@ const SQL_QUERIES = {
10
10
  AND table_name != 'geometry_columns'
11
11
  AND table_name != 'spatial_ref_sys';
12
12
  `,
13
- LIST_COLUMNS: /* sql */ `
14
- SELECT data_type, column_name, character_maximum_length, column_default, is_nullable
13
+ BULK_COLUMNS: /* sql */ `
14
+ SELECT table_name, data_type, column_name, character_maximum_length, column_default, is_nullable
15
15
  FROM information_schema.columns
16
- WHERE table_schema = ? AND table_name = ?;
16
+ WHERE table_schema = ? AND table_name = ANY(?);
17
17
  `,
18
- INDEX_LIST: /* sql */ `
18
+ BULK_INDEXES: /* sql */ `
19
19
  SELECT
20
+ t.relname as table_name,
20
21
  ix.indexrelid,
21
22
  i.relname as index_name,
22
23
  a.attname as column_name,
@@ -36,44 +37,42 @@ const SQL_QUERIES = {
36
37
  AND t.relkind = 'r'
37
38
  AND t.relnamespace = s.oid
38
39
  AND s.nspname = ?
39
- AND t.relname = ?;
40
+ AND t.relname = ANY(?);
40
41
  `,
41
- FOREIGN_KEY_LIST: /* sql */ `
42
+ BULK_FOREIGN_KEYS: /* sql */ `
42
43
  SELECT
43
- tco."constraint_name" as constraint_name
44
- FROM information_schema.table_constraints tco
45
- WHERE
46
- tco.constraint_type = 'FOREIGN KEY'
47
- AND tco.constraint_schema = ?
48
- AND tco.table_name = ?
49
- `,
50
- FOREIGN_KEY_REFERENCES: /* sql */ `
51
- SELECT
52
- kcu."constraint_name" as constraint_name,
53
- kcu."column_name" as column_name
54
-
55
- FROM information_schema.key_column_usage kcu
56
- WHERE kcu.constraint_name=ANY(?)
57
- AND kcu.table_schema = ?
58
- AND kcu.table_name = ?;
59
- `,
60
- FOREIGN_KEY_REFERENCES_CONSTRAIN: /* sql */ `
61
- SELECT
62
- rco.update_rule as on_update,
63
- rco.delete_rule as on_delete,
64
- rco."unique_constraint_name" as unique_constraint_name
65
- FROM information_schema.referential_constraints rco
66
- WHERE rco.constraint_name=ANY(?)
67
- AND rco.constraint_schema = ?
68
- `,
69
- FOREIGN_KEY_REFERENCES_CONSTRAIN_RFERENCE: /* sql */ `
70
- SELECT
71
- rel_kcu."table_name" as foreign_table,
72
- rel_kcu."column_name" as fk_column_name
73
- FROM information_schema.key_column_usage rel_kcu
74
- WHERE rel_kcu.constraint_name=?
75
- AND rel_kcu.table_schema = ?
76
- `
44
+ cl.relname AS table_name,
45
+ c.conname AS constraint_name,
46
+ att.attname AS column_name,
47
+ fcl.relname AS foreign_table,
48
+ fatt.attname AS fk_column_name,
49
+ CASE c.confupdtype
50
+ WHEN 'a' THEN 'NO ACTION'
51
+ WHEN 'r' THEN 'RESTRICT'
52
+ WHEN 'c' THEN 'CASCADE'
53
+ WHEN 'n' THEN 'SET NULL'
54
+ WHEN 'd' THEN 'SET DEFAULT'
55
+ END AS on_update,
56
+ CASE c.confdeltype
57
+ WHEN 'a' THEN 'NO ACTION'
58
+ WHEN 'r' THEN 'RESTRICT'
59
+ WHEN 'c' THEN 'CASCADE'
60
+ WHEN 'n' THEN 'SET NULL'
61
+ WHEN 'd' THEN 'SET DEFAULT'
62
+ END AS on_delete
63
+ FROM pg_constraint c
64
+ JOIN pg_class cl ON cl.oid = c.conrelid
65
+ JOIN pg_namespace n ON n.oid = cl.relnamespace
66
+ JOIN pg_class fcl ON fcl.oid = c.confrelid
67
+ JOIN LATERAL unnest(c.conkey, c.confkey) AS cols(conkey, confkey) ON true
68
+ JOIN pg_attribute att ON att.attrelid = c.conrelid AND att.attnum = cols.conkey
69
+ JOIN pg_attribute fatt ON fatt.attrelid = c.confrelid AND fatt.attnum = cols.confkey
70
+ WHERE c.contype = 'f'
71
+ AND n.nspname = ?
72
+ AND cl.relname = ANY(?)
73
+ AND fcl.relnamespace = cl.relnamespace
74
+ ORDER BY cl.relname, c.conname, cols.conkey;
75
+ `
77
76
  };
78
77
  const toStrapiType = (column)=>{
79
78
  const rootType = column.data_type.toLowerCase().match(/[^(), ]+/)?.[0];
@@ -191,18 +190,23 @@ class PostgresqlSchemaInspector {
191
190
  const schema = {
192
191
  tables: []
193
192
  };
193
+ const dbSchema = this.getDatabaseSchema();
194
194
  const tables = await this.getTables();
195
- schema.tables = await Promise.all(tables.map(async (tableName)=>{
196
- const columns = await this.getColumns(tableName);
197
- const indexes = await this.getIndexes(tableName);
198
- const foreignKeys = await this.getForeignKeys(tableName);
199
- return {
195
+ if (tables.length === 0) {
196
+ return schema;
197
+ }
198
+ // Run 3 bulk queries in parallel instead of N+1 per-table queries
199
+ const [allColumns, allIndexes, allForeignKeys] = await Promise.all([
200
+ this.getBulkColumns(dbSchema, tables),
201
+ this.getBulkIndexes(dbSchema, tables),
202
+ this.getBulkForeignKeys(dbSchema, tables)
203
+ ]);
204
+ schema.tables = tables.map((tableName)=>({
200
205
  name: tableName,
201
- columns,
202
- indexes,
203
- foreignKeys
204
- };
205
- }));
206
+ columns: allColumns.get(tableName) ?? [],
207
+ indexes: allIndexes.get(tableName) ?? [],
208
+ foreignKeys: allForeignKeys.get(tableName) ?? []
209
+ }));
206
210
  return schema;
207
211
  }
208
212
  getDatabaseSchema() {
@@ -214,15 +218,19 @@ class PostgresqlSchemaInspector {
214
218
  ]);
215
219
  return rows.map((row)=>row.table_name);
216
220
  }
217
- async getColumns(tableName) {
218
- const { rows } = await this.db.connection.raw(SQL_QUERIES.LIST_COLUMNS, [
219
- this.getDatabaseSchema(),
220
- tableName
221
+ async getBulkColumns(dbSchema, tableNames) {
222
+ if (tableNames.length === 0) {
223
+ return new Map();
224
+ }
225
+ const { rows } = await this.db.connection.raw(SQL_QUERIES.BULK_COLUMNS, [
226
+ dbSchema,
227
+ tableNames
221
228
  ]);
222
- return rows.map((row)=>{
229
+ const result = new Map();
230
+ for (const row of rows){
223
231
  const { type, args = [], ...rest } = toStrapiType(row);
224
232
  const defaultTo = row.column_default && row.column_default.includes('nextval(') ? null : row.column_default;
225
- return {
233
+ const column = {
226
234
  type,
227
235
  args,
228
236
  defaultTo,
@@ -231,81 +239,114 @@ class PostgresqlSchemaInspector {
231
239
  unsigned: false,
232
240
  ...rest
233
241
  };
234
- });
242
+ const existing = result.get(row.table_name);
243
+ if (existing) {
244
+ existing.push(column);
245
+ } else {
246
+ result.set(row.table_name, [
247
+ column
248
+ ]);
249
+ }
250
+ }
251
+ return result;
235
252
  }
236
- async getIndexes(tableName) {
237
- const { rows } = await this.db.connection.raw(SQL_QUERIES.INDEX_LIST, [
238
- this.getDatabaseSchema(),
239
- tableName
253
+ async getBulkIndexes(dbSchema, tableNames) {
254
+ if (tableNames.length === 0) {
255
+ return new Map();
256
+ }
257
+ const { rows } = await this.db.connection.raw(SQL_QUERIES.BULK_INDEXES, [
258
+ dbSchema,
259
+ tableNames
240
260
  ]);
241
- const ret = {};
261
+ // Group by table, then by indexrelid
262
+ const byTable = new Map();
242
263
  for (const index of rows){
243
264
  if (index.column_name === 'id') {
244
265
  continue;
245
266
  }
246
- if (!ret[index.indexrelid]) {
247
- ret[index.indexrelid] = {
267
+ let tableIndexes = byTable.get(index.table_name);
268
+ if (!tableIndexes) {
269
+ tableIndexes = new Map();
270
+ byTable.set(index.table_name, tableIndexes);
271
+ }
272
+ const existing = tableIndexes.get(index.indexrelid);
273
+ if (existing) {
274
+ existing.columns.push(index.column_name);
275
+ } else {
276
+ tableIndexes.set(index.indexrelid, {
248
277
  columns: [
249
278
  index.column_name
250
279
  ],
251
280
  name: index.index_name,
252
281
  type: getIndexType(index)
253
- };
254
- } else {
255
- ret[index.indexrelid].columns.push(index.column_name);
282
+ });
256
283
  }
257
284
  }
258
- return Object.values(ret);
285
+ const result = new Map();
286
+ for (const [tableName, tableIndexes] of byTable){
287
+ result.set(tableName, Array.from(tableIndexes.values()));
288
+ }
289
+ return result;
290
+ }
291
+ async getIndexes(tableName) {
292
+ const dbSchema = this.getDatabaseSchema();
293
+ const result = await this.getBulkIndexes(dbSchema, [
294
+ tableName
295
+ ]);
296
+ return result.get(tableName) ?? [];
259
297
  }
260
298
  async getForeignKeys(tableName) {
261
- const { rows } = await this.db.connection.raw(SQL_QUERIES.FOREIGN_KEY_LIST, [
262
- this.getDatabaseSchema(),
299
+ const dbSchema = this.getDatabaseSchema();
300
+ const result = await this.getBulkForeignKeys(dbSchema, [
263
301
  tableName
264
302
  ]);
265
- const ret = {};
266
- for (const fk of rows){
267
- ret[fk.constraint_name] = {
268
- name: fk.constraint_name,
269
- columns: [],
270
- referencedColumns: [],
271
- referencedTable: null,
272
- onUpdate: null,
273
- onDelete: null
274
- };
303
+ return result.get(tableName) ?? [];
304
+ }
305
+ async getBulkForeignKeys(dbSchema, tableNames) {
306
+ if (tableNames.length === 0) {
307
+ return new Map();
275
308
  }
276
- const constraintNames = Object.keys(ret);
277
- const dbSchema = this.getDatabaseSchema();
278
- if (constraintNames.length > 0) {
279
- const { rows: fkReferences } = await this.db.connection.raw(SQL_QUERIES.FOREIGN_KEY_REFERENCES, [
280
- [
281
- constraintNames
282
- ],
283
- dbSchema,
284
- tableName
285
- ]);
286
- for (const fkReference of fkReferences){
287
- ret[fkReference.constraint_name].columns.push(fkReference.column_name);
288
- const { rows: fkReferencesConstraint } = await this.db.connection.raw(SQL_QUERIES.FOREIGN_KEY_REFERENCES_CONSTRAIN, [
289
- [
290
- fkReference.constraint_name
309
+ const { rows } = await this.db.connection.raw(SQL_QUERIES.BULK_FOREIGN_KEYS, [
310
+ dbSchema,
311
+ tableNames
312
+ ]);
313
+ // Group by table_name, then by constraint_name
314
+ const byTable = new Map();
315
+ for (const row of rows){
316
+ let tableFKs = byTable.get(row.table_name);
317
+ if (!tableFKs) {
318
+ tableFKs = new Map();
319
+ byTable.set(row.table_name, tableFKs);
320
+ }
321
+ let fk = tableFKs.get(row.constraint_name);
322
+ if (!fk) {
323
+ fk = {
324
+ name: row.constraint_name,
325
+ columns: [
326
+ row.column_name
291
327
  ],
292
- dbSchema
293
- ]);
294
- for (const fkReferenceC of fkReferencesConstraint){
295
- const { rows: fkReferencesConstraintReferece } = await this.db.connection.raw(SQL_QUERIES.FOREIGN_KEY_REFERENCES_CONSTRAIN_RFERENCE, [
296
- fkReferenceC.unique_constraint_name,
297
- dbSchema
298
- ]);
299
- for (const fkReferenceConst of fkReferencesConstraintReferece){
300
- ret[fkReference.constraint_name].referencedTable = fkReferenceConst.foreign_table;
301
- ret[fkReference.constraint_name].referencedColumns.push(fkReferenceConst.fk_column_name);
302
- }
303
- ret[fkReference.constraint_name].onUpdate = fkReferenceC.on_update.toUpperCase();
304
- ret[fkReference.constraint_name].onDelete = fkReferenceC.on_delete.toUpperCase();
328
+ referencedColumns: [
329
+ row.fk_column_name
330
+ ],
331
+ referencedTable: row.foreign_table,
332
+ onUpdate: row.on_update?.toUpperCase() ?? null,
333
+ onDelete: row.on_delete?.toUpperCase() ?? null
334
+ };
335
+ tableFKs.set(row.constraint_name, fk);
336
+ } else {
337
+ if (!fk.columns.includes(row.column_name)) {
338
+ fk.columns.push(row.column_name);
339
+ }
340
+ if (!fk.referencedColumns.includes(row.fk_column_name)) {
341
+ fk.referencedColumns.push(row.fk_column_name);
305
342
  }
306
343
  }
307
344
  }
308
- return Object.values(ret);
345
+ const result = new Map();
346
+ for (const [tableName, tableFKs] of byTable){
347
+ result.set(tableName, Array.from(tableFKs.values()));
348
+ }
349
+ return result;
309
350
  }
310
351
  constructor(db){
311
352
  this.db = db;
@@ -1 +1 @@
1
- {"version":3,"file":"schema-inspector.js","sources":["../../../src/dialects/postgresql/schema-inspector.ts"],"sourcesContent":["import type { Database } from '../..';\nimport type { Schema, Column, Index, ForeignKey } from '../../schema/types';\nimport type { SchemaInspector } from '../dialect';\n\ninterface RawTable {\n table_name: string;\n}\n\ninterface RawColumn {\n data_type: string;\n column_name: string;\n character_maximum_length: number;\n column_default: string;\n is_nullable: string;\n}\n\ninterface RawIndex {\n indexrelid: string;\n index_name: string;\n column_name: string;\n is_unique: boolean;\n is_primary: boolean;\n}\n\ninterface RawForeignKey {\n constraint_name: string;\n}\n\nconst SQL_QUERIES = {\n TABLE_LIST: /* sql */ `\n SELECT *\n FROM information_schema.tables\n WHERE\n table_schema = ?\n AND table_type = 'BASE TABLE'\n AND table_name != 'geometry_columns'\n AND table_name != 'spatial_ref_sys';\n `,\n LIST_COLUMNS: /* sql */ `\n SELECT data_type, column_name, character_maximum_length, column_default, is_nullable\n FROM information_schema.columns\n WHERE table_schema = ? AND table_name = ?;\n `,\n INDEX_LIST: /* sql */ `\n SELECT\n ix.indexrelid,\n i.relname as index_name,\n a.attname as column_name,\n ix.indisunique as is_unique,\n ix.indisprimary as is_primary\n FROM\n pg_class t,\n pg_namespace s,\n pg_class i,\n pg_index ix,\n pg_attribute a\n WHERE\n t.oid = ix.indrelid\n AND i.oid = ix.indexrelid\n AND a.attrelid = t.oid\n AND a.attnum = ANY(ix.indkey)\n AND t.relkind = 'r'\n AND t.relnamespace = s.oid\n AND s.nspname = ?\n AND t.relname = ?;\n `,\n FOREIGN_KEY_LIST: /* sql */ `\n SELECT\n tco.\"constraint_name\" as constraint_name\n FROM information_schema.table_constraints tco\n WHERE\n tco.constraint_type = 'FOREIGN KEY'\n AND tco.constraint_schema = ?\n AND tco.table_name = ?\n `,\n FOREIGN_KEY_REFERENCES: /* sql */ `\n SELECT\n kcu.\"constraint_name\" as constraint_name,\n kcu.\"column_name\" as column_name\n\n FROM information_schema.key_column_usage kcu\n WHERE kcu.constraint_name=ANY(?)\n AND kcu.table_schema = ?\n AND kcu.table_name = ?;\n `,\n\n FOREIGN_KEY_REFERENCES_CONSTRAIN: /* sql */ `\n SELECT\n rco.update_rule as on_update,\n rco.delete_rule as on_delete,\n rco.\"unique_constraint_name\" as unique_constraint_name\n FROM information_schema.referential_constraints rco\n WHERE rco.constraint_name=ANY(?)\n AND rco.constraint_schema = ?\n`,\n FOREIGN_KEY_REFERENCES_CONSTRAIN_RFERENCE: /* sql */ `\n SELECT\n rel_kcu.\"table_name\" as foreign_table,\n rel_kcu.\"column_name\" as fk_column_name\n FROM information_schema.key_column_usage rel_kcu\n WHERE rel_kcu.constraint_name=?\n AND rel_kcu.table_schema = ?\n`,\n};\n\nconst toStrapiType = (column: RawColumn) => {\n const rootType = column.data_type.toLowerCase().match(/[^(), ]+/)?.[0];\n\n switch (rootType) {\n case 'integer': {\n // find a way to figure out the increments\n return { type: 'integer' };\n }\n case 'text': {\n return { type: 'text', args: ['longtext'] };\n }\n case 'boolean': {\n return { type: 'boolean' };\n }\n case 'character': {\n return { type: 'string', args: [column.character_maximum_length] };\n }\n case 'timestamp': {\n return { type: 'datetime', args: [{ useTz: false, precision: 6 }] };\n }\n case 'date': {\n return { type: 'date' };\n }\n case 'time': {\n return { type: 'time', args: [{ precision: 3 }] };\n }\n case 'numeric': {\n return { type: 'decimal', args: [10, 2] };\n }\n case 'real':\n case 'double': {\n return { type: 'double' };\n }\n case 'bigint': {\n return { type: 'bigInteger' };\n }\n case 'jsonb': {\n return { type: 'jsonb' };\n }\n default: {\n return { type: 'specificType', args: [column.data_type] };\n }\n }\n};\n\nconst getIndexType = (index: RawIndex) => {\n if (index.is_primary) {\n return 'primary';\n }\n\n if (index.is_unique) {\n return 'unique';\n }\n};\n\nexport default class PostgresqlSchemaInspector implements SchemaInspector {\n db: Database;\n\n constructor(db: Database) {\n this.db = db;\n }\n\n async getSchema() {\n const schema: Schema = { tables: [] };\n\n const tables = await this.getTables();\n\n schema.tables = await Promise.all(\n tables.map(async (tableName) => {\n const columns = await this.getColumns(tableName);\n const indexes = await this.getIndexes(tableName);\n const foreignKeys = await this.getForeignKeys(tableName);\n\n return {\n name: tableName,\n columns,\n indexes,\n foreignKeys,\n };\n })\n );\n\n return schema;\n }\n\n getDatabaseSchema(): string {\n return this.db.getSchemaName() || 'public';\n }\n\n async getTables(): Promise<string[]> {\n const { rows } = await this.db.connection.raw<{ rows: RawTable[] }>(SQL_QUERIES.TABLE_LIST, [\n this.getDatabaseSchema(),\n ]);\n\n return rows.map((row) => row.table_name);\n }\n\n async getColumns(tableName: string): Promise<Column[]> {\n const { rows } = await this.db.connection.raw<{ rows: RawColumn[] }>(SQL_QUERIES.LIST_COLUMNS, [\n this.getDatabaseSchema(),\n tableName,\n ]);\n\n return rows.map((row) => {\n const { type, args = [], ...rest } = toStrapiType(row);\n\n const defaultTo =\n row.column_default && row.column_default.includes('nextval(') ? null : row.column_default;\n\n return {\n type,\n args,\n defaultTo,\n name: row.column_name,\n notNullable: row.is_nullable === 'NO',\n unsigned: false,\n ...rest,\n };\n });\n }\n\n async getIndexes(tableName: string): Promise<Index[]> {\n const { rows } = await this.db.connection.raw<{ rows: RawIndex[] }>(SQL_QUERIES.INDEX_LIST, [\n this.getDatabaseSchema(),\n tableName,\n ]);\n\n const ret: Record<RawIndex['indexrelid'], Index> = {};\n\n for (const index of rows) {\n if (index.column_name === 'id') {\n continue;\n }\n\n if (!ret[index.indexrelid]) {\n ret[index.indexrelid] = {\n columns: [index.column_name],\n name: index.index_name,\n type: getIndexType(index),\n };\n } else {\n ret[index.indexrelid].columns.push(index.column_name);\n }\n }\n\n return Object.values(ret);\n }\n\n async getForeignKeys(tableName: string): Promise<ForeignKey[]> {\n const { rows } = await this.db.connection.raw<{ rows: RawForeignKey[] }>(\n SQL_QUERIES.FOREIGN_KEY_LIST,\n [this.getDatabaseSchema(), tableName]\n );\n\n const ret: Record<RawForeignKey['constraint_name'], ForeignKey> = {};\n\n for (const fk of rows) {\n ret[fk.constraint_name] = {\n name: fk.constraint_name,\n columns: [],\n referencedColumns: [],\n referencedTable: null,\n onUpdate: null,\n onDelete: null,\n } as unknown as ForeignKey;\n }\n\n const constraintNames = Object.keys(ret);\n const dbSchema = this.getDatabaseSchema();\n if (constraintNames.length > 0) {\n const { rows: fkReferences } = await this.db.connection.raw(\n SQL_QUERIES.FOREIGN_KEY_REFERENCES,\n [[constraintNames], dbSchema, tableName]\n );\n\n for (const fkReference of fkReferences) {\n ret[fkReference.constraint_name].columns.push(fkReference.column_name);\n\n const { rows: fkReferencesConstraint } = await this.db.connection.raw(\n SQL_QUERIES.FOREIGN_KEY_REFERENCES_CONSTRAIN,\n [[fkReference.constraint_name], dbSchema]\n );\n\n for (const fkReferenceC of fkReferencesConstraint) {\n const { rows: fkReferencesConstraintReferece } = await this.db.connection.raw(\n SQL_QUERIES.FOREIGN_KEY_REFERENCES_CONSTRAIN_RFERENCE,\n [fkReferenceC.unique_constraint_name, dbSchema]\n );\n for (const fkReferenceConst of fkReferencesConstraintReferece) {\n ret[fkReference.constraint_name].referencedTable = fkReferenceConst.foreign_table;\n ret[fkReference.constraint_name].referencedColumns.push(\n fkReferenceConst.fk_column_name\n );\n }\n ret[fkReference.constraint_name].onUpdate = fkReferenceC.on_update.toUpperCase();\n ret[fkReference.constraint_name].onDelete = fkReferenceC.on_delete.toUpperCase();\n }\n }\n }\n\n return Object.values(ret);\n }\n}\n"],"names":["SQL_QUERIES","TABLE_LIST","LIST_COLUMNS","INDEX_LIST","FOREIGN_KEY_LIST","FOREIGN_KEY_REFERENCES","FOREIGN_KEY_REFERENCES_CONSTRAIN","FOREIGN_KEY_REFERENCES_CONSTRAIN_RFERENCE","toStrapiType","column","rootType","data_type","toLowerCase","match","type","args","character_maximum_length","useTz","precision","getIndexType","index","is_primary","is_unique","PostgresqlSchemaInspector","getSchema","schema","tables","getTables","Promise","all","map","tableName","columns","getColumns","indexes","getIndexes","foreignKeys","getForeignKeys","name","getDatabaseSchema","db","getSchemaName","rows","connection","raw","row","table_name","rest","defaultTo","column_default","includes","column_name","notNullable","is_nullable","unsigned","ret","indexrelid","index_name","push","Object","values","fk","constraint_name","referencedColumns","referencedTable","onUpdate","onDelete","constraintNames","keys","dbSchema","length","fkReferences","fkReference","fkReferencesConstraint","fkReferenceC","fkReferencesConstraintReferece","unique_constraint_name","fkReferenceConst","foreign_table","fk_column_name","on_update","toUpperCase","on_delete"],"mappings":"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"}
1
+ {"version":3,"file":"schema-inspector.js","sources":["../../../src/dialects/postgresql/schema-inspector.ts"],"sourcesContent":["import type { Database } from '../..';\nimport type { Schema, Column, Index, ForeignKey } from '../../schema/types';\nimport type { SchemaInspector } from '../dialect';\n\ninterface RawColumn {\n table_name: string;\n data_type: string;\n column_name: string;\n character_maximum_length: number;\n column_default: string;\n is_nullable: string;\n}\n\ninterface RawIndex {\n table_name: string;\n indexrelid: string;\n index_name: string;\n column_name: string;\n is_unique: boolean;\n is_primary: boolean;\n}\n\ninterface RawTable {\n table_name: string;\n}\n\nconst SQL_QUERIES = {\n TABLE_LIST: /* sql */ `\n SELECT *\n FROM information_schema.tables\n WHERE\n table_schema = ?\n AND table_type = 'BASE TABLE'\n AND table_name != 'geometry_columns'\n AND table_name != 'spatial_ref_sys';\n `,\n BULK_COLUMNS: /* sql */ `\n SELECT table_name, data_type, column_name, character_maximum_length, column_default, is_nullable\n FROM information_schema.columns\n WHERE table_schema = ? AND table_name = ANY(?);\n `,\n BULK_INDEXES: /* sql */ `\n SELECT\n t.relname as table_name,\n ix.indexrelid,\n i.relname as index_name,\n a.attname as column_name,\n ix.indisunique as is_unique,\n ix.indisprimary as is_primary\n FROM\n pg_class t,\n pg_namespace s,\n pg_class i,\n pg_index ix,\n pg_attribute a\n WHERE\n t.oid = ix.indrelid\n AND i.oid = ix.indexrelid\n AND a.attrelid = t.oid\n AND a.attnum = ANY(ix.indkey)\n AND t.relkind = 'r'\n AND t.relnamespace = s.oid\n AND s.nspname = ?\n AND t.relname = ANY(?);\n `,\n BULK_FOREIGN_KEYS: /* sql */ `\n SELECT\n cl.relname AS table_name,\n c.conname AS constraint_name,\n att.attname AS column_name,\n fcl.relname AS foreign_table,\n fatt.attname AS fk_column_name,\n CASE c.confupdtype\n WHEN 'a' THEN 'NO ACTION'\n WHEN 'r' THEN 'RESTRICT'\n WHEN 'c' THEN 'CASCADE'\n WHEN 'n' THEN 'SET NULL'\n WHEN 'd' THEN 'SET DEFAULT'\n END AS on_update,\n CASE c.confdeltype\n WHEN 'a' THEN 'NO ACTION'\n WHEN 'r' THEN 'RESTRICT'\n WHEN 'c' THEN 'CASCADE'\n WHEN 'n' THEN 'SET NULL'\n WHEN 'd' THEN 'SET DEFAULT'\n END AS on_delete\n FROM pg_constraint c\n JOIN pg_class cl ON cl.oid = c.conrelid\n JOIN pg_namespace n ON n.oid = cl.relnamespace\n JOIN pg_class fcl ON fcl.oid = c.confrelid\n JOIN LATERAL unnest(c.conkey, c.confkey) AS cols(conkey, confkey) ON true\n JOIN pg_attribute att ON att.attrelid = c.conrelid AND att.attnum = cols.conkey\n JOIN pg_attribute fatt ON fatt.attrelid = c.confrelid AND fatt.attnum = cols.confkey\n WHERE c.contype = 'f'\n AND n.nspname = ?\n AND cl.relname = ANY(?)\n AND fcl.relnamespace = cl.relnamespace\n ORDER BY cl.relname, c.conname, cols.conkey;\n `,\n};\n\nconst toStrapiType = (column: RawColumn) => {\n const rootType = column.data_type.toLowerCase().match(/[^(), ]+/)?.[0];\n\n switch (rootType) {\n case 'integer': {\n // find a way to figure out the increments\n return { type: 'integer' };\n }\n case 'text': {\n return { type: 'text', args: ['longtext'] };\n }\n case 'boolean': {\n return { type: 'boolean' };\n }\n case 'character': {\n return { type: 'string', args: [column.character_maximum_length] };\n }\n case 'timestamp': {\n return { type: 'datetime', args: [{ useTz: false, precision: 6 }] };\n }\n case 'date': {\n return { type: 'date' };\n }\n case 'time': {\n return { type: 'time', args: [{ precision: 3 }] };\n }\n case 'numeric': {\n return { type: 'decimal', args: [10, 2] };\n }\n case 'real':\n case 'double': {\n return { type: 'double' };\n }\n case 'bigint': {\n return { type: 'bigInteger' };\n }\n case 'jsonb': {\n return { type: 'jsonb' };\n }\n default: {\n return { type: 'specificType', args: [column.data_type] };\n }\n }\n};\n\nconst getIndexType = (index: RawIndex) => {\n if (index.is_primary) {\n return 'primary';\n }\n\n if (index.is_unique) {\n return 'unique';\n }\n};\n\nexport default class PostgresqlSchemaInspector implements SchemaInspector {\n db: Database;\n\n constructor(db: Database) {\n this.db = db;\n }\n\n async getSchema() {\n const schema: Schema = { tables: [] };\n const dbSchema = this.getDatabaseSchema();\n\n const tables = await this.getTables();\n\n if (tables.length === 0) {\n return schema;\n }\n\n // Run 3 bulk queries in parallel instead of N+1 per-table queries\n const [allColumns, allIndexes, allForeignKeys] = await Promise.all([\n this.getBulkColumns(dbSchema, tables),\n this.getBulkIndexes(dbSchema, tables),\n this.getBulkForeignKeys(dbSchema, tables),\n ]);\n\n schema.tables = tables.map((tableName) => ({\n name: tableName,\n columns: allColumns.get(tableName) ?? [],\n indexes: allIndexes.get(tableName) ?? [],\n foreignKeys: allForeignKeys.get(tableName) ?? [],\n }));\n\n return schema;\n }\n\n getDatabaseSchema(): string {\n return this.db.getSchemaName() || 'public';\n }\n\n async getTables(): Promise<string[]> {\n const { rows } = await this.db.connection.raw<{ rows: RawTable[] }>(SQL_QUERIES.TABLE_LIST, [\n this.getDatabaseSchema(),\n ]);\n\n return rows.map((row) => row.table_name);\n }\n\n async getBulkColumns(dbSchema: string, tableNames: string[]): Promise<Map<string, Column[]>> {\n if (tableNames.length === 0) {\n return new Map();\n }\n\n const { rows } = await this.db.connection.raw<{ rows: RawColumn[] }>(SQL_QUERIES.BULK_COLUMNS, [\n dbSchema,\n tableNames,\n ]);\n\n const result = new Map<string, Column[]>();\n\n for (const row of rows) {\n const { type, args = [], ...rest } = toStrapiType(row);\n const defaultTo =\n row.column_default && row.column_default.includes('nextval(') ? null : row.column_default;\n\n const column: Column = {\n type,\n args,\n defaultTo,\n name: row.column_name,\n notNullable: row.is_nullable === 'NO',\n unsigned: false,\n ...rest,\n };\n\n const existing = result.get(row.table_name);\n if (existing) {\n existing.push(column);\n } else {\n result.set(row.table_name, [column]);\n }\n }\n\n return result;\n }\n\n async getBulkIndexes(dbSchema: string, tableNames: string[]): Promise<Map<string, Index[]>> {\n if (tableNames.length === 0) {\n return new Map();\n }\n\n const { rows } = await this.db.connection.raw<{ rows: RawIndex[] }>(SQL_QUERIES.BULK_INDEXES, [\n dbSchema,\n tableNames,\n ]);\n\n // Group by table, then by indexrelid\n const byTable = new Map<string, Map<string, Index>>();\n\n for (const index of rows) {\n if (index.column_name === 'id') {\n continue;\n }\n\n let tableIndexes = byTable.get(index.table_name);\n if (!tableIndexes) {\n tableIndexes = new Map();\n byTable.set(index.table_name, tableIndexes);\n }\n\n const existing = tableIndexes.get(index.indexrelid);\n if (existing) {\n existing.columns.push(index.column_name);\n } else {\n tableIndexes.set(index.indexrelid, {\n columns: [index.column_name],\n name: index.index_name,\n type: getIndexType(index),\n });\n }\n }\n\n const result = new Map<string, Index[]>();\n for (const [tableName, tableIndexes] of byTable) {\n result.set(tableName, Array.from(tableIndexes.values()));\n }\n\n return result;\n }\n\n async getIndexes(tableName: string): Promise<Index[]> {\n const dbSchema = this.getDatabaseSchema();\n const result = await this.getBulkIndexes(dbSchema, [tableName]);\n return result.get(tableName) ?? [];\n }\n\n async getForeignKeys(tableName: string): Promise<ForeignKey[]> {\n const dbSchema = this.getDatabaseSchema();\n const result = await this.getBulkForeignKeys(dbSchema, [tableName]);\n return result.get(tableName) ?? [];\n }\n\n async getBulkForeignKeys(\n dbSchema: string,\n tableNames: string[]\n ): Promise<Map<string, ForeignKey[]>> {\n if (tableNames.length === 0) {\n return new Map();\n }\n\n const { rows } = await this.db.connection.raw<{\n rows: Array<{\n table_name: string;\n constraint_name: string;\n column_name: string;\n on_update: string;\n on_delete: string;\n foreign_table: string;\n fk_column_name: string;\n }>;\n }>(SQL_QUERIES.BULK_FOREIGN_KEYS, [dbSchema, tableNames]);\n\n // Group by table_name, then by constraint_name\n const byTable = new Map<string, Map<string, ForeignKey>>();\n\n for (const row of rows) {\n let tableFKs = byTable.get(row.table_name);\n if (!tableFKs) {\n tableFKs = new Map();\n byTable.set(row.table_name, tableFKs);\n }\n\n let fk = tableFKs.get(row.constraint_name);\n if (!fk) {\n fk = {\n name: row.constraint_name,\n columns: [row.column_name],\n referencedColumns: [row.fk_column_name],\n referencedTable: row.foreign_table,\n onUpdate: row.on_update?.toUpperCase() ?? null,\n onDelete: row.on_delete?.toUpperCase() ?? null,\n };\n tableFKs.set(row.constraint_name, fk);\n } else {\n if (!fk.columns.includes(row.column_name)) {\n fk.columns.push(row.column_name);\n }\n if (!fk.referencedColumns.includes(row.fk_column_name)) {\n fk.referencedColumns.push(row.fk_column_name);\n }\n }\n }\n\n const result = new Map<string, ForeignKey[]>();\n for (const [tableName, tableFKs] of byTable) {\n result.set(tableName, Array.from(tableFKs.values()));\n }\n\n return result;\n }\n}\n"],"names":["SQL_QUERIES","TABLE_LIST","BULK_COLUMNS","BULK_INDEXES","BULK_FOREIGN_KEYS","toStrapiType","column","rootType","data_type","toLowerCase","match","type","args","character_maximum_length","useTz","precision","getIndexType","index","is_primary","is_unique","PostgresqlSchemaInspector","getSchema","schema","tables","dbSchema","getDatabaseSchema","getTables","length","allColumns","allIndexes","allForeignKeys","Promise","all","getBulkColumns","getBulkIndexes","getBulkForeignKeys","map","tableName","name","columns","get","indexes","foreignKeys","db","getSchemaName","rows","connection","raw","row","table_name","tableNames","Map","result","rest","defaultTo","column_default","includes","column_name","notNullable","is_nullable","unsigned","existing","push","set","byTable","tableIndexes","indexrelid","index_name","Array","from","values","getIndexes","getForeignKeys","tableFKs","fk","constraint_name","referencedColumns","fk_column_name","referencedTable","foreign_table","onUpdate","on_update","toUpperCase","onDelete","on_delete"],"mappings":"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"}