@strapi/database 5.48.0 → 5.49.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.
Files changed (76) hide show
  1. package/dist/connection.js +5 -1
  2. package/dist/connection.js.map +1 -1
  3. package/dist/dialects/mysql/schema-inspector.d.ts +3 -0
  4. package/dist/dialects/mysql/schema-inspector.d.ts.map +1 -1
  5. package/dist/dialects/mysql/schema-inspector.js +145 -85
  6. package/dist/dialects/mysql/schema-inspector.js.map +1 -1
  7. package/dist/dialects/mysql/schema-inspector.mjs +145 -85
  8. package/dist/dialects/mysql/schema-inspector.mjs.map +1 -1
  9. package/dist/dialects/postgresql/schema-inspector.d.ts +3 -1
  10. package/dist/dialects/postgresql/schema-inspector.d.ts.map +1 -1
  11. package/dist/dialects/postgresql/schema-inspector.js +150 -109
  12. package/dist/dialects/postgresql/schema-inspector.js.map +1 -1
  13. package/dist/dialects/postgresql/schema-inspector.mjs +150 -109
  14. package/dist/dialects/postgresql/schema-inspector.mjs.map +1 -1
  15. package/dist/dialects/sqlite/index.js +8 -3
  16. package/dist/dialects/sqlite/index.js.map +1 -1
  17. package/dist/entity-manager/relations-orderer.js +5 -1
  18. package/dist/entity-manager/relations-orderer.js.map +1 -1
  19. package/dist/fields/datetime.js +3 -2
  20. package/dist/fields/datetime.js.map +1 -1
  21. package/dist/fields/index.js +5 -1
  22. package/dist/fields/index.js.map +1 -1
  23. package/dist/fields/shared/parsers.js +3 -2
  24. package/dist/fields/shared/parsers.js.map +1 -1
  25. package/dist/fields/timestamp.js +3 -2
  26. package/dist/fields/timestamp.js.map +1 -1
  27. package/dist/index.js +5 -1
  28. package/dist/index.js.map +1 -1
  29. package/dist/lifecycles/subscribers/timestamps.js +10 -6
  30. package/dist/lifecycles/subscribers/timestamps.js.map +1 -1
  31. package/dist/metadata/relations.js +6 -2
  32. package/dist/metadata/relations.js.map +1 -1
  33. package/dist/migrations/internal-migrations/5.0.0-01-convert-identifiers-long-than-max-length.js +5 -1
  34. package/dist/migrations/internal-migrations/5.0.0-01-convert-identifiers-long-than-max-length.js.map +1 -1
  35. package/dist/migrations/internal-migrations/5.0.0-06-add-document-id-indexes.d.ts +5 -0
  36. package/dist/migrations/internal-migrations/5.0.0-06-add-document-id-indexes.d.ts.map +1 -1
  37. package/dist/migrations/internal-migrations/5.0.0-06-add-document-id-indexes.js +7 -58
  38. package/dist/migrations/internal-migrations/5.0.0-06-add-document-id-indexes.js.map +1 -1
  39. package/dist/migrations/internal-migrations/5.0.0-06-add-document-id-indexes.mjs +7 -58
  40. package/dist/migrations/internal-migrations/5.0.0-06-add-document-id-indexes.mjs.map +1 -1
  41. package/dist/migrations/users.js +6 -2
  42. package/dist/migrations/users.js.map +1 -1
  43. package/dist/query/helpers/order-by.js +11 -7
  44. package/dist/query/helpers/order-by.js.map +1 -1
  45. package/dist/query/helpers/populate/apply.d.ts.map +1 -1
  46. package/dist/query/helpers/populate/apply.js +48 -47
  47. package/dist/query/helpers/populate/apply.js.map +1 -1
  48. package/dist/query/helpers/populate/apply.mjs +4 -7
  49. package/dist/query/helpers/populate/apply.mjs.map +1 -1
  50. package/dist/query/helpers/populate/process.js +7 -3
  51. package/dist/query/helpers/populate/process.js.map +1 -1
  52. package/dist/query/helpers/search.js +5 -1
  53. package/dist/query/helpers/search.js.map +1 -1
  54. package/dist/query/helpers/transform.js +10 -6
  55. package/dist/query/helpers/transform.js.map +1 -1
  56. package/dist/query/helpers/where.d.ts +1 -1
  57. package/dist/query/helpers/where.d.ts.map +1 -1
  58. package/dist/query/helpers/where.js.map +1 -1
  59. package/dist/query/helpers/where.mjs.map +1 -1
  60. package/dist/query/query-builder.js +30 -26
  61. package/dist/query/query-builder.js.map +1 -1
  62. package/dist/schema/builder.js +5 -1
  63. package/dist/schema/builder.js.map +1 -1
  64. package/dist/schema/diff.js +19 -15
  65. package/dist/schema/diff.js.map +1 -1
  66. package/dist/schema/index.js +5 -1
  67. package/dist/schema/index.js.map +1 -1
  68. package/dist/schema/storage.js +5 -1
  69. package/dist/schema/storage.js.map +1 -1
  70. package/dist/utils/identifiers/hash.js +5 -1
  71. package/dist/utils/identifiers/hash.js.map +1 -1
  72. package/dist/utils/identifiers/index.js +5 -1
  73. package/dist/utils/identifiers/index.js.map +1 -1
  74. package/dist/utils/knex.js +6 -1
  75. package/dist/utils/knex.js.map +1 -1
  76. package/package.json +5 -5
@@ -2,6 +2,10 @@
2
2
 
3
3
  var knex = require('knex');
4
4
 
