mirror of
https://github.com/dbgate/dbgate
synced 2024-11-07 20:26:23 +00:00
show table row count for MySQL
This commit is contained in:
parent
0debe66dd0
commit
4e221ecd3a
@ -62,9 +62,10 @@ module.exports = {
|
|||||||
delete this.requests[msgid];
|
delete this.requests[msgid];
|
||||||
},
|
},
|
||||||
handle_status(conid, database, { status }) {
|
handle_status(conid, database, { status }) {
|
||||||
|
// console.log('HANDLE SET STATUS', status);
|
||||||
const existing = this.opened.find(x => x.conid == conid && x.database == database);
|
const existing = this.opened.find(x => x.conid == conid && x.database == database);
|
||||||
if (!existing) return;
|
if (!existing) return;
|
||||||
if (existing.status == status) return;
|
if (existing.status && status && existing.status.counter > status.counter) return;
|
||||||
existing.status = status;
|
existing.status = status;
|
||||||
socket.emitChanged(`database-status-changed-${conid}-${database}`);
|
socket.emitChanged(`database-status-changed-${conid}-${database}`);
|
||||||
},
|
},
|
||||||
|
@ -18,6 +18,12 @@ let lastStatus = null;
|
|||||||
let analysedTime = 0;
|
let analysedTime = 0;
|
||||||
let serverVersion;
|
let serverVersion;
|
||||||
|
|
||||||
|
let statusCounter = 0;
|
||||||
|
function getStatusCounter() {
|
||||||
|
statusCounter += 1;
|
||||||
|
return statusCounter;
|
||||||
|
}
|
||||||
|
|
||||||
async function checkedAsyncCall(promise) {
|
async function checkedAsyncCall(promise) {
|
||||||
try {
|
try {
|
||||||
const res = await promise;
|
const res = await promise;
|
||||||
@ -79,7 +85,7 @@ function handleSyncModel() {
|
|||||||
function setStatus(status) {
|
function setStatus(status) {
|
||||||
const statusString = stableStringify(status);
|
const statusString = stableStringify(status);
|
||||||
if (lastStatus != statusString) {
|
if (lastStatus != statusString) {
|
||||||
process.send({ msgtype: 'status', status });
|
process.send({ msgtype: 'status', status: { ...status, counter: getStatusCounter() } });
|
||||||
lastStatus = statusString;
|
lastStatus = statusString;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,26 @@ const STRUCTURE_FIELDS = ['tables', 'collections', 'views', 'matviews', 'functio
|
|||||||
|
|
||||||
const fp_pick = arg => array => _pick(array, arg);
|
const fp_pick = arg => array => _pick(array, arg);
|
||||||
|
|
||||||
|
function mergeTableRowCounts(info: DatabaseInfo, rowCounts): DatabaseInfo {
|
||||||
|
return {
|
||||||
|
...info,
|
||||||
|
tables: (info.tables || []).map(table => ({
|
||||||
|
...table,
|
||||||
|
tableRowCount: rowCounts.find(x => x.objectId == table.objectId)?.tableRowCount ?? table.tableRowCount,
|
||||||
|
})),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function areDifferentRowCounts(db1: DatabaseInfo, db2: DatabaseInfo) {
|
||||||
|
for (const t1 of db1.tables || []) {
|
||||||
|
const t2 = (db2.tables || []).find(x => x.objectId == t1.objectId);
|
||||||
|
if (t1?.tableRowCount !== t2?.tableRowCount) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
export class DatabaseAnalyser {
|
export class DatabaseAnalyser {
|
||||||
structure: DatabaseInfo;
|
structure: DatabaseInfo;
|
||||||
modifications: DatabaseModification[];
|
modifications: DatabaseModification[];
|
||||||
@ -64,13 +84,29 @@ export class DatabaseAnalyser {
|
|||||||
async incrementalAnalysis(structure) {
|
async incrementalAnalysis(structure) {
|
||||||
this.structure = structure;
|
this.structure = structure;
|
||||||
|
|
||||||
this.modifications = await this.getModifications();
|
const modifications = await this.getModifications();
|
||||||
if (this.modifications == null) {
|
if (modifications == null) {
|
||||||
// modifications not implemented, perform full analysis
|
// modifications not implemented, perform full analysis
|
||||||
this.structure = null;
|
this.structure = null;
|
||||||
return this.addEngineField(await this._runAnalysis());
|
return this.addEngineField(await this._runAnalysis());
|
||||||
}
|
}
|
||||||
if (this.modifications.length == 0) return null;
|
const structureModifications = modifications.filter(x => x.action != 'setTableRowCounts');
|
||||||
|
const setTableRowCounts = modifications.find(x => x.action == 'setTableRowCounts');
|
||||||
|
|
||||||
|
let structureWithRowCounts = null;
|
||||||
|
if (setTableRowCounts) {
|
||||||
|
const newStructure = mergeTableRowCounts(structure, setTableRowCounts.rowCounts);
|
||||||
|
if (areDifferentRowCounts(structure, newStructure)) {
|
||||||
|
structureWithRowCounts = newStructure;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (structureModifications.length == 0) {
|
||||||
|
return structureWithRowCounts ? this.addEngineField(structureWithRowCounts) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.modifications = structureModifications;
|
||||||
|
if (structureWithRowCounts) this.structure = structureWithRowCounts;
|
||||||
console.log('DB modifications detected:', this.modifications);
|
console.log('DB modifications detected:', this.modifications);
|
||||||
return this.addEngineField(this.mergeAnalyseResult(await this._runAnalysis()));
|
return this.addEngineField(this.mergeAnalyseResult(await this._runAnalysis()));
|
||||||
}
|
}
|
||||||
@ -226,6 +262,20 @@ export class DatabaseAnalyser {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const rowCounts = (snapshot.tables || [])
|
||||||
|
.filter(x => x.tableRowCount != null)
|
||||||
|
.map(x => ({
|
||||||
|
objectId: x.objectId,
|
||||||
|
tableRowCount: x.tableRowCount,
|
||||||
|
}));
|
||||||
|
|
||||||
|
if (rowCounts.length > 0) {
|
||||||
|
res.push({
|
||||||
|
action: 'setTableRowCounts',
|
||||||
|
rowCounts,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return [..._compact(res), ...this.getDeletedObjects(snapshot)];
|
return [..._compact(res), ...this.getDeletedObjects(snapshot)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
1
packages/types/dbinfo.d.ts
vendored
1
packages/types/dbinfo.d.ts
vendored
@ -85,6 +85,7 @@ export interface TableInfo extends DatabaseObjectInfo {
|
|||||||
preloadedRows?: any[];
|
preloadedRows?: any[];
|
||||||
preloadedRowsKey?: string[];
|
preloadedRowsKey?: string[];
|
||||||
preloadedRowsInsertOnly?: string[];
|
preloadedRowsInsertOnly?: string[];
|
||||||
|
tableRowCount?: number | string;
|
||||||
__isDynamicStructure?: boolean;
|
__isDynamicStructure?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
1
packages/types/index.d.ts
vendored
1
packages/types/index.d.ts
vendored
@ -11,6 +11,7 @@ export interface OpenedDatabaseConnection {
|
|||||||
status?: {
|
status?: {
|
||||||
name: string;
|
name: string;
|
||||||
message?: string;
|
message?: string;
|
||||||
|
counter: number;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -627,6 +627,7 @@
|
|||||||
showPinnedInsteadOfUnpin={passProps?.showPinnedInsteadOfUnpin}
|
showPinnedInsteadOfUnpin={passProps?.showPinnedInsteadOfUnpin}
|
||||||
onPin={isPinned ? null : () => pinnedTables.update(list => [...list, data])}
|
onPin={isPinned ? null : () => pinnedTables.update(list => [...list, data])}
|
||||||
onUnpin={isPinned ? () => pinnedTables.update(list => list.filter(x => !testEqual(x, data))) : null}
|
onUnpin={isPinned ? () => pinnedTables.update(list => list.filter(x => !testEqual(x, data))) : null}
|
||||||
|
extInfo={data.tableRowCount != null ? `${data.tableRowCount} rows` : null}
|
||||||
on:click={() => handleClick()}
|
on:click={() => handleClick()}
|
||||||
on:middleclick={() => handleClick(true)}
|
on:middleclick={() => handleClick(true)}
|
||||||
on:expand
|
on:expand
|
||||||
|
@ -88,6 +88,7 @@ class Analyser extends DatabaseAnalyser {
|
|||||||
columns: columns.rows.filter(col => col.pureName == table.pureName).map(getColumnInfo),
|
columns: columns.rows.filter(col => col.pureName == table.pureName).map(getColumnInfo),
|
||||||
primaryKey: DatabaseAnalyser.extractPrimaryKeys(table, pkColumns.rows),
|
primaryKey: DatabaseAnalyser.extractPrimaryKeys(table, pkColumns.rows),
|
||||||
foreignKeys: DatabaseAnalyser.extractForeignKeys(table, fkColumns.rows),
|
foreignKeys: DatabaseAnalyser.extractForeignKeys(table, fkColumns.rows),
|
||||||
|
tableRowCount: table.tableRowCount,
|
||||||
indexes: _.uniqBy(
|
indexes: _.uniqBy(
|
||||||
indexes.rows.filter(
|
indexes.rows.filter(
|
||||||
idx =>
|
idx =>
|
||||||
@ -163,6 +164,7 @@ class Analyser extends DatabaseAnalyser {
|
|||||||
...x,
|
...x,
|
||||||
objectId: x.pureName,
|
objectId: x.pureName,
|
||||||
contentHash: _.isDate(x.modifyDate) ? x.modifyDate.toISOString() : x.modifyDate,
|
contentHash: _.isDate(x.modifyDate) ? x.modifyDate.toISOString() : x.modifyDate,
|
||||||
|
tableRowCount: x.tableRowCount,
|
||||||
})),
|
})),
|
||||||
views: tableModificationsQueryData.rows
|
views: tableModificationsQueryData.rows
|
||||||
.filter(x => x.objectType == 'VIEW')
|
.filter(x => x.objectType == 'VIEW')
|
||||||
|
@ -2,6 +2,7 @@ module.exports = `
|
|||||||
select
|
select
|
||||||
TABLE_NAME as pureName,
|
TABLE_NAME as pureName,
|
||||||
TABLE_TYPE as objectType,
|
TABLE_TYPE as objectType,
|
||||||
|
TABLE_ROWS as tableRowCount,
|
||||||
case when ENGINE='InnoDB' then CREATE_TIME else coalesce(UPDATE_TIME, CREATE_TIME) end as modifyDate
|
case when ENGINE='InnoDB' then CREATE_TIME else coalesce(UPDATE_TIME, CREATE_TIME) end as modifyDate
|
||||||
from information_schema.tables
|
from information_schema.tables
|
||||||
where TABLE_SCHEMA = '#DATABASE#'
|
where TABLE_SCHEMA = '#DATABASE#'
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
module.exports = `
|
module.exports = `
|
||||||
select
|
select
|
||||||
TABLE_NAME as pureName,
|
TABLE_NAME as pureName,
|
||||||
|
TABLE_ROWS as tableRowCount,
|
||||||
case when ENGINE='InnoDB' then CREATE_TIME else coalesce(UPDATE_TIME, CREATE_TIME) end as modifyDate
|
case when ENGINE='InnoDB' then CREATE_TIME else coalesce(UPDATE_TIME, CREATE_TIME) end as modifyDate
|
||||||
from information_schema.tables
|
from information_schema.tables
|
||||||
where TABLE_SCHEMA = '#DATABASE#' and TABLE_TYPE='BASE TABLE' and TABLE_NAME =OBJECT_ID_CONDITION;
|
where TABLE_SCHEMA = '#DATABASE#' and TABLE_TYPE='BASE TABLE' and TABLE_NAME =OBJECT_ID_CONDITION;
|
||||||
|
Loading…
Reference in New Issue
Block a user