sqlui 0.1.53 → 0.1.55

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: aecad7b8b4d0000efae09f66acce234f8d0617e83103c2d21a7e19c2b14f4de0
4
- data.tar.gz: 0e35efaf9d1116e7d758dee9a409343654963608ec14e2f5f9714866db85365f
3
+ metadata.gz: 5ac5672ec8d9668ee10c58ccf407a63f297b411ff055cadfc89ce9090369bb2d
4
+ data.tar.gz: 146c7af99506528b86b8721db25dfffec71dbb5af32f9ed711a7b7b781ae0dbb
5
5
  SHA512:
6
- metadata.gz: b8871b41338fff2bec4a4130d783e6fed8d5a9ee80e2b2786f48740ca2ed5d17887a37df2b9c0e3cc8c9a4b2bb13dcc3d74ca3a3f54b5f318f20f9d98df92f6e
7
- data.tar.gz: 1bf1575c392641fb2d3710a093e467382ab69c8656315ec801c837e0afdde5a36c0e0a8134f271c0f38a9249f92156255d5f7ddfb3dd56685b26a20ea0fed791
6
+ metadata.gz: 31d766b04ba02bf3f0bc4d369614b87bc5c527e6f96634d3019875f71cb84d6906aba812d54175ca65782cadee47355df87018c8c190a8cf33fce2a306a32def
7
+ data.tar.gz: c05a7fff480f3fe42925a7a07cddebddbff979f74e3bdac898a585439d251c180d682da66a7e6b98d4f0e175def931f03dff23d3d5406fd9c273f1953dcc0d6a
data/.release-version CHANGED
@@ -1 +1 @@
1
- 0.1.53
1
+ 0.1.55
data/app/server.rb CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  require 'base64'
4
4
  require 'csv'
5
+ require 'digest/md5'
5
6
  require 'erb'
6
7
  require 'json'
7
8
  require 'prometheus/middleware/collector'
@@ -58,6 +59,10 @@ class Server < Sinatra::Base
58
59
  set :raise_errors, false
59
60
  set :show_exceptions, false
60
61
 
62
+ favicon_hash = Digest::MD5.hexdigest(File.read(File.join(resources_dir, 'favicon.svg')))
63
+ css_hash = Digest::MD5.hexdigest(File.read(File.join(resources_dir, 'sqlui.css')))
64
+ js_hash = Digest::MD5.hexdigest(File.read(File.join(resources_dir, 'sqlui.js')))
65
+
61
66
  get '/-/health' do
62
67
  status 200
63
68
  body 'OK'
@@ -68,10 +73,12 @@ class Server < Sinatra::Base
68
73
  end
69
74
 
70
75
  get '/favicon.svg' do
76
+ headers 'Cache-Control' => 'max-age=31536000'
71
77
  send_file File.join(resources_dir, 'favicon.svg')
72
78
  end
73
79
 
74
80
  get "#{config.list_url_path}/?" do
81
+ headers 'Cache-Control' => 'no-cache'
75
82
  erb :databases, locals: { config: config }
76
83
  end
77
84
 
@@ -82,11 +89,13 @@ class Server < Sinatra::Base
82
89
 
83
90
  get "#{database.url_path}/sqlui.css" do
84
91
  headers 'Content-Type' => 'text/css; charset=utf-8'
92
+ headers 'Cache-Control' => 'max-age=31536000'
85
93
  send_file File.join(resources_dir, 'sqlui.css')
86
94
  end
87
95
 
88
96
  get "#{database.url_path}/sqlui.js" do
89
97
  headers 'Content-Type' => 'text/javascript; charset=utf-8'
98
+ headers 'Cache-Control' => 'max-age=31536000'
90
99
  send_file File.join(resources_dir, 'sqlui.js')
91
100
  end
92
101
 
@@ -185,6 +194,7 @@ class Server < Sinatra::Base
185
194
  sql = find_selected_query(sql, params[:selection])
186
195
 
187
196
  content_type 'application/csv; charset=utf-8'
197
+ headers 'Cache-Control' => 'no-cache'
188
198
  attachment 'result.csv'
189
199
  status 200
190
200
 
@@ -201,12 +211,16 @@ class Server < Sinatra::Base
201
211
 