5
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
6
+
7
+ var knex__default = /*#__PURE__*/_interopDefault(knex);
8
+
5
9
  const clientMap = {
6
10
  sqlite: 'better-sqlite3',
7
11
  mysql: 'mysql2',
@@ -36,7 +40,7 @@ const createConnection = (userConfig, strapiConfig)=>{
36
40
  });
37
41
  };
38
42
  }
39
- return knex(knexConfig);
43
+ return knex__default.default(knexConfig);
40
44
  };
41
45
 
42
46
  exports.createConnection = createConnection;
@@ -1 +1 @@
1
- {"version":3,"file":"connection.js","sources":["../src/connection.ts"],"sourcesContent":["import knex from 'knex';\nimport type { Knex } from 'knex';\n\nconst clientMap = {\n sqlite: 'better-sqlite3',\n mysql: 'mysql2',\n postgres: 'pg',\n};\n\nfunction isClientValid(config: { client?: unknown }): config is { client: keyof typeof clientMap } {\n return Object.keys(clientMap).includes(config.client as string);\n}\n\nexport const createConnection = (userConfig: Knex.Config, strapiConfig?: Partial<Knex.Config>) => {\n if (!isClientValid(userConfig)) {\n throw new Error(`Unsupported database client ${userConfig.client}`);\n }\n\n const knexConfig: Knex.Config = { ...userConfig, client: (clientMap as any)[userConfig.client] };\n\n // initialization code to run upon opening a new connection\n if (strapiConfig?.pool?.afterCreate) {\n knexConfig.pool = knexConfig.pool || {};\n // if the user has set their own afterCreate in config, we will replace it and call it\n const userAfterCreate = knexConfig.pool?.afterCreate;\n const strapiAfterCreate = strapiConfig.pool.afterCreate;\n knexConfig.pool.afterCreate = (\n conn: unknown,\n done: (err: Error | null | undefined, connection: any) => void\n ) => {\n strapiAfterCreate(conn, (err: Error | null | undefined, nativeConn: any) => {\n if (err) {\n return done(err, nativeConn);\n }\n if (userAfterCreate) {\n return userAfterCreate(nativeConn, done);\n }\n return done(null, nativeConn);\n });\n };\n }\n\n return knex(knexConfig);\n};\n"],"names":["clientMap","sqlite","mysql","postgres","isClientValid","config","Object","keys","includes","client","createConnection","userConfig","strapiConfig","Error","knexConfig","pool","afterCreate","userAfterCreate","strapiAfterCreate","conn","done","err","nativeConn","knex"],"mappings":";;;;AAGA,MAAMA,SAAAA,GAAY;IAChBC,MAAAA,EAAQ,gBAAA;IACRC,KAAAA,EAAO,QAAA;IACPC,QAAAA,EAAU;AACZ,CAAA;AAEA,SAASC,cAAcC,MAA4B,EAAA;AACjD,IAAA,OAAOC,OAAOC,IAAI,CAACP,WAAWQ,QAAQ,CAACH,OAAOI,MAAM,CAAA;AACtD;AAEO,MAAMC,gBAAAA,GAAmB,CAACC,UAAAA,EAAyBC,YAAAA,GAAAA;IACxD,IAAI,CAACR,cAAcO,UAAAA,CAAAA,EAAa;AAC9B,QAAA,MAAM,IAAIE,KAAAA,CAAM,CAAC,4BAA4B,EAAEF,UAAAA,CAAWF,MAAM,CAAA,CAAE,CAAA;AACpE,IAAA;AAEA,IAAA,MAAMK,UAAAA,GAA0B;AAAE,QAAA,GAAGH,UAAU;AAAEF,QAAAA,MAAAA,EAAQ,SAAkB,CAACE,UAAAA,CAAWF,MAAM;AAAE,KAAA;;IAG/F,IAAIG,YAAAA,EAAcG,MAAMC,WAAAA,EAAa;AACnCF,QAAAA,UAAAA,CAAWC,IAAI,GAAGD,UAAAA,CAAWC,IAAI,IAAI,EAAC;;QAEtC,MAAME,eAAAA,GAAkBH,UAAAA,CAAWC,IAAI,EAAEC,WAAAA;AACzC,QAAA,MAAME,iBAAAA,GAAoBN,YAAAA,CAAaG,IAAI,CAACC,WAAW;AACvDF,QAAAA,UAAAA,CAAWC,IAAI,CAACC,WAAW,GAAG,CAC5BG,IAAAA,EACAC,IAAAA,GAAAA;YAEAF,iBAAAA,CAAkBC,IAAAA,EAAM,CAACE,GAAAA,EAA+BC,UAAAA,GAAAA;AACtD,gBAAA,IAAID,GAAAA,EAAK;AACP,oBAAA,OAAOD,KAAKC,GAAAA,EAAKC,UAAAA,CAAAA;AACnB,gBAAA;AACA,gBAAA,IAAIL,eAAAA,EAAiB;AACnB,oBAAA,OAAOA,gBAAgBK,UAAAA,EAAYF,IAAAA,CAAAA;AACrC,gBAAA;AACA,gBAAA,OAAOA,KAAK,IAAA,EAAME,UAAAA,CAAAA;AACpB,YAAA,CAAA,CAAA;AACF,QAAA,CAAA;AACF,IAAA;AAEA,IAAA,OAAOC,IAAAA,CAAKT,UAAAA,CAAAA;AACd;;;;"}
1
+ {"version":3,"file":"connection.js","sources":["../src/connection.ts"],"sourcesContent":["import knex from 'knex';\nimport type { Knex } from 'knex';\n\nconst clientMap = {\n sqlite: 'better-sqlite3',\n mysql: 'mysql2',\n postgres: 'pg',\n};\n\nfunction isClientValid(config: { client?: unknown }): config is { client: keyof typeof clientMap } {\n return Object.keys(clientMap).includes(config.client as string);\n}\n\nexport const createConnection = (userConfig: Knex.Config, strapiConfig?: Partial<Knex.Config>) => {\n if (!isClientValid(userConfig)) {\n throw new Error(`Unsupported database client ${userConfig.client}`);\n }\n\n const knexConfig: Knex.Config = { ...userConfig, client: (clientMap as any)[userConfig.client] };\n\n // initialization code to run upon opening a new connection\n if (strapiConfig?.pool?.afterCreate) {\n knexConfig.pool = knexConfig.pool || {};\n // if the user has set their own afterCreate in config, we will replace it and call it\n const userAfterCreate = knexConfig.pool?.afterCreate;\n const strapiAfterCreate = strapiConfig.pool.afterCreate;\n knexConfig.pool.afterCreate = (\n conn: unknown,\n done: (err: Error | null | undefined, connection: any) => void\n ) => {\n strapiAfterCreate(conn, (err: Error | null | undefined, nativeConn: any) => {\n if (err) {\n return done(err, nativeConn);\n }\n if (userAfterCreate) {\n return userAfterCreate(nativeConn, done);\n }\n return done(null, nativeConn);\n });\n };\n }\n\n return knex(knexConfig);\n};\n"],"names":["clientMap","sqlite","mysql","postgres","isClientValid","config","Object","keys","includes","client","createConnection","userConfig","strapiConfig","Error","knexConfig","pool","afterCreate","userAfterCreate","strapiAfterCreate","conn","done","err","nativeConn","knex"],"mappings":";;;;;;;;AAGA,MAAMA,SAAAA,GAAY;IAChBC,MAAAA,EAAQ,gBAAA;IACRC,KAAAA,EAAO,QAAA;IACPC,QAAAA,EAAU;AACZ,CAAA;AAEA,SAASC,cAAcC,MAA4B,EAAA;AACjD,IAAA,OAAOC,OAAOC,IAAI,CAACP,WAAWQ,QAAQ,CAACH,OAAOI,MAAM,CAAA;AACtD;AAEO,MAAMC,gBAAAA,GAAmB,CAACC,UAAAA,EAAyBC,YAAAA,GAAAA;IACxD,IAAI,CAACR,cAAcO,UAAAA,CAAAA,EAAa;AAC9B,QAAA,MAAM,IAAIE,KAAAA,CAAM,CAAC,4BAA4B,EAAEF,UAAAA,CAAWF,MAAM,CAAA,CAAE,CAAA;AACpE,IAAA;AAEA,IAAA,MAAMK,UAAAA,GAA0B;AAAE,QAAA,GAAGH,UAAU;AAAEF,QAAAA,MAAAA,EAAQ,SAAkB,CAACE,UAAAA,CAAWF,MAAM;AAAE,KAAA;;IAG/F,IAAIG,YAAAA,EAAcG,MAAMC,WAAAA,EAAa;AACnCF,QAAAA,UAAAA,CAAWC,IAAI,GAAGD,UAAAA,CAAWC,IAAI,IAAI,EAAC;;QAEtC,MAAME,eAAAA,GAAkBH,UAAAA,CAAWC,IAAI,EAAEC,WAAAA;AACzC,QAAA,MAAME,iBAAAA,GAAoBN,YAAAA,CAAaG,IAAI,CAACC,WAAW;AACvDF,QAAAA,UAAAA,CAAWC,IAAI,CAACC,WAAW,GAAG,CAC5BG,IAAAA,EACAC,IAAAA,GAAAA;YAEAF,iBAAAA,CAAkBC,IAAAA,EAAM,CAACE,GAAAA,EAA+BC,UAAAA,GAAAA;AACtD,gBAAA,IAAID,GAAAA,EAAK;AACP,oBAAA,OAAOD,KAAKC,GAAAA,EAAKC,UAAAA,CAAAA;AACnB,gBAAA;AACA,gBAAA,IAAIL,eAAAA,EAAiB;AACnB,oBAAA,OAAOA,gBAAgBK,UAAAA,EAAYF,IAAAA,CAAAA;AACrC,gBAAA;AACA,gBAAA,OAAOA,KAAK,IAAA,EAAME,UAAAA,CAAAA;AACpB,YAAA,CAAA,CAAA;AACF,QAAA,CAAA;AACF,IAAA;AAEA,IAAA,OAAOC,qBAAAA,CAAKT,UAAAA,CAAAA;AACd;;;;"}
@@ -6,8 +6,11 @@ export default class MysqlSchemaInspector implements SchemaInspector {
6
6
  constructor(db: Database);
7
7
  getSchema(): Promise<Schema>;
8
8
  getTables(): Promise<string[]>;
9
+ getBulkColumns(tableNames: string[]): Promise<Map<string, Column[]>>;
9
10
  getColumns(tableName: string): Promise<Column[]>;
11
+ getBulkIndexes(tableNames: string[]): Promise<Map<string, Index[]>>;
10
12
  getIndexes(tableName: string): Promise<Index[]>;
13
+ getBulkForeignKeys(tableNames: string[]): Promise<Map<string, ForeignKey[]>>;
11
14
  getForeignKeys(tableName: string): Promise<ForeignKey[]>;
12
15
  }
