sqlui 0.1.24 → 0.1.25
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.version +1 -1
- data/app/server.rb +39 -36
- data/app/views/databases.erb +36 -15
- data/client/resources/sqlui.css +22 -3
- data/client/resources/sqlui.html +12 -8
- data/client/resources/sqlui.js +317 -220
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 11963565427ad327b2fb3cf1eadb62f789b620c3b3de943f2a0b17f3be505356
|
4
|
+
data.tar.gz: 1be9eaac08e81afba77f4c1f5581a78f8e4a73d007d9e29f0ca238c956d46a6b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 76fc95eeec60f207e1505b4d71d10e6bf329c94ddc42ca15edef83853ca6f74407b275f168f1a721c9b0d50507228dcb5aae5c4f2cb2fa54e46f1dbef79d05cb
|
7
|
+
data.tar.gz: 06140f3797fb34a7fa869c484ef002e5310ceceeea87e57f0c6dd984f13c2a6d75c9dddab253bf64545fa9cd58a93cac41e476b8cb8ee9c7fe86f47b38af39a0
|
data/.version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.25
|
data/app/server.rb
CHANGED
@@ -25,20 +25,17 @@ class Server < Sinatra::Base
|
|
25
25
|
body 'OK'
|
26
26
|
end
|
27
27
|
|
28
|
+
get '/?' do
|
29
|
+
redirect config.list_url_path, 301
|
30
|
+
end
|
31
|
+
|
28
32
|
get "#{config.list_url_path}/?" do
|
29
33
|
erb :databases, locals: { config: config }
|
30
34
|
end
|
31
35
|
|
32
36
|
config.database_configs.each do |database|
|
33
|
-
get database.url_path
|
34
|
-
redirect "#{database.url_path}/
|
35
|
-
end
|
36
|
-
|
37
|
-
get "#{database.url_path}/app" do
|
38
|
-
@html ||= File.read(File.join(resources_dir, 'sqlui.html'))
|
39
|
-
status 200
|
40
|
-
headers 'Content-Type': 'text/html'
|
41
|
-
body @html
|
37
|
+
get "#{database.url_path}/?" do
|
38
|
+
redirect "#{database.url_path}/query", 301
|
42
39
|
end
|
43
40
|
|
44
41
|
get "#{database.url_path}/sqlui.css" do
|
@@ -59,16 +56,23 @@ class Server < Sinatra::Base
|
|
59
56
|
metadata = database.with_client do |client|
|
60
57
|
{
|
61
58
|
server: "#{config.name} - #{database.display_name}",
|
59
|
+
list_url_path: config.list_url_path,
|
62
60
|
schemas: DatabaseMetadata.lookup(client, database),
|
63
|
-
saved: Dir.glob("#{database.saved_path}/*.sql").
|
64
|
-
|
61
|
+
saved: Dir.glob("#{database.saved_path}/*.sql").to_h do |path|
|
62
|
+
contents = File.read(path)
|
63
|
+
comment_lines = contents.split("\n").take_while do |l|
|
65
64
|
l.start_with?('--')
|
66
65
|
end
|
66
|
+
filename = File.basename(path)
|
67
67
|
description = comment_lines.map { |l| l.sub(/^-- */, '') }.join
|
68
|
-
|
69
|
-
filename
|
70
|
-
|
71
|
-
|
68
|
+
[
|
69
|
+
filename,
|
70
|
+
{
|
71
|
+
filename: filename,
|
72
|
+
description: description,
|
73
|
+
contents: contents.strip
|
74
|
+
}
|
75
|
+
]
|
72
76
|
end
|
73
77
|
}
|
74
78
|
end
|
@@ -77,36 +81,28 @@ class Server < Sinatra::Base
|
|
77
81
|
body metadata.to_json
|
78
82
|
end
|
79
83
|
|
80
|
-
get "#{database.url_path}/query_file" do
|
81
|
-
break client_error('missing file param') unless params[:file]
|
82
|
-
|
83
|
-
file = File.join(database.saved_path, params[:file])
|
84
|
-
break client_error('no such file') unless File.exist?(file)
|
85
|
-
|
86
|
-
sql = File.read(file)
|
87
|
-
result = database.with_client do |client|
|
88
|
-
execute_query(client, sql).tap { |r| r[:file] = params[:file] }
|
89
|
-
end
|
90
|
-
|
91
|
-
status 200
|
92
|
-
headers 'Content-Type': 'application/json'
|
93
|
-
body result.to_json
|
94
|
-
end
|
95
|
-
|
96
84
|
post "#{database.url_path}/query" do
|
97
85
|
params.merge!(JSON.parse(request.body.read, symbolize_names: true))
|
98
86
|
break client_error('missing sql') unless params[:sql]
|
99
87
|
|
88
|
+
full_sql = params[:sql]
|
100
89
|
sql = params[:sql]
|
101
|
-
|
102
|
-
|
103
|
-
|
90
|
+
if params[:selection]
|
91
|
+
selection = params[:selection]
|
92
|
+
if selection.include?('-')
|
93
|
+
# sort because the selection could be in either direction
|
94
|
+
selection = params[:selection].split('-').map { |v| Integer(v) }.sort
|
95
|
+
else
|
96
|
+
selection = Integer(selection)
|
97
|
+
selection = [selection, selection]
|
98
|
+
end
|
104
99
|
|
105
100
|
sql = if selection[0] == selection[1]
|
106
101
|
SqlParser.find_statement_at_cursor(params[:sql], selection[0])
|
107
102
|
else
|
108
|
-
|
103
|
+
full_sql[selection[0], selection[1]]
|
109
104
|
end
|
105
|
+
|
110
106
|
break client_error("can't find query at selection") unless sql
|
111
107
|
end
|
112
108
|
|
@@ -115,11 +111,19 @@ class Server < Sinatra::Base
|
|
115
111
|
end
|
116
112
|
|
117
113
|
result[:selection] = params[:selection]
|
114
|
+
result[:query] = full_sql
|
118
115
|
|
119
116
|
status 200
|
120
117
|
headers 'Content-Type': 'application/json'
|
121
118
|
body result.to_json
|
122
119
|
end
|
120
|
+
|
121
|
+
get(%r{#{Regexp.escape(database.url_path)}/(query|graph|structure|saved)}) do
|
122
|
+
@html ||= File.read(File.join(resources_dir, 'sqlui.html'))
|
123
|
+
status 200
|
124
|
+
headers 'Content-Type': 'text/html'
|
125
|
+
body @html
|
126
|
+
end
|
123
127
|
end
|
124
128
|
|
125
129
|
error do |e|
|
@@ -165,7 +169,6 @@ class Server < Sinatra::Base
|
|
165
169
|
columns = []
|
166
170
|
end
|
167
171
|
{
|
168
|
-
query: sql,
|
169
172
|
columns: columns,
|
170
173
|
column_types: column_types,
|
171
174
|
total_rows: rows.size,
|
data/app/views/databases.erb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
|
-
<html>
|
1
|
+
<html lang="en">
|
2
2
|
<head>
|
3
3
|
<title>Databases</title>
|
4
4
|
|
5
5
|
<style>
|
6
6
|
body {
|
7
|
-
font-family: Helvetica;
|
8
|
-
margin:
|
7
|
+
font-family: Helvetica, sans-serif;
|
8
|
+
margin: 0;
|
9
9
|
}
|
10
10
|
|
11
11
|
h1 {
|
@@ -25,7 +25,8 @@
|
|
25
25
|
flex-direction: row;
|
26
26
|
border-bottom: 1px solid #ddd;
|
27
27
|
height: 36px;
|
28
|
-
font-family: Helvetica;
|
28
|
+
font-family: Helvetica, sans-serif;
|
29
|
+
padding: 5px;
|
29
30
|
}
|
30
31
|
|
31
32
|
.header, .server-name {
|
@@ -41,28 +42,34 @@
|
|
41
42
|
font-weight: normal;
|
42
43
|
}
|
43
44
|
|
45
|
+
.name-and-links {
|
46
|
+
display: flex;
|
47
|
+
flex-direction: row;
|
48
|
+
align-items: center;
|
49
|
+
}
|
50
|
+
|
44
51
|
.header {
|
45
52
|
font-weight: bold;
|
46
53
|
padding-left: 5px;
|
47
54
|
}
|
48
55
|
|
49
56
|
.database a {
|
50
|
-
margin-right:
|
57
|
+
margin-right: 5px;
|
51
58
|
color: darkblue;
|
52
|
-
font-size: 16px
|
59
|
+
font-size: 16px;
|
60
|
+
text-decoration: none;
|
53
61
|
}
|
54
62
|
|
55
63
|
.database h2 {
|
56
|
-
margin:
|
64
|
+
margin: 0 10px 0 0;
|
57
65
|
}
|
58
66
|
|
59
67
|
.database p {
|
60
|
-
margin:
|
61
|
-
margin-top: 10px;
|
68
|
+
margin: 10px 0 0;
|
62
69
|
}
|
63
70
|
|
64
71
|
.database {
|
65
|
-
margin:
|
72
|
+
margin: 0;
|
66
73
|
padding: 10px;
|
67
74
|
cursor: pointer;
|
68
75
|
border-bottom: 1px solid #eeeeee;
|
@@ -76,6 +83,18 @@
|
|
76
83
|
background: #eee;
|
77
84
|
}
|
78
85
|
</style>
|
86
|
+
|
87
|
+
<script>
|
88
|
+
function openDatabase(event, url) {
|
89
|
+
if (event.shiftKey) {
|
90
|
+
window.open(url, '_blank').focus()
|
91
|
+
} else if (event.metaKey) {
|
92
|
+
window.open(url).focus()
|
93
|
+
} else {
|
94
|
+
window.location = url
|
95
|
+
}
|
96
|
+
}
|
97
|
+
</script>
|
79
98
|
</head>
|
80
99
|
|
81
100
|
<body>
|
@@ -84,11 +103,13 @@
|
|
84
103
|
<h1 class="server-name"><%= config.name %> Databases</h1>
|
85
104
|
</div>
|
86
105
|
<% config.database_configs.each do |database_config| %>
|
87
|
-
<div class="database" onclick="
|
88
|
-
<
|
89
|
-
|
90
|
-
|
91
|
-
|
106
|
+
<div class="database" onclick="openDatabase(event, '<%= "#{database_config.url_path}/query" %>')">
|
107
|
+
<div class="name-and-links">
|
108
|
+
<h2 class='name'><%= database_config.display_name %></h2>
|
109
|
+
<a class='query-link' href="<%= database_config.url_path %>/query" onclick="event.stopPropagation()">query</a>
|
110
|
+
<a class='saved-link' href="<%= database_config.url_path %>/saved" onclick="event.stopPropagation()">saved</a>
|
111
|
+
<a class='structure-link' href="<%= database_config.url_path %>/structure" onclick="event.stopPropagation()">structure</a>
|
112
|
+
</div>
|
92
113
|
<p class='description'>
|
93
114
|
<%= database_config.description %>
|
94
115
|
</p>
|
data/client/resources/sqlui.css
CHANGED
@@ -71,6 +71,7 @@ p {
|
|
71
71
|
.tab-button, .selected-tab-button {
|
72
72
|
border: none;
|
73
73
|
outline: none;
|
74
|
+
text-decoration: none;
|
74
75
|
cursor: pointer;
|
75
76
|
width: 150px;
|
76
77
|
padding: 2px;
|
@@ -79,6 +80,7 @@ p {
|
|
79
80
|
justify-content: center;
|
80
81
|
background-color: #fff;
|
81
82
|
font-size: 18px;
|
83
|
+
align-self: center;
|
82
84
|
}
|
83
85
|
|
84
86
|
.tab-button {
|
@@ -110,6 +112,7 @@ p {
|
|
110
112
|
.submit-box {
|
111
113
|
display: flex;
|
112
114
|
border-top: 1px solid #ddd;
|
115
|
+
border-bottom: 1px solid #ddd;
|
113
116
|
justify-content: right;
|
114
117
|
}
|
115
118
|
|
@@ -135,15 +138,16 @@ p {
|
|
135
138
|
color: #333;
|
136
139
|
}
|
137
140
|
|
138
|
-
.result-box, .saved-box, .graph-box, .structure-box {
|
141
|
+
.result-box, .fetch-sql-box, .saved-box, .graph-box, .structure-box {
|
139
142
|
flex: 1;
|
140
143
|
overflow: auto;
|
141
144
|
display: flex;
|
142
145
|
flex-direction: column;
|
143
146
|
}
|
144
147
|
|
145
|
-
.
|
146
|
-
|
148
|
+
.fetch-sql-box {
|
149
|
+
justify-content: center;
|
150
|
+
align-items: center;
|
147
151
|
}
|
148
152
|
|
149
153
|
.graph-box {
|
@@ -218,6 +222,7 @@ thead {
|
|
218
222
|
|
219
223
|
.tabs-box {
|
220
224
|
display: flex;
|
225
|
+
padding: 5px;
|
221
226
|
}
|
222
227
|
|
223
228
|
.saved-box {
|
@@ -287,3 +292,17 @@ select {
|
|
287
292
|
color: #333;
|
288
293
|
font-size: 18px;
|
289
294
|
}
|
295
|
+
|
296
|
+
.loader {
|
297
|
+
border: 8px solid #eee; /* Light grey */
|
298
|
+
border-top: 8px solid #888; /* Blue */
|
299
|
+
border-radius: 50%;
|
300
|
+
width: 40px;
|
301
|
+
height: 40px;
|
302
|
+
animation: spin 2s linear infinite;
|
303
|
+
}
|
304
|
+
|
305
|
+
@keyframes spin {
|
306
|
+
0% { transform: rotate(0deg); }
|
307
|
+
100% { transform: rotate(360deg); }
|
308
|
+
}
|
data/client/resources/sqlui.html
CHANGED
@@ -13,12 +13,12 @@
|
|
13
13
|
|
14
14
|
<div id="main-box" class="main-box" style="display:none">
|
15
15
|
<div class="tabs-box">
|
16
|
-
<h1 class="header"><a
|
16
|
+
<h1 class="header"><a id="header-link">SQLUI</a></h1>
|
17
17
|
<h1 id="server-name" class="server-name"></h1>
|
18
|
-
<
|
19
|
-
<
|
20
|
-
<
|
21
|
-
<
|
18
|
+
<a id="query-tab-button" class="tab-button">Query</a>
|
19
|
+
<a id="graph-tab-button" class="tab-button">Graph</a>
|
20
|
+
<a id="saved-tab-button" class="tab-button">Saved</a>
|
21
|
+
<a id="structure-tab-button" class="tab-button">Structure</a>
|
22
22
|
</div>
|
23
23
|
|
24
24
|
<div id="query-box" class="query-box tab-content-element graph-element query-element" style="display: none;">
|
@@ -26,8 +26,8 @@
|
|
26
26
|
</div>
|
27
27
|
|
28
28
|
<div id="submit-box" class="submit-box tab-content-element graph-element query-element" style="display: none;">
|
29
|
-
<input id="submit-
|
30
|
-
<input id="submit-
|
29
|
+
<input id="submit-current-button" class="submit-button" type="button" value="run selection (ctrl-enter)"></input>
|
30
|
+
<input id="submit-all-button" class="submit-button" type="button" value="run (ctrl-shift-enter)"></input>
|
31
31
|
</div>
|
32
32
|
|
33
33
|
<div id="result-box" class="result-box tab-content-element query-element" style="display: none;">
|
@@ -36,6 +36,10 @@
|
|
36
36
|
<div id="graph-box" class="graph-box tab-content-element graph-element" style="display: none;">
|
37
37
|
</div>
|
38
38
|
|
39
|
+
<div id="fetch-sql-box" class="fetch-sql-box tab-content-element graph-element query-element" style="display: none;">
|
40
|
+
<div id="result-loader" class="loader"></div>
|
41
|
+
</div>
|
42
|
+
|
39
43
|
<div id="saved-box" class="saved-box tab-content-element saved-element" style="display: none;">
|
40
44
|
</div>
|
41
45
|
|
@@ -55,7 +59,7 @@
|
|
55
59
|
</div>
|
56
60
|
|
57
61
|
<div id="status-box" class="status-box">
|
58
|
-
<div id="
|
62
|
+
<div id="result-status" class="status tab-content-element query-element"></div>
|
59
63
|
<div id="graph-status" class="status tab-content-element graph-element"></div>
|
60
64
|
<div id="saved-status" class="status tab-content-element saved-element"></div>
|
61
65
|
</div>
|
data/client/resources/sqlui.js
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
(function () {
|
2
2
|
'use strict';
|
3
3
|
|
4
4
|
/**
|
@@ -23851,6 +23851,25 @@ var sqlui = (function (exports) {
|
|
23851
23851
|
/* global google */
|
23852
23852
|
|
23853
23853
|
function init (parent, onSubmit, onShiftSubmit) {
|
23854
|
+
document.getElementById('query-tab-button').addEventListener('click', function (event) {
|
23855
|
+
selectTab(event, 'query');
|
23856
|
+
});
|
23857
|
+
document.getElementById('saved-tab-button').addEventListener('click', function (event) {
|
23858
|
+
selectTab(event, 'saved');
|
23859
|
+
});
|
23860
|
+
document.getElementById('structure-tab-button').addEventListener('click', function (event) {
|
23861
|
+
selectTab(event, 'structure');
|
23862
|
+
});
|
23863
|
+
document.getElementById('graph-tab-button').addEventListener('click', function (event) {
|
23864
|
+
selectTab(event, 'graph');
|
23865
|
+
});
|
23866
|
+
document.getElementById('submit-all-button').addEventListener('click', function (event) {
|
23867
|
+
submitAll(event.target, event);
|
23868
|
+
});
|
23869
|
+
document.getElementById('submit-current-button').addEventListener('click', function (event) {
|
23870
|
+
submitCurrent(event.target, event);
|
23871
|
+
});
|
23872
|
+
|
23854
23873
|
const fixedHeightEditor = EditorView.theme({
|
23855
23874
|
'.cm-scroller': { height: '200px', overflow: 'auto', resize: 'vertical' }
|
23856
23875
|
});
|
@@ -23872,18 +23891,27 @@ var sqlui = (function (exports) {
|
|
23872
23891
|
}
|
23873
23892
|
|
23874
23893
|
function getSelection () {
|
23875
|
-
|
23894
|
+
const anchor = window.editorView.state.selection.main.anchor;
|
23895
|
+
const head = window.editorView.state.selection.main.head;
|
23896
|
+
if (anchor === head) {
|
23897
|
+
return `${anchor}`
|
23898
|
+
} else {
|
23899
|
+
return `${anchor}-${head}`
|
23900
|
+
}
|
23876
23901
|
}
|
23877
23902
|
|
23878
23903
|
function setSelection (selection) {
|
23879
|
-
|
23880
|
-
|
23881
|
-
|
23882
|
-
|
23883
|
-
|
23884
|
-
|
23885
|
-
|
23886
|
-
|
23904
|
+
let anchor;
|
23905
|
+
let head;
|
23906
|
+
if (selection.includes('-')) {
|
23907
|
+
selection = selection.split('-').map(x => parseInt(x));
|
23908
|
+
anchor = Math.min(selection[0], window.editorView.state.doc.length);
|
23909
|
+
head = Math.min(selection[1], window.editorView.state.doc.length);
|
23910
|
+
} else {
|
23911
|
+
anchor = Math.min(parseInt(selection), window.editorView.state.doc.length);
|
23912
|
+
head = anchor;
|
23913
|
+
}
|
23914
|
+
window.editorView.dispatch({ selection: { anchor, head } });
|
23887
23915
|
}
|
23888
23916
|
|
23889
23917
|
function focus () {
|
@@ -23904,30 +23932,62 @@ var sqlui = (function (exports) {
|
|
23904
23932
|
});
|
23905
23933
|
}
|
23906
23934
|
|
23907
|
-
function
|
23908
|
-
|
23935
|
+
function setTabInUrl (url, tab) {
|
23936
|
+
url.pathname = url.pathname.replace(/\/[^/]+$/, `/${tab}`);
|
23937
|
+
}
|
23938
|
+
|
23939
|
+
function getTabFromUrl (url) {
|
23940
|
+
const match = url.pathname.match(/\/([^/]+)$/);
|
23941
|
+
if (match && ['query', 'graph', 'structure', 'saved'].includes(match[1])) {
|
23942
|
+
return match[1]
|
23943
|
+
} else {
|
23944
|
+
throw new Error(`invalid tab: ${url.pathname}`)
|
23945
|
+
}
|
23946
|
+
}
|
23947
|
+
|
23948
|
+
function updateTabs () {
|
23909
23949
|
const url = new URL(window.location);
|
23910
|
-
|
23911
|
-
|
23912
|
-
|
23913
|
-
|
23914
|
-
|
23915
|
-
|
23916
|
-
|
23917
|
-
|
23918
|
-
|
23919
|
-
|
23950
|
+
setTabInUrl(url, 'graph');
|
23951
|
+
document.getElementById('graph-tab-button').href = url.pathname + url.search;
|
23952
|
+
setTabInUrl(url, 'saved');
|
23953
|
+
document.getElementById('saved-tab-button').href = url.pathname + url.search;
|
23954
|
+
setTabInUrl(url, 'structure');
|
23955
|
+
document.getElementById('structure-tab-button').href = url.pathname + url.search;
|
23956
|
+
setTabInUrl(url, 'query');
|
23957
|
+
document.getElementById('query-tab-button').href = url.pathname + url.search;
|
23958
|
+
}
|
23959
|
+
|
23960
|
+
function selectTab (event, tab) {
|
23961
|
+
const url = new URL(window.location);
|
23962
|
+
setTabInUrl(url, tab);
|
23963
|
+
route(event.target, event, url);
|
23964
|
+
}
|
23965
|
+
|
23966
|
+
function route (target = null, event = null, url = null) {
|
23967
|
+
if (url) {
|
23968
|
+
if (event) {
|
23969
|
+
event.preventDefault();
|
23970
|
+
if (!(target instanceof EditorView && event instanceof KeyboardEvent)) {
|
23971
|
+
if (event.shiftKey) {
|
23972
|
+
window.open(url).focus();
|
23973
|
+
return
|
23974
|
+
}
|
23975
|
+
if (event.metaKey) {
|
23976
|
+
window.open(url, '_blank').focus();
|
23977
|
+
return
|
23978
|
+
}
|
23920
23979
|
}
|
23921
23980
|
}
|
23922
|
-
|
23923
|
-
if (tab !== 'query') {
|
23924
|
-
url.searchParams.set('tab', tab);
|
23981
|
+
if (url.href !== window.location.href) {
|
23925
23982
|
window.history.pushState({}, '', url);
|
23926
|
-
return route()
|
23927
23983
|
}
|
23984
|
+
} else {
|
23985
|
+
url = new URL(window.location);
|
23928
23986
|
}
|
23987
|
+
updateTabs();
|
23988
|
+
window.tab = getTabFromUrl(url);
|
23929
23989
|
|
23930
|
-
const tabElement = document.getElementById(`${tab}-tab-button`);
|
23990
|
+
const tabElement = document.getElementById(`${window.tab}-tab-button`);
|
23931
23991
|
Array.prototype.forEach.call(document.getElementsByClassName('selected-tab-button'), function (selected) {
|
23932
23992
|
selected.classList.remove('selected-tab-button');
|
23933
23993
|
selected.classList.add('tab-button');
|
@@ -23939,9 +23999,9 @@ var sqlui = (function (exports) {
|
|
23939
23999
|
selected.style.display = 'none';
|
23940
24000
|
});
|
23941
24001
|
|
23942
|
-
switch (tab) {
|
24002
|
+
switch (window.tab) {
|
23943
24003
|
case 'query':
|
23944
|
-
|
24004
|
+
selectResultTab();
|
23945
24005
|
break
|
23946
24006
|
case 'graph':
|
23947
24007
|
selectGraphTab();
|
@@ -23953,7 +24013,7 @@ var sqlui = (function (exports) {
|
|
23953
24013
|
selectStructureTab();
|
23954
24014
|
break
|
23955
24015
|
default:
|
23956
|
-
throw new Error(`Unexpected tab: ${tab}`)
|
24016
|
+
throw new Error(`Unexpected tab: ${window.tab}`)
|
23957
24017
|
}
|
23958
24018
|
}
|
23959
24019
|
|
@@ -24096,42 +24156,26 @@ var sqlui = (function (exports) {
|
|
24096
24156
|
}
|
24097
24157
|
|
24098
24158
|
function selectGraphTab () {
|
24099
|
-
|
24100
|
-
|
24101
|
-
|
24102
|
-
|
24103
|
-
|
24104
|
-
google.charts.setOnLoadCallback(function () {
|
24105
|
-
loadQueryOrGraphTab(loadGraphResult, queryErrorCallback('graph-status'));
|
24106
|
-
});
|
24159
|
+
document.getElementById('query-box').style.display = 'flex';
|
24160
|
+
document.getElementById('submit-box').style.display = 'flex';
|
24161
|
+
document.getElementById('graph-box').style.display = 'flex';
|
24162
|
+
document.getElementById('graph-status').style.display = 'flex';
|
24163
|
+
maybeFetchResult();
|
24107
24164
|
|
24108
24165
|
const selection = getSelection();
|
24109
24166
|
focus();
|
24110
24167
|
setSelection(selection);
|
24111
24168
|
}
|
24112
24169
|
|
24113
|
-
function
|
24114
|
-
|
24115
|
-
|
24116
|
-
|
24117
|
-
|
24170
|
+
function selectResultTab () {
|
24171
|
+
document.getElementById('query-box').style.display = 'flex';
|
24172
|
+
document.getElementById('submit-box').style.display = 'flex';
|
24173
|
+
document.getElementById('result-box').style.display = 'flex';
|
24174
|
+
document.getElementById('result-status').style.display = 'flex';
|
24118
24175
|
const selection = getSelection();
|
24119
24176
|
focus();
|
24120
24177
|
setSelection(selection);
|
24121
|
-
|
24122
|
-
loadQueryOrGraphTab(loadQueryResult, queryErrorCallback('query-status'));
|
24123
|
-
}
|
24124
|
-
|
24125
|
-
function queryErrorCallback (statusElementId) {
|
24126
|
-
const statusElement = document.getElementById(statusElementId);
|
24127
|
-
return function (message, error) {
|
24128
|
-
if (error) {
|
24129
|
-
console.log(`${message}\n${error}`);
|
24130
|
-
statusElement.innerText = `error: ${message} (check console)`;
|
24131
|
-
} else {
|
24132
|
-
statusElement.innerText = `error: ${message}`;
|
24133
|
-
}
|
24134
|
-
}
|
24178
|
+
maybeFetchResult();
|
24135
24179
|
}
|
24136
24180
|
|
24137
24181
|
function selectSavedTab () {
|
@@ -24149,22 +24193,20 @@ var sqlui = (function (exports) {
|
|
24149
24193
|
}
|
24150
24194
|
|
24151
24195
|
const saved = window.metadata.saved;
|
24152
|
-
if (saved
|
24196
|
+
if (Object.keys(saved).length === 1) {
|
24153
24197
|
setSavedStatus('1 file');
|
24154
24198
|
} else {
|
24155
24199
|
setSavedStatus(`${saved.length} files`);
|
24156
24200
|
}
|
24157
|
-
saved.forEach(file => {
|
24201
|
+
Object.values(saved).forEach(file => {
|
24158
24202
|
const divElement = document.createElement('div');
|
24159
24203
|
divElement.classList.add('saved-list-item');
|
24160
24204
|
divElement.addEventListener('click', function (event) {
|
24161
24205
|
clearResult();
|
24162
|
-
const url = new URL(window.location);
|
24163
|
-
url
|
24164
|
-
url.searchParams.delete('tab');
|
24206
|
+
const url = new URL(window.location.origin + window.location.pathname);
|
24207
|
+
setTabInUrl(url, 'query');
|
24165
24208
|
url.searchParams.set('file', file.filename);
|
24166
|
-
|
24167
|
-
route();
|
24209
|
+
route(event.target, event, url);
|
24168
24210
|
});
|
24169
24211
|
const nameElement = document.createElement('h2');
|
24170
24212
|
nameElement.innerText = file.filename;
|
@@ -24179,59 +24221,68 @@ var sqlui = (function (exports) {
|
|
24179
24221
|
window.savedLoaded = true;
|
24180
24222
|
}
|
24181
24223
|
|
24182
|
-
function submitAll () {
|
24183
|
-
submit(
|
24224
|
+
function submitAll (target, event) {
|
24225
|
+
submit(target, event);
|
24184
24226
|
}
|
24185
24227
|
|
24186
|
-
function submitCurrent () {
|
24187
|
-
submit(getSelection());
|
24228
|
+
function submitCurrent (target, event) {
|
24229
|
+
submit(target, event, getSelection());
|
24188
24230
|
}
|
24189
24231
|
|
24190
|
-
function submit (selection) {
|
24232
|
+
function submit (target, event, selection = null) {
|
24233
|
+
clearResult();
|
24191
24234
|
const url = new URL(window.location);
|
24192
|
-
if (selection) {
|
24193
|
-
url.searchParams.set('selection', selection.join(':'));
|
24194
|
-
} else {
|
24195
|
-
url.searchParams.delete('selection');
|
24196
|
-
}
|
24197
|
-
|
24198
24235
|
let sql = getValue().trim();
|
24199
24236
|
sql = sql === '' ? null : sql;
|
24200
24237
|
|
24238
|
+
url.searchParams.delete('run');
|
24239
|
+
|
24201
24240
|
if (url.searchParams.has('file')) {
|
24202
|
-
url.searchParams.
|
24203
|
-
|
24204
|
-
|
24241
|
+
if (window.metadata.saved[url.searchParams.get('file')].contents !== getValue()) {
|
24242
|
+
url.searchParams.delete('file');
|
24243
|
+
url.searchParams.set('sql', sql);
|
24244
|
+
}
|
24205
24245
|
} else {
|
24206
24246
|
let sqlParam = url.searchParams.get('sql')?.trim();
|
24207
24247
|
sqlParam = sqlParam === '' ? null : sqlParam;
|
24208
24248
|
|
24209
|
-
if (sqlParam !== sql) {
|
24210
|
-
|
24211
|
-
|
24212
|
-
|
24213
|
-
|
24214
|
-
|
24215
|
-
|
24216
|
-
|
24249
|
+
if (sqlParam !== sql && sql === null) {
|
24250
|
+
url.searchParams.delete('sql');
|
24251
|
+
} else if (sqlParam !== sql) {
|
24252
|
+
url.searchParams.set('sql', sql);
|
24253
|
+
}
|
24254
|
+
}
|
24255
|
+
|
24256
|
+
if (sql) {
|
24257
|
+
if (selection) {
|
24258
|
+
url.searchParams.set('selection', selection);
|
24217
24259
|
} else {
|
24218
|
-
|
24260
|
+
url.searchParams.delete('selection');
|
24219
24261
|
}
|
24262
|
+
} else {
|
24263
|
+
url.searchParams.delete('selection');
|
24264
|
+
url.searchParams.delete('sql');
|
24265
|
+
url.searchParams.delete('file');
|
24220
24266
|
}
|
24221
|
-
|
24222
|
-
route();
|
24267
|
+
|
24268
|
+
route(target, event, url);
|
24223
24269
|
}
|
24224
24270
|
|
24225
24271
|
function clearResult () {
|
24226
24272
|
clearGraphStatus();
|
24227
|
-
|
24273
|
+
clearResultStatus();
|
24228
24274
|
clearGraphBox();
|
24229
24275
|
clearResultBox();
|
24230
|
-
|
24276
|
+
const existingRequest = window.sqlFetch;
|
24277
|
+
if (existingRequest?.state === 'pending') {
|
24278
|
+
existingRequest.state = 'aborted';
|
24279
|
+
existingRequest.fetchController.abort();
|
24280
|
+
}
|
24281
|
+
window.sqlFetch = null;
|
24231
24282
|
}
|
24232
24283
|
|
24233
|
-
function
|
24234
|
-
document.getElementById('
|
24284
|
+
function clearResultStatus () {
|
24285
|
+
document.getElementById('result-status').innerText = '';
|
24235
24286
|
}
|
24236
24287
|
|
24237
24288
|
function clearGraphStatus () {
|
@@ -24252,7 +24303,7 @@ var sqlui = (function (exports) {
|
|
24252
24303
|
}
|
24253
24304
|
}
|
24254
24305
|
|
24255
|
-
function fetchSql (
|
24306
|
+
function fetchSql (request, selection, callback) {
|
24256
24307
|
fetch('query', {
|
24257
24308
|
headers: {
|
24258
24309
|
Accept: 'application/json',
|
@@ -24260,137 +24311,165 @@ var sqlui = (function (exports) {
|
|
24260
24311
|
},
|
24261
24312
|
method: 'POST',
|
24262
24313
|
body: JSON.stringify({
|
24263
|
-
sql,
|
24314
|
+
sql: request.sql,
|
24264
24315
|
selection
|
24265
|
-
})
|
24316
|
+
}),
|
24317
|
+
signal: request.fetchController.signal
|
24266
24318
|
})
|
24267
24319
|
.then((response) => {
|
24268
24320
|
const contentType = response.headers.get('content-type');
|
24269
24321
|
if (contentType && contentType.indexOf('application/json') !== -1) {
|
24270
24322
|
response.json().then((result) => {
|
24271
24323
|
if (result?.query) {
|
24272
|
-
|
24273
|
-
|
24274
|
-
errorCallback(result.error, result.stacktrace);
|
24275
|
-
} else if (result) {
|
24276
|
-
errorCallback('failed to execute query', result.toString());
|
24324
|
+
request.state = 'success';
|
24325
|
+
request.result = result;
|
24277
24326
|
} else {
|
24278
|
-
|
24327
|
+
request.state = 'error';
|
24328
|
+
if (result?.error) {
|
24329
|
+
request.error_message = result.error;
|
24330
|
+
request.error_details = result.stacktrace;
|
24331
|
+
} else if (result) {
|
24332
|
+
request.error_message = 'failed to execute query';
|
24333
|
+
request.error_details = result.toString();
|
24334
|
+
} else {
|
24335
|
+
request.error_message = 'failed to execute query';
|
24336
|
+
}
|
24279
24337
|
}
|
24338
|
+
callback(request);
|
24280
24339
|
});
|
24281
24340
|
} else {
|
24282
24341
|
response.text().then((result) => {
|
24283
|
-
|
24342
|
+
request.state = 'error';
|
24343
|
+
request.error_message = 'failed to execute query';
|
24344
|
+
request.error_details = result;
|
24345
|
+
callback(request);
|
24284
24346
|
});
|
24285
24347
|
}
|
24286
24348
|
})
|
24287
24349
|
.catch(function (error) {
|
24288
|
-
|
24289
|
-
|
24290
|
-
|
24291
|
-
|
24292
|
-
|
24293
|
-
fetch(`query_file?file=${name}`, {
|
24294
|
-
headers: {
|
24295
|
-
Accept: 'application/json'
|
24296
|
-
},
|
24297
|
-
method: 'GET'
|
24298
|
-
})
|
24299
|
-
.then((response) => {
|
24300
|
-
const contentType = response.headers.get('content-type');
|
24301
|
-
if (contentType && contentType.indexOf('application/json') !== -1) {
|
24302
|
-
response.json().then((result) => {
|
24303
|
-
if (result?.query) {
|
24304
|
-
successCallback(result);
|
24305
|
-
} else if (result?.error) {
|
24306
|
-
errorCallback(result.error, result.stacktrace);
|
24307
|
-
} else if (result) {
|
24308
|
-
errorCallback('failed to load file ', result.toString());
|
24309
|
-
} else {
|
24310
|
-
errorCallback('failed to load file');
|
24311
|
-
}
|
24312
|
-
});
|
24313
|
-
} else {
|
24314
|
-
errorCallback('failed to load file', response.toString());
|
24350
|
+
if (request.state === 'pending') {
|
24351
|
+
request.state = 'error';
|
24352
|
+
request.error_message = 'failed to execute query';
|
24353
|
+
request.error_details = error.stack;
|
24354
|
+
callback(request);
|
24315
24355
|
}
|
24316
|
-
})
|
24317
|
-
.catch(function (error) {
|
24318
|
-
errorCallback('failed to load file', error.stack);
|
24319
24356
|
});
|
24320
24357
|
}
|
24321
24358
|
|
24322
|
-
function
|
24359
|
+
function maybeFetchResult () {
|
24323
24360
|
const params = new URLSearchParams(window.location.search);
|
24324
24361
|
const sql = params.get('sql');
|
24325
24362
|
const file = params.get('file');
|
24326
|
-
const selection = params.
|
24363
|
+
const selection = params.get('selection');
|
24364
|
+
const run = !params.has('run') || !['0', 'false'].includes(params.get('run').toLowerCase());
|
24327
24365
|
|
24328
|
-
if (params.has('
|
24329
|
-
callback();
|
24330
|
-
return
|
24331
|
-
} else if (params.has('file') && window.result && file === window.result.file) {
|
24332
|
-
callback();
|
24333
|
-
return
|
24334
|
-
}
|
24335
|
-
|
24336
|
-
if (params.has('file') && params.has('sql') && selection === window.result.selection) {
|
24366
|
+
if (params.has('file') && params.has('sql')) {
|
24337
24367
|
// TODO: show an error.
|
24338
24368
|
throw new Error('You can only specify a file or sql, not both.')
|
24339
24369
|
}
|
24340
24370
|
|
24371
|
+
const request = {
|
24372
|
+
fetchController: new AbortController(),
|
24373
|
+
state: 'pending',
|
24374
|
+
sql,
|
24375
|
+
file,
|
24376
|
+
selection
|
24377
|
+
};
|
24378
|
+
|
24379
|
+
if (params.has('file')) {
|
24380
|
+
const fileDetails = window.metadata.saved[params.get('file')];
|
24381
|
+
if (!fileDetails) {
|
24382
|
+
throw new Error(`no such file: ${params.get('file')}`)
|
24383
|
+
}
|
24384
|
+
request.file = file;
|
24385
|
+
request.sql = fileDetails.contents;
|
24386
|
+
} else if (params.has('sql')) {
|
24387
|
+
request.sql = sql;
|
24388
|
+
}
|
24389
|
+
|
24390
|
+
const existingRequest = window.sqlFetch;
|
24391
|
+
if (existingRequest) {
|
24392
|
+
const selectionMatches = selection === existingRequest.selection;
|
24393
|
+
const sqlMatches = params.has('sql') && sql === existingRequest.sql;
|
24394
|
+
const fileMatches = params.has('file') && file === existingRequest.file;
|
24395
|
+
const queryMatches = sqlMatches || fileMatches;
|
24396
|
+
if (selectionMatches && queryMatches) {
|
24397
|
+
displaySqlFetch(existingRequest);
|
24398
|
+
if (params.has('selection')) {
|
24399
|
+
focus();
|
24400
|
+
setSelection(selection);
|
24401
|
+
}
|
24402
|
+
return
|
24403
|
+
}
|
24404
|
+
}
|
24405
|
+
|
24341
24406
|
clearResult();
|
24342
24407
|
|
24343
|
-
if (params.has('sql')) {
|
24344
|
-
setValue(sql);
|
24345
|
-
|
24346
|
-
window.
|
24347
|
-
|
24348
|
-
|
24349
|
-
|
24350
|
-
setValue('');
|
24351
|
-
fetchFile(file, function (result) {
|
24352
|
-
window.result = result;
|
24353
|
-
setValue(result.query);
|
24354
|
-
callback();
|
24355
|
-
}, errorCallback);
|
24408
|
+
if (params.has('sql') || params.has('file')) {
|
24409
|
+
setValue(request.sql);
|
24410
|
+
if (run) {
|
24411
|
+
window.sqlFetch = request;
|
24412
|
+
displaySqlFetch(request);
|
24413
|
+
fetchSql(request, selection, displaySqlFetch);
|
24414
|
+
}
|
24356
24415
|
}
|
24357
24416
|
if (params.has('selection')) {
|
24358
24417
|
focus();
|
24359
|
-
setSelection(
|
24418
|
+
setSelection(selection);
|
24360
24419
|
}
|
24361
24420
|
}
|
24362
24421
|
|
24363
|
-
function
|
24364
|
-
const
|
24365
|
-
|
24422
|
+
function displaySqlFetchInResultTab (fetch) {
|
24423
|
+
const fetchSqlBoxElement = document.getElementById('fetch-sql-box');
|
24424
|
+
const resultBoxElement = document.getElementById('result-box');
|
24425
|
+
if (fetch.state === 'pending') {
|
24426
|
+
clearResultBox();
|
24427
|
+
resultBoxElement.style.display = 'none';
|
24428
|
+
fetchSqlBoxElement.style.display = 'flex';
|
24366
24429
|
return
|
24367
24430
|
}
|
24368
24431
|
|
24369
|
-
|
24432
|
+
resultBoxElement.style.display = 'flex';
|
24433
|
+
fetchSqlBoxElement.style.display = 'none';
|
24434
|
+
|
24435
|
+
if (fetch.state === 'error') {
|
24436
|
+
clearResultBox();
|
24437
|
+
displaySqlFetchError('result-status', fetch.error_message, fetch.error_details);
|
24438
|
+
return
|
24439
|
+
}
|
24370
24440
|
|
24371
|
-
|
24372
|
-
|
24373
|
-
|
24441
|
+
if (fetch.state !== 'success') {
|
24442
|
+
throw new Error(`unexpected fetch sql request status: ${fetch.status}`)
|
24443
|
+
}
|
24444
|
+
|
24445
|
+
if (document.getElementById('result-table')) {
|
24446
|
+
// Results already displayed.
|
24447
|
+
return
|
24448
|
+
}
|
24449
|
+
|
24450
|
+
clearResultBox();
|
24451
|
+
displaySqlFetchResultStatus('result-status', fetch.result);
|
24374
24452
|
|
24375
24453
|
const tableElement = document.createElement('table');
|
24454
|
+
tableElement.id = 'result-table';
|
24376
24455
|
const theadElement = document.createElement('thead');
|
24377
24456
|
const headerElement = document.createElement('tr');
|
24378
24457
|
const tbodyElement = document.createElement('tbody');
|
24379
24458
|
theadElement.appendChild(headerElement);
|
24380
24459
|
tableElement.appendChild(theadElement);
|
24381
24460
|
tableElement.appendChild(tbodyElement);
|
24382
|
-
|
24461
|
+
resultBoxElement.appendChild(tableElement);
|
24383
24462
|
|
24384
|
-
|
24463
|
+
fetch.result.columns.forEach(column => {
|
24385
24464
|
const template = document.createElement('template');
|
24386
24465
|
template.innerHTML = `<th class="cell">${column}</th>`;
|
24387
24466
|
headerElement.appendChild(template.content.firstChild);
|
24388
24467
|
});
|
24389
|
-
if (
|
24468
|
+
if (fetch.result.columns.length > 0) {
|
24390
24469
|
headerElement.appendChild(document.createElement('th'));
|
24391
24470
|
}
|
24392
24471
|
let highlight = false;
|
24393
|
-
|
24472
|
+
fetch.result.rows.forEach(function (row) {
|
24394
24473
|
const rowElement = document.createElement('tr');
|
24395
24474
|
if (highlight) {
|
24396
24475
|
rowElement.classList.add('highlighted-row');
|
@@ -24404,29 +24483,67 @@ var sqlui = (function (exports) {
|
|
24404
24483
|
});
|
24405
24484
|
rowElement.appendChild(document.createElement('td'));
|
24406
24485
|
});
|
24486
|
+
}
|
24407
24487
|
|
24408
|
-
|
24488
|
+
function displaySqlFetch (fetch) {
|
24489
|
+
if (window.tab === 'query') {
|
24490
|
+
displaySqlFetchInResultTab(fetch);
|
24491
|
+
} else if (window.tab === 'graph') {
|
24492
|
+
displaySqlFetchInGraphTab(fetch);
|
24493
|
+
}
|
24494
|
+
}
|
24495
|
+
|
24496
|
+
function displaySqlFetchError (statusElementId, message, details) {
|
24497
|
+
const statusElement = document.getElementById(statusElementId);
|
24498
|
+
if (details) {
|
24499
|
+
console.log(`${message}\n${details}`);
|
24500
|
+
statusElement.innerText = `error: ${message} (check console)`;
|
24501
|
+
} else {
|
24502
|
+
statusElement.innerText = `error: ${message}`;
|
24503
|
+
}
|
24409
24504
|
}
|
24410
24505
|
|
24411
|
-
function
|
24412
|
-
|
24506
|
+
function displaySqlFetchInGraphTab (fetch) {
|
24507
|
+
const graphBoxElement = document.getElementById('graph-box');
|
24508
|
+
const fetchSqlBoxElement = document.getElementById('fetch-sql-box');
|
24509
|
+
if (fetch.state === 'pending') {
|
24510
|
+
clearGraphBox();
|
24511
|
+
graphBoxElement.style.display = 'none';
|
24512
|
+
fetchSqlBoxElement.style.display = 'flex';
|
24513
|
+
return
|
24514
|
+
}
|
24515
|
+
|
24516
|
+
graphBoxElement.style.display = 'flex';
|
24517
|
+
fetchSqlBoxElement.style.display = 'none';
|
24413
24518
|
|
24414
|
-
if (
|
24519
|
+
if (fetch.state === 'error') {
|
24520
|
+
clearGraphBox();
|
24521
|
+
displaySqlFetchError('graph-status', fetch.error_message, fetch.error_details);
|
24415
24522
|
return
|
24416
24523
|
}
|
24417
|
-
|
24524
|
+
|
24525
|
+
if (fetch.state !== 'success') {
|
24526
|
+
throw new Error(`unexpected fetch sql request status: ${fetch.status}`)
|
24527
|
+
}
|
24528
|
+
clearGraphBox();
|
24529
|
+
displaySqlFetchResultStatus('graph-status', fetch.result);
|
24530
|
+
|
24531
|
+
if (!fetch.result.rows) {
|
24532
|
+
return
|
24533
|
+
}
|
24534
|
+
if (fetch.result.rows.length === 0 || fetch.result.columns.length < 2) {
|
24418
24535
|
return
|
24419
24536
|
}
|
24420
24537
|
const dataTable = new google.visualization.DataTable();
|
24421
|
-
|
24422
|
-
dataTable.addColumn(
|
24538
|
+
fetch.result.columns.forEach((column, index) => {
|
24539
|
+
dataTable.addColumn(fetch.result.column_types[index], column);
|
24423
24540
|
});
|
24424
24541
|
|
24425
|
-
|
24542
|
+
fetch.result.rows.forEach((row) => {
|
24426
24543
|
const rowValues = row.map((value, index) => {
|
24427
|
-
if (
|
24544
|
+
if (fetch.result.column_types[index] === 'date' || fetch.result.column_types[index] === 'datetime') {
|
24428
24545
|
return new Date(value)
|
24429
|
-
} else if (
|
24546
|
+
} else if (fetch.result.column_types[index] === 'timeofday') {
|
24430
24547
|
// TODO: This should be hour, minute, second, milliseconds
|
24431
24548
|
return [0, 0, 0, 0]
|
24432
24549
|
} else {
|
@@ -24436,36 +24553,20 @@ var sqlui = (function (exports) {
|
|
24436
24553
|
dataTable.addRow(rowValues);
|
24437
24554
|
});
|
24438
24555
|
|
24439
|
-
const graphBoxElement = document.getElementById('graph-box');
|
24440
|
-
|
24441
24556
|
const chart = new google.visualization.LineChart(graphBoxElement);
|
24442
24557
|
const options = {
|
24443
24558
|
hAxis: {
|
24444
|
-
title:
|
24559
|
+
title: fetch.result.columns[0]
|
24445
24560
|
},
|
24446
24561
|
vAxis: {
|
24447
|
-
title:
|
24562
|
+
title: fetch.result.columns[1]
|
24448
24563
|
}
|
24449
24564
|
};
|
24450
24565
|
chart.draw(dataTable, options);
|
24451
24566
|
}
|
24452
24567
|
|
24453
|
-
function
|
24454
|
-
const statusElement = document.getElementById(
|
24455
|
-
|
24456
|
-
if (result.total_rows === 1) {
|
24457
|
-
statusElement.innerText = `${result.total_rows} row`;
|
24458
|
-
} else {
|
24459
|
-
statusElement.innerText = `${result.total_rows} rows`;
|
24460
|
-
}
|
24461
|
-
|
24462
|
-
if (result.total_rows > result.rows.length) {
|
24463
|
-
statusElement.innerText += ` (truncated to ${result.rows.length})`;
|
24464
|
-
}
|
24465
|
-
}
|
24466
|
-
|
24467
|
-
function setQueryStatus (result) {
|
24468
|
-
const statusElement = document.getElementById('query-status');
|
24568
|
+
function displaySqlFetchResultStatus (statusElementId, result) {
|
24569
|
+
const statusElement = document.getElementById(statusElementId);
|
24469
24570
|
|
24470
24571
|
if (result.total_rows === 1) {
|
24471
24572
|
statusElement.innerText = `${result.total_rows} row`;
|
@@ -24487,24 +24588,24 @@ var sqlui = (function (exports) {
|
|
24487
24588
|
});
|
24488
24589
|
|
24489
24590
|
window.addEventListener('resize', function (event) {
|
24490
|
-
if (window.tab === 'graph' && window.result) {
|
24591
|
+
if (window.tab === 'graph' && window.sqlFetch.result) {
|
24491
24592
|
clearGraphBox();
|
24492
|
-
|
24593
|
+
displaySqlFetchInGraphTab(window.sqlFetch);
|
24493
24594
|
}
|
24494
24595
|
});
|
24495
24596
|
|
24496
|
-
function route () {
|
24497
|
-
selectTab(new URLSearchParams(window.location.search).get('tab') || 'query');
|
24498
|
-
}
|
24499
|
-
|
24500
24597
|
window.onload = function () {
|
24501
|
-
|
24502
|
-
|
24503
|
-
|
24504
|
-
|
24505
|
-
|
24506
|
-
|
24507
|
-
|
24598
|
+
Promise.all([
|
24599
|
+
google.charts.load('current', { packages: ['corechart', 'line'] }),
|
24600
|
+
fetch('metadata', {
|
24601
|
+
headers: {
|
24602
|
+
Accept: 'application/json'
|
24603
|
+
},
|
24604
|
+
method: 'GET'
|
24605
|
+
})
|
24606
|
+
])
|
24607
|
+
.then((results) => {
|
24608
|
+
const response = results[1];
|
24508
24609
|
const contentType = response.headers.get('content-type');
|
24509
24610
|
if (contentType && contentType.indexOf('application/json') !== -1) {
|
24510
24611
|
return response.json().then((result) => {
|
@@ -24525,7 +24626,9 @@ var sqlui = (function (exports) {
|
|
24525
24626
|
window.metadata = result;
|
24526
24627
|
document.getElementById('loading-box').style.display = 'none';
|
24527
24628
|
document.getElementById('main-box').style.display = 'flex';
|
24528
|
-
document.getElementById('server-name').innerText =
|
24629
|
+
document.getElementById('server-name').innerText = window.metadata.server;
|
24630
|
+
document.title = `SQLUI ${window.metadata.server}`;
|
24631
|
+
document.getElementById('header-link').href = result.list_url_path;
|
24529
24632
|
const queryElement = document.getElementById('query');
|
24530
24633
|
|
24531
24634
|
init(queryElement, submitCurrent, submitAll);
|
@@ -24547,10 +24650,4 @@ var sqlui = (function (exports) {
|
|
24547
24650
|
});
|
24548
24651
|
};
|
24549
24652
|
|
24550
|
-
|
24551
|
-
exports.submitAll = submitAll;
|
24552
|
-
exports.submitCurrent = submitCurrent;
|
24553
|
-
|
24554
|
-
return exports;
|
24555
|
-
|
24556
|
-
})({});
|
24653
|
+
})();
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sqlui
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.25
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nick Dower
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-10-
|
11
|
+
date: 2022-10-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: mysql2
|