query grid

This commit is contained in:
Jan Prochazka
2021-03-08 20:00:51 +01:00
parent 904d35d26a
commit a35d5525a3
10 changed files with 244 additions and 19 deletions

View File

@@ -0,0 +1,29 @@
<script lang="ts">
import { createGridCache, createGridConfig, JslGridDisplay } from 'dbgate-datalib';
import { writable } from 'svelte/store';
import socket from '../utility/socket';
import useEffect from '../utility/useEffect';
import useFetch from '../utility/useFetch';
import DataGrid from './DataGrid.svelte';
import JslDataGridCore from './JslDataGridCore.svelte';
export let jslid;
$: info = useFetch({
params: { jslid },
url: 'jsldata/get-info',
defaultValue: {},
});
$: columns = ($info && $info.columns) || [];
const config = writable(createGridConfig());
const cache = writable(createGridCache());
$: display = new JslGridDisplay(jslid, columns, $config, config.update, $cache, cache.update);
</script>
{#key jslid}
<DataGrid {display} {jslid} gridCoreComponent={JslDataGridCore} />
{/key}

View File

@@ -0,0 +1,83 @@
<script context="module" lang="ts">
async function loadDataPage(props, offset, limit) {
const { jslid, display } = props;
const response = await axios.post('jsldata/get-rows', {
jslid,
offset,
limit,
filters: display ? display.compileFilters() : null,
});
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;
}
</script>
<script lang="ts">
import _ from 'lodash';
import axios from '../utility/axios';
import socket from '../utility/socket';
import useEffect from '../utility/useEffect';
import LoadingDataGridCore from './LoadingDataGridCore.svelte';
import RowsArrayGrider from './RowsArrayGrider';
export let jslid;
let loadedRows = [];
let domGrid;
let changeIndex = 0;
let rowCountLoaded = null;
const throttleLoadNext = _.throttle(() => domGrid.loadNextData(), 500);
const handleJslDataStats = stats => {
if (stats.changeIndex < changeIndex) return;
changeIndex = stats.changeIndex;
rowCountLoaded = stats.rowCount;
throttleLoadNext();
};
$: effect = useEffect(() => onJslId(jslid));
function onJslId(jslidVal) {
if (jslidVal) {
socket.on(`jsldata-stats-${jslidVal}`, handleJslDataStats);
return () => {
socket.off(`jsldata-stats-${jslidVal}`, handleJslDataStats);
};
}
}
$: $effect;
$: grider = new RowsArrayGrider(loadedRows);
</script>
<LoadingDataGridCore
bind:this={domGrid}
{...$$props}
bind:loadedRows
{loadDataPage}
{dataPageAvailable}
{loadRowCount}
{grider}
{rowCountLoaded}
/>

View File

@@ -15,7 +15,7 @@
let loadedTime = new Date().getTime();
let allRowCount = null;
let errorMessage = null;
let loadNextDataToken = 0;
const loadNextDataRef = { current: false };
const loadedTimeRef = { current: null };
const handleLoadRowCount = async () => {
@@ -23,8 +23,9 @@
allRowCount = rowCount;
};
async function loadNextData() {
export async function loadNextData() {
if (isLoading) return;
loadNextDataRef.current = false;
isLoading = true;
const loadStart = new Date().getTime();
@@ -60,6 +61,9 @@
// }));
}
if (loadNextDataRef.current) {
loadNextData();
}
// console.log('LOADED', nextRows, loadedRows);
}
@@ -82,7 +86,8 @@
isLoadedAll = false;
loadedTime = new Date().getTime();
errorMessage = null;
loadNextDataToken = 0;
loadNextDataRef.current = false;
// loadNextDataToken = 0;
}
$: if (display.cache.refreshTime > loadedTime) {

View File

@@ -0,0 +1,13 @@
import Grider, { GriderRowStatus } from './Grider';
export default class RowsArrayGrider extends Grider {
constructor(private rows: any[]) {
super();
}
getRowData(index: any) {
return this.rows[index];
}
get rowCount() {
return this.rows.length;
}
}

View File

@@ -9,6 +9,13 @@
export let tabs: TabDef[];
export let value = 0;
export let isInline = false;
export function setValue(index) {
value = index;
}
export function getValue() {
return value;
}
</script>
<div class="main">

View File

@@ -0,0 +1,66 @@
<script lang="ts">
import _ from 'lodash';
import { tick } from 'svelte';
import JslDataGrid from '../datagrid/JslDataGrid.svelte';
import TabControl from '../elements/TabControl.svelte';
import socket from '../utility/socket';
import useEffect from '../utility/useEffect';
export let tabs = [];
export let sessionId;
export let executeNumber;
let resultInfos = [];
let domTabs;
const handleResultSet = async props => {
const { jslid, resultIndex } = props;
resultInfos = [...resultInfos, { jslid, resultIndex }];
await tick();
const currentTab = allTabs[domTabs.getValue()];
if (!currentTab?.isResult) domTabs.setValue(_.findIndex(allTabs, x => x.isResult));
};
$: allTabs = [
...tabs,
...resultInfos.map((info, index) => ({
label: `Result ${index + 1}`,
isResult: true,
component: JslDataGrid,
props: { jslid: info.jslid },
})),
];
$: {
if (executeNumber >= 0) {
resultInfos = [];
}
}
$: effect = useEffect(() => {
return onSession(sessionId);
});
function onSession(sid) {
if (sid) {
socket.on(`session-recordset-${sid}`, handleResultSet);
return () => {
socket.off(`session-recordset-${sid}`, handleResultSet);
};
}
return () => {};
}
$: $effect;
</script>
<TabControl bind:this={domTabs} tabs={allTabs}>
<slot name="0" slot="0" />
<slot name="1" slot="1" />
<slot name="2" slot="2" />
<slot name="3" slot="3" />
<slot name="4" slot="4" />
<slot name="5" slot="5" />
<slot name="6" slot="6" />
<slot name="7" slot="7" />
</TabControl>

View File

@@ -18,12 +18,10 @@
let displayedMessages = [];
const displayCachedMessages = _.throttle(() => {
console.log('THROTTLE', cachedMessagesRef.current);
displayedMessages = [...cachedMessagesRef.current];
}, 500);
const handleInfo = info => {
console.log('ACCEPTED', info);
cachedMessagesRef.current.push(info);
displayCachedMessages();
};
@@ -40,15 +38,12 @@
$: {
if (executeNumber >= 0) {
console.log('CLEAR');
displayedMessages = [];
cachedMessagesRef.current = [];
}
}
$: $effect;
$: console.log('displayedMessages', displayedMessages);
</script>
{#if !displayedMessages || displayedMessages.length == 0}

View File

@@ -48,6 +48,7 @@
import SocketMessageView from '../query/SocketMessageView.svelte';
import memberStore from '../utility/memberStore';
import useEffect from '../utility/useEffect';
import ResultTabs from '../query/ResultTabs.svelte';
export let tabid;
export let conid;
@@ -71,15 +72,17 @@
$: connection = useConnectionInfo({ conid });
$: effect = useEffect(() => {
if (sessionId) {
const sid = sessionId;
return onSession(sessionId);
});
function onSession(sid) {
if (sid) {
socket.on(`session-done-${sid}`, handleSessionDone);
return () => {
socket.off(`session-done-${sid}`, handleSessionDone);
};
}
return () => {};
});
}
$: $effect;
$: {
@@ -161,12 +164,16 @@
/>
</svelte:fragment>
<svelte:fragment slot="2">
<SocketMessageView
eventName={sessionId ? `session-info-${sessionId}` : null}
on:messageClick={handleMesageClick}
{executeNumber}
showProcedure
showLine
/>
<ResultTabs tabs={[{ label: 'Messages', slot: 0 }]} {sessionId} {executeNumber}>
<svelte:fragment slot="0">
<SocketMessageView
eventName={sessionId ? `session-info-${sessionId}` : null}
on:messageClick={handleMesageClick}
{executeNumber}
showProcedure
showLine
/>
</svelte:fragment>
</ResultTabs>
</svelte:fragment>
</VerticalSplitter>

View File

@@ -8,7 +8,6 @@ export default function memberStore(store, extractStore) {
if (unsubscribeSub) unsubscribeSub();
unsubscribeSub = subStore.subscribe(subValue => {
if (res) {
console.log('subValue', subValue);
res.set(subValue);
} else {
res = writable(subValue);

View File

@@ -0,0 +1,21 @@
import _ from 'lodash';
import axios from './axios';
import { writable } from 'svelte/store';
export default function useFetch({ url, data = undefined, params = undefined, defaultValue = undefined, ...config }) {
const result = writable(defaultValue);
axios
.request({
method: 'get',
params,
url,
data,
...config,
})
.then(resp => {
result.set(resp.data);
});
return result;
}