Files
dbgate/plugins/dbgate-plugin-sqlite/src/backend/Analyser.js
2021-05-23 19:53:47 +02:00

104 lines
2.9 KiB
JavaScript

const _ = require('lodash');
const { DatabaseAnalyser } = require('dbgate-tools');
class Analyser extends DatabaseAnalyser {
constructor(pool, driver) {
super(pool, driver);
}
async _runAnalysis() {
const objects = await this.driver.query(this.pool, "select * from sqlite_master where type='table' or type='view'");
const tables = objects.rows.filter((x) => x.type == 'table');
const views = objects.rows.filter((x) => x.type == 'view');
// console.log('TABLES', tables);
const tableSqls = _.zipObject(
tables.map((x) => x.name),
tables.map((x) => x.sql)
);
const tableList = tables.map((x) => ({
pureName: x.name,
objectId: x.name,
contentHash: x.sql,
}));
const viewList = views.map((x) => ({
pureName: x.name,
objectId: x.name,
contentHash: x.sql,
createSql: x.sql,
}));
for (const tableName of this.getRequestedObjectPureNames(
'tables',
tables.map((x) => x.name)
)) {
const tableObj = tableList.find((x) => x.pureName == tableName);
if (!tableObj) continue;
const info = await this.driver.query(this.pool, `pragma table_info('${tableName}')`);
tableObj.columns = info.rows.map((col) => ({
columnName: col.name,
dataType: col.type,
notNull: !!col.notnull,
defaultValue: col.dflt_value == null ? undefined : col.dflt_value,
autoIncrement: tableSqls[tableName].toLowerCase().includes('autoincrement') && !!col.pk,
}));
const pkColumns = info.rows
.filter((x) => x.pk)
.map((col) => ({
columnName: col.name,
}));
if (pkColumns.length > 0) {
tableObj.primaryKey = {
columns: pkColumns,
};
}
const fklist = await this.driver.query(this.pool, `pragma foreign_key_list('${tableName}')`);
tableObj.foreignKeys = _.values(_.groupBy(fklist.rows, 'id')).map((fkcols) => {
const fkcol = fkcols[0];
const fk = {
pureName: tableName,
refTableName: fkcol.table,
columns: fkcols.map((col) => ({
columnName: col.from,
refColumnName: col.to,
})),
updateAction: fkcol.on_update,
deleteAction: fkcol.on_delete,
constraintName: `FK_${tableName}_${fkcol.id}`,
};
return fk;
});
// console.log(info);
}
for (const viewName of this.getRequestedObjectPureNames(
'views',
views.map((x) => x.name)
)) {
const viewObj = viewList.find((x) => x.pureName == viewName);
if (!viewObj) continue;
const info = await this.driver.query(this.pool, `pragma table_info('${viewName}')`);
viewObj.columns = info.rows.map((col) => ({
columnName: col.name,
dataType: col.type,
notNull: !!col.notnull,
}));
}
return {
tables: tableList,
views: viewList,
};
}
}
module.exports = Analyser;