@strapi/database 5.48.0 → 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.
@@ -8,13 +8,14 @@ const SQL_QUERIES = {
8
8
  AND table_name != 'geometry_columns'
9
9
  AND table_name != 'spatial_ref_sys';
10
10
  `,
11
- LIST_COLUMNS: /* sql */ `
12
- SELECT data_type, column_name, character_maximum_length, column_default, is_nullable
11
+ BULK_COLUMNS: /* sql */ `
12
+ SELECT table_name, data_type, column_name, character_maximum_length, column_default, is_nullable
13
13
  FROM information_schema.columns
14
- WHERE table_schema = ? AND table_name = ?;
14
+ WHERE table_schema = ? AND table_name = ANY(?);
15
15
  `,
16
- INDEX_LIST: /* sql */ `
16
+ BULK_INDEXES: /* sql */ `
17
17
  SELECT
18
+ t.relname as table_name,
18
19
  ix.indexrelid,
19
20
  i.relname as index_name,
20
21
  a.attname as column_name,
@@ -34,44 +35,42 @@ const SQL_QUERIES = {
34
35
  AND t.relkind = 'r'
35
36
  AND t.relnamespace = s.oid
36
37
  AND s.nspname = ?
37
- AND t.relname = ?;
38
+ AND t.relname = ANY(?);
38
39
  `,
39
- FOREIGN_KEY_LIST: /* sql */ `
40
+ BULK_FOREIGN_KEYS: /* sql */ `
40
41
  SELECT
41
- tco."constraint_name" as constraint_name
42
- FROM information_schema.table_constraints tco
43
- WHERE
44
- tco.constraint_type = 'FOREIGN KEY'
45
- AND tco.constraint_schema = ?
46
- AND tco.table_name = ?
47
- `,
48
- FOREIGN_KEY_REFERENCES: /* sql */ `
49
- SELECT
50
- kcu."constraint_name" as constraint_name,
51
- kcu."column_name" as column_name
52
-
53
- FROM information_schema.key_column_usage kcu
54
- WHERE kcu.constraint_name=ANY(?)
55
- AND kcu.table_schema = ?
56
- AND kcu.table_name = ?;
57
- `,
58
- FOREIGN_KEY_REFERENCES_CONSTRAIN: /* sql */ `
59
- SELECT
60
- rco.update_rule as on_update,
61
- rco.delete_rule as on_delete,
62
- rco."unique_constraint_name" as unique_constraint_name
63
- FROM information_schema.referential_constraints rco
64
- WHERE rco.constraint_name=ANY(?)
65
- AND rco.constraint_schema = ?
66
- `,
67
- FOREIGN_KEY_REFERENCES_CONSTRAIN_RFERENCE: /* sql */ `
68
- SELECT
69
- rel_kcu."table_name" as foreign_table,
70
- rel_kcu."column_name" as fk_column_name
71
- FROM information_schema.key_column_usage rel_kcu
72
- WHERE rel_kcu.constraint_name=?
73
- AND rel_kcu.table_schema = ?
74
- `
42
+ cl.relname AS table_name,
43
+ c.conname AS constraint_name,
44
+ att.attname AS column_name,
45
+ fcl.relname AS foreign_table,
46
+ fatt.attname AS fk_column_name,
47
+ CASE c.confupdtype
48
+ WHEN 'a' THEN 'NO ACTION'
49
+ WHEN 'r' THEN 'RESTRICT'
50
+ WHEN 'c' THEN 'CASCADE'
51
+ WHEN 'n' THEN 'SET NULL'
52
+ WHEN 'd' THEN 'SET DEFAULT'
53
+ END AS on_update,
54
+ CASE c.confdeltype
55
+ WHEN 'a' THEN 'NO ACTION'
56
+ WHEN 'r' THEN 'RESTRICT'
57
+ WHEN 'c' THEN 'CASCADE'
58
+ WHEN 'n' THEN 'SET NULL'
59
+ WHEN 'd' THEN 'SET DEFAULT'
60
+ END AS on_delete
61
+ FROM pg_constraint c
62
+ JOIN pg_class cl ON cl.oid = c.conrelid
63
+ JOIN pg_namespace n ON n.oid = cl.relnamespace
64
+ JOIN pg_class fcl ON fcl.oid = c.confrelid
65
+ JOIN LATERAL unnest(c.conkey, c.confkey) AS cols(conkey, confkey) ON true
66
+ JOIN pg_attribute att ON att.attrelid = c.conrelid AND att.attnum = cols.conkey
67
+ JOIN pg_attribute fatt ON fatt.attrelid = c.confrelid AND fatt.attnum = cols.confkey
68
+ WHERE c.contype = 'f'
69
+ AND n.nspname = ?
70
+ AND cl.relname = ANY(?)
71
+ AND fcl.relnamespace = cl.relnamespace
72
+ ORDER BY cl.relname, c.conname, cols.conkey;
73
+ `
75
74
  };
76
75
  const toStrapiType = (column)=>{
77
76
  const rootType = column.data_type.toLowerCase().match(/[^(), ]+/)?.[0];
@@ -189,18 +188,23 @@ class PostgresqlSchemaInspector {
189
188
  const schema = {
190
189
  tables: []
191
190
  };
191
+ const dbSchema = this.getDatabaseSchema();
192
192
  const tables = await this.getTables();
193
- schema.tables = await Promise.all(tables.map(async (tableName)=>{
194
- const columns = await this.getColumns(tableName);
195
- const indexes = await this.getIndexes(tableName);
196
- const foreignKeys = await this.getForeignKeys(tableName);
197
- return {
193
+ if (tables.length === 0) {
194
+ return schema;
195
+ }
196
+ // Run 3 bulk queries in parallel instead of N+1 per-table queries
197
+ const [allColumns, allIndexes, allForeignKeys] = await Promise.all([
198
+ this.getBulkColumns(dbSchema, tables),
199
+ this.getBulkIndexes(dbSchema, tables),
200
+ this.getBulkForeignKeys(dbSchema, tables)
201
+ ]);
202
+ schema.tables = tables.map((tableName)=>({
198
203
  name: tableName,
199
- columns,
200
- indexes,
201
- foreignKeys
202
- };
203
- }));
204
+ columns: allColumns.get(tableName) ?? [],
205
+ indexes: allIndexes.get(tableName) ?? [],
206
+ foreignKeys: allForeignKeys.get(tableName) ?? []
207
+ }));
204
208
  return schema;
205
209
  }
206
210
  getDatabaseSchema() {
@@ -212,15 +216,19 @@ class PostgresqlSchemaInspector {
212
216
  ]);
213
217
  return rows.map((row)=>row.table_name);
214
218
  }
215
- async getColumns(tableName) {
216
- const { rows } = await this.db.connection.raw(SQL_QUERIES.LIST_COLUMNS, [
217
- this.getDatabaseSchema(),
218
- tableName
219
+ async getBulkColumns(dbSchema, tableNames) {
220
+ if (tableNames.length === 0) {
221
+ return new Map();
222
+ }
223
+ const { rows } = await this.db.connection.raw(SQL_QUERIES.BULK_COLUMNS, [
224
+ dbSchema,
225
+ tableNames
219
226
  ]);
220
- return rows.map((row)=>{
227
+ const result = new Map();
228
+ for (const row of rows){
221
229
  const { type, args = [], ...rest } = toStrapiType(row);
222
230
  const defaultTo = row.column_default && row.column_default.includes('nextval(') ? null : row.column_default;
223
- return {
231
+ const column = {
224
232
  type,
225
233
  args,
226
234
  defaultTo,
@@ -229,81 +237,114 @@ class PostgresqlSchemaInspector {
229
237
  unsigned: false,
230
238
  ...rest
231
239
  };
232
- });
240
+ const existing = result.get(row.table_name);
241
+ if (existing) {
242
+ existing.push(column);
243
+ } else {
244
+ result.set(row.table_name, [
245
+ column
246
+ ]);
247
+ }
248
+ }
249
+ return result;
233
250
  }
234
- async getIndexes(tableName) {
235
- const { rows } = await this.db.connection.raw(SQL_QUERIES.INDEX_LIST, [
236
- this.getDatabaseSchema(),
237
- tableName
251
+ async getBulkIndexes(dbSchema, tableNames) {
252
+ if (tableNames.length === 0) {
253
+ return new Map();
254
+ }
255
+ const { rows } = await this.db.connection.raw(SQL_QUERIES.BULK_INDEXES, [
256
+ dbSchema,
257
+ tableNames
238
258
  ]);
239
- const ret = {};
259
+ // Group by table, then by indexrelid
260
+ const byTable = new Map();
240
261
  for (const index of rows){
241
262
  if (index.column_name === 'id') {
242
263
  continue;
243
264
  }
244
- if (!ret[index.indexrelid]) {
245
- ret[index.indexrelid] = {
265
+ let tableIndexes = byTable.get(index.table_name);
266
+ if (!tableIndexes) {
267
+ tableIndexes = new Map();
268
+ byTable.set(index.table_name, tableIndexes);
269
+ }
270
+ const existing = tableIndexes.get(index.indexrelid);
271
+ if (existing) {
272
+ existing.columns.push(index.column_name);
273
+ } else {
274
+ tableIndexes.set(index.indexrelid, {
246
275
  columns: [
247
276
  index.column_name
248
277
  ],
249
278
  name: index.index_name,
250
279
  type: getIndexType(index)
251
- };
252
- } else {
253
- ret[index.indexrelid].columns.push(index.column_name);
280
+ });
254
281
  }
255
282
  }
256
- return Object.values(ret);
283
+ const result = new Map();
284
+ for (const [tableName, tableIndexes] of byTable){
285
+ result.set(tableName, Array.from(tableIndexes.values()));
286
+ }
287
+ return result;
288
+ }
289
+ async getIndexes(tableName) {
290
+ const dbSchema = this.getDatabaseSchema();
291
+ const result = await this.getBulkIndexes(dbSchema, [
292
+ tableName
293
+ ]);
294
+ return result.get(tableName) ?? [];
257
295
  }
258
296
  async getForeignKeys(tableName) {
259
- const { rows } = await this.db.connection.raw(SQL_QUERIES.FOREIGN_KEY_LIST, [
260
- this.getDatabaseSchema(),
297
+ const dbSchema = this.getDatabaseSchema();
298
+ const result = await this.getBulkForeignKeys(dbSchema, [
261
299
  tableName
262
300
  ]);
263
- const ret = {};
264
- for (const fk of rows){
265
- ret[fk.constraint_name] = {
266
- name: fk.constraint_name,
267
- columns: [],
268
- referencedColumns: [],
269
- referencedTable: null,
270
- onUpdate: null,
271
- onDelete: null
272
- };
301
+ return result.get(tableName) ?? [];
302
+ }
303
+ async getBulkForeignKeys(dbSchema, tableNames) {
304
+ if (tableNames.length === 0) {
305
+ return new Map();
273
306
  }
274
- const constraintNames = Object.keys(ret);
275
- const dbSchema = this.getDatabaseSchema();
276
- if (constraintNames.length > 0) {
277
- const { rows: fkReferences } = await this.db.connection.raw(SQL_QUERIES.FOREIGN_KEY_REFERENCES, [
278
- [
279
- constraintNames
280
- ],
281
- dbSchema,
282
- tableName
283
- ]);
284
- for (const fkReference of fkReferences){
285
- ret[fkReference.constraint_name].columns.push(fkReference.column_name);
286
- const { rows: fkReferencesConstraint } = await this.db.connection.raw(SQL_QUERIES.FOREIGN_KEY_REFERENCES_CONSTRAIN, [
287
- [
288
- fkReference.constraint_name
307
+ const { rows } = await this.db.connection.raw(SQL_QUERIES.BULK_FOREIGN_KEYS, [
308
+ dbSchema,
309
+ tableNames
310
+ ]);
311
+ // Group by table_name, then by constraint_name
312
+ const byTable = new Map();
313
+ for (const row of rows){
314
+ let tableFKs = byTable.get(row.table_name);
315
+ if (!tableFKs) {
316
+ tableFKs = new Map();
317
+ byTable.set(row.table_name, tableFKs);
318
+ }
319
+ let fk = tableFKs.get(row.constraint_name);
320
+ if (!fk) {
321
+ fk = {
322
+ name: row.constraint_name,
323
+ columns: [
324
+ row.column_name
289
325
  ],
290
- dbSchema
291
- ]);
292
- for (const fkReferenceC of fkReferencesConstraint){
293
- const { rows: fkReferencesConstraintReferece } = await this.db.connection.raw(SQL_QUERIES.FOREIGN_KEY_REFERENCES_CONSTRAIN_RFERENCE, [
294
- fkReferenceC.unique_constraint_name,
295
- dbSchema
296
- ]);
297
- for (const fkReferenceConst of fkReferencesConstraintReferece){
298
- ret[fkReference.constraint_name].referencedTable = fkReferenceConst.foreign_table;
299
- ret[fkReference.constraint_name].referencedColumns.push(fkReferenceConst.fk_column_name);
300
- }
301
- ret[fkReference.constraint_name].onUpdate = fkReferenceC.on_update.toUpperCase();
302
- ret[fkReference.constraint_name].onDelete = fkReferenceC.on_delete.toUpperCase();
326
+ referencedColumns: [
327
+ row.fk_column_name
328
+ ],
329
+ referencedTable: row.foreign_table,
330
+ onUpdate: row.on_update?.toUpperCase() ?? null,
331
+ onDelete: row.on_delete?.toUpperCase() ?? null
332
+ };
333
+ tableFKs.set(row.constraint_name, fk);
334
+ } else {
335
+ if (!fk.columns.includes(row.column_name)) {
336
+ fk.columns.push(row.column_name);
337
+ }
338
+ if (!fk.referencedColumns.includes(row.fk_column_name)) {
339
+ fk.referencedColumns.push(row.fk_column_name);
303
340
  }
304
341
  }
305
342
  }
306
- return Object.values(ret);
343
+ const result = new Map();
344
+ for (const [tableName, tableFKs] of byTable){
345
+ result.set(tableName, Array.from(tableFKs.values()));
346
+ }
347
+ return result;
307
348
  }
308
349
  constructor(db){
309
350
  this.db = db;
@@ -1 +1 @@
1
- {"version":3,"file":"schema-inspector.mjs","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.mjs","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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"}
@@ -1,3 +1,8 @@
1
1
  import type { Migration } from '../common';
2
+ /**
3
+ * Previously created secondary indexes on `document_id` (and composites) via raw DDL.
4
+ * Those indexes are now owned by schema sync from model metadata (see transform-content-types-to-models).
5
+ * Keep this migration as a stable no-op so Umzug / `strapi_migrations_internal` stay consistent.
6
+ */
2
7
  export declare const addDocumentIdIndexes: Migration;
3
8
  //# sourceMappingURL=5.0.0-06-add-document-id-indexes.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"5.0.0-06-add-document-id-indexes.d.ts","sourceRoot":"","sources":["../../../src/migrations/internal-migrations/5.0.0-06-add-document-id-indexes.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAgE3C,eAAO,MAAM,oBAAoB,EAAE,SAelC,CAAC"}
1
+ {"version":3,"file":"5.0.0-06-add-document-id-indexes.d.ts","sourceRoot":"","sources":["../../../src/migrations/internal-migrations/5.0.0-06-add-document-id-indexes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAE3C;;;;GAIG;AAEH,eAAO,MAAM,oBAAoB,EAAE,SAQlC,CAAC"}
@@ -1,64 +1,13 @@
1
1
  'use strict';
2
2
 
3
- // Add an index if it does not already exist
4
- const createIndex = async (knex, tableName, columns, indexName)=>{
5
- try {
6
- // If the database can check for indexes, avoid duplicates
7
- const hasIndex = knex.schema.hasIndex;
8
- if (hasIndex) {
9
- const exists = await hasIndex.call(knex.schema, tableName, indexName);
10
- if (exists) {
11
- return;
12
- }
13
- }
14
- await knex.schema.alterTable(tableName, (table)=>{
15
- table.index(columns, indexName);
16
- });
17
- } catch (error) {
18
- // If the index exists (or cannot be created), move on
19
- }
20
- };
21
- const addIndexesForTable = async (knex, tableName)=>{
22
- // Only add indexes when the column is present
23
- const hasDocumentId = await knex.schema.hasColumn(tableName, 'document_id');
24
- if (!hasDocumentId) {
25
- return;
26
- }
27
- const hasLocale = await knex.schema.hasColumn(tableName, 'locale');
28
- const hasPublishedAt = await knex.schema.hasColumn(tableName, 'published_at');
29
- // Single column index for basic lookups
30
- await createIndex(knex, tableName, [
31
- 'document_id'
32
- ], `${tableName}_document_id_idx`);
33
- if (hasLocale && hasPublishedAt) {
34
- // Composite index for common filters
35
- await createIndex(knex, tableName, [
36
- 'document_id',
37
- 'locale',
38
- 'published_at'
39
- ], `${tableName}_document_id_locale_published_at_idx`);
40
- } else if (hasLocale) {
41
- await createIndex(knex, tableName, [
42
- 'document_id',
43
- 'locale'
44
- ], `${tableName}_document_id_locale_idx`);
45
- } else if (hasPublishedAt) {
46
- await createIndex(knex, tableName, [
47
- 'document_id',
48
- 'published_at'
49
- ], `${tableName}_document_id_published_at_idx`);
50
- }
51
- };
52
- const addDocumentIdIndexes = {
3
+ /**
4
+ * Previously created secondary indexes on `document_id` (and composites) via raw DDL.
5
+ * Those indexes are now owned by schema sync from model metadata (see transform-content-types-to-models).
6
+ * Keep this migration as a stable no-op so Umzug / `strapi_migrations_internal` stay consistent.
7
+ */ const addDocumentIdIndexes = {
53
8
  name: '5.0.0-06-add-document-id-indexes',
54
- async up (knex, db) {
55
- for (const meta of db.metadata.values()){
56
- const hasTable = await knex.schema.hasTable(meta.tableName);
57
- if (!hasTable) {
58
- continue;
59
- }
60
- await addIndexesForTable(knex, meta.tableName);
61
- }
9
+ async up () {
10
+ // No-op: the document_id indexes are now created by schema sync (see transform-content-types-to-models).
62
11
  },
63
12
  async down () {
64
13
  throw new Error('not implemented');
@@ -1 +1 @@
1
- {"version":3,"file":"5.0.0-06-add-document-id-indexes.js","sources":["../../../src/migrations/internal-migrations/5.0.0-06-add-document-id-indexes.ts"],"sourcesContent":["import type { Knex } from 'knex';\n\nimport type { Migration } from '../common';\n\n// Add an index if it does not already exist\nconst createIndex = async (knex: Knex, tableName: string, columns: string[], indexName: string) => {\n try {\n // If the database can check for indexes, avoid duplicates\n const hasIndex = (\n knex.schema as unknown as {\n hasIndex?: (tableName: string, indexName: string) => Promise<boolean>;\n }\n ).hasIndex;\n if (hasIndex) {\n const exists = await hasIndex.call(knex.schema, tableName, indexName);\n if (exists) {\n return;\n }\n }\n\n await knex.schema.alterTable(tableName, (table) => {\n table.index(columns, indexName);\n });\n } catch (error) {\n // If the index exists (or cannot be created), move on\n }\n};\n\nconst addIndexesForTable = async (knex: Knex, tableName: string) => {\n // Only add indexes when the column is present\n const hasDocumentId = await knex.schema.hasColumn(tableName, 'document_id');\n if (!hasDocumentId) {\n return;\n }\n\n const hasLocale = await knex.schema.hasColumn(tableName, 'locale');\n const hasPublishedAt = await knex.schema.hasColumn(tableName, 'published_at');\n\n // Single column index for basic lookups\n await createIndex(knex, tableName, ['document_id'], `${tableName}_document_id_idx`);\n\n if (hasLocale && hasPublishedAt) {\n // Composite index for common filters\n await createIndex(\n knex,\n tableName,\n ['document_id', 'locale', 'published_at'],\n `${tableName}_document_id_locale_published_at_idx`\n );\n } else if (hasLocale) {\n await createIndex(\n knex,\n tableName,\n ['document_id', 'locale'],\n `${tableName}_document_id_locale_idx`\n );\n } else if (hasPublishedAt) {\n await createIndex(\n knex,\n tableName,\n ['document_id', 'published_at'],\n `${tableName}_document_id_published_at_idx`\n );\n }\n};\n\nexport const addDocumentIdIndexes: Migration = {\n name: '5.0.0-06-add-document-id-indexes',\n async up(knex, db) {\n for (const meta of db.metadata.values()) {\n const hasTable = await knex.schema.hasTable(meta.tableName);\n if (!hasTable) {\n continue;\n }\n\n await addIndexesForTable(knex, meta.tableName);\n }\n },\n async down() {\n throw new Error('not implemented');\n },\n};\n"],"names":["createIndex","knex","tableName","columns","indexName","hasIndex","schema","exists","call","alterTable","table","index","error","addIndexesForTable","hasDocumentId","hasColumn","hasLocale","hasPublishedAt","addDocumentIdIndexes","name","up","db","meta","metadata","values","hasTable","down","Error"],"mappings":";;AAIA;AACA,MAAMA,WAAAA,GAAc,OAAOC,IAAAA,EAAYC,SAAAA,EAAmBC,OAAAA,EAAmBC,SAAAA,GAAAA;IAC3E,IAAI;;AAEF,QAAA,MAAMC,QAAAA,GACJJ,IAAAA,CAAKK,MAAM,CAGXD,QAAQ;AACV,QAAA,IAAIA,QAAAA,EAAU;YACZ,MAAME,MAAAA,GAAS,MAAMF,QAAAA,CAASG,IAAI,CAACP,IAAAA,CAAKK,MAAM,EAAEJ,SAAAA,EAAWE,SAAAA,CAAAA;AAC3D,YAAA,IAAIG,MAAAA,EAAQ;AACV,gBAAA;AACF,YAAA;AACF,QAAA;AAEA,QAAA,MAAMN,KAAKK,MAAM,CAACG,UAAU,CAACP,WAAW,CAACQ,KAAAA,GAAAA;YACvCA,KAAAA,CAAMC,KAAK,CAACR,OAAAA,EAASC,SAAAA,CAAAA;AACvB,QAAA,CAAA,CAAA;AACF,IAAA,CAAA,CAAE,OAAOQ,KAAAA,EAAO;;AAEhB,IAAA;AACF,CAAA;AAEA,MAAMC,kBAAAA,GAAqB,OAAOZ,IAAAA,EAAYC,SAAAA,GAAAA;;AAE5C,IAAA,MAAMY,gBAAgB,MAAMb,IAAAA,CAAKK,MAAM,CAACS,SAAS,CAACb,SAAAA,EAAW,aAAA,CAAA;AAC7D,IAAA,IAAI,CAACY,aAAAA,EAAe;AAClB,QAAA;AACF,IAAA;AAEA,IAAA,MAAME,YAAY,MAAMf,IAAAA,CAAKK,MAAM,CAACS,SAAS,CAACb,SAAAA,EAAW,QAAA,CAAA;AACzD,IAAA,MAAMe,iBAAiB,MAAMhB,IAAAA,CAAKK,MAAM,CAACS,SAAS,CAACb,SAAAA,EAAW,cAAA,CAAA;;IAG9D,MAAMF,WAAAA,CAAYC,MAAMC,SAAAA,EAAW;AAAC,QAAA;KAAc,EAAE,CAAA,EAAGA,SAAAA,CAAU,gBAAgB,CAAC,CAAA;AAElF,IAAA,IAAIc,aAAaC,cAAAA,EAAgB;;QAE/B,MAAMjB,WAAAA,CACJC,MACAC,SAAAA,EACA;AAAC,YAAA,aAAA;AAAe,YAAA,QAAA;AAAU,YAAA;SAAe,EACzC,CAAA,EAAGA,SAAAA,CAAU,oCAAoC,CAAC,CAAA;AAEtD,IAAA,CAAA,MAAO,IAAIc,SAAAA,EAAW;QACpB,MAAMhB,WAAAA,CACJC,MACAC,SAAAA,EACA;AAAC,YAAA,aAAA;AAAe,YAAA;SAAS,EACzB,CAAA,EAAGA,SAAAA,CAAU,uBAAuB,CAAC,CAAA;AAEzC,IAAA,CAAA,MAAO,IAAIe,cAAAA,EAAgB;QACzB,MAAMjB,WAAAA,CACJC,MACAC,SAAAA,EACA;AAAC,YAAA,aAAA;AAAe,YAAA;SAAe,EAC/B,CAAA,EAAGA,SAAAA,CAAU,6BAA6B,CAAC,CAAA;AAE/C,IAAA;AACF,CAAA;MAEagB,oBAAAA,GAAkC;IAC7CC,IAAAA,EAAM,kCAAA;IACN,MAAMC,EAAAA,CAAAA,CAAGnB,IAAI,EAAEoB,EAAE,EAAA;AACf,QAAA,KAAK,MAAMC,IAAAA,IAAQD,EAAAA,CAAGE,QAAQ,CAACC,MAAM,EAAA,CAAI;YACvC,MAAMC,QAAAA,GAAW,MAAMxB,IAAAA,CAAKK,MAAM,CAACmB,QAAQ,CAACH,KAAKpB,SAAS,CAAA;AAC1D,YAAA,IAAI,CAACuB,QAAAA,EAAU;AACb,gBAAA;AACF,YAAA;YAEA,MAAMZ,kBAAAA,CAAmBZ,IAAAA,EAAMqB,IAAAA,CAAKpB,SAAS,CAAA;AAC/C,QAAA;AACF,IAAA,CAAA;IACA,MAAMwB,IAAAA,CAAAA,GAAAA;AACJ,QAAA,MAAM,IAAIC,KAAAA,CAAM,iBAAA,CAAA;AAClB,IAAA;AACF;;;;"}
1
+ {"version":3,"file":"5.0.0-06-add-document-id-indexes.js","sources":["../../../src/migrations/internal-migrations/5.0.0-06-add-document-id-indexes.ts"],"sourcesContent":["import type { Migration } from '../common';\n\n/**\n * Previously created secondary indexes on `document_id` (and composites) via raw DDL.\n * Those indexes are now owned by schema sync from model metadata (see transform-content-types-to-models).\n * Keep this migration as a stable no-op so Umzug / `strapi_migrations_internal` stay consistent.\n */\n\nexport const addDocumentIdIndexes: Migration = {\n name: '5.0.0-06-add-document-id-indexes',\n async up() {\n // No-op: the document_id indexes are now created by schema sync (see transform-content-types-to-models).\n },\n async down() {\n throw new Error('not implemented');\n },\n};\n"],"names":["addDocumentIdIndexes","name","up","down","Error"],"mappings":";;AAEA;;;;UAMaA,oBAAAA,GAAkC;IAC7CC,IAAAA,EAAM,kCAAA;IACN,MAAMC,EAAAA,CAAAA,GAAAA;;AAEN,IAAA,CAAA;IACA,MAAMC,IAAAA,CAAAA,GAAAA;AACJ,QAAA,MAAM,IAAIC,KAAAA,CAAM,iBAAA,CAAA;AAClB,IAAA;AACF;;;;"}
@@ -1,62 +1,11 @@
1
- // Add an index if it does not already exist
2
- const createIndex = async (knex, tableName, columns, indexName)=>{
3
- try {
4
- // If the database can check for indexes, avoid duplicates
5
- const hasIndex = knex.schema.hasIndex;
6
- if (hasIndex) {
7
- const exists = await hasIndex.call(knex.schema, tableName, indexName);
8
- if (exists) {
9
- return;
10
- }
11
- }
12
- await knex.schema.alterTable(tableName, (table)=>{
13
- table.index(columns, indexName);
14
- });
15
- } catch (error) {
16
- // If the index exists (or cannot be created), move on
17
- }
18
- };
19
- const addIndexesForTable = async (knex, tableName)=>{
20
- // Only add indexes when the column is present
21
- const hasDocumentId = await knex.schema.hasColumn(tableName, 'document_id');
22
- if (!hasDocumentId) {
23
- return;
24
- }
25
- const hasLocale = await knex.schema.hasColumn(tableName, 'locale');
26
- const hasPublishedAt = await knex.schema.hasColumn(tableName, 'published_at');
27
- // Single column index for basic lookups
28
- await createIndex(knex, tableName, [
29
- 'document_id'
30
- ], `${tableName}_document_id_idx`);
31
- if (hasLocale && hasPublishedAt) {
32
- // Composite index for common filters
33
- await createIndex(knex, tableName, [
34
- 'document_id',
35
- 'locale',
36
- 'published_at'
37
- ], `${tableName}_document_id_locale_published_at_idx`);
38
- } else if (hasLocale) {
39
- await createIndex(knex, tableName, [
40
- 'document_id',
41
- 'locale'
42
- ], `${tableName}_document_id_locale_idx`);
43
- } else if (hasPublishedAt) {
44
- await createIndex(knex, tableName, [
45
- 'document_id',
46
- 'published_at'
47
- ], `${tableName}_document_id_published_at_idx`);
48
- }
49
- };
50
- const addDocumentIdIndexes = {
1
+ /**
2
+ * Previously created secondary indexes on `document_id` (and composites) via raw DDL.
3
+ * Those indexes are now owned by schema sync from model metadata (see transform-content-types-to-models).
4
+ * Keep this migration as a stable no-op so Umzug / `strapi_migrations_internal` stay consistent.
5
+ */ const addDocumentIdIndexes = {
51
6
  name: '5.0.0-06-add-document-id-indexes',
52
- async up (knex, db) {
53
- for (const meta of db.metadata.values()){
54
- const hasTable = await knex.schema.hasTable(meta.tableName);
55
- if (!hasTable) {
56
- continue;
57
- }
58
- await addIndexesForTable(knex, meta.tableName);
59
- }
7
+ async up () {
8
+ // No-op: the document_id indexes are now created by schema sync (see transform-content-types-to-models).
60
9
  },
61
10
  async down () {
62
11
  throw new Error('not implemented');
@@ -1 +1 @@
1
- {"version":3,"file":"5.0.0-06-add-document-id-indexes.mjs","sources":["../../../src/migrations/internal-migrations/5.0.0-06-add-document-id-indexes.ts"],"sourcesContent":["import type { Knex } from 'knex';\n\nimport type { Migration } from '../common';\n\n// Add an index if it does not already exist\nconst createIndex = async (knex: Knex, tableName: string, columns: string[], indexName: string) => {\n try {\n // If the database can check for indexes, avoid duplicates\n const hasIndex = (\n knex.schema as unknown as {\n hasIndex?: (tableName: string, indexName: string) => Promise<boolean>;\n }\n ).hasIndex;\n if (hasIndex) {\n const exists = await hasIndex.call(knex.schema, tableName, indexName);\n if (exists) {\n return;\n }\n }\n\n await knex.schema.alterTable(tableName, (table) => {\n table.index(columns, indexName);\n });\n } catch (error) {\n // If the index exists (or cannot be created), move on\n }\n};\n\nconst addIndexesForTable = async (knex: Knex, tableName: string) => {\n // Only add indexes when the column is present\n const hasDocumentId = await knex.schema.hasColumn(tableName, 'document_id');\n if (!hasDocumentId) {\n return;\n }\n\n const hasLocale = await knex.schema.hasColumn(tableName, 'locale');\n const hasPublishedAt = await knex.schema.hasColumn(tableName, 'published_at');\n\n // Single column index for basic lookups\n await createIndex(knex, tableName, ['document_id'], `${tableName}_document_id_idx`);\n\n if (hasLocale && hasPublishedAt) {\n // Composite index for common filters\n await createIndex(\n knex,\n tableName,\n ['document_id', 'locale', 'published_at'],\n `${tableName}_document_id_locale_published_at_idx`\n );\n } else if (hasLocale) {\n await createIndex(\n knex,\n tableName,\n ['document_id', 'locale'],\n `${tableName}_document_id_locale_idx`\n );\n } else if (hasPublishedAt) {\n await createIndex(\n knex,\n tableName,\n ['document_id', 'published_at'],\n `${tableName}_document_id_published_at_idx`\n );\n }\n};\n\nexport const addDocumentIdIndexes: Migration = {\n name: '5.0.0-06-add-document-id-indexes',\n async up(knex, db) {\n for (const meta of db.metadata.values()) {\n const hasTable = await knex.schema.hasTable(meta.tableName);\n if (!hasTable) {\n continue;\n }\n\n await addIndexesForTable(knex, meta.tableName);\n }\n },\n async down() {\n throw new Error('not implemented');\n },\n};\n"],"names":["createIndex","knex","tableName","columns","indexName","hasIndex","schema","exists","call","alterTable","table","index","error","addIndexesForTable","hasDocumentId","hasColumn","hasLocale","hasPublishedAt","addDocumentIdIndexes","name","up","db","meta","metadata","values","hasTable","down","Error"],"mappings":"AAIA;AACA,MAAMA,WAAAA,GAAc,OAAOC,IAAAA,EAAYC,SAAAA,EAAmBC,OAAAA,EAAmBC,SAAAA,GAAAA;IAC3E,IAAI;;AAEF,QAAA,MAAMC,QAAAA,GACJJ,IAAAA,CAAKK,MAAM,CAGXD,QAAQ;AACV,QAAA,IAAIA,QAAAA,EAAU;YACZ,MAAME,MAAAA,GAAS,MAAMF,QAAAA,CAASG,IAAI,CAACP,IAAAA,CAAKK,MAAM,EAAEJ,SAAAA,EAAWE,SAAAA,CAAAA;AAC3D,YAAA,IAAIG,MAAAA,EAAQ;AACV,gBAAA;AACF,YAAA;AACF,QAAA;AAEA,QAAA,MAAMN,KAAKK,MAAM,CAACG,UAAU,CAACP,WAAW,CAACQ,KAAAA,GAAAA;YACvCA,KAAAA,CAAMC,KAAK,CAACR,OAAAA,EAASC,SAAAA,CAAAA;AACvB,QAAA,CAAA,CAAA;AACF,IAAA,CAAA,CAAE,OAAOQ,KAAAA,EAAO;;AAEhB,IAAA;AACF,CAAA;AAEA,MAAMC,kBAAAA,GAAqB,OAAOZ,IAAAA,EAAYC,SAAAA,GAAAA;;AAE5C,IAAA,MAAMY,gBAAgB,MAAMb,IAAAA,CAAKK,MAAM,CAACS,SAAS,CAACb,SAAAA,EAAW,aAAA,CAAA;AAC7D,IAAA,IAAI,CAACY,aAAAA,EAAe;AAClB,QAAA;AACF,IAAA;AAEA,IAAA,MAAME,YAAY,MAAMf,IAAAA,CAAKK,MAAM,CAACS,SAAS,CAACb,SAAAA,EAAW,QAAA,CAAA;AACzD,IAAA,MAAMe,iBAAiB,MAAMhB,IAAAA,CAAKK,MAAM,CAACS,SAAS,CAACb,SAAAA,EAAW,cAAA,CAAA;;IAG9D,MAAMF,WAAAA,CAAYC,MAAMC,SAAAA,EAAW;AAAC,QAAA;KAAc,EAAE,CAAA,EAAGA,SAAAA,CAAU,gBAAgB,CAAC,CAAA;AAElF,IAAA,IAAIc,aAAaC,cAAAA,EAAgB;;QAE/B,MAAMjB,WAAAA,CACJC,MACAC,SAAAA,EACA;AAAC,YAAA,aAAA;AAAe,YAAA,QAAA;AAAU,YAAA;SAAe,EACzC,CAAA,EAAGA,SAAAA,CAAU,oCAAoC,CAAC,CAAA;AAEtD,IAAA,CAAA,MAAO,IAAIc,SAAAA,EAAW;QACpB,MAAMhB,WAAAA,CACJC,MACAC,SAAAA,EACA;AAAC,YAAA,aAAA;AAAe,YAAA;SAAS,EACzB,CAAA,EAAGA,SAAAA,CAAU,uBAAuB,CAAC,CAAA;AAEzC,IAAA,CAAA,MAAO,IAAIe,cAAAA,EAAgB;QACzB,MAAMjB,WAAAA,CACJC,MACAC,SAAAA,EACA;AAAC,YAAA,aAAA;AAAe,YAAA;SAAe,EAC/B,CAAA,EAAGA,SAAAA,CAAU,6BAA6B,CAAC,CAAA;AAE/C,IAAA;AACF,CAAA;MAEagB,oBAAAA,GAAkC;IAC7CC,IAAAA,EAAM,kCAAA;IACN,MAAMC,EAAAA,CAAAA,CAAGnB,IAAI,EAAEoB,EAAE,EAAA;AACf,QAAA,KAAK,MAAMC,IAAAA,IAAQD,EAAAA,CAAGE,QAAQ,CAACC,MAAM,EAAA,CAAI;YACvC,MAAMC,QAAAA,GAAW,MAAMxB,IAAAA,CAAKK,MAAM,CAACmB,QAAQ,CAACH,KAAKpB,SAAS,CAAA;AAC1D,YAAA,IAAI,CAACuB,QAAAA,EAAU;AACb,gBAAA;AACF,YAAA;YAEA,MAAMZ,kBAAAA,CAAmBZ,IAAAA,EAAMqB,IAAAA,CAAKpB,SAAS,CAAA;AAC/C,QAAA;AACF,IAAA,CAAA;IACA,MAAMwB,IAAAA,CAAAA,GAAAA;AACJ,QAAA,MAAM,IAAIC,KAAAA,CAAM,iBAAA,CAAA;AAClB,IAAA;AACF;;;;"}
1
+ {"version":3,"file":"5.0.0-06-add-document-id-indexes.mjs","sources":["../../../src/migrations/internal-migrations/5.0.0-06-add-document-id-indexes.ts"],"sourcesContent":["import type { Migration } from '../common';\n\n/**\n * Previously created secondary indexes on `document_id` (and composites) via raw DDL.\n * Those indexes are now owned by schema sync from model metadata (see transform-content-types-to-models).\n * Keep this migration as a stable no-op so Umzug / `strapi_migrations_internal` stay consistent.\n */\n\nexport const addDocumentIdIndexes: Migration = {\n name: '5.0.0-06-add-document-id-indexes',\n async up() {\n // No-op: the document_id indexes are now created by schema sync (see transform-content-types-to-models).\n },\n async down() {\n throw new Error('not implemented');\n },\n};\n"],"names":["addDocumentIdIndexes","name","up","down","Error"],"mappings":"AAEA;;;;UAMaA,oBAAAA,GAAkC;IAC7CC,IAAAA,EAAM,kCAAA;IACN,MAAMC,EAAAA,CAAAA,GAAAA;;AAEN,IAAA,CAAA;IACA,MAAMC,IAAAA,CAAAA,GAAAA;AACJ,QAAA,MAAM,IAAIC,KAAAA,CAAM,iBAAA,CAAA;AAClB,IAAA;AACF;;;;"}