| 71 | } |
| 72 | |
| 73 | export default class MySQL implements SchemaInspector { |
| 74 | knex: Knex; |
| 75 | |
| 76 | constructor(knex: Knex) { |
| 77 | this.knex = knex; |
| 78 | } |
| 79 | |
| 80 | // Overview |
| 81 | // =============================================================================================== |
| 82 | |
| 83 | async overview(): Promise<SchemaOverview> { |
| 84 | const columns = await this.knex.raw( |
| 85 | ` |
| 86 | SELECT |
| 87 | C.TABLE_NAME as table_name, |
| 88 | C.COLUMN_NAME as column_name, |
| 89 | C.COLUMN_DEFAULT as default_value, |
| 90 | C.IS_NULLABLE as is_nullable, |
| 91 | C.COLUMN_TYPE as data_type, |
| 92 | C.COLUMN_KEY as column_key, |
| 93 | C.CHARACTER_MAXIMUM_LENGTH as max_length, |
| 94 | C.EXTRA as extra |
| 95 | FROM |
| 96 | INFORMATION_SCHEMA.COLUMNS AS C |
| 97 | LEFT JOIN |
| 98 | INFORMATION_SCHEMA.TABLES AS T ON C.TABLE_NAME = T.TABLE_NAME |
| 99 | AND C.TABLE_SCHEMA = T.TABLE_SCHEMA |
| 100 | WHERE |
| 101 | T.TABLE_TYPE = 'BASE TABLE' AND |
| 102 | C.TABLE_SCHEMA = ?; |
| 103 | `, |
| 104 | [this.knex.client.database()], |
| 105 | ); |
| 106 | |
| 107 | const overview: SchemaOverview = {}; |
| 108 | |
| 109 | for (const column of columns[0]) { |
| 110 | if (column.table_name in overview === false) { |
| 111 | const primaryKeys = columns[0].filter((nested: { column_key: string; table_name: string }) => { |
| 112 | return nested.table_name === column.table_name && nested.column_key === 'PRI'; |
| 113 | }); |
| 114 | |
| 115 | overview[column.table_name] = { |
| 116 | primary: primaryKeys.length !== 1 ? undefined : primaryKeys[0].column_name, |
| 117 | columns: {}, |
| 118 | }; |
| 119 | } |
| 120 | |
| 121 | let dataType = column.data_type.replace(/\(.*?\)/, ''); |
| 122 | |
| 123 | if (column.data_type.startsWith('tinyint(1)')) { |
| 124 | dataType = 'boolean'; |
| 125 | } |
| 126 | |
| 127 | overview[column.table_name]!.columns[column.column_name] = { |
| 128 | ...column, |
| 129 | default_value: column.extra === 'auto_increment' ? 'AUTO_INCREMENT' : parseDefaultValue(column.default_value), |
| 130 | is_nullable: column.is_nullable === 'YES', |
nothing calls this directly
no outgoing calls
no test coverage detected