202
212
  get(%r{#{Regexp.escape(database.url_path)}/(query|graph|structure|saved)}) do
203
213
  status 200
214
+ headers 'Cache-Control' => 'no-cache'
204
215
  client_config = config.airbrake[:client] || {}
205
216
  erb :sqlui, locals: {
206
217
  environment: config.environment.to_s,
207
218
  airbrake_enabled: client_config[:enabled] || false,
208
219
  airbrake_project_id: client_config[:project_id] || '',
209
- airbrake_project_key: client_config[:project_key] || ''
220
+ airbrake_project_key: client_config[:project_key] || '',
221
+ js_hash: js_hash,
222
+ css_hash: css_hash,
223
+ favicon_hash: favicon_hash
210
224
  }
211
225
  end
212
226
  end
data/app/sqlui.rb CHANGED
@@ -6,7 +6,7 @@ require_relative 'version'
6
6
 
7
7
  # Main entry point.
8
8
  class Sqlui
9
- MAX_ROWS = 10_000
9
+ MAX_ROWS = 5_000
10
10
  MAX_BYTES = 10 * 1_024 * 1_024
11
11
 
12
12
  def initialize(config_file)
data/app/views/sqlui.erb CHANGED
@@ -1,8 +1,9 @@
1
+ <!DOCTYPE html>
1
2
  <html lang="en">
2
3
  <head>
3
4
  <meta charset="utf-8">
4
5
  <title>SQLUI</title>
5
- <link rel="icon" type="image/x-icon" href="/favicon.svg">
6
+ <link rel="icon" type="image/x-icon" href="/favicon.svg?<%= favicon_hash %>">
6
7
  <!-- Initialize Airbrake before loading the main app JS so that we can catch errors as early as possible. -->
7
8
  <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/@airbrake/browser"></script>
8
9
  <script type="text/javascript">
@@ -18,9 +19,9 @@
18
19
  window.airbrake?.notify(error)
19
20
  }
20
21
  </script>
21
- <script type="text/javascript" src="sqlui.js"></script>
22
+ <script type="text/javascript" src="sqlui.js?<%= js_hash %>"></script>
22
23
  <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
23
- <link rel="stylesheet" href="sqlui.css">
24
+ <link rel="stylesheet" href="sqlui.css?<%= css_hash %>">
24
25
  </head>
25
26
 
26
27
  <body>
@@ -95,9 +96,13 @@
95
96
  </div>
96
97
 
97
98
  <div id="status-box" class="status-box">
98
- <div id="result-status" class="status tab-content-element query-element"></div>
99
- <div id="graph-status" class="status tab-content-element graph-element"></div>
100
- <div id="saved-status" class="status tab-content-element saved-element"></div>
99
+ <div id="status-message"></div>
100
+ <div style="flex: 1;"></div>
101
+ <div id="pagination-box" class="tab-content-element">
102
+ <div id="page-count-box"></div>
103
+ <input id="prev-button" class="pagination-button" type="button" value="Prev" />
104
+ <input id="next-button" class="pagination-button" type="button" value="Next" />
105
+ </div>
101
106
  </div>
102
107
  </div>
103
108
  </body>
@@ -1,4 +1,9 @@
1
+ html {
2
+ height: 100%;
3
+ }
4
+
1
5
  body {
6
+ height: 100%;
2
7
  margin: 0;
3
8
  overflow: hidden;
4
9
  }
@@ -98,10 +103,6 @@ p {
98
103
  font-weight: bold;
99
104
  }
100
105
 
101
- .tab-content-element {
102
- display: none;
103
- }
104
-
105
106
  .query-box {
106
107
  display: flex;
107
108
  flex-direction: column;
@@ -227,11 +228,11 @@ p {
227
228
  background: none !important;
228
229
  }
229
230
 
230
- .status {
231
+ .status-message {
231
232
  display: flex;
232
233
  justify-content: center;
233
234
  align-content: center;
234
- flex-direction: column;
235
+ flex-direction: row;
235
236
  font-family: Helvetica, sans-serif;
236
237
  white-space: nowrap;
237
238
  overflow: hidden;
@@ -245,8 +246,8 @@ p {
245
246
  display: flex;
246
247
  flex-direction: column;
247
248
  }
248
- #result-table tbody tr td{
249
- height: calc(21px + 10px); // 21 for text, 10 for top and bottom padding of 5
249
+ table tbody tr td {
250
+ height: 21px;
250
251
  }
251
252
 
252
253
  #result-table tbody tr td abbr a {
@@ -264,10 +265,7 @@ p {
264
265
  margin: 0 5px 0 0;
265
266
  text-decoration: none;
266
267
  position: relative;
267
- }
268
-
269
- #result-table tbody tr td abbr:last-child {
270
- margin: 0;
268
+ bottom: 2px; /* To make the links look vertically centered. */
271
269
  }
272
270
 
273
271
  .fetch-sql-box {
@@ -281,41 +279,62 @@ p {
281
279
 
282
280
  table {
283
281
  font-family: monospace;
284
- flex: 1;
285
282
  border-spacing: 0;
286
- display: flex;
287
- width: 100%;
288
283
  color: #333;
289
284
  font-size: 18px;
285
+ width: 100%;
286
+ table-layout: auto; /* Will be overridden if a column is resized. */
290
287
  }
291
288
 
292
289
  table td:last-child, table th:last-child {
293
- width: 100%;
294
290
  border-right: none !important;
295
291
  }
296
292
 
297
293
  td, th {
298
- padding: 5px 10px;
299
294
  font-weight: normal;
300
295
  white-space: nowrap;
301
296
  max-width: 500px;
302
- overflow: hidden;
303
- text-overflow: ellipsis;
304
297
  }
305
298
 
306
299
  td {
300
+ overflow: hidden;
301
+ text-overflow: ellipsis;
302
+ padding: 5px 10px;
307
303
  text-align: right;
308
304
  }
309
305
 
306
+ #result-table tbody tr td .cell-content-wrapper {
307
+ display: flex;
308
+ }
309
+
310
+ #result-table tbody tr td .cell-value {
311
+ flex: 1;
312
+ }
313
+
310
314
  th {
311
- text-align: left;
312
315
  font-weight: bold;
313
316
  border-bottom: 1px solid #ddd;
314
317
  border-right: 1px solid #ddd;
315
318
  }
316
319
 
317
- table {
318
- display: block;
320
+ th div.col-content-wrapper {
321
+ display: flex;
322
+ }
323
+
324
+ th div.col-name {
325
+ overflow: hidden;
326
+ text-overflow: ellipsis;
327
+ flex: 1;
328
+ height: 21px;
329
+ text-align: left;
330
+ padding: 5px 10px;
331
+ }
332
+
333
+ th div.col-resizer {
334
+ width: 7px;
335
+ position: relative;
336
+ left: 5px; /* center over the right border */
337
+ cursor: col-resize;
319
338
  }
320
339
 
321
340
  thead {
@@ -325,7 +344,6 @@ thead {
325
344
  position: sticky;
326
345
  top: 0;
327
346
  z-index: 1;
328
- table-layout: fixed;
329
347
  }
330
348
 
331
349
  .highlighted-row {
@@ -333,12 +351,13 @@ thead {
333
351
  }
334
352
 
335
353
  .status-box {
336
- padding: 5px;
354
+ padding: 5px 15px;
337
355
  display: flex;
338
356
  flex-direction: row;
339
- justify-content: space-between;
340
357
  border-top: 1px solid #ddd;
341
358
  height: 30px;
359
+ align-items: center;
360
+ font-family: Helvetica, sans-serif;
342
361
  }
343
362
 
344
363
  .CodeMirror pre.CodeMirror-placeholder {
@@ -461,3 +480,35 @@ select {
461
480
  color: #333;
462
481
  font-size: 14px;
463
482
  }
483
+
484
+ #pagination-box {
485
+ display: flex;
486
+ flex-direction: row;
487
+ }
488
+
489
+ #page-count-box {
490
+ align-self: center;
491
+ font-size: 16px;
492
+ }
493
+
494
+ #next-button {
495
+
496
+ }
497
+
498
+ #prev-button {
499
+ margin: 0 10px;
500
+ }
501
+
502
+ .pagination-button {
503
+ cursor: pointer;
504
+ background: none;
505
+ color: #333;
506
+ border: 1px solid #888;
507
+ font-size: 16px;
508
+ padding: 2px 10px;
509
+ }
510
+
511
+ .pagination-button:disabled {
512
+ color: #888;
513
+ border: 1px solid #ddd;
514
+ }