feat(SQLite): keys support

This commit is contained in:
Fabio Di Stasio 2021-11-16 12:27:51 +01:00
parent 94c899eb82
commit fd321beece
1 changed files with 113 additions and 53 deletions

View File

@ -286,20 +286,40 @@ export class SQLiteClient extends AntaresCore {
* @memberof SQLiteClient * @memberof SQLiteClient
*/ */
async getTableIndexes ({ schema, table }) { async getTableIndexes ({ schema, table }) {
const { rows } = await this.raw(`SHOW INDEXES FROM \`${table}\` FROM \`${schema}\``); const remappedIndexes = [];
const { rows: primaryKeys } = await this.raw(`SELECT * FROM "${schema}".pragma_table_info('${table}') WHERE pk != 0`);
return rows.map(row => { for (const key of primaryKeys) {
return { remappedIndexes.push({
unique: !row.Non_unique, name: 'PRIMARY',
name: row.Key_name, column: key.name,
column: row.Column_name, indexType: null,
indexType: row.Index_type, type: 'PRIMARY',
type: row.Key_name === 'PRIMARY' ? 'PRIMARY' : !row.Non_unique ? 'UNIQUE' : row.Index_type === 'FULLTEXT' ? 'FULLTEXT' : 'INDEX', cardinality: null,
cardinality: row.Cardinality, comment: '',
comment: row.Comment, indexComment: ''
indexComment: row.Index_comment });
}; }
});
const { rows: indexes } = await this.raw(`SELECT * FROM "${schema}".pragma_index_list('${table}');`);
for (const index of indexes) {
const { rows: details } = await this.raw(`SELECT * FROM "${schema}".pragma_index_info('${index.name}');`);
for (const detail of details) {
remappedIndexes.push({
name: index.name,
column: detail.name,
indexType: null,
type: index.unique === 1 ? 'UNIQUE' : 'INDEX',
cardinality: null,
comment: '',
indexComment: ''
});
}
}
return remappedIndexes;
} }
/** /**
@ -1235,7 +1255,7 @@ export class SQLiteClient extends AntaresCore {
sql = sql.replace(/(\/\*(.|[\r\n])*?\*\/)|(--(.*|[\r\n]))/gm, '');// Remove comments sql = sql.replace(/(\/\*(.|[\r\n])*?\*\/)|(--(.*|[\r\n]))/gm, '');// Remove comments
const resultsArr = []; const resultsArr = [];
// let paramsArr = []; let paramsArr = [];
const queries = args.split const queries = args.split
? sql.split(/((?:[^;'"]*(?:"(?:\\.|[^"])*"|'(?:\\.|[^'])*')[^;'"]*)+)|;/gm) ? sql.split(/((?:[^;'"]*(?:"(?:\\.|[^"])*"|'(?:\\.|[^'])*')[^;'"]*)+)|;/gm)
.filter(Boolean) .filter(Boolean)
@ -1250,51 +1270,91 @@ export class SQLiteClient extends AntaresCore {
const keysArr = []; const keysArr = [];
const { rows, report, fields, keys, duration } = await new Promise((resolve, reject) => { const { rows, report, fields, keys, duration } = await new Promise((resolve, reject) => {
let queryResult; (async () => {
let affectedRows; let queryResult;
let fields; let affectedRows;
const detectedTypes = {}; let fields;
const detectedTypes = {};
const stmt = connection.prepare(query); const stmt = connection.prepare(query);
if (stmt.reader) { if (stmt.reader) {
queryResult = stmt.all(); queryResult = stmt.all();
fields = stmt.columns(); fields = stmt.columns();
if (queryResult.length) { if (queryResult.length) {
fields.forEach(field => { fields.forEach(field => {
detectedTypes[field.name] = typeof queryResult[0][field.name]; detectedTypes[field.name] = typeof queryResult[0][field.name];
}); });
}
}
else {
const info = queryResult = stmt.run();
affectedRows = info.changes;
} }
}
else {
const info = queryResult = stmt.run();
affectedRows = info.changes;
}
const remappedFields = fields timeStop = new Date();
? fields.map(field => {
return {
name: field.name,
alias: field.name,
orgName: field.column,
schema: field.database,
table: field.table,
tableAlias: field.table,
orgTable: field.table,
type: field.type !== null ? field.type : detectedTypes[field.name]
};
}).filter(Boolean)
: [];
timeStop = new Date(); let remappedFields = fields
? fields.map(field => {
return {
name: field.name,
alias: field.name,
orgName: field.column,
schema: field.database,
table: field.table,
tableAlias: field.table,
orgTable: field.table,
type: field.type !== null ? field.type : detectedTypes[field.name]
};
}).filter(Boolean)
: [];
resolve({ if (args.details) {
duration: timeStop - timeStart, paramsArr = remappedFields.map(field => {
rows: Array.isArray(queryResult) ? queryResult.some(el => Array.isArray(el)) ? [] : queryResult : false, return {
report: affectedRows !== undefined ? { affectedRows } : null, table: field.table,
fields: remappedFields, schema: field.schema
keys: keysArr };
}); }).filter((val, i, arr) => arr.findIndex(el => el.schema === val.schema && el.table === val.table) === i);
for (const paramObj of paramsArr) {
if (!paramObj.table || !paramObj.schema) continue;
try {
const indexes = await this.getTableIndexes(paramObj);
remappedFields = remappedFields.map(field => {
// const detailedField = columns.find(f => f.name === field.name);
const fieldIndex = indexes.find(i => i.column === field.name);
if (field.table === paramObj.table && field.schema === paramObj.schema) {
// if (detailedField) {
// const length = detailedField.numPrecision || detailedField.charLength || detailedField.datePrecision || null;
// field = { ...field, ...detailedField, length };
// }
if (fieldIndex) {
const key = fieldIndex.type === 'PRIMARY' ? 'pri' : fieldIndex.type === 'UNIQUE' ? 'uni' : 'mul';
field = { ...field, key };
};
}
return field;
});
}
catch (err) {
reject(err);
}
}
}
resolve({
duration: timeStop - timeStart,
rows: Array.isArray(queryResult) ? queryResult.some(el => Array.isArray(el)) ? [] : queryResult : false,
report: affectedRows !== undefined ? { affectedRows } : null,
fields: remappedFields,
keys: keysArr
});
})();
}); });
resultsArr.push({ rows, report, fields, keys, duration }); resultsArr.push({ rows, report, fields, keys, duration });