perf(SQLite): improvements in data visualization

This commit is contained in:
Fabio Di Stasio 2021-11-15 18:09:34 +01:00
parent f2fcc98839
commit 94c899eb82
8 changed files with 62 additions and 30 deletions

View File

@ -37,6 +37,9 @@ module.exports = {
databaseEdit: false,
schemaEdit: false,
tableSettings: false,
tableOptions: false,
tableArray: false,
tableRealCount: false,
viewSettings: false,
triggerSettings: false,
triggerFunctionSettings: false,
@ -49,13 +52,11 @@ module.exports = {
unsigned: false,
nullable: false,
zerofill: false,
tableOptions: false,
autoIncrement: false,
comment: false,
collation: false,
definer: false,
onUpdate: false,
tableArray: false,
viewAlgorithm: false,
viewSqlSecurity: false,
viewUpdateOption: false,

View File

@ -35,6 +35,8 @@ module.exports = {
databaseEdit: false,
schemaEdit: false,
tableSettings: false,
tableArray: false,
tableRealCount: true,
viewSettings: false,
triggerSettings: false,
triggerFunctionSettings: false,
@ -53,7 +55,6 @@ module.exports = {
collation: false,
definer: false,
onUpdate: false,
tableArray: false,
viewAlgorithm: false,
viewSqlSecurity: false,
viewUpdateOption: false,

View File

@ -54,7 +54,7 @@ export class SQLiteClient extends AntaresCore {
for (const db of filteredDatabases) {
if (!schemas.has(db.name)) continue;
let { rows: tables } = await this.raw(`SELECT * FROM "${db.name}".sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%';`);
let { rows: tables } = await this.raw(`SELECT * FROM "${db.name}".sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' ORDER BY name`);
if (tables.length) {
tables = tables.map(table => {
table.Db = db.name;
@ -77,17 +77,7 @@ export class SQLiteClient extends AntaresCore {
if (schemas.has(db.name)) {
// TABLES
const remappedTables = tablesArr.filter(table => table.Db === db.name).map(table => {
let tableType;
switch (table.Comment) {
case 'VIEW':
tableType = 'view';
break;
default:
tableType = 'table';
break;
}
const tableSize = table.Data_length + table.Index_length;
const tableSize = 0;
schemaSize += tableSize;
return {
@ -246,7 +236,7 @@ export class SQLiteClient extends AntaresCore {
* @memberof SQLiteClient
*/
async getTableApproximateCount ({ schema, table }) {
const { rows } = await this.raw(`SELECT table_rows "count" FROM information_schema.tables WHERE table_name = "${table}" AND table_schema = "${schema}"`);
const { rows } = await this.raw(`SELECT COUNT(*) AS count FROM "${schema}"."${table}"`);
return rows.length ? rows[0].count : 0;
}
@ -1182,10 +1172,12 @@ export class SQLiteClient extends AntaresCore {
else if (Object.keys(this._query.insert).length)
fromRaw = 'INTO';
fromRaw += this._query.from ? ` ${this._query.schema ? `\`${this._query.schema}\`.` : ''}\`${this._query.from}\` ` : '';
fromRaw += this._query.from ? ` ${this._query.schema ? `"${this._query.schema}".` : ''}"${this._query.from}" ` : '';
// WHERE
const whereArray = this._query.where.reduce(this._reducer, []);
const whereArray = this._query.where
.reduce(this._reducer, [])
?.map(clausole => clausole.replace('= null', 'IS NULL'));
const whereRaw = whereArray.length ? `WHERE ${whereArray.join(' AND ')} ` : '';
// UPDATE
@ -1258,9 +1250,26 @@ export class SQLiteClient extends AntaresCore {
const keysArr = [];
const { rows, report, fields, keys, duration } = await new Promise((resolve, reject) => {
let queryResult;
let affectedRows;
let fields;
const detectedTypes = {};
const stmt = connection.prepare(query);
const queryResult = stmt.all();
const fields = stmt.columns();
if (stmt.reader) {
queryResult = stmt.all();
fields = stmt.columns();
if (queryResult.length) {
fields.forEach(field => {
detectedTypes[field.name] = typeof queryResult[0][field.name];
});
}
}
else {
const info = queryResult = stmt.run();
affectedRows = info.changes;
}
const remappedFields = fields
? fields.map(field => {
@ -1272,7 +1281,7 @@ export class SQLiteClient extends AntaresCore {
table: field.table,
tableAlias: field.table,
orgTable: field.table,
type: field.type
type: field.type !== null ? field.type : detectedTypes[field.name]
};
}).filter(Boolean)
: [];
@ -1282,7 +1291,7 @@ export class SQLiteClient extends AntaresCore {
resolve({
duration: timeStop - timeStart,
rows: Array.isArray(queryResult) ? queryResult.some(el => Array.isArray(el)) ? [] : queryResult : false,
report: !Array.isArray(queryResult) ? queryResult : false,
report: affectedRows !== undefined ? { affectedRows } : null,
fields: remappedFields,
keys: keysArr
});

View File

@ -43,7 +43,7 @@
<span v-html="highlightWord(table.name)" />
</a>
<div
v-if="table.type === 'table'"
v-if="table.type === 'table' && table.size !== false"
class="table-size tooltip tooltip-left mr-1"
:data-tooltip="formatBytes(table.size)"
>

View File

@ -93,7 +93,7 @@
<div v-if="resultsCount">
{{ $t('word.results') }}: <b>{{ resultsCount.toLocaleString() }}</b>
</div>
<div v-if="affectedCount">
<div v-if="affectedCount !== null">
{{ $t('message.affectedRows') }}: <b>{{ affectedCount }}</b>
</div>
<div class="input-group" :title="$t('word.schema')">
@ -170,7 +170,7 @@ export default {
selectedSchema: null,
resultsCount: 0,
durationsCount: 0,
affectedCount: 0,
affectedCount: null,
editorHeight: 200,
isHistoryOpen: false
};
@ -255,9 +255,14 @@ export default {
if (status === 'success') {
this.results = Array.isArray(response) ? response : [response];
this.resultsCount += this.results.reduce((acc, curr) => acc + (curr.rows ? curr.rows.length : 0), 0);
this.durationsCount += this.results.reduce((acc, curr) => acc + curr.duration, 0);
this.affectedCount += this.results.reduce((acc, curr) => acc + (curr.report ? curr.report.affectedRows : 0), 0);
this.resultsCount = this.results.reduce((acc, curr) => acc + (curr.rows ? curr.rows.length : 0), 0);
this.durationsCount = this.results.reduce((acc, curr) => acc + curr.duration, 0);
this.affectedCount = this.results
.filter(result => result.report !== null)
.reduce((acc, curr) => {
if (acc === null) acc = 0;
return acc + (curr.report ? curr.report.affectedRows : 0);
}, null);
this.updateTabContent({
uid: this.connection.uid,
@ -285,7 +290,7 @@ export default {
this.results = [];
this.resultsCount = 0;
this.durationsCount = 0;
this.affectedCount = 0;
this.affectedCount = null;
},
resize (e) {
const el = this.$refs.queryEditor.$el;

View File

@ -120,7 +120,12 @@
{{ $t('word.results') }}: <b>{{ results[0].rows.length | localeString }}</b>
</div>
<div v-if="hasApproximately || (page > 1 && approximateCount)">
{{ $t('word.total') }}: <b :title="$t('word.approximately')"> {{ approximateCount | localeString }}</b>
{{ $t('word.total') }}: <b
:title="!customizations.tableRealCount ? $t('word.approximately') : ''"
>
<span v-if="!customizations.tableRealCount"></span>
{{ approximateCount | localeString }}
</b>
</div>
<div class="d-flex" :title="$t('word.schema')">
<i class="mdi mdi-18px mdi-database mr-1" /><b>{{ schema }}</b>
@ -231,6 +236,9 @@ export default {
workspace () {
return this.getWorkspace(this.connection.uid);
},
customizations () {
return this.workspace.customizations;
},
isTable () {
return !!this.workspace.breadcrumbs.table;
},

View File

@ -17,10 +17,12 @@
(
"char": $string-color,
"varchar": $string-color,
"longvarchar": $string-color,
"text": $string-color,
"tinytext": $string-color,
"mediumtext": $string-color,
"longtext": $string-color,
"string": $string-color,
"json": $string-color,
"name": $string-color,
"character": $string-color,
@ -50,6 +52,7 @@
"oid": $number-color,
"xid": $number-color,
"money": $number-color,
"number": $number-color,
"datetime": $date-color,
"date": $date-color,
"time": $date-color,

View File

@ -412,6 +412,11 @@ export default {
indexTypes = require('common/index-types/postgresql');
customizations = require('common/customizations/postgresql');
break;
case 'sqlite':
// dataTypes = require('common/data-types/sqlite');
// indexTypes = require('common/index-types/sqlite');
customizations = require('common/customizations/sqlite');
break;
}
const { status, response: version } = await Schema.getVersion(connection.uid);