sqlui 0.1.24 → 0.1.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|