mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-04-19 23:35:59 +00:00
query grid
This commit is contained in:
29
packages/web/src/datagrid/JslDataGrid.svelte
Normal file
29
packages/web/src/datagrid/JslDataGrid.svelte
Normal 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}
|
||||
83
packages/web/src/datagrid/JslDataGridCore.svelte
Normal file
83
packages/web/src/datagrid/JslDataGridCore.svelte
Normal 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}
|
||||
/>
|
||||
@@ -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) {
|
||||
|
||||
13
packages/web/src/datagrid/RowsArrayGrider.ts
Normal file
13
packages/web/src/datagrid/RowsArrayGrider.ts
Normal 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;
|
||||
}
|
||||
}
|
||||
@@ -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">
|
||||
|
||||
66
packages/web/src/query/ResultTabs.svelte
Normal file
66
packages/web/src/query/ResultTabs.svelte
Normal 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>
|
||||
@@ -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}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
|
||||
21
packages/web/src/utility/useFetch.ts
Normal file
21
packages/web/src/utility/useFetch.ts
Normal 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;
|
||||
}
|
||||
Reference in New Issue
Block a user