diff --git a/packages/api/src/proc/sessionProcess.js b/packages/api/src/proc/sessionProcess.js
index a15bb3f83..ef15c74af 100644
--- a/packages/api/src/proc/sessionProcess.js
+++ b/packages/api/src/proc/sessionProcess.js
@@ -19,7 +19,7 @@ class TableWriter {
this.jslid = uuidv1();
this.currentFile = path.join(jsldir(), `${this.jslid}.jsonl`);
this.currentRowCount = 0;
- this.currentChangeIndex = 0;
+ this.currentChangeIndex = 1;
fs.writeFileSync(this.currentFile, JSON.stringify({ columns }) + '\n');
this.currentStream = fs.createWriteStream(this.currentFile, { flags: 'a' });
this.writeCurrentStats(false, false);
diff --git a/packages/web/src/datagrid/ChangeSetDataGrid.js b/packages/web/src/datagrid/ChangeSetDataGrid.js
deleted file mode 100644
index 3c20ec515..000000000
--- a/packages/web/src/datagrid/ChangeSetDataGrid.js
+++ /dev/null
@@ -1,17 +0,0 @@
-import { getChangeSetInsertedRows } from '@dbgate/datalib';
-import React from 'react';
-import DataGridCore from './DataGridCore';
-
-export default function ChangeSetDataGrid(props) {
- const { changeSet, display, dispatchChangeSet } = props;
- function undo() {
- dispatchChangeSet({ type: 'undo' });
- }
- function redo() {
- dispatchChangeSet({ type: 'redo' });
- }
-
- const insertedRows = getChangeSetInsertedRows(changeSet, display.baseTable);
-
- return ;
-}
diff --git a/packages/web/src/datagrid/DataGrid.js b/packages/web/src/datagrid/DataGrid.js
index f7cfb19c4..c03078fc1 100644
--- a/packages/web/src/datagrid/DataGrid.js
+++ b/packages/web/src/datagrid/DataGrid.js
@@ -15,7 +15,6 @@ import {
} from './ManagerStyles';
import ReferenceManager from './ReferenceManager';
import { HorizontalSplitter } from '../widgets/Splitter';
-import LoadingDataGrid from './LoadingDataGrid';
const MainContainer = styled.div`
position: absolute;
@@ -42,8 +41,8 @@ const DataGridContainer = styled.div`
flex-grow: 1;
`;
-/** @param props {import('./types').LoadingDataGridProps} */
export default function DataGrid(props) {
+ const { GridCore } = props;
const Container1 = props.showReferences ? ManagerOuterContainer1 : ManagerOuterContainerFull;
const [managerSize, setManagerSize] = React.useState(0);
return (
@@ -62,7 +61,7 @@ export default function DataGrid(props) {
-
+
diff --git a/packages/web/src/datagrid/DataGridCore.js b/packages/web/src/datagrid/DataGridCore.js
index d67480e8c..6edaf3e5d 100644
--- a/packages/web/src/datagrid/DataGridCore.js
+++ b/packages/web/src/datagrid/DataGridCore.js
@@ -145,8 +145,6 @@ export default function DataGridCore(props) {
openQuery,
insertedRowCount,
isLoading,
- undo,
- redo
} = props;
// console.log('RENDER GRID', display.baseTable.pureName);
const columns = React.useMemo(() => display.allColumns, [display]);
@@ -687,6 +685,13 @@ export default function DataGridCore(props) {
setvScrollValueToSetDate(new Date());
}
+ function undo() {
+ dispatchChangeSet({ type: 'undo' });
+ }
+ function redo() {
+ dispatchChangeSet({ type: 'redo' });
+ }
+
function handleSave() {
if (inplaceEditorState.cell) {
// @ts-ignore
diff --git a/packages/web/src/datagrid/JslDataGridCore.js b/packages/web/src/datagrid/JslDataGridCore.js
new file mode 100644
index 000000000..53ae17505
--- /dev/null
+++ b/packages/web/src/datagrid/JslDataGridCore.js
@@ -0,0 +1,93 @@
+import React from 'react';
+import axios from '../utility/axios';
+import { useSetOpenedTabs } from '../utility/globalState';
+import DataGridCore from './DataGridCore';
+import useSocket from '../utility/SocketProvider';
+import useShowModal from '../modals/showModal';
+import ImportExportModal from '../modals/ImportExportModal';
+import { getChangeSetInsertedRows } from '@dbgate/datalib';
+import { openNewTab } from '../utility/common';
+import LoadingDataGridCore from './LoadingDataGridCore';
+
+async function loadDataPage(props, offset, limit) {
+ const { jslid } = props;
+
+ const response = await axios.request({
+ url: 'jsldata/get-rows',
+ method: 'get',
+ params: {
+ jslid,
+ offset,
+ limit,
+ },
+ });
+ return response.data;
+}
+
+function dataPageAvailable(props) {
+ return true;
+}
+
+async function loadRowCount(props) {
+ const { jslid } = props;
+
+ const response = await axios.request({
+ url: 'jsldata/get-stats',
+ method: 'get',
+ params: {
+ jslid,
+ },
+ });
+ return response.data.rowCount;
+}
+
+export default function JslDataGridCore(props) {
+ const { jslid } = props;
+ const [changeIndex, setChangeIndex] = React.useState(0);
+
+ const showModal = useShowModal();
+
+ const setOpenedTabs = useSetOpenedTabs();
+ const socket = useSocket();
+
+ function exportGrid() {
+ const initialValues = {};
+ const archiveMatch = jslid.match(/^archive:\/\/([^/]+)\/(.*)$/);
+ if (archiveMatch) {
+ initialValues.sourceStorageType = 'archive';
+ initialValues.sourceArchiveFolder = archiveMatch[1];
+ initialValues.sourceList = [archiveMatch[2]];
+ } else {
+ initialValues.sourceStorageType = 'jsldata';
+ initialValues.sourceJslId = jslid;
+ initialValues.sourceList = ['query-data'];
+ }
+ showModal((modalState) => );
+ }
+
+ const handleJslDataStats = React.useCallback((stats) => {
+ if (stats.changeIndex < changeIndex) return;
+ setChangeIndex(stats.changeIndex);
+ }, [changeIndex]);
+
+ React.useEffect(() => {
+ if (jslid && socket) {
+ socket.on(`jsldata-stats-${jslid}`, handleJslDataStats);
+ return () => {
+ socket.off(`jsldata-stats-${jslid}`, handleJslDataStats);
+ };
+ }
+ }, [jslid]);
+
+ return (
+ setChangeIndex(0)}
+ />
+ );
+}
diff --git a/packages/web/src/datagrid/LoadingDataGrid.js b/packages/web/src/datagrid/LoadingDataGridCore.js
similarity index 69%
rename from packages/web/src/datagrid/LoadingDataGrid.js
rename to packages/web/src/datagrid/LoadingDataGridCore.js
index d08ce67ea..9b87ff74f 100644
--- a/packages/web/src/datagrid/LoadingDataGrid.js
+++ b/packages/web/src/datagrid/LoadingDataGridCore.js
@@ -6,7 +6,6 @@ import useSocket from '../utility/SocketProvider';
import useShowModal from '../modals/showModal';
import ImportExportModal from '../modals/ImportExportModal';
import { getChangeSetInsertedRows } from '@dbgate/datalib';
-import ChangeSetDataGrid from './ChangeSetDataGrid';
import { openNewTab } from '../utility/common';
/** @param props {import('./types').LoadingDataGridProps} */
@@ -79,8 +78,20 @@ async function loadRowCount(props) {
return parseInt(response.data.rows[0].count);
}
-export default function LoadingDataGrid(props) {
- const { conid, database, display, changeSetState, dispatchChangeSet, tabVisible, jslid } = props;
+export default function LoadingDataGridCore(props) {
+ const {
+ display,
+ changeSetState,
+ dispatchChangeSet,
+ tabVisible,
+ loadDataPage,
+ dataPageAvailable,
+ loadRowCount,
+ loadNextDataToken,
+ onReload,
+ exportGrid,
+ openQuery,
+ } = props;
const [loadProps, setLoadProps] = React.useState({
isLoading: false,
@@ -89,8 +100,7 @@ export default function LoadingDataGrid(props) {
loadedTime: new Date().getTime(),
allRowCount: null,
errorMessage: null,
- jslStatsCounter: 0,
- jslChangeIndex: 0,
+ loadNextDataToken: 0,
});
const { isLoading, loadedRows, isLoadedAll, loadedTime, allRowCount, errorMessage } = loadProps;
const showModal = useShowModal();
@@ -122,34 +132,11 @@ export default function LoadingDataGrid(props) {
isLoadedAll: false,
loadedTime: new Date().getTime(),
errorMessage: null,
- jslStatsCounter: 0,
- jslChangeIndex: 0,
+ loadNextDataToken: 0,
});
+ if (onReload) onReload();
};
- function exportGrid() {
- const initialValues = {};
- if (jslid) {
- const archiveMatch = jslid.match(/^archive:\/\/([^/]+)\/(.*)$/);
- if (archiveMatch) {
- initialValues.sourceStorageType = 'archive';
- initialValues.sourceArchiveFolder = archiveMatch[1];
- initialValues.sourceList = [archiveMatch[2]];
- } else {
- initialValues.sourceStorageType = 'jsldata';
- initialValues.sourceJslId = jslid;
- initialValues.sourceList = ['query-data'];
- }
- } else {
- initialValues.sourceStorageType = 'query';
- initialValues.sourceConnectionId = conid;
- initialValues.sourceDatabaseName = database;
- initialValues.sourceSql = display.getExportQuery();
- initialValues.sourceList = display.baseTable ? [display.baseTable.pureName] : [];
- }
- showModal((modalState) => );
- }
-
React.useEffect(() => {
if (props.masterLoadedTime && props.masterLoadedTime > loadedTime) {
display.reload();
@@ -193,31 +180,19 @@ export default function LoadingDataGrid(props) {
setLoadProps((oldLoadProps) => ({
...oldLoadProps,
isLoading: false,
- isLoadedAll: oldLoadProps.jslStatsCounter == loadProps.jslStatsCounter && nextRows.length === 0,
+ isLoadedAll: oldLoadProps.loadNextDataToken == loadNextDataToken && nextRows.length === 0,
+ loadNextDataToken,
...loadedInfo,
}));
}
};
- const handleJslDataStats = React.useCallback((stats) => {
- if (stats.changeIndex < loadProps.jslChangeIndex) return;
+ React.useEffect(()=>{
setLoadProps((oldProps) => ({
...oldProps,
- allRowCount: stats.rowCount,
isLoadedAll: false,
- jslStatsCounter: oldProps.jslStatsCounter + 1,
- jslChangeIndex: stats.changeIndex,
}));
- }, []);
-
- React.useEffect(() => {
- if (jslid && socket) {
- socket.on(`jsldata-stats-${jslid}`, handleJslDataStats);
- return () => {
- socket.off(`jsldata-stats-${jslid}`, handleJslDataStats);
- };
- }
- }, [jslid]);
+ },[loadNextDataToken]);
const insertedRows = getChangeSetInsertedRows(changeSet, display.baseTable);
const rowCountNewIncluded = loadedRows.length + insertedRows.length;
@@ -231,23 +206,8 @@ export default function LoadingDataGrid(props) {
}
};
- function openQuery() {
- openNewTab(setOpenedTabs, {
- title: 'Query',
- icon: 'sql.svg',
- tabComponent: 'QueryTab',
- props: {
- initialScript: display.getExportQuery(),
- schemaName: display.baseTable.schemaName,
- pureName: display.baseTable.pureName,
- conid,
- database,
- },
- });
- }
-
return (
-
diff --git a/packages/web/src/datagrid/SqlDataGridCore.js b/packages/web/src/datagrid/SqlDataGridCore.js
new file mode 100644
index 000000000..c44711124
--- /dev/null
+++ b/packages/web/src/datagrid/SqlDataGridCore.js
@@ -0,0 +1,95 @@
+import React from 'react';
+import axios from '../utility/axios';
+import { useSetOpenedTabs } from '../utility/globalState';
+import DataGridCore from './DataGridCore';
+import useSocket from '../utility/SocketProvider';
+import useShowModal from '../modals/showModal';
+import ImportExportModal from '../modals/ImportExportModal';
+import { getChangeSetInsertedRows } from '@dbgate/datalib';
+import { openNewTab } from '../utility/common';
+import LoadingDataGridCore from './LoadingDataGridCore';
+
+/** @param props {import('./types').LoadingDataGridProps} */
+async function loadDataPage(props, offset, limit) {
+ const { display, conid, database } = props;
+
+ const sql = display.getPageQuery(offset, limit);
+
+ const response = await axios.request({
+ url: 'database-connections/query-data',
+ method: 'post',
+ params: {
+ conid,
+ database,
+ },
+ data: { sql },
+ });
+
+ if (response.data.errorMessage) return response.data;
+ return response.data.rows;
+}
+
+function dataPageAvailable(props) {
+ const { display } = props;
+ const sql = display.getPageQuery(0, 1);
+ return !!sql;
+}
+
+async function loadRowCount(props) {
+ const { display, conid, database } = 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);
+}
+
+export default function SqlDataGridCore(props) {
+ const { conid, database, display, changeSetState, dispatchChangeSet, tabVisible } = props;
+ const showModal = useShowModal();
+ const setOpenedTabs = useSetOpenedTabs();
+
+ function exportGrid() {
+ const initialValues = {};
+ initialValues.sourceStorageType = 'query';
+ initialValues.sourceConnectionId = conid;
+ initialValues.sourceDatabaseName = database;
+ initialValues.sourceSql = display.getExportQuery();
+ initialValues.sourceList = display.baseTable ? [display.baseTable.pureName] : [];
+ showModal((modalState) => );
+ }
+ function openQuery() {
+ openNewTab(setOpenedTabs, {
+ title: 'Query',
+ icon: 'sql.svg',
+ tabComponent: 'QueryTab',
+ props: {
+ initialScript: display.getExportQuery(),
+ schemaName: display.baseTable.schemaName,
+ pureName: display.baseTable.pureName,
+ conid,
+ database,
+ },
+ });
+ }
+
+ return (
+
+ );
+}
diff --git a/packages/web/src/datagrid/TableDataGrid.js b/packages/web/src/datagrid/TableDataGrid.js
index 685465fe6..0f2fd147c 100644
--- a/packages/web/src/datagrid/TableDataGrid.js
+++ b/packages/web/src/datagrid/TableDataGrid.js
@@ -10,6 +10,7 @@ import useSocket from '../utility/SocketProvider';
import { VerticalSplitter } from '../widgets/Splitter';
import stableStringify from 'json-stable-stringify';
import ReferenceHeader from './ReferenceHeader';
+import SqlDataGridCore from './SqlDataGridCore';
const ReferenceContainer = styled.div`
position: absolute;
@@ -162,6 +163,7 @@ export default function TableDataGrid({
onReferenceSourceChanged={reference ? handleReferenceSourceChanged : null}
refReloadToken={refReloadToken.toString()}
masterLoadedTime={masterLoadedTime}
+ GridCore={SqlDataGridCore}
/>
{reference && (
diff --git a/packages/web/src/sqleditor/JslDataGrid.js b/packages/web/src/sqleditor/JslDataGrid.js
index ad4dd3378..192c0ce03 100644
--- a/packages/web/src/sqleditor/JslDataGrid.js
+++ b/packages/web/src/sqleditor/JslDataGrid.js
@@ -2,6 +2,7 @@ import React from 'react';
import DataGrid from '../datagrid/DataGrid';
import { JslGridDisplay, createGridConfig, createGridCache } from '@dbgate/datalib';
import useFetch from '../utility/useFetch';
+import JslDataGridCore from '../datagrid/JslDataGridCore';
export default function JslDataGrid({ jslid }) {
const info = useFetch({
@@ -19,5 +20,5 @@ export default function JslDataGrid({ jslid }) {
cache,
]);
- return ;
+ return ;
}
diff --git a/packages/web/src/tabs/ViewDataTab.js b/packages/web/src/tabs/ViewDataTab.js
index ca134c2fa..14d0c546f 100644
--- a/packages/web/src/tabs/ViewDataTab.js
+++ b/packages/web/src/tabs/ViewDataTab.js
@@ -10,6 +10,7 @@ import useUndoReducer from '../utility/useUndoReducer';
import usePropsCompare from '../utility/usePropsCompare';
import { useUpdateDatabaseForTab } from '../utility/globalState';
import useGridConfig from '../utility/useGridConfig';
+import SqlDataGridCore from '../datagrid/SqlDataGridCore';
export default function ViewDataTab({ conid, database, schemaName, pureName, tabVisible, toolbarPortalRef, tabid }) {
const viewInfo = useViewInfo({ conid, database, schemaName, pureName });
@@ -50,6 +51,7 @@ export default function ViewDataTab({ conid, database, schemaName, pureName, tab
changeSetState={changeSetState}
dispatchChangeSet={dispatchChangeSet}
toolbarPortalRef={toolbarPortalRef}
- />
+ GridCore={SqlDataGridCore}
+ />
);
}