mirror of
https://github.com/dbgate/dbgate
synced 2024-11-07 20:26:23 +00:00
nosql queries
This commit is contained in:
parent
3b047dbe6d
commit
6af21b8bae
@ -17,12 +17,12 @@ let afterConnectCallbacks = [];
|
||||
// let currentHandlers = [];
|
||||
|
||||
class TableWriter {
|
||||
constructor(columns, resultIndex) {
|
||||
constructor(structure, resultIndex) {
|
||||
this.jslid = uuidv1();
|
||||
this.currentFile = path.join(jsldir(), `${this.jslid}.jsonl`);
|
||||
this.currentRowCount = 0;
|
||||
this.currentChangeIndex = 1;
|
||||
fs.writeFileSync(this.currentFile, JSON.stringify({ columns }) + '\n');
|
||||
fs.writeFileSync(this.currentFile, JSON.stringify(structure) + '\n');
|
||||
this.currentStream = fs.createWriteStream(this.currentFile, { flags: 'a' });
|
||||
this.writeCurrentStats(false, false);
|
||||
this.resultIndex = resultIndex;
|
||||
@ -92,7 +92,7 @@ class StreamHandler {
|
||||
|
||||
recordset(columns) {
|
||||
this.closeCurrentWriter();
|
||||
this.currentWriter = new TableWriter(columns, this.resultIndexHolder.value);
|
||||
this.currentWriter = new TableWriter(Array.isArray(columns) ? { columns } : columns, this.resultIndexHolder.value);
|
||||
this.resultIndexHolder.value += 1;
|
||||
|
||||
// this.writeCurrentStats();
|
||||
|
@ -21,7 +21,7 @@ function requirePlugin(packageName, requiredPlugin = null) {
|
||||
// @ts-ignore
|
||||
module = __non_webpack_require__(modulePath);
|
||||
} catch (err) {
|
||||
console.error('Failed load webpacked module', err);
|
||||
console.log('Failed load webpacked module', err.message);
|
||||
module = require(modulePath);
|
||||
}
|
||||
requiredPlugin = module.__esModule ? module.default : module;
|
||||
|
@ -25,46 +25,12 @@ function createHeaderText(path) {
|
||||
return res;
|
||||
}
|
||||
|
||||
export class CollectionGridDisplay extends GridDisplay {
|
||||
constructor(
|
||||
public collection: CollectionInfo,
|
||||
driver: EngineDriver,
|
||||
config: GridConfig,
|
||||
setConfig: ChangeConfigFunc,
|
||||
cache: GridCache,
|
||||
setCache: ChangeCacheFunc,
|
||||
loadedRows
|
||||
) {
|
||||
super(config, setConfig, cache, setCache, driver);
|
||||
this.columns = this.getDisplayColumns(loadedRows || []);
|
||||
this.filterable = true;
|
||||
this.sortable = true;
|
||||
this.editable = true;
|
||||
this.supportsReload = true;
|
||||
this.isDynamicStructure = true;
|
||||
this.changeSetKeyFields = ['_id'];
|
||||
this.baseCollection = collection;
|
||||
}
|
||||
|
||||
getDisplayColumns(rows) {
|
||||
const res = [];
|
||||
for (const row of rows) {
|
||||
this.getColumnsForObject([], row, res);
|
||||
}
|
||||
return (
|
||||
res.map(col => ({
|
||||
...col,
|
||||
isChecked: this.isColumnChecked(col),
|
||||
})) || []
|
||||
);
|
||||
}
|
||||
|
||||
getColumnsForObject(basePath, obj, res: any[]) {
|
||||
function getColumnsForObject(basePath, obj, res: any[], display) {
|
||||
for (const name of getObjectKeys(obj)) {
|
||||
const uniqueName = [...basePath, name].join('.');
|
||||
let column = res.find(x => x.uniqueName == uniqueName);
|
||||
if (!column) {
|
||||
column = this.getDisplayColumn(basePath, name);
|
||||
column = getDisplayColumn(basePath, name, display);
|
||||
if (basePath.length > 0) {
|
||||
const lastIndex1 = _.findLastIndex(res, x => x.parentHeaderText.startsWith(column.parentHeaderText));
|
||||
const lastIndex2 = _.findLastIndex(res, x => x.headerText == column.parentHeaderText);
|
||||
@ -80,13 +46,13 @@ export class CollectionGridDisplay extends GridDisplay {
|
||||
column.isExpandable = true;
|
||||
}
|
||||
|
||||
if (this.isExpandedColumn(column.uniqueName)) {
|
||||
this.getColumnsForObject([...basePath, name], obj[name], res);
|
||||
if (display.isExpandedColumn(column.uniqueName)) {
|
||||
getColumnsForObject([...basePath, name], obj[name], res, display);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getDisplayColumn(basePath, columnName) {
|
||||
function getDisplayColumn(basePath, columnName, display) {
|
||||
const uniquePath = [...basePath, columnName];
|
||||
const uniqueName = uniquePath.join('.');
|
||||
return {
|
||||
@ -97,8 +63,42 @@ export class CollectionGridDisplay extends GridDisplay {
|
||||
isStructured: true,
|
||||
parentHeaderText: createHeaderText(basePath),
|
||||
filterType: 'mongo',
|
||||
pureName: this.collection.pureName,
|
||||
schemaName: this.collection.schemaName,
|
||||
pureName: display.collection?.pureName,
|
||||
schemaName: display.collection?.schemaName,
|
||||
};
|
||||
}
|
||||
|
||||
export function analyseCollectionDisplayColumns(rows, display) {
|
||||
const res = [];
|
||||
for (const row of rows || []) {
|
||||
getColumnsForObject([], row, res, display);
|
||||
}
|
||||
return (
|
||||
res.map(col => ({
|
||||
...col,
|
||||
isChecked: display.isColumnChecked(col),
|
||||
})) || []
|
||||
);
|
||||
}
|
||||
|
||||
export class CollectionGridDisplay extends GridDisplay {
|
||||
constructor(
|
||||
public collection: CollectionInfo,
|
||||
driver: EngineDriver,
|
||||
config: GridConfig,
|
||||
setConfig: ChangeConfigFunc,
|
||||
cache: GridCache,
|
||||
setCache: ChangeCacheFunc,
|
||||
loadedRows
|
||||
) {
|
||||
super(config, setConfig, cache, setCache, driver);
|
||||
this.columns = analyseCollectionDisplayColumns(loadedRows, this);
|
||||
this.filterable = true;
|
||||
this.sortable = true;
|
||||
this.editable = true;
|
||||
this.supportsReload = true;
|
||||
this.isDynamicStructure = true;
|
||||
this.changeSetKeyFields = ['_id'];
|
||||
this.baseCollection = collection;
|
||||
}
|
||||
}
|
||||
|
@ -1,21 +1,24 @@
|
||||
import { GridDisplay, ChangeCacheFunc, ChangeConfigFunc } from './GridDisplay';
|
||||
import { QueryResultColumn } from 'dbgate-types';
|
||||
import { GridConfig, GridCache } from './GridConfig';
|
||||
import { analyseCollectionDisplayColumns } from './CollectionGridDisplay';
|
||||
|
||||
export class JslGridDisplay extends GridDisplay {
|
||||
constructor(
|
||||
jslid,
|
||||
columns: QueryResultColumn[],
|
||||
structure,
|
||||
config: GridConfig,
|
||||
setConfig: ChangeConfigFunc,
|
||||
cache: GridCache,
|
||||
setCache: ChangeCacheFunc
|
||||
setCache: ChangeCacheFunc,
|
||||
rows: any
|
||||
) {
|
||||
super(config, setConfig, cache, setCache, null);
|
||||
|
||||
this.filterable = true;
|
||||
|
||||
this.columns = columns
|
||||
if (structure.columns) {
|
||||
this.columns = structure.columns
|
||||
.map(col => ({
|
||||
columnName: col.columnName,
|
||||
headerText: col.columnName,
|
||||
@ -31,4 +34,11 @@ export class JslGridDisplay extends GridDisplay {
|
||||
isChecked: this.isColumnChecked(col),
|
||||
}));
|
||||
}
|
||||
|
||||
if (structure.__isDynamicStructure) {
|
||||
this.columns = analyseCollectionDisplayColumns(rows, this);
|
||||
}
|
||||
|
||||
if (!this.columns) this.columns = [];
|
||||
}
|
||||
}
|
||||
|
@ -10,20 +10,27 @@
|
||||
|
||||
export let jslid;
|
||||
|
||||
let loadedRows;
|
||||
|
||||
$: info = useFetch({
|
||||
params: { jslid },
|
||||
url: 'jsldata/get-info',
|
||||
defaultValue: {},
|
||||
});
|
||||
|
||||
$: columns = ($info && $info.columns) || [];
|
||||
// $: columns = ($info && $info.columns) || [];
|
||||
const config = writable(createGridConfig());
|
||||
const cache = writable(createGridCache());
|
||||
|
||||
$: display = new JslGridDisplay(jslid, columns, $config, config.update, $cache, cache.update);
|
||||
|
||||
$: display = new JslGridDisplay(jslid, $info, $config, config.update, $cache, cache.update, loadedRows);
|
||||
</script>
|
||||
|
||||
{#key jslid}
|
||||
<DataGrid {display} {jslid} gridCoreComponent={JslDataGridCore} />
|
||||
<DataGrid
|
||||
{display}
|
||||
{jslid}
|
||||
gridCoreComponent={JslDataGridCore}
|
||||
bind:loadedRows
|
||||
isDynamicStructure={$info?.__isDynamicStructure}
|
||||
/>
|
||||
{/key}
|
||||
|
@ -60,7 +60,7 @@
|
||||
|
||||
export const activator = createActivator('JslDataGridCore', false);
|
||||
|
||||
let loadedRows = [];
|
||||
export let loadedRows = [];
|
||||
let domGrid;
|
||||
|
||||
let changeIndex = 0;
|
||||
|
@ -36,6 +36,7 @@
|
||||
$: {
|
||||
if (executeNumber >= 0) {
|
||||
resultInfos = [];
|
||||
if (domTabs) domTabs.setValue(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
id: 'query.formatCode',
|
||||
category: 'Query',
|
||||
name: 'Format code',
|
||||
testEnabled: () => getCurrentEditor() != null,
|
||||
testEnabled: () => getCurrentEditor()?.isSqlEditor(),
|
||||
onClick: () => getCurrentEditor().formatCode(),
|
||||
});
|
||||
registerCommand({
|
||||
@ -13,7 +13,7 @@
|
||||
category: 'Query',
|
||||
name: 'Insert SQL Join',
|
||||
keyText: 'Ctrl+J',
|
||||
testEnabled: () => getCurrentEditor() != null,
|
||||
testEnabled: () => getCurrentEditor()?.isSqlEditor(),
|
||||
onClick: () => getCurrentEditor().insertSqlJoin(),
|
||||
});
|
||||
registerFileCommands({
|
||||
@ -54,6 +54,8 @@
|
||||
import InsertJoinModal from '../modals/InsertJoinModal.svelte';
|
||||
import useTimerLabel from '../utility/useTimerLabel';
|
||||
import createActivator, { getActiveComponent } from '../utility/createActivator';
|
||||
import { findEngineDriver } from 'dbgate-tools';
|
||||
import AceEditor from '../query/AceEditor.svelte';
|
||||
|
||||
export let tabid;
|
||||
export let conid;
|
||||
@ -73,6 +75,7 @@
|
||||
let domEditor;
|
||||
|
||||
$: connection = useConnectionInfo({ conid });
|
||||
$: driver = findEngineDriver($connection, $extensions);
|
||||
|
||||
$: effect = useEffect(() => {
|
||||
return onSession(sessionId);
|
||||
@ -102,6 +105,10 @@
|
||||
domEditor?.getEditor()?.focus();
|
||||
}
|
||||
|
||||
export function isSqlEditor() {
|
||||
return !driver?.dialect?.nosql;
|
||||
}
|
||||
|
||||
export function canKill() {
|
||||
return !!sessionId;
|
||||
}
|
||||
@ -225,6 +232,19 @@
|
||||
|
||||
<VerticalSplitter isSplitter={visibleResultTabs}>
|
||||
<svelte:fragment slot="1">
|
||||
{#if driver?.dialect?.nosql}
|
||||
<AceEditor
|
||||
mode="javascript"
|
||||
value={$editorState.value || ''}
|
||||
menu={createMenu()}
|
||||
on:input={e => setEditorData(e.detail)}
|
||||
on:focus={() => {
|
||||
activator.activate();
|
||||
invalidateCommands();
|
||||
}}
|
||||
bind:this={domEditor}
|
||||
/>
|
||||
{:else}
|
||||
<SqlEditor
|
||||
engine={$connection && $connection.engine}
|
||||
{conid}
|
||||
@ -238,6 +258,7 @@
|
||||
}}
|
||||
bind:this={domEditor}
|
||||
/>
|
||||
{/if}
|
||||
</svelte:fragment>
|
||||
<svelte:fragment slot="2">
|
||||
<ResultTabs tabs={[{ label: 'Messages', slot: 0 }]} {sessionId} {executeNumber}>
|
||||
|
Loading…
Reference in New Issue
Block a user