Skip to content

Commit

Permalink
feat: fetch index info into the model
Browse files Browse the repository at this point in the history
Signed-off-by: Muhammad Aaqil <[email protected]>
  • Loading branch information
aaqilniz committed Oct 20, 2024
1 parent 6af3b7c commit 4de6c6e
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 70 deletions.
140 changes: 70 additions & 70 deletions lib/discovery.js
Original file line number Diff line number Diff line change
Expand Up @@ -158,89 +158,89 @@ function mixinDiscovery(MySQL, mysql) {
let sql = null;
if (schema) {
sql = paginateSQL(
`SELECT
c.table_schema AS "owner",
c.table_name AS "tableName",
c.column_name AS "columnName",
c.data_type AS "dataType",
c.character_maximum_length AS "dataLength",
c.numeric_precision AS "dataPrecision",
c.numeric_scale AS "dataScale",
c.column_type AS "columnType",
c.is_nullable = 'YES' AS "nullable",
CASE WHEN c.extra LIKE '%auto_increment%' THEN 1 ELSE 0 END AS "generated",
s.index_name AS "indexName",
s.non_unique AS "nonUnique",
s.seq_in_index AS "seqInIndex",
s.cardinality AS "cardinality",
s.index_type AS "indexType",
CASE WHEN fk.column_name IS NOT NULL THEN 1 ELSE 0 END AS "isForeignKey" -- Flag for foreign key
FROM
information_schema.columns c
LEFT JOIN
information_schema.statistics s
ON
c.table_schema = s.table_schema
AND c.table_name = s.table_name
AND c.column_name = s.column_name
LEFT JOIN
information_schema.KEY_COLUMN_USAGE fk
ON
c.table_schema = fk.table_schema
AND c.table_name = fk.table_name
AND c.column_name = fk.column_name
AND fk.referenced_table_name IS NOT NULL -- Ensure it's a foreign key
WHERE
c.table_schema = ${mysql.escape(schema)}
${table ? ' AND c.table_name = ' + mysql.escape(table) : ''}
`SELECT
cols.table_schema AS "owner",
cols.table_name AS "tableName",
cols.column_name AS "columnName",
cols.data_type AS "dataType",
cols.character_maximum_length AS "dataLength",
cols.numeric_precision AS "dataPrecision",
cols.numeric_scale AS "dataScale",
cols.column_type AS "columnType",
cols.is_nullable = 'YES' AS "nullable",
CASE WHEN cols.extra LIKE '%auto_increment%' THEN 1 ELSE 0 END AS "generated",
indexes.index_name AS "indexName",
indexes.non_unique AS "nonUnique",
indexes.seq_in_index AS "seqInIndex",
indexes.cardinality AS "cardinality",
indexes.index_type AS "indexType",
CASE WHEN fk.column_name IS NOT NULL THEN 1 ELSE 0 END AS "isForeignKey"
FROM
information_schema.columns cols
LEFT JOIN
information_schema.statistics indexes
ON
cols.table_schema = indexes.table_schema
AND cols.table_name = indexes.table_name
AND cols.column_name = indexes.column_name
LEFT JOIN
information_schema.KEY_COLUMN_USAGE fk
ON
cols.table_schema = fk.table_schema
AND cols.table_name = fk.table_name
AND cols.column_name = fk.column_name
AND fk.referenced_table_name IS NOT NULL
WHERE
cols.table_schema = ${mysql.escape(schema)}
${table ? ' AND cols.table_name = ' + mysql.escape(table) : ''}
`,
'c.table_name, c.ordinal_position',
'cols.table_name, cols.ordinal_position',
{},
);
} else {
sql = paginateSQL(
`SELECT
columns.table_schema AS "owner",
columns.table_name AS "tableName",
columns.column_name AS "columnName",
columns.data_type AS "dataType",
columns.character_maximum_length AS "dataLength",
columns.numeric_precision AS "dataPrecision",
columns.numeric_scale AS "dataScale",
columns.column_type AS "columnType",
columns.is_nullable = 'YES' AS "nullable",
CASE WHEN columns.extra LIKE '%auto_increment%' THEN 1 ELSE 0 END AS "generated",
`SELECT
cols.table_schema AS "owner",
cols.table_name AS "tableName",
cols.column_name AS "columnName",
cols.data_type AS "dataType",
cols.character_maximum_length AS "dataLength",
cols.numeric_precision AS "dataPrecision",
cols.numeric_scale AS "dataScale",
cols.column_type AS "columnType",
cols.is_nullable = 'YES' AS "nullable",
CASE WHEN cols.extra LIKE '%auto_increment%' THEN 1 ELSE 0 END AS "generated",
indexes.index_name AS "indexName",
indexes.seq_in_index AS "indexColumnOrder",
indexes.non_unique AS "nonUnique",
indexes.cardinality AS "cardinality", -- Cardinality of the index
indexes.index_type AS "indexType", -- Type of the index
CASE WHEN fk.column_name IS NOT NULL THEN 1 ELSE 0 END AS "isForeignKey" -- Flag for foreign key
FROM
information_schema.columns AS columns
LEFT JOIN
information_schema.statistics AS indexes
ON
columns.table_schema = indexes.table_schema
AND columns.table_name = indexes.table_name
AND columns.column_name = indexes.column_name
LEFT JOIN
information_schema.KEY_COLUMN_USAGE AS fk
ON
columns.table_schema = fk.table_schema
AND columns.table_name = fk.table_name
AND columns.column_name = fk.column_name
AND fk.referenced_table_name IS NOT NULL -- Ensure it's a foreign key
WHERE
columns.table_schema = ${mysql.escape(schema)}
${table ? ' AND columns.table_name = ' + mysql.escape(table) : ''}
indexes.cardinality AS "cardinality",
indexes.index_type AS "indexType",
CASE WHEN fk.column_name IS NOT NULL THEN 1 ELSE 0 END AS "isForeignKey"
FROM
information_schema.columns AS cols
LEFT JOIN
information_schema.statistics AS indexes
ON
cols.table_schema = indexes.table_schema
AND cols.table_name = indexes.table_name
AND cols.column_name = indexes.column_name
LEFT JOIN
information_schema.KEY_COLUMN_USAGE AS fk
ON
cols.table_schema = fk.table_schema
AND cols.table_name = fk.table_name
AND cols.column_name = fk.column_name
AND fk.referenced_table_name IS NOT NULL
WHERE
cols.table_schema = ${mysql.escape(schema)}
${table ? ' AND cols.table_name = ' + mysql.escape(table) : ''}
`,
'columns.table_name, columns.ordinal_position',
'cols.table_name, cols.ordinal_position',
{},
);
}
if (options.orderBy) {
sql += ' ORDER BY ' + options.orderBy;
sql += ' ORDER BY ' + 'cols.' + options.orderBy;
}
return sql;
};
Expand Down
18 changes: 18 additions & 0 deletions test/mysql.discover.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,24 @@ describe('Discover model primary keys', function() {
});
});


