sqlui 0.1.25 → 0.1.26

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: 11963565427ad327b2fb3cf1eadb62f789b620c3b3de943f2a0b17f3be505356
4
- data.tar.gz: 1be9eaac08e81afba77f4c1f5581a78f8e4a73d007d9e29f0ca238c956d46a6b
3
+ metadata.gz: 20b037b445c287b8e9586a2f5820d4be597bb977db8a9412721790a5239a2f87
4
+ data.tar.gz: '08e5d525245186d568bd2deb86f4a5d25adc9a57d3729651ff74d6fe90e22451'
5
5
  SHA512:
6
- metadata.gz: 76fc95eeec60f207e1505b4d71d10e6bf329c94ddc42ca15edef83853ca6f74407b275f168f1a721c9b0d50507228dcb5aae5c4f2cb2fa54e46f1dbef79d05cb
7
- data.tar.gz: 06140f3797fb34a7fa869c484ef002e5310ceceeea87e57f0c6dd984f13c2a6d75c9dddab253bf64545fa9cd58a93cac41e476b8cb8ee9c7fe86f47b38af39a0
6
+ metadata.gz: 631086186d72bfe55f633e88a1017e911d53c4185b9139da4ebf0d462ec9fb48fbf639154fc014453285835c504b1ce8a18f20e9de9c78239a95566b2cde3177
7
+ data.tar.gz: 24cd3591e88d28785765b6add934a19458c19920cdd77c02f31f7356ca6cefdf4971e45df560c1e451a50ee4192c1ca4d9f8cae227cfe7daa87463b82f7ada6f
data/.version CHANGED
@@ -1 +1 @@
1
- 0.1.25
1
+ 0.1.26
@@ -1,6 +1,6 @@
1
1
  <html lang="en">
2
2
  <head>
3
- <title>Databases</title>
3
+ <title><%= config.name %> Databases</title>
4
4
 
5
5
  <style>
