mirror of
https://github.com/dbgate/dbgate
synced 2024-11-07 20:26:23 +00:00
loading redis keys
This commit is contained in:
parent
425841bb38
commit
51942be0a6
@ -151,6 +151,16 @@ module.exports = {
|
||||
return res.result;
|
||||
},
|
||||
|
||||
loadKeys_meta: true,
|
||||
async loadKeys({ conid, database, root }) {
|
||||
const opened = await this.ensureOpened(conid, database);
|
||||
const res = await this.sendRequest(opened, { msgtype: 'loadKeys', root });
|
||||
if (res.errorMessage) {
|
||||
console.error(res.errorMessage);
|
||||
}
|
||||
return res.result || null;
|
||||
},
|
||||
|
||||
updateCollection_meta: true,
|
||||
async updateCollection({ conid, database, changeSet }) {
|
||||
const opened = await this.ensureOpened(conid, database);
|
||||
|
@ -183,6 +183,17 @@ async function handleCollectionData({ msgid, options }) {
|
||||
}
|
||||
}
|
||||
|
||||
async function handleLoadKeys({ msgid, root }) {
|
||||
await waitConnected();
|
||||
const driver = requireEngineDriver(storedConnection);
|
||||
try {
|
||||
const result = await driver.loadKeys(systemConnection, root);
|
||||
process.send({ msgtype: 'response', msgid, result });
|
||||
} catch (err) {
|
||||
process.send({ msgtype: 'response', msgid, errorMessage: err.message });
|
||||
}
|
||||
}
|
||||
|
||||
async function handleUpdateCollection({ msgid, changeSet }) {
|
||||
await waitConnected();
|
||||
const driver = requireEngineDriver(storedConnection);
|
||||
@ -248,6 +259,7 @@ const messageHandlers = {
|
||||
runScript: handleRunScript,
|
||||
updateCollection: handleUpdateCollection,
|
||||
collectionData: handleCollectionData,
|
||||
loadKeys: handleLoadKeys,
|
||||
sqlPreview: handleSqlPreview,
|
||||
ping: handlePing,
|
||||
syncModel: handleSyncModel,
|
||||
|
1
packages/types/engines.d.ts
vendored
1
packages/types/engines.d.ts
vendored
@ -75,6 +75,7 @@ export interface EngineDriver {
|
||||
name: string;
|
||||
}[]
|
||||
>;
|
||||
loadKeys(pool, root: string): Promise;
|
||||
analyseFull(pool: any, serverVersion): Promise<DatabaseInfo>;
|
||||
analyseIncremental(pool: any, structure: DatabaseInfo, serverVersion): Promise<DatabaseInfo>;
|
||||
dialect: SqlDialect;
|
||||
|
@ -78,6 +78,12 @@ const databaseListLoader = ({ conid }) => ({
|
||||
},
|
||||
});
|
||||
|
||||
const databaseKeysLoader = ({ conid, database, root }) => ({
|
||||
url: 'database-connections/load-keys',
|
||||
params: { conid, database, root },
|
||||
reloadTrigger: `database-keys-changed-${conid}-${database}`,
|
||||
});
|
||||
|
||||
const serverVersionLoader = ({ conid }) => ({
|
||||
url: 'server-connections/version',
|
||||
params: { conid },
|
||||
@ -429,3 +435,10 @@ export function getAuthTypes(args) {
|
||||
export function useAuthTypes(args) {
|
||||
return useCore(authTypesLoader, args);
|
||||
}
|
||||
|
||||
export function getDatabaseKeys(args) {
|
||||
return getCore(databaseKeysLoader, args);
|
||||
}
|
||||
export function useDatabaseKeys(args) {
|
||||
return useCore(databaseKeysLoader, args);
|
||||
}
|
||||
|
@ -11,6 +11,7 @@
|
||||
import WidgetColumnBar from './WidgetColumnBar.svelte';
|
||||
import WidgetColumnBarItem from './WidgetColumnBarItem.svelte';
|
||||
import SqlObjectList from './SqlObjectList.svelte';
|
||||
import DbKeysTree from './DbKeysTree.svelte';
|
||||
|
||||
export let hidden = false;
|
||||
|
||||
@ -49,7 +50,9 @@
|
||||
<SqlObjectList {conid} {database} />
|
||||
</WidgetColumnBarItem>
|
||||
{:else if driver?.databaseEngineTypes?.includes('keyvalue')}
|
||||
<WidgetColumnBarItem title={'Keys'} name="dbObjects" storageName="dbObjectsWidget" />
|
||||
<WidgetColumnBarItem title={'Keys'} name="dbObjects" storageName="dbObjectsWidget">
|
||||
<DbKeysTree {conid} {database} />
|
||||
</WidgetColumnBarItem>
|
||||
{/if}
|
||||
{:else}
|
||||
<WidgetColumnBarItem title="Database content" name="dbObjects" storageName="dbObjectsWidget">
|
||||
|
16
packages/web/src/widgets/DbKeysSubTree.svelte
Normal file
16
packages/web/src/widgets/DbKeysSubTree.svelte
Normal file
@ -0,0 +1,16 @@
|
||||
<script lang="ts">
|
||||
import { useDatabaseKeys } from '../utility/metadataLoaders';
|
||||
|
||||
export let conid;
|
||||
export let database;
|
||||
|
||||
export let root;
|
||||
|
||||
$: keys = useDatabaseKeys({ conid, database, root });
|
||||
</script>
|
||||
|
||||
{#each $keys || [] as key}
|
||||
<div>
|
||||
{key.text}
|
||||
</div>
|
||||
{/each}
|
8
packages/web/src/widgets/DbKeysTree.svelte
Normal file
8
packages/web/src/widgets/DbKeysTree.svelte
Normal file
@ -0,0 +1,8 @@
|
||||
<script lang="ts">
|
||||
import DbKeysSubTree from './DbKeysSubTree.svelte';
|
||||
|
||||
export let conid;
|
||||
export let database;
|
||||
</script>
|
||||
|
||||
<DbKeysSubTree {conid} {database} root="" />
|
@ -1,19 +0,0 @@
|
||||
<script lang="ts">
|
||||
import _ from 'lodash';
|
||||
import { currentDatabase } from '../stores';
|
||||
import ErrorInfo from '../elements/ErrorInfo.svelte';
|
||||
import SqlObjectList from './SqlObjectList.svelte';
|
||||
import WidgetsInnerContainer from './WidgetsInnerContainer.svelte';
|
||||
|
||||
$: conid = _.get($currentDatabase, 'connection._id');
|
||||
$: singleDatabase = _.get($currentDatabase, 'connection.singleDatabase');
|
||||
$: database = _.get($currentDatabase, 'name');
|
||||
</script>
|
||||
|
||||
{#if conid && (database || singleDatabase)}
|
||||
<SqlObjectList {conid} {database} />
|
||||
{:else}
|
||||
<WidgetsInnerContainer>
|
||||
<ErrorInfo message="Database not selected" icon="img alert" />
|
||||
</WidgetsInnerContainer>
|
||||
{/if}
|
@ -37,6 +37,7 @@
|
||||
"webpack-cli": "^3.3.11"
|
||||
},
|
||||
"dependencies": {
|
||||
"async": "^3.2.3",
|
||||
"ioredis": "^4.28.5"
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
const _ = require('lodash');
|
||||
const async = require('async');
|
||||
const stream = require('stream');
|
||||
const driverBase = require('../frontend/driver');
|
||||
const Analyser = require('./Analyser');
|
||||
@ -9,11 +10,14 @@ const driver = {
|
||||
...driverBase,
|
||||
analyserClass: Analyser,
|
||||
async connect({ server, port, password, database }) {
|
||||
let db = 0;
|
||||
if (_.isString(database) && database.startsWith('db')) db = parseInt(database.substring(2));
|
||||
if (_.isNumber(database)) db = database;
|
||||
const pool = new Redis({
|
||||
host: server,
|
||||
port,
|
||||
password,
|
||||
db: 0,
|
||||
db,
|
||||
});
|
||||
return pool;
|
||||
},
|
||||
@ -62,6 +66,61 @@ const driver = {
|
||||
|
||||
return _.range(16).map((index) => ({ name: `db${index}`, extInfo: info[`db${index}`], sortOrder: index }));
|
||||
},
|
||||
|
||||
async loadKeys(pool, root = '') {
|
||||
const keys = await this.getKeys(pool, root);
|
||||
const res = this.extractKeysFromLevel(root, keys);
|
||||
await this.enrichKeyInfo(pool, res);
|
||||
return res;
|
||||
},
|
||||
|
||||
async getKeys(pool, root = '') {
|
||||
const res = [];
|
||||
let cursor = 0;
|
||||
do {
|
||||
const [strCursor, keys] = await pool.scan(cursor, 'MATCH', root ? `${root}:*` : '*', 'COUNT', 100);
|
||||
res.push(...keys);
|
||||
cursor = parseInt(strCursor);
|
||||
} while (cursor > 0);
|
||||
return res;
|
||||
},
|
||||
|
||||
extractKeysFromLevel(root, keys) {
|
||||
const prefix = root ? `${root}:` : '';
|
||||
const rootSplit = _.compact(root.split(':'));
|
||||
const res = {};
|
||||
for (const key of keys) {
|
||||
if (!key.startsWith(prefix)) continue;
|
||||
const keySplit = key.split(':');
|
||||
if (keySplit.length > rootSplit.length) {
|
||||
if (keySplit.length == rootSplit.length + 1) {
|
||||
res[keySplit[rootSplit.length]] = {
|
||||
text: keySplit[rootSplit.length],
|
||||
key,
|
||||
};
|
||||
} else {
|
||||
res[keySplit[rootSplit.length]] = {
|
||||
text: keySplit[rootSplit.length],
|
||||
type: 'dir',
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
return Object.values(res);
|
||||
},
|
||||
|
||||
async enrichOneKeyInfo(pool, item) {
|
||||
const type = await pool.type(item.key);
|
||||
item.type = type;
|
||||
},
|
||||
|
||||
async enrichKeyInfo(pool, levelInfo) {
|
||||
await async.eachLimit(
|
||||
levelInfo.filter((x) => x.key),
|
||||
10,
|
||||
async (item) => await this.enrichOneKeyInfo(pool, item)
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = driver;
|
||||
|
@ -1856,6 +1856,11 @@ async@^2.6.2:
|
||||
dependencies:
|
||||
lodash "^4.17.14"
|
||||
|
||||
async@^3.2.3:
|
||||
version "3.2.3"
|
||||
resolved "https://registry.yarnpkg.com/async/-/async-3.2.3.tgz#ac53dafd3f4720ee9e8a160628f18ea91df196c9"
|
||||
integrity sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g==
|
||||
|
||||
asynckit@^0.4.0:
|
||||
version "0.4.0"
|
||||
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
|
||||
|
Loading…
Reference in New Issue
Block a user