diff --git a/packages/api/package.json b/packages/api/package.json
index 0ac5da100..8d8ee1eff 100644
--- a/packages/api/package.json
+++ b/packages/api/package.json
@@ -33,6 +33,7 @@
"express-basic-auth": "^1.2.0",
"express-fileupload": "^1.2.0",
"fs-extra": "^9.1.0",
+ "fs-reverse": "^0.0.3",
"get-port": "^5.1.1",
"http": "^0.0.0",
"json-stable-stringify": "^1.0.1",
@@ -71,4 +72,4 @@
"optionalDependencies": {
"msnodesqlv8": "^2.0.10"
}
-}
\ No newline at end of file
+}
diff --git a/packages/api/src/controllers/queryHistory.js b/packages/api/src/controllers/queryHistory.js
new file mode 100644
index 000000000..e6a3ea077
--- /dev/null
+++ b/packages/api/src/controllers/queryHistory.js
@@ -0,0 +1,45 @@
+const fsReverse = require('fs-reverse');
+const fs = require('fs-extra');
+const path = require('path');
+const { datadir } = require('../utility/directories');
+const _ = require('lodash');
+const { filterName } = require('dbgate-tools');
+
+function readCore(reader, skip, limit, filter) {
+ return new Promise(resolve => {
+ const res = [];
+ let readed = 0;
+ reader.on('data', line => {
+ const json = JSON.parse(line);
+ if (filterName(filter, json.sql)) {
+ if (!skip || readed >= skip) {
+ res.push(json);
+ }
+ readed++;
+ if (limit && readed > (skip || 0) + limit) {
+ reader.destroy();
+ resolve(res);
+ }
+ }
+ });
+ reader.on('end', () => resolve(res));
+ });
+}
+
+module.exports = {
+ read_meta: 'get',
+ async read({ skip, limit, filter }) {
+ const fileName = path.join(datadir(), 'query-history.jsonl');
+ // @ts-ignore
+ if (!(await fs.exists(fileName))) return [];
+ const reader = fsReverse(fileName);
+ const res = await readCore(reader, skip, limit, filter);
+ return res;
+ },
+
+ write_meta: 'post',
+ async write({ data }) {
+ const fileName = path.join(datadir(), 'query-history.jsonl');
+ await fs.appendFile(fileName, JSON.stringify(data) + '\n');
+ },
+};
diff --git a/packages/api/src/main.js b/packages/api/src/main.js
index 3171aec00..29159fca9 100644
--- a/packages/api/src/main.js
+++ b/packages/api/src/main.js
@@ -27,6 +27,7 @@ const uploads = require('./controllers/uploads');
const plugins = require('./controllers/plugins');
const files = require('./controllers/files');
const scheduler = require('./controllers/scheduler');
+const queryHistory = require('./controllers/queryHistory');
const { rundir } = require('./utility/directories');
const platformInfo = require('./utility/platformInfo');
@@ -102,6 +103,7 @@ function start() {
useController(app, '/plugins', plugins);
useController(app, '/files', files);
useController(app, '/scheduler', scheduler);
+ useController(app, '/query-history', queryHistory);
// if (process.env.PAGES_DIRECTORY) {
// app.use('/pages', express.static(process.env.PAGES_DIRECTORY));
diff --git a/packages/datalib/src/FormViewDisplay.ts b/packages/datalib/src/FormViewDisplay.ts
index 48ccdd907..20a372a10 100644
--- a/packages/datalib/src/FormViewDisplay.ts
+++ b/packages/datalib/src/FormViewDisplay.ts
@@ -1,19 +1,7 @@
import _ from 'lodash';
import { GridConfig, GridCache, GridConfigColumns, createGridCache, GroupFunc } from './GridConfig';
-import {
- ForeignKeyInfo,
- TableInfo,
- ColumnInfo,
- EngineDriver,
- NamedObjectInfo,
- DatabaseInfo,
- SqlDialect,
-} from 'dbgate-types';
-import { parseFilter, getFilterType, getFilterValueExpression } from 'dbgate-filterparser';
-import { filterName } from './filterName';
-import { ChangeSetFieldDefinition, ChangeSetRowDefinition } from './ChangeSet';
-import { Expression, Select, treeToSql, dumpSqlSelect, Condition } from 'dbgate-sqltree';
-import { isTypeLogical } from 'dbgate-tools';
+import { TableInfo, EngineDriver, DatabaseInfo, SqlDialect } from 'dbgate-types';
+import { getFilterValueExpression } from 'dbgate-filterparser';
import { ChangeCacheFunc, ChangeConfigFunc, DisplayColumn } from './GridDisplay';
export class FormViewDisplay {
diff --git a/packages/datalib/src/GridDisplay.ts b/packages/datalib/src/GridDisplay.ts
index 6b7a78c66..9b5678a82 100644
--- a/packages/datalib/src/GridDisplay.ts
+++ b/packages/datalib/src/GridDisplay.ts
@@ -11,7 +11,7 @@ import {
SqlDialect,
} from 'dbgate-types';
import { parseFilter, getFilterType } from 'dbgate-filterparser';
-import { filterName } from './filterName';
+import { filterName } from 'dbgate-tools';
import { ChangeSetFieldDefinition, ChangeSetRowDefinition } from './ChangeSet';
import { Expression, Select, treeToSql, dumpSqlSelect, Condition } from 'dbgate-sqltree';
import { isTypeLogical } from 'dbgate-tools';
diff --git a/packages/datalib/src/TableFormViewDisplay.ts b/packages/datalib/src/TableFormViewDisplay.ts
index 6043ca7b1..7c6bb292f 100644
--- a/packages/datalib/src/TableFormViewDisplay.ts
+++ b/packages/datalib/src/TableFormViewDisplay.ts
@@ -12,7 +12,6 @@ import {
Condition,
OrderByExpression,
} from 'dbgate-sqltree';
-import { filterName } from './filterName';
import { TableGridDisplay } from './TableGridDisplay';
import stableStringify from 'json-stable-stringify';
import { ChangeSetFieldDefinition, ChangeSetRowDefinition } from './ChangeSet';
diff --git a/packages/datalib/src/TableGridDisplay.ts b/packages/datalib/src/TableGridDisplay.ts
index 16d215e42..46bc64d5a 100644
--- a/packages/datalib/src/TableGridDisplay.ts
+++ b/packages/datalib/src/TableGridDisplay.ts
@@ -1,9 +1,9 @@
import _ from 'lodash';
+import { filterName } from 'dbgate-tools';
import { GridDisplay, ChangeCacheFunc, DisplayColumn, DisplayedColumnInfo, ChangeConfigFunc } from './GridDisplay';
import { TableInfo, EngineDriver, ViewInfo, ColumnInfo, NamedObjectInfo, DatabaseInfo } from 'dbgate-types';
import { GridConfig, GridCache, createGridCache } from './GridConfig';
import { Expression, Select, treeToSql, dumpSqlSelect } from 'dbgate-sqltree';
-import { filterName } from './filterName';
export class TableGridDisplay extends GridDisplay {
public table: TableInfo;
diff --git a/packages/datalib/src/index.ts b/packages/datalib/src/index.ts
index 2e1788de6..b29344daf 100644
--- a/packages/datalib/src/index.ts
+++ b/packages/datalib/src/index.ts
@@ -4,7 +4,6 @@ export * from './TableGridDisplay';
export * from './ViewGridDisplay';
export * from './JslGridDisplay';
export * from './ChangeSet';
-export * from './filterName';
export * from './FreeTableGridDisplay';
export * from './FreeTableModel';
export * from './MacroDefinition';
diff --git a/packages/datalib/src/filterName.ts b/packages/tools/src/filterName.ts
similarity index 89%
rename from packages/datalib/src/filterName.ts
rename to packages/tools/src/filterName.ts
index a99dbda67..95867d507 100644
--- a/packages/datalib/src/filterName.ts
+++ b/packages/tools/src/filterName.ts
@@ -1,4 +1,4 @@
-import _ from 'lodash';
+import _compact from 'lodash/compact';
// original C# variant
// public bool Match(string value)
@@ -39,6 +39,6 @@ export function filterName(filter: string, ...names: string[]) {
// const camelVariants = [name.replace(/[^A-Z]/g, '')]
const tokens = filter.split(' ').map(x => x.trim());
- return !!_.compact(names).find(name => !tokens.find(token => !name.toUpperCase().includes(token.toUpperCase())));
+ return !!_compact(names).find(name => !tokens.find(token => !name.toUpperCase().includes(token.toUpperCase())));
// return name.toUpperCase().includes(filter.toUpperCase());
}
diff --git a/packages/tools/src/index.ts b/packages/tools/src/index.ts
index c3b1c611e..0418719e0 100644
--- a/packages/tools/src/index.ts
+++ b/packages/tools/src/index.ts
@@ -10,3 +10,4 @@ export * from './testPermission';
export * from './SqlGenerator';
export * from './structureTools';
export * from './settingsExtractors';
+export * from './filterName';
diff --git a/packages/web/src/appobj/AppObjectList.svelte b/packages/web/src/appobj/AppObjectList.svelte
index cf27e6652..cefe1ecf3 100644
--- a/packages/web/src/appobj/AppObjectList.svelte
+++ b/packages/web/src/appobj/AppObjectList.svelte
@@ -9,7 +9,7 @@
export let subItemsComponent = undefined;
export let expandOnClick = false;
export let isExpandable = undefined;
- export let filter;
+ export let filter = undefined;
export let expandIconFunc = undefined;
export let checkedObjectsStore = null;
export let disableContextMenu = false;
@@ -34,6 +34,7 @@
: null;
$: groups = groupFunc ? _.groupBy(listGrouped, 'group') : null;
+
{#if groupFunc}
diff --git a/packages/web/src/appobj/ArchiveFileAppObject.svelte b/packages/web/src/appobj/ArchiveFileAppObject.svelte
index 9031f0a24..c1da6219c 100644
--- a/packages/web/src/appobj/ArchiveFileAppObject.svelte
+++ b/packages/web/src/appobj/ArchiveFileAppObject.svelte
@@ -17,7 +17,7 @@
diff --git a/packages/web/src/datagrid/ReferenceManager.svelte b/packages/web/src/datagrid/ReferenceManager.svelte
index 4534c81c5..cb0b5b0dd 100644
--- a/packages/web/src/datagrid/ReferenceManager.svelte
+++ b/packages/web/src/datagrid/ReferenceManager.svelte
@@ -1,5 +1,6 @@
@@ -86,4 +88,5 @@
.link:hover {
text-decoration: underline;
}
+
diff --git a/packages/web/src/formview/FormView.svelte b/packages/web/src/formview/FormView.svelte
index b9617935b..baf296642 100644
--- a/packages/web/src/formview/FormView.svelte
+++ b/packages/web/src/formview/FormView.svelte
@@ -156,7 +156,7 @@
diff --git a/packages/web/src/widgets/FilesWidget.svelte b/packages/web/src/widgets/FilesWidget.svelte
index 94f2d1993..ea4717951 100644
--- a/packages/web/src/widgets/FilesWidget.svelte
+++ b/packages/web/src/widgets/FilesWidget.svelte
@@ -3,9 +3,30 @@
import WidgetColumnBar from './WidgetColumnBar.svelte';
import WidgetColumnBarItem from './WidgetColumnBarItem.svelte';
+
+ import AppObjectList from '../appobj/AppObjectList.svelte';
+ import * as closedTabAppObject from '../appobj/ClosedTabAppObject.svelte';
+ import * as favoriteFileAppObject from '../appobj/FavoriteFileAppObject.svelte';
+ import { openedTabs } from '../stores';
+
+ import hasPermission from '../utility/hasPermission';
+ import { useFavorites } from '../utility/metadataLoaders';
+
+ import WidgetsInnerContainer from './WidgetsInnerContainer.svelte';
+
+ $: favorites = useFavorites();
+
+ {#if hasPermission('files/favorites/read')}
+
+
+
+
+
+ {/if}
+
diff --git a/packages/web/src/widgets/FavoritesWidget.svelte b/packages/web/src/widgets/HistoryWidget.svelte
similarity index 77%
rename from packages/web/src/widgets/FavoritesWidget.svelte
rename to packages/web/src/widgets/HistoryWidget.svelte
index c4280ca5d..66a356d07 100644
--- a/packages/web/src/widgets/FavoritesWidget.svelte
+++ b/packages/web/src/widgets/HistoryWidget.svelte
@@ -14,16 +14,10 @@
import WidgetsInnerContainer from './WidgetsInnerContainer.svelte';
$: favorites = useFavorites();
+
- {#if hasPermission('files/favorites/read')}
-
-
-
-
-
- {/if}
{#if $selectedWidget == 'database'}
@@ -14,15 +15,15 @@ import CellDataWidget from './CellDataWidget.svelte';
{#if $selectedWidget == 'file'}
{/if}
+{#if $selectedWidget == 'history'}
+
+{/if}
{#if $selectedWidget == 'archive'}
{/if}
{#if $selectedWidget == 'plugins'}
{/if}
-{#if $selectedWidget == 'favorites'}
-
-{/if}
{#if $selectedWidget == 'cell-data'}
{/if}
diff --git a/packages/web/src/widgets/WidgetIconPanel.svelte b/packages/web/src/widgets/WidgetIconPanel.svelte
index 637a541e9..41dd2e07a 100644
--- a/packages/web/src/widgets/WidgetIconPanel.svelte
+++ b/packages/web/src/widgets/WidgetIconPanel.svelte
@@ -18,7 +18,12 @@
{
icon: 'icon file',
name: 'file',
- title: 'Closed tabs & Saved SQL files',
+ title: 'Favorites & Saved files',
+ },
+ {
+ icon: 'icon history',
+ name: 'history',
+ title: 'Query history & Closed tabs',
},
{
icon: 'icon archive',
@@ -30,11 +35,6 @@
name: 'plugins',
title: 'Extensions & Plugins',
},
- {
- icon: 'icon favorite',
- name: 'favorites',
- title: 'Favorites',
- },
{
icon: 'icon cell-data',
name: 'cell-data',
diff --git a/yarn.lock b/yarn.lock
index 71c97e2ae..27759e55b 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -4359,6 +4359,11 @@ from2@^2.1.0:
inherits "^2.0.1"
readable-stream "^2.0.0"
+from@~0.1:
+ version "0.1.7"
+ resolved "https://registry.yarnpkg.com/from/-/from-0.1.7.tgz#83c60afc58b9c56997007ed1a768b3ab303a44fe"
+ integrity sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4=
+
fs-constants@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad"
@@ -4408,6 +4413,13 @@ fs-minipass@^2.0.0, fs-minipass@^2.1.0:
dependencies:
minipass "^3.0.0"
+fs-reverse@^0.0.3:
+ version "0.0.3"
+ resolved "https://registry.yarnpkg.com/fs-reverse/-/fs-reverse-0.0.3.tgz#5ef1e180a65fc0ee3cfb972d376114814203b43d"
+ integrity sha512-zu+5yhmaWueDBAWm7y6ejj2PipVep3EQlQYdfS6r3zsfzIfTVkcdbrsqye2UovisDqogu5dJFxae/dUAOYQqBA==
+ dependencies:
+ from "~0.1"
+
fs-write-stream-atomic@^1.0.8:
version "1.0.10"
resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9"