6
6
  body {
@@ -71,30 +71,13 @@
71
71
  .database {
72
72
  margin: 0;
73
73
  padding: 10px;
74
- cursor: pointer;
75
74
  border-bottom: 1px solid #eeeeee;
76
75
  }
77
76
 
78
77
  .database:last-child {
79
78
  border-bottom: none;
80
79
  }
81
-
82
- .database:hover {
83
- background: #eee;
84
- }
85
80
  </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>
98
81
  </head>
99
82
 
100
83
  <body>
@@ -103,12 +86,12 @@
103
86
  <h1 class="server-name"><%= config.name %> Databases</h1>
104
87
  </div>
105
88
  <% config.database_configs.each do |database_config| %>
106
- <div class="database" onclick="openDatabase(event, '<%= "#{database_config.url_path}/query" %>')">
89
+ <div class="database">
107
90
  <div class="name-and-links">
108
91
  <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>
92
+ <a class='query-link' href="<%= database_config.url_path %>/query">query</a>
93
+ <a class='saved-link' href="<%= database_config.url_path %>/saved">saved</a>
94
+ <a class='structure-link' href="<%= database_config.url_path %>/structure">structure</a>
112
95
  </div>
113
96
  <p class='description'>
114
97
  <%= database_config.description %>
@@ -113,7 +113,11 @@ p {
113
113
  display: flex;
114
114
  border-top: 1px solid #ddd;
115
115
  border-bottom: 1px solid #ddd;
116
- justify-content: right;
116
+ }
117
+
118
+ .submit-fill {
119
+ display: flex;
120
+ flex: 1
117
121
  }
118
122
 
119
123
  .submit-button {
@@ -243,18 +247,30 @@ thead {
243
247
  }
244
248
 
245
249
  .saved-list-item {
246
- cursor: pointer;
247
250
  border-bottom: 1px solid #eeeeee;
248
251
  margin: 0;
249
252
  padding: 10px;
250
253
  }
251
254
 
252
255
  .saved-list-item h2 {
253
- margin: 0 0 5px;
256
+ margin: 0 10px 0 0;
254
257
  }
255
258
 
256
- .saved-box div:hover {
257
- background: #eee;
259
+ .saved-list-item p {
260
+ margin: 10px 0 0;
261
+ }
262
+
263
+ .name-and-links {
264
+ display: flex;
265
+ flex-direction: row;
266
+ align-items: center;
267
+ }
268
+
269
+ .name-and-links a {
270
+ margin-right: 5px;
271
+ color: darkblue;
272
+ font-size: 16px;
273
+ text-decoration: none;
258
274
  }
259
275
 
260
276
  .cm-editor.cm-focused {
@@ -26,6 +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="cancel-button" class="submit-button" type="button" value="cancel"></input>
30
+ <div class="submit-fill"></div>
29
31
  <input id="submit-current-button" class="submit-button" type="button" value="run selection (ctrl-enter)"></input>
30
32
  <input id="submit-all-button" class="submit-button" type="button" value="run (ctrl-shift-enter)"></input>
31
33
  </div>
@@ -23869,6 +23869,9 @@
23869
23869
  document.getElementById('submit-current-button').addEventListener('click', function (event) {
23870
23870
  submitCurrent(event.target, event);
23871
23871
  });
23872
+ document.getElementById('cancel-button').addEventListener('click', function (event) {
23873
+ clearResult();
23874
+ });
23872
23875
 
23873
23876
  const fixedHeightEditor = EditorView.theme({
23874
23877
  '.cm-scroller': { height: '200px', overflow: 'auto', resize: 'vertical' }
@@ -24160,6 +24163,8 @@
24160
24163
  document.getElementById('submit-box').style.display = 'flex';
24161
24164
  document.getElementById('graph-box').style.display = 'flex';
24162
24165
  document.getElementById('graph-status').style.display = 'flex';
24166
+ document.getElementById('fetch-sql-box').style.display = 'none';
24167
+ document.getElementById('cancel-button').style.display = 'none';
24163
24168
  maybeFetchResult();
24164
24169
 
24165
24170
  const selection = getSelection();
@@ -24172,6 +24177,8 @@
24172
24177
  document.getElementById('submit-box').style.display = 'flex';
24173
24178
  document.getElementById('result-box').style.display = 'flex';
24174
24179
  document.getElementById('result-status').style.display = 'flex';
24180
+ document.getElementById('fetch-sql-box').style.display = 'none';
24181
+ document.getElementById('cancel-button').style.display = 'none';
24175
24182
  const selection = getSelection();
24176
24183
  focus();
24177
24184
  setSelection(selection);
@@ -24199,21 +24206,48 @@
24199
24206
  setSavedStatus(`${saved.length} files`);
24200
24207
  }
24201
24208
  Object.values(saved).forEach(file => {
24202
- const divElement = document.createElement('div');
24203
- divElement.classList.add('saved-list-item');
24204
- divElement.addEventListener('click', function (event) {
24209
+ const viewUrl = new URL(window.location.origin + window.location.pathname);
24210
+ setTabInUrl(viewUrl, 'query');
24211
+ viewUrl.searchParams.set('file', file.filename);
24212
+
24213
+ const viewLinkElement = document.createElement('a');
24214
+ viewLinkElement.classList.add('view-link');
24215
+ viewLinkElement.innerText = 'view';
24216
+ viewLinkElement.href = viewUrl.pathname + viewUrl.search;
24217
+ viewLinkElement.addEventListener('click', function (event) {
24205
24218
  clearResult();
24206
- const url = new URL(window.location.origin + window.location.pathname);
24207
- setTabInUrl(url, 'query');
24208
- url.searchParams.set('file', file.filename);
24209
- route(event.target, event, url);
24219
+ route(event.target, event, viewUrl);
24210
24220
  });
24221
+
24222
+ const runUrl = new URL(window.location.origin + window.location.pathname);
24223
+ setTabInUrl(runUrl, 'query');
24224
+ runUrl.searchParams.set('file', file.filename);
24225
+ runUrl.searchParams.set('run', 'true');
24226
+
24227
+ const runLinkElement = document.createElement('a');
24228
+ runLinkElement.classList.add('run-link');
24229
+ runLinkElement.innerText = 'run';
24230
+ runLinkElement.href = runUrl.pathname + runUrl.search;
24231
+ runLinkElement.addEventListener('click', function (event) {
24232
+ clearResult();
24233
+ route(event.target, event, runUrl);
24234
+ });
24235
+
24211
24236
  const nameElement = document.createElement('h2');
24212
24237
  nameElement.innerText = file.filename;
24213
- divElement.appendChild(nameElement);
24238
+
24239
+ const nameAndLinksElement = document.createElement('div');
24240
+ nameAndLinksElement.classList.add('name-and-links');
24241
+ nameAndLinksElement.appendChild(nameElement);
24242
+ nameAndLinksElement.appendChild(viewLinkElement);
24243
+ nameAndLinksElement.appendChild(runLinkElement);
24214
24244
 
24215
24245
  const descriptionElement = document.createElement('p');
24216
24246
  descriptionElement.innerText = file.description;
24247
+
24248
+ const divElement = document.createElement('div');
24249
+ divElement.classList.add('saved-list-item');
24250
+ divElement.appendChild(nameAndLinksElement);
24217
24251
  divElement.appendChild(descriptionElement);
24218
24252
 
24219
24253
  savedElement.appendChild(divElement);
@@ -24235,7 +24269,7 @@
24235
24269
  let sql = getValue().trim();
24236
24270
  sql = sql === '' ? null : sql;
24237
24271
 
24238
- url.searchParams.delete('run');
24272
+ url.searchParams.set('run', 'true');
24239
24273
 
24240
24274
  if (url.searchParams.has('file')) {
24241
24275
  if (window.metadata.saved[url.searchParams.get('file')].contents !== getValue()) {
@@ -24263,22 +24297,25 @@
24263
24297
  url.searchParams.delete('selection');
24264
24298
  url.searchParams.delete('sql');
24265
24299
  url.searchParams.delete('file');
24300
+ url.searchParams.delete('run');
24266
24301
  }
24267
24302
 
24268
24303
  route(target, event, url);
24269
24304
  }
24270
24305
 
24271
24306
  function clearResult () {
24272
- clearGraphStatus();
24273
- clearResultStatus();
24274
- clearGraphBox();
24275
- clearResultBox();
24276
- const existingRequest = window.sqlFetch;
24277
- if (existingRequest?.state === 'pending') {
24278
- existingRequest.state = 'aborted';
24279
- existingRequest.fetchController.abort();
24307
+ const existingFetch = window.sqlFetch;
24308
+ if (existingFetch?.state === 'pending') {
24309
+ existingFetch.state = 'aborted';
24310
+ existingFetch.fetchController.abort();
24280
24311
  }
24281
24312
  window.sqlFetch = null;
24313
+
24314
+ clearGraphBox();
24315
+ clearGraphStatus();
24316
+
24317
+ clearResultBox();
24318
+ clearResultStatus();
24282
24319
  }
24283
24320
 
24284
24321
  function clearResultStatus () {
@@ -24303,7 +24340,7 @@
24303
24340
  }
24304
24341
  }
24305
24342
 
24306
- function fetchSql (request, selection, callback) {
24343
+ function fetchSql (sqlFetch, selection, callback) {
24307
24344
  fetch('query', {
24308
24345
  headers: {
24309
24346
  Accept: 'application/json',
@@ -24311,64 +24348,65 @@
24311
24348
  },
24312
24349
  method: 'POST',
24313
24350
  body: JSON.stringify({
24314
- sql: request.sql,
24351
+ sql: sqlFetch.sql,
24315
24352
  selection
24316
24353
  }),
24317
- signal: request.fetchController.signal
24354
+ signal: sqlFetch.fetchController.signal
24318
24355
  })
24319
24356
  .then((response) => {
24320
24357
  const contentType = response.headers.get('content-type');
24321
24358
  if (contentType && contentType.indexOf('application/json') !== -1) {
24322
24359
  response.json().then((result) => {
24323
24360
  if (result?.query) {
24324
- request.state = 'success';
24325
- request.result = result;
24361
+ sqlFetch.state = 'success';
24362
+ sqlFetch.result = result;
24326
24363
  } else {
24327
- request.state = 'error';
24364
+ sqlFetch.state = 'error';
24328
24365
  if (result?.error) {
24329
- request.error_message = result.error;
24330
- request.error_details = result.stacktrace;
24366
+ sqlFetch.error_message = result.error;
24367
+ sqlFetch.error_details = result.stacktrace;
24331
24368
  } else if (result) {
24332
- request.error_message = 'failed to execute query';
24333
- request.error_details = result.toString();
24369
+ sqlFetch.error_message = 'failed to execute query';
24370
+ sqlFetch.error_details = result.toString();
24334
24371
  } else {
24335
- request.error_message = 'failed to execute query';
24372
+ sqlFetch.error_message = 'failed to execute query';
24336
24373
  }
24337
24374
  }
24338
- callback(request);
24375
+ callback(sqlFetch);
24339
24376
  });
24340
24377
  } else {
24341
24378
  response.text().then((result) => {
24342
- request.state = 'error';
24343
- request.error_message = 'failed to execute query';
24344
- request.error_details = result;
24345
- callback(request);
24379
+ sqlFetch.state = 'error';
24380
+ sqlFetch.error_message = 'failed to execute query';
24381
+ sqlFetch.error_details = result;
24382
+ callback(sqlFetch);
24346
24383
  });
24347
24384
  }
24348
24385
  })
24349
24386
  .catch(function (error) {
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);
24387
+ if (sqlFetch.state === 'pending') {
24388
+ sqlFetch.state = 'error';
24389
+ sqlFetch.error_message = 'failed to execute query';
24390
+ sqlFetch.error_details = error;
24355
24391
  }
24392
+ callback(sqlFetch);
24356
24393
  });
24357
24394
  }
24358
24395
 
24359
24396
  function maybeFetchResult () {
24360
- const params = new URLSearchParams(window.location.search);
24397
+ const url = new URL(window.location);
24398
+ const params = url.searchParams;
24361
24399
  const sql = params.get('sql');
24362
24400
  const file = params.get('file');
24363
24401
  const selection = params.get('selection');
24364
- const run = !params.has('run') || !['0', 'false'].includes(params.get('run').toLowerCase());
24402
+ const run = ['1', 'true'].includes(params.get('run')?.toLowerCase());
24365
24403
 
24366
24404
  if (params.has('file') && params.has('sql')) {
24367
24405
  // TODO: show an error.
24368
24406
  throw new Error('You can only specify a file or sql, not both.')
24369
24407
  }
24370
24408
 
24371
- const request = {
24409
+ const sqlFetch = {
24372
24410
  fetchController: new AbortController(),
24373
24411
  state: 'pending',
24374
24412
  sql,
@@ -24381,10 +24419,10 @@
24381
24419
  if (!fileDetails) {
24382
24420
  throw new Error(`no such file: ${params.get('file')}`)
24383
24421
  }
24384
- request.file = file;
24385
- request.sql = fileDetails.contents;
24422
+ sqlFetch.file = file;
24423
+ sqlFetch.sql = fileDetails.contents;
24386
24424
  } else if (params.has('sql')) {
24387
- request.sql = sql;
24425
+ sqlFetch.sql = sql;
24388
24426
  }
24389
24427
 
24390
24428
  const existingRequest = window.sqlFetch;
@@ -24406,11 +24444,13 @@
24406
24444
  clearResult();
24407
24445
 
24408
24446
  if (params.has('sql') || params.has('file')) {
24409
- setValue(request.sql);
24447
+ setValue(sqlFetch.sql);
24410
24448
  if (run) {
24411
- window.sqlFetch = request;
24412
- displaySqlFetch(request);
24413
- fetchSql(request, selection, displaySqlFetch);
24449
+ url.searchParams.delete('run');
24450
+ window.history.replaceState({}, '', url);
24451
+ window.sqlFetch = sqlFetch;
24452
+ displaySqlFetch(sqlFetch);
24453
+ fetchSql(sqlFetch, selection, displaySqlFetch);
24414
24454
  }
24415
24455
  }
24416
24456
  if (params.has('selection')) {
@@ -24420,17 +24460,22 @@
24420
24460
  }
24421
24461
 
24422
24462
  function displaySqlFetchInResultTab (fetch) {
24423
- const fetchSqlBoxElement = document.getElementById('fetch-sql-box');
24424
- const resultBoxElement = document.getElementById('result-box');
24425
24463
  if (fetch.state === 'pending') {
24426
24464
  clearResultBox();
24427
- resultBoxElement.style.display = 'none';
24428
- fetchSqlBoxElement.style.display = 'flex';
24465
+ document.getElementById('cancel-button').style.display = 'flex';
24466
+ document.getElementById('result-box').style.display = 'none';
24467
+ document.getElementById('fetch-sql-box').style.display = 'flex';
24429
24468
  return
24430
24469
  }
24431
24470
 
24432
- resultBoxElement.style.display = 'flex';
24433
- fetchSqlBoxElement.style.display = 'none';
24471
+ document.getElementById('cancel-button').style.display = 'none';
24472
+ document.getElementById('fetch-sql-box').style.display = 'none';
24473
+ document.getElementById('result-box').style.display = 'flex';
24474
+
24475
+ if (fetch.state === 'aborted') {
24476
+ clearResultBox();
24477
+ return
24478
+ }
24434
24479
 
24435
24480
  if (fetch.state === 'error') {
24436
24481
  clearResultBox();
@@ -24458,7 +24503,7 @@
24458
24503
  theadElement.appendChild(headerElement);
24459
24504
  tableElement.appendChild(theadElement);
24460
24505
  tableElement.appendChild(tbodyElement);
24461
- resultBoxElement.appendChild(tableElement);
24506
+ document.getElementById('result-box').appendChild(tableElement);
24462
24507
 
24463
24508
  fetch.result.columns.forEach(column => {
24464
24509
  const template = document.createElement('template');
@@ -24504,17 +24549,22 @@
24504
24549
  }
24505
24550
 
24506
24551
  function displaySqlFetchInGraphTab (fetch) {
24507
- const graphBoxElement = document.getElementById('graph-box');
24508
- const fetchSqlBoxElement = document.getElementById('fetch-sql-box');
24509
24552
  if (fetch.state === 'pending') {
24510
24553
  clearGraphBox();
24511
- graphBoxElement.style.display = 'none';
24512
- fetchSqlBoxElement.style.display = 'flex';
24554
+ document.getElementById('cancel-button').style.display = 'flex';
24555
+ document.getElementById('graph-box').style.display = 'none';
24556
+ document.getElementById('fetch-sql-box').style.display = 'flex';
24513
24557
  return
24514
24558
  }
24515
24559
 
24516
- graphBoxElement.style.display = 'flex';
24517
- fetchSqlBoxElement.style.display = 'none';
24560
+ document.getElementById('cancel-button').style.display = 'none';
24561
+ document.getElementById('fetch-sql-box').style.display = 'none';
24562
+ document.getElementById('graph-box').style.display = 'flex';
24563
+
24564
+ if (fetch.state === 'aborted') {
24565
+ clearGraphBox();
24566
+ return
24567
+ }
24518
24568
 
24519
24569
  if (fetch.state === 'error') {
24520
24570
  clearGraphBox();
@@ -24553,7 +24603,7 @@
24553
24603
  dataTable.addRow(rowValues);
24554
24604
  });
24555
24605
 
24556
- const chart = new google.visualization.LineChart(graphBoxElement);
24606
+ const chart = new google.visualization.LineChart(document.getElementById('graph-box'));
24557
24607
  const options = {
24558
24608
  hAxis: {
24559
24609
  title: fetch.result.columns[0]
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.25
4
+ version: 0.1.26
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-30 00:00:00.000000000 Z
11
+ date: 2022-10-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mysql2