diff options
| -rw-r--r-- | README.md | 43 | ||||
| -rw-r--r-- | editor-instance.html | 45 | ||||
| -rw-r--r-- | editor-instance.js | 19 | ||||
| -rw-r--r-- | html/editor-instance.html | 45 | ||||
| -rw-r--r-- | html/index.html (renamed from index.html) | 6 | ||||
| -rw-r--r-- | html/new-connection.html (renamed from new-connection.html) | 6 | ||||
| -rw-r--r-- | html/query-executor-wrapper.html | 7 | ||||
| -rw-r--r-- | instance-manager.js | 2 | ||||
| -rw-r--r-- | main.js | 6 | ||||
| -rw-r--r-- | query-executor-wrapper.html | 7 | ||||
| -rw-r--r-- | styles/editor-instance.css | 15 |
11 files changed, 136 insertions, 65 deletions
@@ -1 +1,42 @@ -# sql-plus-plus
\ No newline at end of file +# SQL++ +[](https://travis-ci.org/jamesbarnett91/sql-plus-plus) + +A simple cross platform SQL editor and statement runner. +Currently for Postgres only, but MySQL and Oracle support planned. + +<p align="center"> + <img alt="VS Code in action" src="https://james-barnett.net/files/spp/screenshots/app2.png"> +</p> + +# Features +- Rich editor features. Syntax highlighting, autocomplete, bracket matching etc. +- Cross platform. Linux (.deb), Windows and MacOS binaries available. +- Simple editor interface. Doesn't have a huge array of GUI features like pgAdmin or Toad. For people who prefer a clean way to edit and run SQL. +- Sortable and resizable query results table. + +# Installation +Download one of the binary distributions from the releases page. +Or, to run locally: +```sh +$ git clone https://github.com/jamesbarnett91/sql-plus-plus && cd sql-plus-plus +$ npm install +$ npm start +``` + +# Roadmap +- [x] Store connection config +- [x] Handle multiple simultaneous connections +- [ ] Add schema tree view (listing tables>columns, packages, sequences etc.) +- [ ] Load/Save .sql files +- [ ] Improve autocomplete to be more schema aware +- [ ] Support MySQL +- [ ] Support Oracle +- [ ] Save and display query history +- [ ] CSV download of query results +- [ ] 'Interpreter' mode. Run single queries with a CLI type interface (like Postgres psql and Oracle SQL*Plus) +- [ ] Build .rpms + +# Note +This is just a personal project, and a work in progress. There might be a few bugs in the result parsing, so don't rely on it for anything important unless you enjoy living on the edge. + +Connection details (including passwords) are stored encrypted, but the key is in the source code so it's only a basic level of obfuscation. I wouldn't connect to any prod databases with this.
\ No newline at end of file diff --git a/editor-instance.html b/editor-instance.html deleted file mode 100644 index 454c6ce..0000000 --- a/editor-instance.html +++ /dev/null @@ -1,45 +0,0 @@ -<!DOCTYPE html> -<html> - -<head> - <meta charset="UTF-8"> - <title>SQL++</title> - - <link rel="stylesheet" href="node_modules/codemirror/lib/codemirror.css"></link> - <link rel="stylesheet" href="node_modules/codemirror/theme/dracula.css"></link> - <link rel="stylesheet" href="node_modules/codemirror/addon/hint/show-hint.css"></link> - <link rel="stylesheet" href="node_modules/jquery.tabulator/dist/css/tabulator.css"></link> - <link rel="stylesheet" type="text/css" href="./styles/editor-instance.css"></link> - <link rel="stylesheet" type="text/css" href="./styles/table-style.css"></link> - -</head> - -<body> - - <div class="flex-wrapper"> - <div class="row header"> - <input id="run-query" type="button" value="Run"></input> - </div> - - - <div class="row content"> - <div id="editor" class="editor-row split-row"></div> - - <div class="results-row split-row"> - <div id="result-table"></div> - <div id="result-error"></div> - </div> - </div> - - <div class="row footer"> - <div id="execution-status" class="exec-idle">Idle</div> - <div id="execution-time"></div> - <div id="cursor-coords"></div> - </div> - </div> - <script> - require("./editor-instance.js"); - </script> -</body> - -</html>
\ No newline at end of file diff --git a/editor-instance.js b/editor-instance.js index 8ed6674..6e2fd67 100644 --- a/editor-instance.js +++ b/editor-instance.js @@ -188,7 +188,7 @@ function handleResult(results) { dataTable = $("#result-table").tabulator({ height: "100%", columns: _mapColumnProperties(results), - data: results.rows + data: _escapeRowFieldNames(results.rows) }); _setExecutionStatusIndicator("OK"); @@ -198,12 +198,27 @@ function handleResult(results) { function _mapColumnProperties(results) { return results.fields.map((column) => { return { - field: column.name, + field: "_" + column.name, // "_" to match up to the output of _escapeRowFieldNames() title: column.name }; }); } +/** + * Return the row object with all fields prefixed with an underscore. + * This avoids issues with Tabulator which doesn't like fields to have the same identifiers + * as built in JS properties/functions (e.g. 'length') + */ +function _escapeRowFieldNames(rows) { + return rows.map(row => { + let escapedRow = {} + Object.keys(row).forEach(key => { + escapedRow["_" + key] = row[key]; + }); + return escapedRow; + }); +} + function _resultTable() { return $("#result-table"); } diff --git a/html/editor-instance.html b/html/editor-instance.html new file mode 100644 index 0000000..eaa2599 --- /dev/null +++ b/html/editor-instance.html @@ -0,0 +1,45 @@ +<!DOCTYPE html> +<html> + + <head> + <meta charset="UTF-8"> + <title>SQL++</title> + + <link rel="stylesheet" href="../node_modules/codemirror/lib/codemirror.css"></link> + <link rel="stylesheet" href="../node_modules/codemirror/theme/dracula.css"></link> + <link rel="stylesheet" href="../node_modules/codemirror/addon/hint/show-hint.css"></link> + <link rel="stylesheet" href="../node_modules/jquery.tabulator/dist/css/tabulator.css"></link> + <link rel="stylesheet" type="text/css" href="../styles/editor-instance.css"></link> + <link rel="stylesheet" type="text/css" href="../styles/table-style.css"></link> + + </head> + + <body> + + <div class="flex-wrapper"> + <div class="row header"> + <input id="run-query" type="button" class="button" value="Run"></input> + </div> + + + <div class="row content"> + <div id="editor" class="editor-row split-row"></div> + + <div class="results-row split-row"> + <div id="result-table"></div> + <div id="result-error"></div> + </div> + </div> + + <div class="row footer"> + <div id="execution-status" class="exec-idle">Idle</div> + <div id="execution-time"></div> + <div id="cursor-coords"></div> + </div> + </div> + <script> + require("../editor-instance.js"); + </script> + </body> + +</html>
\ No newline at end of file diff --git a/index.html b/html/index.html index 2d8dbee..b1997bf 100644 --- a/index.html +++ b/html/index.html @@ -4,8 +4,8 @@ <meta charset="UTF-8"> <title>SQL++</title> - <link rel="stylesheet" href="node_modules/electron-tabs/electron-tabs.css"></link> - <link rel="stylesheet" href="./styles/instance-manager.css"></link> + <link rel="stylesheet" href="../node_modules/electron-tabs/electron-tabs.css"></link> + <link rel="stylesheet" href="../styles/instance-manager.css"></link> </head> <body> @@ -20,7 +20,7 @@ <div class="etabs-views"></div> <script> - require("./instance-manager.js"); + require("../instance-manager.js"); </script> </body> </html>
\ No newline at end of file diff --git a/new-connection.html b/html/new-connection.html index ddfb380..192c9b9 100644 --- a/new-connection.html +++ b/html/new-connection.html @@ -3,8 +3,8 @@ <head> <meta charset="UTF-8"> <title>SQL++ - New connection</title> - <link rel="stylesheet" href="node_modules/bulma/css/bulma.css"></link> - <link rel="stylesheet" href="./styles/new-connection.css"></link> + <link rel="stylesheet" href="../node_modules/bulma/css/bulma.css"></link> + <link rel="stylesheet" href="../styles/new-connection.css"></link> </head> <body> @@ -68,6 +68,6 @@ </form> </body> <script> - require("./new-connection.js"); + require("../new-connection.js"); </script> </html>
\ No newline at end of file diff --git a/html/query-executor-wrapper.html b/html/query-executor-wrapper.html new file mode 100644 index 0000000..ddc9ffc --- /dev/null +++ b/html/query-executor-wrapper.html @@ -0,0 +1,7 @@ +<!DOCTYPE html> +<html> + <head> + <script>require("../query-executor.js");</script> + </head> + <body/> +</html>
\ No newline at end of file diff --git a/instance-manager.js b/instance-manager.js index 96151ab..2debb57 100644 --- a/instance-manager.js +++ b/instance-manager.js @@ -13,7 +13,7 @@ function createNewConnection() { function registerNewInstance(payload) { tabGroup.addTab({ title: getTabTitle(payload.connectionConfig), - src: "file://" + __dirname + "/editor-instance.html", + src: "file://" + __dirname + "/html/editor-instance.html", visible: true, active: true, webviewAttributes: {"nodeintegration":true}, @@ -20,7 +20,7 @@ function createMainWindow() { height: 600 }); uiWindow.loadURL(url.format({ - pathname: path.join(__dirname, "index.html"), + pathname: path.join(__dirname, "html", "index.html"), protocol: "file:", slashes: true })); @@ -54,7 +54,7 @@ function createNewConnectionDialog() { height: 600 }); newConnectionDialog.loadURL(url.format({ - pathname: path.join(__dirname, "new-connection.html"), + pathname: path.join(__dirname, "html", "new-connection.html"), protocol: "file:", slashes: true })); @@ -79,7 +79,7 @@ function createQueryExecutor(payload) { console.log("created executor with id:" + executor.executorId); executor.loadURL(url.format({ - pathname: path.join(__dirname, "./query-executor-wrapper.html"), + pathname: path.join(__dirname, "html", "query-executor-wrapper.html"), protocol: "file:", slashes: true })); diff --git a/query-executor-wrapper.html b/query-executor-wrapper.html deleted file mode 100644 index 68c0356..0000000 --- a/query-executor-wrapper.html +++ /dev/null @@ -1,7 +0,0 @@ -<!DOCTYPE html> -<html> - <head> - <script>require("./query-executor.js");</script> - </head> - <body/> -</html>
\ No newline at end of file diff --git a/styles/editor-instance.css b/styles/editor-instance.css index 7ae5727..cb3aa95 100644 --- a/styles/editor-instance.css +++ b/styles/editor-instance.css @@ -130,4 +130,19 @@ body { .statement-pointer { width: 10px; +} + +.button { + padding: 4px 6px; + background: #6D8A88; + border: none; + border-radius: 2px; + font-size: 12px; + margin: 6px; + text-align: center; +} + +.button:hover { + color: #eee; + background-color: #aaa; }
\ No newline at end of file |