From 1cf2b3d8ccb0ed90c0e0a12d817ebc4406b319d0 Mon Sep 17 00:00:00 2001 From: Liam Barry Allan Date: Mon, 30 May 2022 16:34:25 -0400 Subject: [PATCH] Ability to generate SQL from JSON --- package.json | 13 ++++++++- src/extension.js | 4 +-- src/language/json.js | 65 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 79 insertions(+), 3 deletions(-) create mode 100644 src/language/json.js diff --git a/package.json b/package.json index 29af4733..8cc47f6c 100644 --- a/package.json +++ b/package.json @@ -105,9 +105,20 @@ "title": "Generate SQL", "category": "Db2 for i", "icon": "$(add)" - } + }, + { + "command": "vscode-db2i.pasteGenerator", + "title": "Paste JSON as SQL" + } ], "menus": { + "editor/context": [ + { + "command": "vscode-db2i.pasteGenerator", + "group": "1_sql", + "when": "editorLangId == sql" + } + ], "view/title": [ { "command": "vscode-db2i.addSchemaToSchemaBrowser", diff --git a/src/extension.js b/src/extension.js index 9a3004b0..bf6bfac2 100644 --- a/src/extension.js +++ b/src/extension.js @@ -3,8 +3,7 @@ const vscode = require(`vscode`); const schemaBrowser = require(`./views/schemaBrowser`); -const Configuration = require(`./configuration`); - +const JSONServices = require(`./language/json`); const languageProvider = require(`./language/provider`); // this method is called when your extension is activated @@ -26,6 +25,7 @@ function activate(context) { ), ); + JSONServices.initialise(context); languageProvider.initialise(context); } diff --git a/src/language/json.js b/src/language/json.js new file mode 100644 index 00000000..9363ce58 --- /dev/null +++ b/src/language/json.js @@ -0,0 +1,65 @@ +const vscode = require(`vscode`); + +const Statement = require(`../database/statement`); + +/** + * + * @param {vscode.ExtensionContext} context + */ +exports.initialise = (context) => { + context.subscriptions.push( + vscode.commands.registerCommand(`vscode-db2i.pasteGenerator`, async () => { + try { + const clipboard_content = await vscode.env.clipboard.readText(); + const parsedData = JSON.parse(clipboard_content); + + const sql = exports.generateSQL(parsedData); + const formatted = Statement.format(sql); + + if (vscode.window.activeTextEditor) { + vscode.window.activeTextEditor.edit((edit) => { + edit.insert(vscode.window.activeTextEditor.selection.active, formatted); + }); + } + } catch (e) { + vscode.window.showErrorMessage(`Error: ${e.message}`); + } + }), + ) +} + +exports.generateSQL = (jsonIn) => { + if (Array.isArray(jsonIn)) { + return generateArray(jsonIn); + } else { + return generateObject(jsonIn); + } +} + +const generateArray = (elementIn) => { + const firstValue = Array.isArray(elementIn) ? elementIn[0] : elementIn; + if (typeof firstValue === `object`) { + return `(SELECT json_arrayagg(${generateObject(firstValue)}) from SYSIBM.SYSDUMMY1)` + } else { + return `(SELECT json_arrayagg(${typeof firstValue === `string` ? `'${firstValue}'` : firstValue}) from SYSIBM.SYSDUMMY1)` + } +} + +const generateObject = (objIn) => { + const items = []; + + Object.keys(objIn).forEach((key) => { + const value = objIn[key]; + if (typeof value === `object`) { + if (Array.isArray(value)) { + items.push(`'${key}': ${generateArray(value[0])} format json`); + } else { + items.push(`'${key}': ${generateObject(value)}`); + } + } else { + items.push(`'${key}': ${typeof value === `string` ? `'${value}'` : value}`); + } + }); + + return `json_object(${items.join(`, `)})`; +} \ No newline at end of file