Check failure on line 202 in test/mysql.discover.test.js

View workflow job for this annotation

GitHub Actions / Code Lint

More than 1 blank line not allowed

Check failure on line 202 in test/mysql.discover.test.js

View workflow job for this annotation

GitHub Actions / build (18)

More than 1 blank line not allowed

Check failure on line 202 in test/mysql.discover.test.js

View workflow job for this annotation

GitHub Actions / build (20)

More than 1 blank line not allowed
describe('Discover user model with index', function() {
it('should return user with index', function(done) {
db.discoverModelProperties('user', function(err, models) {
if (err) {
console.error(err);
done(err);
} else {
models.forEach(function(m) {
assert(m.tableName.toLowerCase() === 'user');
assert(m.properties.email.index);
});
done(null, models);
}
});
});
});

describe('Discover model foreign keys', function() {
it('should return an array of foreign keys for INVENTORY', function(done) {
db.discoverForeignKeys('INVENTORY', function(err, models) {
Expand Down
15 changes: 15 additions & 0 deletions test/schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,21 @@ LOCK TABLES `RESERVATION` WRITE;
/*!40000 ALTER TABLE `RESERVATION` ENABLE KEYS */;
UNLOCK TABLES;

DROP TABLE IF EXISTS `USER`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;

CREATE TABLE `USER` (
`ID` VARCHAR(20) NOT NULL,
`NAME` VARCHAR(100) NOT NULL,
`EMAIL` VARCHAR(255) NOT NULL,
`PASSWORD` VARCHAR(255) NOT NULL,
`CREATED_AT` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
`UPDATED_AT` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`ID`),
UNIQUE KEY `USER_EMAIL_UNIQUE` (`EMAIL`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

--
-- Table structure for table `TESTGEN`
--
Expand Down

0 comments on commit 4de6c6e

Please sign in to comment.