Skip to content

Commit

Permalink
MySQL optimisation (knex#138)
Browse files Browse the repository at this point in the history
  • Loading branch information
Bobby Alex Philip authored Mar 1, 2023
1 parent 9712422 commit c50b30d
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 28 deletions.
52 changes: 24 additions & 28 deletions lib/dialects/mysql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -289,35 +289,31 @@ export default class MySQL implements SchemaInspector {
// ===============================================================================================

async foreignKeys(table?: string) {
const result = await this.knex.raw<[ForeignKey[]]>(
`
SELECT DISTINCT
rc.TABLE_NAME AS 'table',
kcu.COLUMN_NAME AS 'column',
rc.REFERENCED_TABLE_NAME AS 'foreign_key_table',
kcu.REFERENCED_COLUMN_NAME AS 'foreign_key_column',
rc.CONSTRAINT_NAME AS 'constraint_name',
rc.UPDATE_RULE AS on_update,
rc.DELETE_RULE AS on_delete
FROM
information_schema.referential_constraints AS rc
JOIN information_schema.key_column_usage AS kcu ON
rc.CONSTRAINT_NAME = kcu.CONSTRAINT_NAME
AND kcu.CONSTRAINT_SCHEMA = rc.CONSTRAINT_SCHEMA
WHERE
rc.CONSTRAINT_SCHEMA = ?;
`,
[this.knex.client.database()]
);

// Mapping casts "RowDataPacket" object from mysql to plain JS object

const query = this.knex
.select(
`rc.TABLE_NAME AS table`,
`kcu.COLUMN_NAME AS column`,
`rc.REFERENCED_TABLE_NAME AS foreign_key_table`,
`kcu.REFERENCED_COLUMN_NAME AS foreign_key_column`,
`rc.CONSTRAINT_NAME AS constraint_name`,
`rc.UPDATE_RULE AS on_update`,
`rc.DELETE_RULE AS on_delete`
)
.from(`information_schema.referential_constraints AS rc`)
.leftJoin(`information_schema.key_column_usage AS kcu `, function () {
this.on(`rc.CONSTRAINT_NAME`, `=`, `kcu.CONSTRAINT_NAME`).andOn(
`kcu.CONSTRAINT_SCHEMA`,
`=`,
`rc.CONSTRAINT_SCHEMA`
);
})
.where({
'rc.CONSTRAINT_SCHEMA': this.knex.client.database(),
});
if (table) {
return result?.[0]
?.filter((row) => row.table === table)
.map((row) => ({ ...row }));
query.andWhere({ 'rc.TABLE_NAME': table });
}

return result?.[0].map((row) => ({ ...row }));
const result: ForeignKey[] = await query;
return result;
}
}
14 changes: 14 additions & 0 deletions test/mysql.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -609,5 +609,19 @@ describe('mysql', () => {
it('filters based on table param', async () => {
expect(await inspector.foreignKeys('teams')).to.deep.equal([]);
});

it('filters valid tables based on param', async () => {
expect(await inspector.foreignKeys('users')).to.deep.equal([
{
table: 'users',
column: 'team_id',
foreign_key_table: 'teams',
foreign_key_column: 'id',
constraint_name: 'fk_team_id',
on_delete: 'CASCADE',
on_update: 'CASCADE',
},
]);
});
});
});

0 comments on commit c50b30d

Please sign in to comment.