sqlui 0.1.20 → 0.1.21
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/mysql_types.rb +1 -1
- data/app/server.rb +19 -17
- data/app/views/databases.erb +70 -38
- data/client/resources/sqlui.css +46 -21
- data/client/resources/sqlui.html +2 -2
- data/client/resources/sqlui.js +2 -1
- 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: 1781b502f4bf82b9a87461d495cb6776f9290bfb5a2809a7ddb12e992ce7cc5c
|
4
|
+
data.tar.gz: a992696d1bbd1f809290035fa23c7cfec262f827073665e9013254420794d6d4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b6bfc097c3e9f427aec918c9b3eabeef74a69a3109fff6588c2a87201c9f43a7a0839463ec1cbe400b5d880ee1c3f069e6ecea6978acb02fd152633cc841f448
|
7
|
+
data.tar.gz: 9ec1cfb0f64cc425331723856e89aab3d2fac02f107a381a7c7ab6b2f1c4f0ee40adbe87b458c14fb537fe72ecb5eff044f02812e82fceb9c1263cff369a6ee3
|
data/.version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.21
|
data/app/mysql_types.rb
CHANGED
data/app/server.rb
CHANGED
@@ -56,12 +56,11 @@ class Server < Sinatra::Base
|
|
56
56
|
end
|
57
57
|
|
58
58
|
get "#{database.url_path}/metadata" do
|
59
|
-
|
60
|
-
metadata = database_config.with_client do |client|
|
59
|
+
metadata = database.with_client do |client|
|
61
60
|
{
|
62
61
|
server: config.name,
|
63
|
-
schemas: DatabaseMetadata.lookup(client,
|
64
|
-
saved: Dir.glob("#{
|
62
|
+
schemas: DatabaseMetadata.lookup(client, database),
|
63
|
+
saved: Dir.glob("#{database.saved_path}/*.sql").map do |path|
|
65
64
|
comment_lines = File.readlines(path).take_while do |l|
|
66
65
|
l.start_with?('--')
|
67
66
|
end
|
@@ -80,11 +79,12 @@ class Server < Sinatra::Base
|
|
80
79
|
|
81
80
|
get "#{database.url_path}/query_file" do
|
82
81
|
break client_error('missing file param') unless params[:file]
|
83
|
-
break client_error('no such file') unless File.exist?(params[:file])
|
84
82
|
|
85
|
-
|
86
|
-
|
87
|
-
|
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
88
|
execute_query(client, sql).tap { |r| r[:file] = params[:file] }
|
89
89
|
end
|
90
90
|
|
@@ -110,8 +110,7 @@ class Server < Sinatra::Base
|
|
110
110
|
break client_error("can't find query at selection") unless sql
|
111
111
|
end
|
112
112
|
|
113
|
-
|
114
|
-
result = database_config.with_client do |client|
|
113
|
+
result = database.with_client do |client|
|
115
114
|
execute_query(client, sql)
|
116
115
|
end
|
117
116
|
|
@@ -126,8 +125,10 @@ class Server < Sinatra::Base
|
|
126
125
|
error do |e|
|
127
126
|
status 500
|
128
127
|
headers 'Content-Type': 'application/json'
|
128
|
+
message = e.message.lines.first&.strip || 'unexpected error'
|
129
|
+
message = "#{message[0..80]}…" if message.length > 80
|
129
130
|
result = {
|
130
|
-
error:
|
131
|
+
error: message,
|
131
132
|
stacktrace: e.backtrace.map { |b| b }.join("\n")
|
132
133
|
}
|
133
134
|
body result.to_json
|
@@ -145,12 +146,13 @@ class Server < Sinatra::Base
|
|
145
146
|
end
|
146
147
|
|
147
148
|
def execute_query(client, sql)
|
148
|
-
if sql.include?(';')
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
149
|
+
queries = if sql.include?(';')
|
150
|
+
sql.split(/(?<=;)/).map(&:strip).reject(&:empty?)
|
151
|
+
else
|
152
|
+
[sql]
|
153
|
+
end
|
154
|
+
results = queries.map { |current| client.query(current) }
|
155
|
+
result = results[-1]
|
154
156
|
# NOTE: the call to result.field_types must go before any other interaction with the result. Otherwise you will
|
155
157
|
# get a seg fault. Seems to be a bug in Mysql2.
|
156
158
|
if result
|
data/app/views/databases.erb
CHANGED
@@ -1,66 +1,98 @@
|
|
1
1
|
<html>
|
2
|
-
|
3
|
-
|
2
|
+
<head>
|
3
|
+
<title>Databases</title>
|
4
4
|
|
5
|
-
|
5
|
+
<style>
|
6
6
|
body {
|
7
|
-
|
8
|
-
|
7
|
+
font-family: Helvetica;
|
8
|
+
margin: 0px;
|
9
9
|
}
|
10
10
|
|
11
11
|
h1 {
|
12
|
-
|
13
|
-
|
12
|
+
font-size: 22px;
|
13
|
+
}
|
14
|
+
|
15
|
+
h2 {
|
16
|
+
font-size: 20px;
|
17
|
+
}
|
18
|
+
|
19
|
+
p {
|
20
|
+
font-size: 18px;
|
21
|
+
}
|
22
|
+
|
23
|
+
.header-box {
|
24
|
+
display: flex;
|
25
|
+
flex-direction: row;
|
26
|
+
border-bottom: 1px solid #ddd;
|
27
|
+
height: 36px;
|
28
|
+
font-family: Helvetica;
|
29
|
+
}
|
30
|
+
|
31
|
+
.header, .server-name {
|
32
|
+
display: flex;
|
33
|
+
align-items: center;
|
34
|
+
justify-content: start;
|
35
|
+
color: #333;
|
36
|
+
}
|
37
|
+
|
38
|
+
.server-name {
|
39
|
+
flex: 1;
|
40
|
+
padding-left: 15px;
|
41
|
+
font-weight: normal;
|
42
|
+
}
|
14
43
|
|
44
|
+
.header {
|
45
|
+
font-weight: bold;
|
46
|
+
padding-left: 5px;
|
15
47
|
}
|
16
48
|
|
17
49
|
.database a {
|
18
|
-
|
19
|
-
|
20
|
-
|
50
|
+
margin-right: 10px;
|
51
|
+
color: darkblue;
|
52
|
+
font-size: 16px
|
21
53
|
}
|
22
54
|
|
23
55
|
.database h2 {
|
24
|
-
|
25
|
-
font-size: 20px;
|
26
|
-
font-weight: bold;
|
56
|
+
margin: 0px;
|
27
57
|
}
|
28
58
|
|
29
59
|
.database p {
|
30
|
-
|
31
|
-
|
32
|
-
font-size: 16px;
|
60
|
+
margin: 0px;
|
61
|
+
margin-top: 10px;
|
33
62
|
}
|
34
63
|
|
35
64
|
.database {
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
65
|
+
margin: 0px;
|
66
|
+
padding: 10px;
|
67
|
+
cursor: pointer;
|
68
|
+
border-bottom: 1px solid #eeeeee;
|
40
69
|
}
|
41
70
|
|
42
71
|
.database:last-child {
|
43
|
-
|
72
|
+
border-bottom: none;
|
44
73
|
}
|
45
74
|
|
46
75
|
.database:hover {
|
47
|
-
|
76
|
+
background: #eee;
|
48
77
|
}
|
49
|
-
|
50
|
-
|
78
|
+
</style>
|
79
|
+
</head>
|
51
80
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
81
|
+
<body>
|
82
|
+
<div class="header-box">
|
83
|
+
<h1 class="header">SQLUI</h1>
|
84
|
+
<h1 class="server-name"><%= config.name %> Databases</h1>
|
85
|
+
</div>
|
86
|
+
<% config.database_configs.each do |database_config| %>
|
87
|
+
<div class="database" onclick="window.location='<%= "#{database_config.url_path}/app" %>'">
|
88
|
+
<h2 class='name'><%= database_config.display_name %></h2>
|
89
|
+
<a class='query-link' href="<%= database_config.url_path %>/app">query</a>
|
90
|
+
<a class='saved-link' href="<%= database_config.url_path %>/app?tab=saved">saved</a>
|
91
|
+
<a class='structure-link' href="<%= database_config.url_path %>/app?tab=structure">structure</a>
|
92
|
+
<p class='description'>
|
93
|
+
<%= database_config.description %>
|
94
|
+
</p>
|
95
|
+
</div>
|
96
|
+
<% end %>
|
97
|
+
</body>
|
66
98
|
</html>
|
data/client/resources/sqlui.css
CHANGED
@@ -2,6 +2,18 @@ body {
|
|
2
2
|
margin: 0;
|
3
3
|
}
|
4
4
|
|
5
|
+
h1 {
|
6
|
+
font-size: 22px;
|
7
|
+
}
|
8
|
+
|
9
|
+
h2 {
|
10
|
+
font-size: 20px;
|
11
|
+
}
|
12
|
+
|
13
|
+
p {
|
14
|
+
font-size: 18px;
|
15
|
+
}
|
16
|
+
|
5
17
|
.loading-box {
|
6
18
|
font-family: monospace;
|
7
19
|
display: flex;
|
@@ -13,6 +25,7 @@ body {
|
|
13
25
|
align-items: start;
|
14
26
|
justify-content: start;
|
15
27
|
padding: 10px;
|
28
|
+
color: #333;
|
16
29
|
}
|
17
30
|
|
18
31
|
.main-box {
|
@@ -36,9 +49,15 @@ body {
|
|
36
49
|
padding-left: 5px;
|
37
50
|
}
|
38
51
|
|
52
|
+
.header a {
|
53
|
+
text-decoration: none;
|
54
|
+
color: #333
|
55
|
+
}
|
56
|
+
|
39
57
|
.server-name {
|
40
58
|
flex: 1;
|
41
59
|
padding-left: 15px;
|
60
|
+
font-weight: normal;
|
42
61
|
}
|
43
62
|
|
44
63
|
.tabs-box {
|
@@ -46,7 +65,7 @@ body {
|
|
46
65
|
flex-direction: row;
|
47
66
|
border-bottom: 1px solid #ddd;
|
48
67
|
height: 36px;
|
49
|
-
font-family: Helvetica;
|
68
|
+
font-family: Helvetica, sans-serif;
|
50
69
|
}
|
51
70
|
|
52
71
|
.tab-button, .selected-tab-button {
|
@@ -55,10 +74,11 @@ body {
|
|
55
74
|
cursor: pointer;
|
56
75
|
width: 150px;
|
57
76
|
padding: 2px;
|
58
|
-
margin:
|
77
|
+
margin: 0;
|
59
78
|
display: flex;
|
60
79
|
justify-content: center;
|
61
80
|
background-color: #fff;
|
81
|
+
font-size: 18px;
|
62
82
|
}
|
63
83
|
|
64
84
|
.tab-button {
|
@@ -100,6 +120,8 @@ body {
|
|
100
120
|
border: 1px solid #888;
|
101
121
|
background: none;
|
102
122
|
padding: 5px;
|
123
|
+
font-size: 18px;
|
124
|
+
color: #333;
|
103
125
|
}
|
104
126
|
|
105
127
|
.status {
|
@@ -107,9 +129,11 @@ body {
|
|
107
129
|
justify-content: center;
|
108
130
|
align-content: center;
|
109
131
|
flex-direction: column;
|
110
|
-
font-family: Helvetica;
|
132
|
+
font-family: Helvetica, sans-serif;
|
111
133
|
white-space: nowrap;
|
112
134
|
overflow: hidden;
|
135
|
+
font-size: 18px;
|
136
|
+
color: #333;
|
113
137
|
}
|
114
138
|
|
115
139
|
.result-box, .saved-box, .graph-box, .structure-box {
|
@@ -130,9 +154,10 @@ body {
|
|
130
154
|
table {
|
131
155
|
font-family: monospace;
|
132
156
|
flex: 1;
|
133
|
-
border-spacing:
|
157
|
+
border-spacing: 0;
|
134
158
|
display: flex;
|
135
159
|
width: 100%;
|
160
|
+
color: #333;
|
136
161
|
}
|
137
162
|
|
138
163
|
table td:last-child, table th:last-child {
|
@@ -165,11 +190,11 @@ table {
|
|
165
190
|
}
|
166
191
|
|
167
192
|
thead {
|
168
|
-
padding:
|
193
|
+
padding: 0;
|
169
194
|
background-color: #fff;
|
170
195
|
position: -webkit-sticky;
|
171
196
|
position: sticky;
|
172
|
-
top:
|
197
|
+
top: 0;
|
173
198
|
z-index: 100;
|
174
199
|
table-layout: fixed;
|
175
200
|
}
|
@@ -181,7 +206,7 @@ thead {
|
|
181
206
|
.status-box {
|
182
207
|
padding: 5px;
|
183
208
|
display: flex;
|
184
|
-
flex-direction:
|
209
|
+
flex-direction: row;
|
185
210
|
justify-content: space-between;
|
186
211
|
border-top: 1px solid #ddd;
|
187
212
|
height: 30px;
|
@@ -196,31 +221,31 @@ thead {
|
|
196
221
|
}
|
197
222
|
|
198
223
|
.saved-box {
|
199
|
-
font-family: Helvetica;
|
224
|
+
font-family: Helvetica, sans-serif;
|
200
225
|
}
|
201
226
|
|
202
|
-
.saved-box
|
203
|
-
margin:
|
204
|
-
padding-left: 10px;
|
205
|
-
padding-right: 10px;
|
206
|
-
padding-top: 10px;
|
207
|
-
padding-bottom: 10px;
|
227
|
+
.saved-box h2 {
|
228
|
+
margin: 0;
|
208
229
|
font-weight: bold;
|
209
230
|
}
|
210
231
|
|
211
|
-
.saved-
|
232
|
+
.saved-list-item:last-child {
|
212
233
|
border-top: none !important;
|
213
234
|
}
|
214
235
|
|
215
236
|
.saved-box p {
|
216
|
-
margin:
|
217
|
-
padding-left: 20px;
|
218
|
-
padding-bottom: 20px;
|
237
|
+
margin: 0;
|
219
238
|
}
|
220
239
|
|
221
|
-
.saved-
|
240
|
+
.saved-list-item {
|
222
241
|
cursor: pointer;
|
223
|
-
border-
|
242
|
+
border-bottom: 1px solid #eeeeee;
|
243
|
+
margin: 0;
|
244
|
+
padding: 10px;
|
245
|
+
}
|
246
|
+
|
247
|
+
.saved-list-item h2 {
|
248
|
+
margin: 0 0 5px;
|
224
249
|
}
|
225
250
|
|
226
251
|
.saved-box div:hover {
|
@@ -239,7 +264,6 @@ thead {
|
|
239
264
|
|
240
265
|
.table-info {
|
241
266
|
display: grid;
|
242
|
-
grid-template-columns: 1;
|
243
267
|
grid-template-rows: 0.5fr 0.5fr;
|
244
268
|
justify-items: stretch;
|
245
269
|
flex: 1;
|
@@ -260,4 +284,5 @@ thead {
|
|
260
284
|
|
261
285
|
select {
|
262
286
|
outline: none;
|
287
|
+
color: #333;
|
263
288
|
}
|
data/client/resources/sqlui.html
CHANGED
@@ -13,8 +13,8 @@
|
|
13
13
|
|
14
14
|
<div id="main-box" class="main-box" style="display:none">
|
15
15
|
<div class="tabs-box">
|
16
|
-
<
|
17
|
-
<
|
16
|
+
<h1 class="header"><a href="/sqlui">SQLUI</a></h1>
|
17
|
+
<h1 id="server-name" class="server-name"></h1>
|
18
18
|
<input id="query-tab-button" class="tab-button" type="button" value="Query" onclick="sqlui.selectTab('query')"></input>
|
19
19
|
<input id="graph-tab-button" class="tab-button" type="button" value="Graph" onclick="sqlui.selectTab('graph')"></input>
|
20
20
|
<input id="saved-tab-button" class="tab-button" type="button" value="Saved" onclick="sqlui.selectTab('saved')"></input>
|
data/client/resources/sqlui.js
CHANGED
@@ -24156,6 +24156,7 @@ var sqlui = (function (exports) {
|
|
24156
24156
|
}
|
24157
24157
|
saved.forEach(file => {
|
24158
24158
|
const divElement = document.createElement('div');
|
24159
|
+
divElement.classList.add('saved-list-item');
|
24159
24160
|
divElement.addEventListener('click', function (event) {
|
24160
24161
|
clearResult();
|
24161
24162
|
const url = new URL(window.location);
|
@@ -24165,7 +24166,7 @@ var sqlui = (function (exports) {
|
|
24165
24166
|
window.history.pushState({}, '', url);
|
24166
24167
|
route();
|
24167
24168
|
});
|
24168
|
-
const nameElement = document.createElement('
|
24169
|
+
const nameElement = document.createElement('h2');
|
24169
24170
|
nameElement.innerText = file.filename;
|
24170
24171
|
divElement.appendChild(nameElement);
|
24171
24172
|
|
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.21
|
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-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: mysql2
|