From c0fdcf2fd12ac10f61e71aede5116b51396f924b Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Sat, 26 Mar 2022 10:36:44 +0100 Subject: [PATCH] redis: execute commands --- packages/types/engines.d.ts | 1 + packages/web/src/tabs/QueryTab.svelte | 18 ++-- .../src/frontend/driver.js | 1 + plugins/dbgate-plugin-redis/package.json | 7 +- .../dbgate-plugin-redis/src/backend/driver.js | 88 ++++++++++++++++++- .../src/frontend/driver.js | 3 + yarn.lock | 18 +++- 7 files changed, 120 insertions(+), 16 deletions(-) diff --git a/packages/types/engines.d.ts b/packages/types/engines.d.ts index 69115d19..94f233fa 100644 --- a/packages/types/engines.d.ts +++ b/packages/types/engines.d.ts @@ -56,6 +56,7 @@ export interface EngineDriver { title: string; defaultPort?: number; databaseEngineTypes: string[]; + editorMode?: string; readOnlySessions: boolean; supportedKeyTypes: SupportedDbKeyType[]; supportsDatabaseUrl?: boolean; diff --git a/packages/web/src/tabs/QueryTab.svelte b/packages/web/src/tabs/QueryTab.svelte index 1fe3af03..06eac7f1 100644 --- a/packages/web/src/tabs/QueryTab.svelte +++ b/packages/web/src/tabs/QueryTab.svelte @@ -281,11 +281,13 @@ - {#if driver?.databaseEngineTypes?.includes('document')} - setEditorData(e.detail)} on:focus={() => { @@ -295,12 +297,10 @@ bind:this={domEditor} /> {:else} - setEditorData(e.detail)} on:focus={() => { diff --git a/plugins/dbgate-plugin-mongo/src/frontend/driver.js b/plugins/dbgate-plugin-mongo/src/frontend/driver.js index 9a06164b..e2cc3701 100644 --- a/plugins/dbgate-plugin-mongo/src/frontend/driver.js +++ b/plugins/dbgate-plugin-mongo/src/frontend/driver.js @@ -29,6 +29,7 @@ const driver = { dialect, engine: 'mongo@dbgate-plugin-mongo', title: 'MongoDB', + editorMode: 'javascript', defaultPort: 27017, supportsDatabaseUrl: true, databaseUrlPlaceholder: 'e.g. mongodb://username:password@mongodb.mydomain.net/dbname', diff --git a/plugins/dbgate-plugin-redis/package.json b/plugins/dbgate-plugin-redis/package.json index 75f1f19a..5b83146c 100644 --- a/plugins/dbgate-plugin-redis/package.json +++ b/plugins/dbgate-plugin-redis/package.json @@ -34,10 +34,9 @@ "dbgate-tools": "^4.1.1", "lodash": "^4.17.21", "webpack": "^4.42.0", - "webpack-cli": "^3.3.11" - }, - "dependencies": { + "webpack-cli": "^3.3.11", "async": "^3.2.3", - "ioredis": "^4.28.5" + "ioredis": "^4.28.5", + "node-redis-dump2": "^0.5.0" } } diff --git a/plugins/dbgate-plugin-redis/src/backend/driver.js b/plugins/dbgate-plugin-redis/src/backend/driver.js index 5efd1842..987821e3 100644 --- a/plugins/dbgate-plugin-redis/src/backend/driver.js +++ b/plugins/dbgate-plugin-redis/src/backend/driver.js @@ -4,6 +4,77 @@ const stream = require('stream'); const driverBase = require('../frontend/driver'); const Analyser = require('./Analyser'); const Redis = require('ioredis'); +const RedisDump = require('node-redis-dump2'); + +function splitCommandLine(str) { + let results = []; + let word = ''; + let validWord; + for (let i = 0; i < str.length; ) { + if (/\s/.test(str[i])) { + //Skips spaces. + while (i < str.length && /\s/.test(str[i])) { + i++; + } + results.push(word); + word = ''; + validWord = false; + continue; + } + + if (str[i] === '"') { + i++; + while (i < str.length) { + if (str[i] === '"') { + validWord = true; + break; + } + + if (str[i] === '\\') { + i++; + word += str[i++]; + continue; + } + + word += str[i++]; + } + i++; + continue; + } + + if (str[i] === "'") { + i++; + while (i < str.length) { + if (str[i] === "'") { + validWord = true; + break; + } + + if (str[i] === '\\') { + i++; + word += str[i++]; + continue; + } + + word += str[i++]; + } + i++; + continue; + } + + if (str[i] === '\\') { + i++; + word += str[i++]; + continue; + } + validWord = true; + word += str[i++]; + } + if (validWord) { + results.push(word); + } + return results; +} /** @type {import('dbgate-types').EngineDriver} */ const driver = { @@ -29,7 +100,22 @@ const driver = { }; }, async stream(pool, sql, options) { - return null; + const parts = splitCommandLine(sql); + if (parts.length < 1) { + options.done(); + return; + } + const command = parts[0].toLowerCase(); + const args = parts.slice(1); + const res = await pool.call(command, ...args); + + options.info({ + message: JSON.stringify(res), + time: new Date(), + severity: 'info', + }); + + options.done(); }, async readQuery(pool, sql, structure) { const pass = new stream.PassThrough({ diff --git a/plugins/dbgate-plugin-redis/src/frontend/driver.js b/plugins/dbgate-plugin-redis/src/frontend/driver.js index fb97cee6..b9019919 100644 --- a/plugins/dbgate-plugin-redis/src/frontend/driver.js +++ b/plugins/dbgate-plugin-redis/src/frontend/driver.js @@ -1,4 +1,5 @@ const { driverBase } = global.DBGATE_TOOLS; +const { redisSplitterOptions } = require('dbgate-query-splitter/lib/options'); const Dumper = require('./Dumper'); /** @type {import('dbgate-types').SqlDialect} */ @@ -21,7 +22,9 @@ const driver = { engine: 'redis@dbgate-plugin-redis', title: 'Redis (experimental)', defaultPort: 6379, + editorMode: 'text', databaseEngineTypes: ['keyvalue'], + getQuerySplitterOptions: () => redisSplitterOptions, supportedKeyTypes: [ { name: 'string', diff --git a/yarn.lock b/yarn.lock index 7d8923f2..d1e8a3ff 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1856,7 +1856,7 @@ async@^2.6.2: dependencies: lodash "^4.17.14" -async@^3.2.3: +async@^3.2.0, 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== @@ -5214,7 +5214,7 @@ invert-kv@^2.0.0: resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02" integrity sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA== -ioredis@^4.28.5: +ioredis@^4.27.0, ioredis@^4.28.5: version "4.28.5" resolved "https://registry.yarnpkg.com/ioredis/-/ioredis-4.28.5.tgz#5c149e6a8d76a7f8fa8a504ffc85b7d5b6797f9f" integrity sha512-3GYo0GJtLqgNXj4YhrisLaNNvWSNwSS2wS4OELGfGxH8I69+XfNdnmV1AyN+ZqMh0i7eX+SWjrwFKDBDgfBC1A== @@ -7658,6 +7658,15 @@ node-notifier@^5.4.2: shellwords "^0.1.1" which "^1.3.0" +node-redis-dump2@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/node-redis-dump2/-/node-redis-dump2-0.5.0.tgz#22cdb8ef37d8d0234e68027136b2d2a7b66af103" + integrity sha512-rG54sksxPvNB0/1tsUESVBhapzCX0yAIwW2cv3k0jFK01nc0Zu/yaHGC28tCk6DHDVs9+kCFdAWewMrslJTrEA== + dependencies: + async "^3.2.0" + ioredis "^4.27.0" + underscore "^1.13.1" + node-releases@^1.1.71: version "1.1.72" resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.72.tgz#14802ab6b1039a79a0c7d662b610a5bbd76eacbe" @@ -10752,6 +10761,11 @@ undefsafe@^2.0.2: resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.13.0.tgz#3ccdcbb824230fc6bf234ad0ddcd83dff4eafe5f" integrity sha512-sCs4H3pCytsb5K7i072FAEC9YlSYFIbosvM0tAKAlpSSUgD7yC1iXSEGdl5XrDKQ1YUB+p/HDzYrSG2H2Vl36g== +underscore@^1.13.1: + version "1.13.2" + resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.13.2.tgz#276cea1e8b9722a8dbed0100a407dda572125881" + integrity sha512-ekY1NhRzq0B08g4bGuX4wd2jZx5GnKz6mKSqFL4nqBlfyMGiG10gDFhDTMEfYmDL6Jy0FUIZp7wiRB+0BP7J2g== + union-value@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847"