aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md43
-rw-r--r--editor-instance.html45
-rw-r--r--editor-instance.js19
-rw-r--r--html/editor-instance.html45
-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.html7
-rw-r--r--instance-manager.js2
-rw-r--r--main.js6
-rw-r--r--query-executor-wrapper.html7
-rw-r--r--styles/editor-instance.css15
11 files changed, 136 insertions, 65 deletions
diff --git a/README.md b/README.md
index 52a6337..260cb70 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,42 @@
-# sql-plus-plus \ No newline at end of file
+# SQL++
+[![Build Status](https://travis-ci.org/jamesbarnett91/sql-plus-plus.svg?branch=master)](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},
diff --git a/main.js b/main.js
index e7f0e44..d211c1e 100644
--- a/main.js
+++ b/main.js
@@ -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