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;
|
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,
|
updateCollection_meta: true,
|
||||||
async updateCollection({ conid, database, changeSet }) {
|
async updateCollection({ conid, database, changeSet }) {
|
||||||
const opened = await this.ensureOpened(conid, database);
|
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 }) {
|
async function handleUpdateCollection({ msgid, changeSet }) {
|
||||||
await waitConnected();
|
await waitConnected();
|
||||||
const driver = requireEngineDriver(storedConnection);
|
const driver = requireEngineDriver(storedConnection);
|
||||||
@ -248,6 +259,7 @@ const messageHandlers = {
|
|||||||
runScript: handleRunScript,
|
runScript: handleRunScript,
|
||||||
updateCollection: handleUpdateCollection,
|
updateCollection: handleUpdateCollection,
|
||||||
collectionData: handleCollectionData,
|
collectionData: handleCollectionData,
|
||||||
|
loadKeys: handleLoadKeys,
|
||||||
sqlPreview: handleSqlPreview,
|
sqlPreview: handleSqlPreview,
|
||||||
ping: handlePing,
|
ping: handlePing,
|
||||||
syncModel: handleSyncModel,
|
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;
|
name: string;
|
||||||
}[]
|
}[]
|
||||||
>;
|
>;
|
||||||
|
loadKeys(pool, root: string): Promise;
|
||||||
analyseFull(pool: any, serverVersion): Promise<DatabaseInfo>;
|
analyseFull(pool: any, serverVersion): Promise<DatabaseInfo>;
|
||||||
analyseIncremental(pool: any, structure: DatabaseInfo, serverVersion): Promise<DatabaseInfo>;
|
analyseIncremental(pool: any, structure: DatabaseInfo, serverVersion): Promise<DatabaseInfo>;
|
||||||
dialect: SqlDialect;
|
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 }) => ({
|
const serverVersionLoader = ({ conid }) => ({
|
||||||
url: 'server-connections/version',
|
url: 'server-connections/version',
|
||||||
params: { conid },
|
params: { conid },
|
||||||
@ -429,3 +435,10 @@ export function getAuthTypes(args) {
|
|||||||
export function useAuthTypes(args) {
|
export function useAuthTypes(args) {
|
||||||
return useCore(authTypesLoader, 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 WidgetColumnBar from './WidgetColumnBar.svelte';
|
||||||
import WidgetColumnBarItem from './WidgetColumnBarItem.svelte';
|
import WidgetColumnBarItem from './WidgetColumnBarItem.svelte';
|
||||||
import SqlObjectList from './SqlObjectList.svelte';
|
import SqlObjectList from './SqlObjectList.svelte';
|
||||||
|
import DbKeysTree from './DbKeysTree.svelte';
|
||||||
|
|
||||||
export let hidden = false;
|
export let hidden = false;
|
||||||
|
|
||||||
@ -49,7 +50,9 @@
|
|||||||
<SqlObjectList {conid} {database} />
|
<SqlObjectList {conid} {database} />
|
||||||
</WidgetColumnBarItem>
|
</WidgetColumnBarItem>
|
||||||
{:else if driver?.databaseEngineTypes?.includes('keyvalue')}
|
{: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}
|
{/if}
|
||||||
{:else}
|
{:else}
|
||||||
<WidgetColumnBarItem title="Database content" name="dbObjects" storageName="dbObjectsWidget">
|
<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"
|
"webpack-cli": "^3.3.11"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"async": "^3.2.3",
|
||||||
"ioredis": "^4.28.5"
|
"ioredis": "^4.28.5"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
const _ = require('lodash');
|
const _ = require('lodash');
|
||||||
|
const async = require('async');
|
||||||
const stream = require('stream');
|
const stream = require('stream');
|
||||||
const driverBase = require('../frontend/driver');
|
const driverBase = require('../frontend/driver');
|
||||||
const Analyser = require('./Analyser');
|
const Analyser = require('./Analyser');
|
||||||
@ -9,11 +10,14 @@ const driver = {
|
|||||||
...driverBase,
|
...driverBase,
|
||||||
analyserClass: Analyser,
|
analyserClass: Analyser,
|
||||||
async connect({ server, port, password, database }) {
|
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({
|
const pool = new Redis({
|
||||||
host: server,
|
host: server,
|
||||||
port,
|
port,
|
||||||
password,
|
password,
|
||||||
db: 0,
|
db,
|
||||||
});
|
});
|
||||||
return pool;
|
return pool;
|
||||||
},
|
},
|
||||||
@ -62,6 +66,61 @@ const driver = {
|
|||||||
|
|
||||||
return _.range(16).map((index) => ({ name: `db${index}`, extInfo: info[`db${index}`], sortOrder: index }));
|
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;
|
module.exports = driver;
|
||||||
|
@ -1856,6 +1856,11 @@ async@^2.6.2:
|
|||||||
dependencies:
|
dependencies:
|
||||||
lodash "^4.17.14"
|
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:
|
asynckit@^0.4.0:
|
||||||
version "0.4.0"
|
version "0.4.0"
|
||||||
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
|
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
|
||||||
|
Loading…
Reference in New Issue
Block a user