Initial interface to connect to server using gui

This commit is contained in:
Dan Sosedoff 2014-11-01 15:44:24 -05:00
parent 7ac9bee098
commit 9a431f6e41
5 changed files with 180 additions and 49 deletions

10
api.go
View File

@ -57,7 +57,10 @@ func API_Connect(c *gin.Context) {
info, err := client.Info()
if err == nil {
dbClient.db.Close()
if dbClient != nil {
dbClient.db.Close()
}
dbClient = client
}
@ -135,6 +138,11 @@ func API_History(c *gin.Context) {
}
func API_Info(c *gin.Context) {
if dbClient == nil {
c.JSON(400, Error{"Not connected"})
return
}
res, err := dbClient.Info()
if err != nil {

21
main.go
View File

@ -17,11 +17,11 @@ var options struct {
Version bool `short:"v" long:"version" description:"Print version"`
Debug bool `short:"d" long:"debug" description:"Enable debugging mode" default:"false"`
Url string `long:"url" description:"Database connection string"`
Host string `long:"host" description:"Server hostname or IP" default:"localhost"`
Host string `long:"host" description:"Server hostname or IP"`
Port int `long:"port" description:"Server port" default:"5432"`
User string `long:"user" description:"Database user" default:"postgres"`
User string `long:"user" description:"Database user"`
Pass string `long:"pass" description:"Password for user"`
DbName string `long:"db" description:"Database name" default:"postgres"`
DbName string `long:"db" description:"Database name"`
Ssl string `long:"ssl" description:"SSL option" default:"disable"`
HttpHost string `long:"bind" description:"HTTP server host" default:"localhost"`
HttpPort uint `long:"listen" description:"HTTP server listen port" default:"8080"`
@ -62,7 +62,18 @@ func getConnectionString() string {
return str
}
func connectionSettingsBlank() bool {
return options.Host == "" &&
options.User == "" &&
options.DbName == "" &&
options.Url == ""
}
func initClient() {
if connectionSettingsBlank() {
return
}
client, err := NewClient()
if err != nil {
exitWithMessage(err.Error())
@ -158,7 +169,9 @@ func main() {
initOptions()
initClient()
defer dbClient.db.Close()
if dbClient != nil {
defer dbClient.db.Close()
}
if !options.Debug {
gin.SetMode("release")

View File

@ -1,3 +1,7 @@
#main {
display: none;
}
#nav {
position: fixed;
top: 0;
@ -13,6 +17,7 @@
padding: 0px;
height: 50px;
display: block;
width: 550px;
}
#nav ul li {
@ -331,4 +336,40 @@
#custom_query {
height: 205px;
}
#connection_window {
z-index: 2;
position: fixed;
background: #ebeef0;
top: 0px;
left: 0px;
bottom: 0px;
right: 0px;
display: none;
}
#connection_error {
display: none;
}
.connection-settings {
width: 500px;
margin: 0px auto;
margin-top: 50px;
}
.connection-settings h1 {
text-align: center;
margin-bottom: 25px;
color: #95A7B7;
font-weight: normal;
}
.connection-settings form {
background: #fff;
padding: 40px 25px;
border-radius: 4px;
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
}

View File

@ -13,52 +13,79 @@
<script type="text/javascript" src="/static/js/app.js"></script>
</head>
<body>
<div id="nav">
<ul>
<li id="table_content">Content</li>
<li id="table_structure">Structure</li>
<li id="table_indexes">Indexes</li>
<li id="table_query" class="selected">SQL Query</li>
<li id="table_history">History</li>
<li id="table_connection">Connection</li>
</ul>
</div>
<div id="sidebar">
<div class="tables-list">
<div class="wrap">
<div class="title">Database Tables</div>
<ul id="tables"></ul>
</div>
<div id="main">
<div id="nav">
<ul>
<li id="table_content">Content</li>
<li id="table_structure">Structure</li>
<li id="table_indexes">Indexes</li>
<li id="table_query" class="selected">SQL Query</li>
<li id="table_history">History</li>
<li id="table_connection">Connection</li>
</ul>
</div>
<div class="table-information">
<div class="wrap">
<div class="title">Table Information</div>
<ul>
<li>Size: <span id="table_total_size"></span></li>
<li>Data size: <span id="table_data_size"></span></li>
<li>Index size: <span id="table_index_size"></span></li>
<li>Rows: <span id="table_rows_count"></span></li>
</ul>
<div id="sidebar">
<div class="tables-list">
<div class="wrap">
<div class="title">Database Tables</div>
<ul id="tables"></ul>
</div>
</div>
</div>
</div>
<div id="body">
<div id="input">
<div class="wrapper">
<div id="custom_query"></div>
<div class="actions">
<input type="button" id="run" value="Run Query" class="btn btn-sm btn-primary" />
<input type="button" id="explain" value="Explain Query" class="btn btn-sm btn-default" />
<input type="button" id="csv" value="Download CSV" class="btn btn-sm btn-default" />
<div id="query_progress">Please wait, query is executing...</div>
<div class="table-information">
<div class="wrap">
<div class="title">Table Information</div>
<ul>
<li>Size: <span id="table_total_size"></span></li>
<li>Data size: <span id="table_data_size"></span></li>
<li>Index size: <span id="table_index_size"></span></li>
<li>Rows: <span id="table_rows_count"></span></li>
</ul>
</div>
</div>
</div>
<div id="output">
<div class="wrapper">
<table id="results" class="table"></table>
<div id="body">
<div id="input">
<div class="wrapper">
<div id="custom_query"></div>
<div class="actions">
<input type="button" id="run" value="Run Query" class="btn btn-sm btn-primary" />
<input type="button" id="explain" value="Explain Query" class="btn btn-sm btn-default" />
<input type="button" id="csv" value="Download CSV" class="btn btn-sm btn-default" />
<div id="query_progress">Please wait, query is executing...</div>
</div>
</div>
</div>
<div id="output">
<div class="wrapper">
<table id="results" class="table"></table>
</div>
</div>
</div>
</div>
<div id="connection_window">
<div class="connection-settings">
<h1>pgweb</h1>
<form role="form" id="connection_form">
<div class="form-group">
<label>Enter server URL scheme</label>
<input type="text" class="form-control" id="connection_url" placeholder="postgres://user:password@host:port/db">
</div>
<div class="form-group">
<label>SSL Mode</label>
<select class="form-control" id="connection_ssl">
<option value="disable">disable</option>
<option value="require" selected="selected">require</option>
<option value="verify-full">verify-full</option>
</select>
</div>
<div id="connection_error" class="alert alert-danger"></div>
<button type="submit" class="btn btn-primary">Connect</button>
</form>
</div>
</div>
</body>

View File

@ -29,6 +29,8 @@ function explainQuery(query, cb) {
}
function loadTables() {
$("#tables li").remove();
getTables(function(data) {
data.forEach(function(item) {
$("<li><span>" + item + "</span></li>").appendTo("#tables");
@ -306,9 +308,6 @@ function addShortcutTooltips() {
}
$(document).ready(function() {
initEditor();
addShortcutTooltips();
$("#table_content").on("click", function() { showTableContent(); });
$("#table_structure").on("click", function() { showTableStructure(); });
$("#table_indexes").on("click", function() { showTableIndexes(); });
@ -340,5 +339,48 @@ $(document).ready(function() {
showTableInfo();
});
loadTables();
$("#connection_form").on("submit", function(e) {
e.preventDefault();
var button = $(this).children("button");
var url = $.trim($("#connection_url").val());
var ssl = $("#connection_ssl").val();
if (url.length == 0) {
return;
}
if (url.indexOf("sslmode") == -1) {
url += "?sslmode=" + ssl;
}
$("#connection_error").hide();
button.prop("disabled", true).text("Please wait...");
apiCall("post", "/connect", { url: url }, function(resp) {
button.prop("disabled", false).text("Connect");
if (resp.error) {
$("#connection_error").text(resp.error).show();
}
else {
$("#connection_window").hide();
loadTables();
$("#main").show();
}
});
});
initEditor();
addShortcutTooltips();
apiCall("get", "/info", {}, function(resp) {
if (resp.error) {
$("#connection_window").show();
}
else {
loadTables();
$("#main").show();
}
});
});