loading redis keys

This commit is contained in:
Jan Prochazka 2022-03-05 18:46:18 +01:00
parent 425841bb38
commit 51942be0a6
11 changed files with 130 additions and 21 deletions

View File

@ -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);

View File

@ -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,

View File

@ -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;

View File

@ -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);
}

View File

@ -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">

View 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}

View File

@ -0,0 +1,8 @@
<script lang="ts">
import DbKeysSubTree from './DbKeysSubTree.svelte';
export let conid;
export let database;
</script>
<DbKeysSubTree {conid} {database} root="" />

View File

@ -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}

View File

@ -37,6 +37,7 @@
"webpack-cli": "^3.3.11"
},
"dependencies": {
"async": "^3.2.3",
"ioredis": "^4.28.5"
}
}

View File

@ -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;

View File

@ -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"