From 113016c25cb7e1fb90d921381fe1e13e2ec74e9c Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Tue, 14 Apr 2020 19:37:31 +0200 Subject: [PATCH] load row count --- packages/datalib/src/GridDisplay.ts | 16 ++++++++- packages/sqltree/src/dumpSqlExpression.ts | 4 +++ packages/sqltree/src/types.ts | 7 +++- packages/web/src/datagrid/DataGridCore.js | 40 ++++++++++++++++++++++- 4 files changed, 64 insertions(+), 3 deletions(-) diff --git a/packages/datalib/src/GridDisplay.ts b/packages/datalib/src/GridDisplay.ts index 33965ef0..0f13e334 100644 --- a/packages/datalib/src/GridDisplay.ts +++ b/packages/datalib/src/GridDisplay.ts @@ -269,7 +269,7 @@ export abstract class GridDisplay { this.columns.map((col) => ({ ...col, sourceAlias: 'basetbl' })), 'uniqueName' ); - const action = this.processReferences(select, displayedColumnInfo) + const action = this.processReferences(select, displayedColumnInfo); this.applyFilterOnSelect(select, displayedColumnInfo); this.applySortOnSelect(select, displayedColumnInfo); if (action == 'loadRequired') { @@ -286,4 +286,18 @@ export abstract class GridDisplay { const sql = treeToSql(this.driver, select, dumpSqlSelect); return sql; } + + getCountQuery() { + const select = this.createSelect(); + select.columns = [ + { + exprType: 'raw', + sql: 'COUNT(*)', + alias: 'count', + }, + ]; + select.orderBy = null; + const sql = treeToSql(this.driver, select, dumpSqlSelect); + return sql; + } } diff --git a/packages/sqltree/src/dumpSqlExpression.ts b/packages/sqltree/src/dumpSqlExpression.ts index 89daeca9..337c7908 100644 --- a/packages/sqltree/src/dumpSqlExpression.ts +++ b/packages/sqltree/src/dumpSqlExpression.ts @@ -23,5 +23,9 @@ export function dumpSqlExpression(dmp: SqlDumper, expr: Expression) { case 'value': dmp.put('%v', expr.value); break; + + case 'raw': + dmp.put('%s', expr.sql); + break; } } diff --git a/packages/sqltree/src/types.ts b/packages/sqltree/src/types.ts index a088ac11..8243391d 100644 --- a/packages/sqltree/src/types.ts +++ b/packages/sqltree/src/types.ts @@ -112,7 +112,12 @@ export interface PlaceholderExpression { exprType: 'placeholder'; } -export type Expression = ColumnRefExpression | ValueExpression | PlaceholderExpression; +export interface RawExpression { + exprType: 'raw'; + sql: string; +} + +export type Expression = ColumnRefExpression | ValueExpression | PlaceholderExpression | RawExpression; export type OrderByExpression = Expression & { direction: 'ASC' | 'DESC' }; export type ResultField = Expression & { alias?: string }; diff --git a/packages/web/src/datagrid/DataGridCore.js b/packages/web/src/datagrid/DataGridCore.js index d92f0593..cd0f6359 100644 --- a/packages/web/src/datagrid/DataGridCore.js +++ b/packages/web/src/datagrid/DataGridCore.js @@ -94,6 +94,13 @@ const FocusField = styled.input` top: -1000px; `; +const RowCountLabel = styled.div` + position: absolute; + background-color: lightgoldenrodyellow; + right: 40px; + bottom: 20px; +`; + /** @param props {import('./types').DataGridProps} */ async function loadDataPage(props, offset, limit) { const { display, conid, database, jslid } = props; @@ -133,6 +140,24 @@ function dataPageAvailable(props) { return !!sql; } +/** @param props {import('./types').DataGridProps} */ +async function loadRowCount(props) { + const { display, conid, database, jslid } = props; + const sql = display.getCountQuery(); + + const response = await axios.request({ + url: 'database-connections/query-data', + method: 'post', + params: { + conid, + database, + }, + data: { sql }, + }); + + return parseInt(response.data.rows[0].count); +} + /** @param props {import('./types').DataGridProps} */ export default function DataGridCore(props) { const { conid, database, display, changeSetState, dispatchChangeSet, tabVisible } = props; @@ -147,8 +172,9 @@ export default function DataGridCore(props) { loadedRows: [], isLoadedAll: false, loadedTime: new Date().getTime(), + allRowCount: null, }); - const { isLoading, loadedRows, isLoadedAll, loadedTime } = loadProps; + const { isLoading, loadedRows, isLoadedAll, loadedTime, allRowCount } = loadProps; const loadedTimeRef = React.useRef(0); const focusFieldRef = React.useRef(); @@ -186,11 +212,20 @@ export default function DataGridCore(props) { [selectedCells] ); + const handleLoadRowCount = async () => { + const rowCount = await loadRowCount(props); + setLoadProps({ + ...loadProps, + allRowCount: rowCount, + }); + }; + const loadNextData = async () => { if (isLoading) return; setLoadProps({ ...loadProps, isLoading: true, + allRowCount: null, }); const loadStart = new Date().getTime(); loadedTimeRef.current = loadStart; @@ -205,6 +240,7 @@ export default function DataGridCore(props) { // nextRows = []; // } // console.log('nextRows', nextRows); + if (allRowCount == null) handleLoadRowCount(); const loadedInfo = { loadedRows: [...loadedRows, ...nextRows], loadedTime, @@ -290,6 +326,7 @@ export default function DataGridCore(props) { const reload = () => { setLoadProps({ + allRowCount: null, isLoading: false, loadedRows: [], isLoadedAll: false, @@ -984,6 +1021,7 @@ export default function DataGridCore(props) { engine={display.engine} onConfirm={handleConfirmSql} /> + {allRowCount && Rows: {allRowCount.toLocaleString()}} {props.toolbarPortalRef && tabVisible && ReactDOM.createPortal(