13
16
  //# sourceMappingURL=schema-inspector.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"schema-inspector.d.ts","sourceRoot":"","sources":["../../../src/dialects/mysql/schema-inspector.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAsItC,MAAM,CAAC,OAAO,OAAO,oBAAqB,YAAW,eAAe;IAClE,EAAE,EAAE,QAAQ,CAAC;gBAED,EAAE,EAAE,QAAQ;IAIlB,SAAS;IAuBT,SAAS,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAM9B,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAoBhD,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;IA4B/C,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;CA+C/D"}
1
+ {"version":3,"file":"schema-inspector.d.ts","sourceRoot":"","sources":["../../../src/dialects/mysql/schema-inspector.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAiJtC,MAAM,CAAC,OAAO,OAAO,oBAAqB,YAAW,eAAe;IAClE,EAAE,EAAE,QAAQ,CAAC;gBAED,EAAE,EAAE,QAAQ;IAIlB,SAAS;IA0BT,SAAS,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAM9B,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAmCpE,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAKhD,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;IA8CnE,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;IAK/C,kBAAkB,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;IAmD5E,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;CAI/D"}
@@ -8,8 +8,9 @@ const SQL_QUERIES = {
8
8
  WHERE table_type = 'BASE TABLE'
9
9
  AND table_schema = schema();
10
10
  `,
11
- LIST_COLUMNS: /* sql */ `
11
+ BULK_COLUMNS: /* sql */ `
12
12
  SELECT
13
+ c.table_name as table_name,
13
14
  c.data_type as data_type,
14
15
  c.column_name as column_name,
15
16
  c.character_maximum_length as character_maximum_length,
@@ -19,39 +20,41 @@ const SQL_QUERIES = {
19
20
  c.column_key as column_key
20
21
  FROM information_schema.columns c
21
22
  WHERE table_schema = database()
22
- AND table_name = ?;
23
+ AND table_name in (:tables);
23
24
  `,
24
- INDEX_LIST: /* sql */ `
25
- show index from ??;
26
- `,
27
- FOREIGN_KEY_LIST: /* sql */ `
25
+ BULK_INDEXES: /* sql */ `
28
26
  SELECT
29
- tc.constraint_name as constraint_name
30
- FROM information_schema.table_constraints tc
31
- WHERE tc.constraint_type = 'FOREIGN KEY'
32
- AND tc.table_schema = database()
33
- AND tc.table_name = ?;
27
+ s.table_name as table_name,
28
+ s.index_name as key_name,
29
+ s.column_name as column_name,
30
+ s.non_unique as non_unique
31
+ FROM information_schema.statistics s
32
+ WHERE s.table_schema = database()
33
+ AND s.table_name in (:tables)
34
+ ORDER BY s.table_name, s.index_name, s.seq_in_index;
34
35
  `,
35
- FOREIGN_KEY_REFERENCES: /* sql */ `
36
+ BULK_FOREIGN_KEYS: /* sql */ `
36
37
  SELECT
37
- kcu.constraint_name as constraint_name,
38
+ tc.table_name as table_name,
39
+ tc.constraint_name as constraint_name,
38
40
  kcu.column_name as column_name,
39
41
  kcu.referenced_table_name as referenced_table_name,
40
- kcu.referenced_column_name as referenced_column_name
41
- FROM information_schema.key_column_usage kcu
42
- WHERE kcu.constraint_name in (?)
43
- AND kcu.table_schema = database()
44
- AND kcu.table_name = ?;
45
- `,
46
- FOREIGN_KEY_REFERENTIALS_CONSTRAINTS: /* sql */ `
47
- SELECT
48
- rc.constraint_name as constraint_name,
42
+ kcu.referenced_column_name as referenced_column_name,
49
43
  rc.update_rule as on_update,
50
44
  rc.delete_rule as on_delete
51
- FROM information_schema.referential_constraints AS rc
52
- WHERE rc.constraint_name in (?)
53
- AND rc.constraint_schema = database()
54
- AND rc.table_name = ?;
45
+ FROM information_schema.table_constraints tc
46
+ JOIN information_schema.key_column_usage kcu
47
+ ON tc.constraint_name = kcu.constraint_name
48
+ AND tc.table_schema = kcu.table_schema
49
+ AND tc.table_name = kcu.table_name
50
+ JOIN information_schema.referential_constraints rc
51
+ ON tc.constraint_name = rc.constraint_name
52
+ AND tc.table_schema = rc.constraint_schema
53
+ AND tc.table_name = rc.table_name
54
+ WHERE tc.constraint_type = 'FOREIGN KEY'
55
+ AND tc.table_schema = database()
56
+ AND tc.table_name in (:tables)
57
+ ORDER BY tc.table_name, tc.constraint_name, kcu.ordinal_position;
55
58
  `
56
59
  };
57
60
  const toStrapiType = (column)=>{
@@ -191,30 +194,38 @@ class MysqlSchemaInspector {
191
194
  tables: []
192
195
  };
193
196
  const tables = await this.getTables();
194
- schema.tables = await Promise.all(tables.map(async (tableName)=>{
195
- const columns = await this.getColumns(tableName);
196
- const indexes = await this.getIndexes(tableName);
197
- const foreignKeys = await this.getForeignKeys(tableName);
198
- return {
197
+ if (tables.length === 0) {
198
+ return schema;
199
+ }
200
+ // Run 3 bulk queries in parallel instead of N+1 per-table queries
201
+ const [allColumns, allIndexes, allForeignKeys] = await Promise.all([
202
+ this.getBulkColumns(tables),
203
+ this.getBulkIndexes(tables),
204
+ this.getBulkForeignKeys(tables)
205
+ ]);
206
+ schema.tables = tables.map((tableName)=>({
199
207
  name: tableName,
200
- columns,
201
- indexes,
202
- foreignKeys
203
- };
204
- }));
208
+ columns: allColumns.get(tableName) ?? [],
209
+ indexes: allIndexes.get(tableName) ?? [],
210
+ foreignKeys: allForeignKeys.get(tableName) ?? []
211
+ }));
205
212
  return schema;
206
213
  }
207
214
  async getTables() {
208
215
  const [rows] = await this.db.connection.raw(SQL_QUERIES.TABLE_LIST);
209
216
  return rows.map((row)=>row.table_name);
210
217
  }
211
- async getColumns(tableName) {
212
- const [rows] = await this.db.connection.raw(SQL_QUERIES.LIST_COLUMNS, [
213
- tableName
214
- ]);
215
- return rows.map((row)=>{
218
+ async getBulkColumns(tableNames) {
219
+ if (tableNames.length === 0) {
220
+ return new Map();
221
+ }
222
+ const [rows] = await this.db.connection.raw(SQL_QUERIES.BULK_COLUMNS, {
223
+ tables: this.db.connection.raw(tableNames.map(()=>'?').join(', '), tableNames)
224
+ });
225
+ const result = new Map();
226
+ for (const row of rows){
216
227
  const { type, args = [], ...rest } = toStrapiType(row);
217
- return {
228
+ const column = {
218
229
  type,
219
230
  args,
220
231
  defaultTo: row.column_default,
@@ -223,70 +234,119 @@ class MysqlSchemaInspector {
223
234
  unsigned: row.column_type.endsWith(' unsigned'),
224
235
  ...rest
225
236
  };
226
- });
237
+ const existing = result.get(row.table_name);
238
+ if (existing) {
239
+ existing.push(column);
240
+ } else {
241
+ result.set(row.table_name, [
242
+ column
243
+ ]);
244
+ }
245
+ }
246
+ return result;
227
247
  }
228
- async getIndexes(tableName) {
229
- const [rows] = await this.db.connection.raw(SQL_QUERIES.INDEX_LIST, [
248
+ async getColumns(tableName) {
249
+ const result = await this.getBulkColumns([
230
250
  tableName
231
251
  ]);
232
- const ret = {};
252
+ return result.get(tableName) ?? [];
253
+ }
254
+ async getBulkIndexes(tableNames) {
255
+ if (tableNames.length === 0) {
256
+ return new Map();
257
+ }
258
+ const [rows] = await this.db.connection.raw(SQL_QUERIES.BULK_INDEXES, {
259
+ tables: this.db.connection.raw(tableNames.map(()=>'?').join(', '), tableNames)
260
+ });
261
+ // Group by table, then by key_name
262
+ const byTable = new Map();
233
263
  for (const index of rows){
234
- if (index.Column_name === 'id') {
264
+ if (index.column_name === 'id') {
235
265
  continue;
236
266
  }
237
- if (!ret[index.Key_name]) {
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.key_name);
273
+ if (existing) {
274
+ existing.columns.push(index.column_name);
275
+ } else {
238
276
  const indexInfo = {
239
277
  columns: [
240
- index.Column_name
278
+ index.column_name
241
279
  ],
242
- name: index.Key_name
280
+ name: index.key_name
243
281
  };
244
- if (!index.Non_unique || index.Non_unique === '0') {
282
+ if (!index.non_unique || index.non_unique === '0') {
245
283
  indexInfo.type = 'unique';
246
284
  }
247
- ret[index.Key_name] = indexInfo;
248
- } else {
249
- ret[index.Key_name].columns.push(index.Column_name);
285
+ tableIndexes.set(index.key_name, indexInfo);
250
286
  }
251
287
  }
252
- return Object.values(ret);
288
+ const result = new Map();
289
+ for (const [tableName, tableIndexes] of byTable){
290
+ result.set(tableName, Array.from(tableIndexes.values()));
291
+ }
292
+ return result;
253
293
  }
254
- async getForeignKeys(tableName) {
255
- const [rows] = await this.db.connection.raw(SQL_QUERIES.FOREIGN_KEY_LIST, [
294
+ async getIndexes(tableName) {
295
+ const result = await this.getBulkIndexes([
256
296
  tableName
257
297
  ]);
258
- const ret = {};
259
- for (const fk of rows){
260
- ret[fk.constraint_name] = {
261
- name: fk.constraint_name,
262
- columns: [],
263
- referencedColumns: [],
264
- referencedTable: null,
265
- onUpdate: null,
266
- onDelete: null
267
- };
298
+ return result.get(tableName) ?? [];
299
+ }
300
+ async getBulkForeignKeys(tableNames) {
301
+ if (tableNames.length === 0) {
302
+ return new Map();
268
303
  }
269
- const contraintNames = Object.keys(ret);
270
- if (contraintNames.length > 0) {
271
- const [fkReferences] = await this.db.connection.raw(SQL_QUERIES.FOREIGN_KEY_REFERENCES, [
272
- contraintNames,
273
- tableName
274
- ]);
275
- for (const fkReference of fkReferences){
276
- ret[fkReference.constraint_name].referencedTable = fkReference.referenced_table_name;
277
- ret[fkReference.constraint_name].columns.push(fkReference.column_name);
278
- ret[fkReference.constraint_name].referencedColumns.push(fkReference.referenced_column_name);
304
+ const [rows] = await this.db.connection.raw(SQL_QUERIES.BULK_FOREIGN_KEYS, {
305
+ tables: this.db.connection.raw(tableNames.map(()=>'?').join(', '), tableNames)
306
+ });
307
+ // Group by table_name, then by constraint_name
308
+ const byTable = new Map();
309
+ for (const row of rows){
310
+ let tableFKs = byTable.get(row.table_name);
311
+ if (!tableFKs) {
312
+ tableFKs = new Map();
313
+ byTable.set(row.table_name, tableFKs);
279
314
  }
280
- const [fkReferentialConstraints] = await this.db.connection.raw(SQL_QUERIES.FOREIGN_KEY_REFERENTIALS_CONSTRAINTS, [
281
- contraintNames,
282
- tableName
283
- ]);
284
- for (const fkReferentialConstraint of fkReferentialConstraints){
285
- ret[fkReferentialConstraint.constraint_name].onUpdate = fkReferentialConstraint.on_update.toUpperCase();
286
- ret[fkReferentialConstraint.constraint_name].onDelete = fkReferentialConstraint.on_delete.toUpperCase();
315
+ let fk = tableFKs.get(row.constraint_name);
316
+ if (!fk) {
317
+ fk = {
318
+ name: row.constraint_name,
319
+ columns: [
320
+ row.column_name
321
+ ],
322
+ referencedColumns: row.referenced_column_name ? [
323
+ row.referenced_column_name
324
+ ] : [],
325
+ referencedTable: row.referenced_table_name,
326
+ onUpdate: row.on_update?.toUpperCase() ?? null,
327
+ onDelete: row.on_delete?.toUpperCase() ?? null
328
+ };
329
+ tableFKs.set(row.constraint_name, fk);
330
+ } else {
331
+ if (!fk.columns.includes(row.column_name)) {
332
+ fk.columns.push(row.column_name);
333
+ }
334
+ if (row.referenced_column_name && !fk.referencedColumns.includes(row.referenced_column_name)) {
335
+ fk.referencedColumns.push(row.referenced_column_name);
336
+ }
287
337
  }
288
338
  }
289
- return Object.values(ret);
339
+ const result = new Map();
340
+ for (const [tableName, tableFKs] of byTable){
341
+ result.set(tableName, Array.from(tableFKs.values()));
342
+ }
343
+ return result;
344
+ }
345
+ async getForeignKeys(tableName) {
346
+ const result = await this.getBulkForeignKeys([
347
+ tableName
348
+ ]);
349
+ return result.get(tableName) ?? [];
290
350
  }
291
351
  constructor(db){
292
352
  this.db = db;
@@ -1 +1 @@
1
- {"version":3,"file":"schema-inspector.js","sources":["../../../src/dialects/mysql/schema-inspector.ts"],"sourcesContent":["import type { Column, ForeignKey, Index, Schema } from '../../schema/types';\nimport type { SchemaInspector } from '../dialect';\nimport type { Database } from '../..';\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 column_type: string;\n column_key: string;\n}\n\ninterface RawIndex {\n Key_name: string;\n Column_name: string;\n Non_unique: boolean | string;\n}\n\ninterface RawForeignKey {\n constraint_name: string;\n}\n\nconst SQL_QUERIES = {\n TABLE_LIST: /* sql */ `\n SELECT\n t.table_name as table_name\n FROM information_schema.tables t\n WHERE table_type = 'BASE TABLE'\n AND table_schema = schema();\n `,\n LIST_COLUMNS: /* sql */ `\n SELECT\n c.data_type as data_type,\n c.column_name as column_name,\n c.character_maximum_length as character_maximum_length,\n c.column_default as column_default,\n c.is_nullable as is_nullable,\n c.column_type as column_type,\n c.column_key as column_key\n FROM information_schema.columns c\n WHERE table_schema = database()\n AND table_name = ?;\n `,\n INDEX_LIST: /* sql */ `\n show index from ??;\n `,\n FOREIGN_KEY_LIST: /* sql */ `\n SELECT\n tc.constraint_name as constraint_name\n FROM information_schema.table_constraints tc\n WHERE tc.constraint_type = 'FOREIGN KEY'\n AND tc.table_schema = database()\n AND tc.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 kcu.referenced_table_name as referenced_table_name,\n kcu.referenced_column_name as referenced_column_name\n FROM information_schema.key_column_usage kcu\n WHERE kcu.constraint_name in (?)\n AND kcu.table_schema = database()\n AND kcu.table_name = ?;\n `,\n FOREIGN_KEY_REFERENTIALS_CONSTRAINTS: /* sql */ `\n SELECT\n rc.constraint_name as constraint_name,\n rc.update_rule as on_update,\n rc.delete_rule as on_delete\n FROM information_schema.referential_constraints AS rc\n WHERE rc.constraint_name in (?)\n AND rc.constraint_schema = database()\n AND rc.table_name = ?;\n `,\n};\n\nconst toStrapiType = (column: RawColumn) => {\n const rootType = column.data_type.toLowerCase().match(/[^(), ]+/)?.[0];\n\n switch (rootType) {\n case 'int': {\n if (column.column_key === 'PRI') {\n return { type: 'increments', args: [{ primary: true, primaryKey: true }], unsigned: false };\n }\n\n return { type: 'integer' };\n }\n case 'decimal': {\n return { type: 'decimal', args: [10, 2] };\n }\n case 'double': {\n return { type: 'double' };\n }\n case 'bigint': {\n return { type: 'bigInteger' };\n }\n case 'enum': {\n return { type: 'string' };\n }\n case 'tinyint': {\n return { type: 'boolean' };\n }\n case 'longtext': {\n return { type: 'text', args: ['longtext'] };\n }\n case 'varchar': {\n return { type: 'string', args: [column.character_maximum_length] };\n }\n case 'datetime': {\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 'timestamp': {\n return { type: 'timestamp', args: [{ useTz: false, precision: 6 }] };\n }\n case 'json': {\n return { type: 'jsonb' };\n }\n default: {\n return { type: 'specificType', args: [column.data_type] };\n }\n }\n};\n\nexport default class MysqlSchemaInspector 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 async getTables(): Promise<string[]> {\n const [rows] = await this.db.connection.raw<[RawTable[]]>(SQL_QUERIES.TABLE_LIST);\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<[RawColumn[]]>(SQL_QUERIES.LIST_COLUMNS, [\n tableName,\n ]);\n\n return rows.map((row) => {\n const { type, args = [], ...rest } = toStrapiType(row);\n\n return {\n type,\n args,\n defaultTo: row.column_default,\n name: row.column_name,\n notNullable: row.is_nullable === 'NO',\n unsigned: row.column_type.endsWith(' unsigned'),\n ...rest,\n };\n });\n }\n\n async getIndexes(tableName: string): Promise<Index[]> {\n const [rows] = await this.db.connection.raw<[RawIndex[]]>(SQL_QUERIES.INDEX_LIST, [tableName]);\n\n const ret: Record<RawIndex['Key_name'], Index> = {};\n\n for (const index of rows) {\n if (index.Column_name === 'id') {\n continue;\n }\n\n if (!ret[index.Key_name]) {\n const indexInfo: Index = {\n columns: [index.Column_name],\n name: index.Key_name,\n };\n if (!index.Non_unique || index.Non_unique === '0') {\n indexInfo.type = 'unique';\n }\n\n ret[index.Key_name] = indexInfo;\n } else {\n ret[index.Key_name].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<[RawForeignKey[]]>(SQL_QUERIES.FOREIGN_KEY_LIST, [\n 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 contraintNames = Object.keys(ret);\n\n if (contraintNames.length > 0) {\n const [fkReferences] = await this.db.connection.raw(SQL_QUERIES.FOREIGN_KEY_REFERENCES, [\n contraintNames,\n tableName,\n ]);\n\n for (const fkReference of fkReferences) {\n ret[fkReference.constraint_name].referencedTable = fkReference.referenced_table_name;\n ret[fkReference.constraint_name].columns.push(fkReference.column_name);\n ret[fkReference.constraint_name].referencedColumns.push(fkReference.referenced_column_name);\n }\n\n const [fkReferentialConstraints] = await this.db.connection.raw(\n SQL_QUERIES.FOREIGN_KEY_REFERENTIALS_CONSTRAINTS,\n [contraintNames, tableName]\n );\n\n for (const fkReferentialConstraint of fkReferentialConstraints) {\n ret[fkReferentialConstraint.constraint_name].onUpdate =\n fkReferentialConstraint.on_update.toUpperCase();\n ret[fkReferentialConstraint.constraint_name].onDelete =\n fkReferentialConstraint.on_delete.toUpperCase();\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_REFERENTIALS_CONSTRAINTS","toStrapiType","column","rootType","data_type","toLowerCase","match","column_key","type","args","primary","primaryKey","unsigned","character_maximum_length","useTz","precision","MysqlSchemaInspector","getSchema","schema","tables","getTables","Promise","all","map","tableName","columns","getColumns","indexes","getIndexes","foreignKeys","getForeignKeys","name","rows","db","connection","raw","row","table_name","rest","defaultTo","column_default","column_name","notNullable","is_nullable","column_type","endsWith","ret","index","Column_name","Key_name","indexInfo","Non_unique","push","Object","values","fk","constraint_name","referencedColumns","referencedTable","onUpdate","onDelete","contraintNames","keys","length","fkReferences","fkReference","referenced_table_name","referenced_column_name","fkReferentialConstraints","fkReferentialConstraint","on_update","toUpperCase","on_delete"],"mappings":"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"}
1
+ {"version":3,"file":"schema-inspector.js","sources":["../../../src/dialects/mysql/schema-inspector.ts"],"sourcesContent":["import type { Column, ForeignKey, Index, Schema } from '../../schema/types';\nimport type { SchemaInspector } from '../dialect';\nimport type { Database } from '../..';\n\ninterface RawTable {\n table_name: string;\n}\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 column_type: string;\n column_key: string;\n}\n\ninterface RawIndex {\n table_name: string;\n key_name: string;\n column_name: string;\n non_unique: number | string;\n}\n\ninterface RawForeignKey {\n table_name: string;\n constraint_name: string;\n column_name: string;\n referenced_table_name: string | null;\n referenced_column_name: string | null;\n on_update: string;\n on_delete: string;\n}\n\nconst SQL_QUERIES = {\n TABLE_LIST: /* sql */ `\n SELECT\n t.table_name as table_name\n FROM information_schema.tables t\n WHERE table_type = 'BASE TABLE'\n AND table_schema = schema();\n `,\n BULK_COLUMNS: /* sql */ `\n SELECT\n c.table_name as table_name,\n c.data_type as data_type,\n c.column_name as column_name,\n c.character_maximum_length as character_maximum_length,\n c.column_default as column_default,\n c.is_nullable as is_nullable,\n c.column_type as column_type,\n c.column_key as column_key\n FROM information_schema.columns c\n WHERE table_schema = database()\n AND table_name in (:tables);\n `,\n BULK_INDEXES: /* sql */ `\n SELECT\n s.table_name as table_name,\n s.index_name as key_name,\n s.column_name as column_name,\n s.non_unique as non_unique\n FROM information_schema.statistics s\n WHERE s.table_schema = database()\n AND s.table_name in (:tables)\n ORDER BY s.table_name, s.index_name, s.seq_in_index;\n `,\n BULK_FOREIGN_KEYS: /* sql */ `\n SELECT\n tc.table_name as table_name,\n tc.constraint_name as constraint_name,\n kcu.column_name as column_name,\n kcu.referenced_table_name as referenced_table_name,\n kcu.referenced_column_name as referenced_column_name,\n rc.update_rule as on_update,\n rc.delete_rule as on_delete\n FROM information_schema.table_constraints tc\n JOIN information_schema.key_column_usage kcu\n ON tc.constraint_name = kcu.constraint_name\n AND tc.table_schema = kcu.table_schema\n AND tc.table_name = kcu.table_name\n JOIN information_schema.referential_constraints rc\n ON tc.constraint_name = rc.constraint_name\n AND tc.table_schema = rc.constraint_schema\n AND tc.table_name = rc.table_name\n WHERE tc.constraint_type = 'FOREIGN KEY'\n AND tc.table_schema = database()\n AND tc.table_name in (:tables)\n ORDER BY tc.table_name, tc.constraint_name, kcu.ordinal_position;\n `,\n};\n\nconst toStrapiType = (column: RawColumn) => {\n const rootType = column.data_type.toLowerCase().match(/[^(), ]+/)?.[0];\n\n switch (rootType) {\n case 'int': {\n if (column.column_key === 'PRI') {\n return { type: 'increments', args: [{ primary: true, primaryKey: true }], unsigned: false };\n }\n\n return { type: 'integer' };\n }\n case 'decimal': {\n return { type: 'decimal', args: [10, 2] };\n }\n case 'double': {\n return { type: 'double' };\n }\n case 'bigint': {\n return { type: 'bigInteger' };\n }\n case 'enum': {\n return { type: 'string' };\n }\n case 'tinyint': {\n return { type: 'boolean' };\n }\n case 'longtext': {\n return { type: 'text', args: ['longtext'] };\n }\n case 'varchar': {\n return { type: 'string', args: [column.character_maximum_length] };\n }\n case 'datetime': {\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 'timestamp': {\n return { type: 'timestamp', args: [{ useTz: false, precision: 6 }] };\n }\n case 'json': {\n return { type: 'jsonb' };\n }\n default: {\n return { type: 'specificType', args: [column.data_type] };\n }\n }\n};\n\nexport default class MysqlSchemaInspector 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 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(tables),\n this.getBulkIndexes(tables),\n this.getBulkForeignKeys(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 async getTables(): Promise<string[]> {\n const [rows] = await this.db.connection.raw<[RawTable[]]>(SQL_QUERIES.TABLE_LIST);\n\n return rows.map((row) => row.table_name);\n }\n\n async getBulkColumns(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<[RawColumn[]]>(SQL_QUERIES.BULK_COLUMNS, {\n tables: this.db.connection.raw(tableNames.map(() => '?').join(', '), 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\n const column: Column = {\n type,\n args,\n defaultTo: row.column_default,\n name: row.column_name,\n notNullable: row.is_nullable === 'NO',\n unsigned: row.column_type.endsWith(' unsigned'),\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 getColumns(tableName: string): Promise<Column[]> {\n const result = await this.getBulkColumns([tableName]);\n return result.get(tableName) ?? [];\n }\n\n async getBulkIndexes(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<[RawIndex[]]>(SQL_QUERIES.BULK_INDEXES, {\n tables: this.db.connection.raw(tableNames.map(() => '?').join(', '), tableNames),\n });\n\n // Group by table, then by key_name\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.key_name);\n if (existing) {\n existing.columns.push(index.column_name);\n } else {\n const indexInfo: Index = {\n columns: [index.column_name],\n name: index.key_name,\n };\n if (!index.non_unique || index.non_unique === '0') {\n indexInfo.type = 'unique';\n }\n tableIndexes.set(index.key_name, indexInfo);\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 result = await this.getBulkIndexes([tableName]);\n return result.get(tableName) ?? [];\n }\n\n async getBulkForeignKeys(tableNames: string[]): Promise<Map<string, ForeignKey[]>> {\n if (tableNames.length === 0) {\n return new Map();\n }\n\n const [rows] = await this.db.connection.raw<[RawForeignKey[]]>(SQL_QUERIES.BULK_FOREIGN_KEYS, {\n tables: this.db.connection.raw(tableNames.map(() => '?').join(', '), tableNames),\n });\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.referenced_column_name ? [row.referenced_column_name] : [],\n referencedTable: row.referenced_table_name,\n onUpdate: row.on_update?.toUpperCase() ?? null,\n onDelete: row.on_delete?.toUpperCase() ?? null,\n } as unknown as ForeignKey;\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 (\n row.referenced_column_name &&\n !fk.referencedColumns.includes(row.referenced_column_name)\n ) {\n fk.referencedColumns.push(row.referenced_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 async getForeignKeys(tableName: string): Promise<ForeignKey[]> {\n const result = await this.getBulkForeignKeys([tableName]);\n return result.get(tableName) ?? [];\n }\n}\n"],"names":["SQL_QUERIES","TABLE_LIST","BULK_COLUMNS","BULK_INDEXES","BULK_FOREIGN_KEYS","toStrapiType","column","rootType","data_type","toLowerCase","match","column_key","type","args","primary","primaryKey","unsigned","character_maximum_length","useTz","precision","MysqlSchemaInspector","getSchema","schema","tables","getTables","length","allColumns","allIndexes","allForeignKeys","Promise","all","getBulkColumns","getBulkIndexes","getBulkForeignKeys","map","tableName","name","columns","get","indexes","foreignKeys","rows","db","connection","raw","row","table_name","tableNames","Map","join","result","rest","defaultTo","column_default","column_name","notNullable","is_nullable","column_type","endsWith","existing","push","set","getColumns","byTable","index","tableIndexes","key_name","indexInfo","non_unique","Array","from","values","getIndexes","tableFKs","fk","constraint_name","referencedColumns","referenced_column_name","referencedTable","referenced_table_name","onUpdate","on_update","toUpperCase","onDelete","on_delete","includes","getForeignKeys"],"mappings":"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"}