sqlui 0.1.25 → 0.1.27

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 11963565427ad327b2fb3cf1eadb62f789b620c3b3de943f2a0b17f3be505356
4
- data.tar.gz: 1be9eaac08e81afba77f4c1f5581a78f8e4a73d007d9e29f0ca238c956d46a6b
3
+ metadata.gz: 50a8e5f8fde6faea1c434919376eff89ec0a66390bfaa19c3b048871b477cdcb
4
+ data.tar.gz: f0bff25248a68088654c1971c876dd7032692e2e861d9653e838423381e610ab
5
5
  SHA512:
6
- metadata.gz: 76fc95eeec60f207e1505b4d71d10e6bf329c94ddc42ca15edef83853ca6f74407b275f168f1a721c9b0d50507228dcb5aae5c4f2cb2fa54e46f1dbef79d05cb
7
- data.tar.gz: 06140f3797fb34a7fa869c484ef002e5310ceceeea87e57f0c6dd984f13c2a6d75c9dddab253bf64545fa9cd58a93cac41e476b8cb8ee9c7fe86f47b38af39a0
6
+ metadata.gz: b5f5cf0a9aef2e58418fd84bd573930b0e4cdf4d62959b1ea17b0ed1a29a1a0a9fa1b9f95c1e3df6c1447e5b942b5fcb3b7648ba36dc2cacae06d1c5e9ddb547
7
+ data.tar.gz: dd640abdff43a2ebe422b5e01c6656c8ebe38c13e16bd923f0276afdd2cde335d0fd0bd63c819327eaeef1797828c4c4f193b257b29e71b8fa88cd8ecfadaa33
data/.version CHANGED
@@ -1 +1 @@
1
- 0.1.25
1
+ 0.1.27
@@ -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);
@@ -24191,29 +24198,52 @@
24191
24198
  if (savedElement.children.length > 0) {
24192
24199
  return
24193
24200
  }
24194
-
24195
24201
  const saved = window.metadata.saved;
24196
- if (Object.keys(saved).length === 1) {
24197
- setSavedStatus('1 file');
24198
- } else {
24199
- setSavedStatus(`${saved.length} files`);
24200
- }
24202
+ const numFiles = Object.keys(saved).length;
24203
+ setSavedStatus(`${numFiles} file${numFiles === 1 ? '' : 's'}`);
24201
24204
  Object.values(saved).forEach(file => {
24202
- const divElement = document.createElement('div');
24203
- divElement.classList.add('saved-list-item');
24204
- divElement.addEventListener('click', function (event) {
24205
+ const viewUrl = new URL(window.location.origin + window.location.pathname);
24206
+ setTabInUrl(viewUrl, 'query');
24207
+ viewUrl.searchParams.set('file', file.filename);
24208
+
24209
+ const viewLinkElement = document.createElement('a');
24210
+ viewLinkElement.classList.add('view-link');
24211
+ viewLinkElement.innerText = 'view';
24212
+ viewLinkElement.href = viewUrl.pathname + viewUrl.search;
24213
+ viewLinkElement.addEventListener('click', function (event) {
24205
24214
  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);
24215
+ route(event.target, event, viewUrl);
24210
24216
  });
24217
+
24218
+ const runUrl = new URL(window.location.origin + window.location.pathname);
24219
+ setTabInUrl(runUrl, 'query');
24220
+ runUrl.searchParams.set('file', file.filename);
24221
+ runUrl.searchParams.set('run', 'true');
24222
+
24223
+ const runLinkElement = document.createElement('a');
24224
+ runLinkElement.classList.add('run-link');
24225
+ runLinkElement.innerText = 'run';
24226
+ runLinkElement.href = runUrl.pathname + runUrl.search;
24227
+ runLinkElement.addEventListener('click', function (event) {
24228
+ clearResult();
24229
+ route(event.target, event, runUrl);
24230
+ });
24231
+
24211
24232
  const nameElement = document.createElement('h2');
24212
24233
  nameElement.innerText = file.filename;
24213
- divElement.appendChild(nameElement);
24234
+
24235
+ const nameAndLinksElement = document.createElement('div');
24236
+ nameAndLinksElement.classList.add('name-and-links');
24237
+ nameAndLinksElement.appendChild(nameElement);
24238
+ nameAndLinksElement.appendChild(viewLinkElement);
24239
+ nameAndLinksElement.appendChild(runLinkElement);
24214
24240
 
24215
24241
  const descriptionElement = document.createElement('p');
24216
24242
  descriptionElement.innerText = file.description;
24243
+
24244
+ const divElement = document.createElement('div');
24245
+ divElement.classList.add('saved-list-item');
24246
+ divElement.appendChild(nameAndLinksElement);
24217
24247
  divElement.appendChild(descriptionElement);
24218
24248
 
24219
24249
  savedElement.appendChild(divElement);
@@ -24235,7 +24265,7 @@
24235
24265
  let sql = getValue().trim();
24236
24266
  sql = sql === '' ? null : sql;
24237
24267
 
24238
- url.searchParams.delete('run');
24268
+ url.searchParams.set('run', 'true');
24239
24269
 
24240
24270
  if (url.searchParams.has('file')) {
24241
24271
  if (window.metadata.saved[url.searchParams.get('file')].contents !== getValue()) {
@@ -24263,22 +24293,25 @@
24263
24293
  url.searchParams.delete('selection');
24264
24294
  url.searchParams.delete('sql');
24265
24295
  url.searchParams.delete('file');
24296
+ url.searchParams.delete('run');
24266
24297
  }
24267
24298
 
24268
24299
  route(target, event, url);
24269
24300
  }
24270
24301
 
24271
24302
  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();
24303
+ const existingFetch = window.sqlFetch;
24304
+ if (existingFetch?.state === 'pending') {
24305
+ existingFetch.state = 'aborted';
24306
+ existingFetch.fetchController.abort();
24280
24307
  }
24281
24308
  window.sqlFetch = null;
24309
+
24310
+ clearGraphBox();
24311
+ clearGraphStatus();
24312
+
24313
+ clearResultBox();
24314
+ clearResultStatus();
24282
24315
  }
24283
24316
 
24284
24317
  function clearResultStatus () {
@@ -24303,7 +24336,7 @@
24303
24336
  }
24304
24337
  }
24305
24338
 
24306
- function fetchSql (request, selection, callback) {
24339
+ function fetchSql (sqlFetch, selection, callback) {
24307
24340
  fetch('query', {
24308
24341
  headers: {
24309
24342
  Accept: 'application/json',
@@ -24311,64 +24344,65 @@
24311
24344
  },
24312
24345
  method: 'POST',
24313
24346
  body: JSON.stringify({
24314
- sql: request.sql,
24347
+ sql: sqlFetch.sql,
24315
24348
  selection
24316
24349
  }),
24317
- signal: request.fetchController.signal
24350
+ signal: sqlFetch.fetchController.signal
24318
24351
  })
24319
24352
  .then((response) => {
24320
24353
  const contentType = response.headers.get('content-type');
24321
24354
  if (contentType && contentType.indexOf('application/json') !== -1) {
24322
24355
  response.json().then((result) => {
24323
24356
  if (result?.query) {
24324
- request.state = 'success';
24325
- request.result = result;
24357
+ sqlFetch.state = 'success';
24358
+ sqlFetch.result = result;
24326
24359
  } else {
24327
- request.state = 'error';
24360
+ sqlFetch.state = 'error';
24328
24361
  if (result?.error) {
24329
- request.error_message = result.error;
24330
- request.error_details = result.stacktrace;
24362
+ sqlFetch.error_message = result.error;
24363
+ sqlFetch.error_details = result.stacktrace;
24331
24364
  } else if (result) {
24332
- request.error_message = 'failed to execute query';
24333
- request.error_details = result.toString();
24365
+ sqlFetch.error_message = 'failed to execute query';
24366
+ sqlFetch.error_details = result.toString();
24334
24367
  } else {
24335
- request.error_message = 'failed to execute query';
24368
+ sqlFetch.error_message = 'failed to execute query';
24336
24369
  }
24337
24370
  }
24338
- callback(request);
24371
+ callback(sqlFetch);
24339
24372
  });
24340
24373
  } else {
24341
24374
  response.text().then((result) => {
24342
- request.state = 'error';
24343
- request.error_message = 'failed to execute query';
24344
- request.error_details = result;
24345
- callback(request);
24375
+ sqlFetch.state = 'error';
24376
+ sqlFetch.error_message = 'failed to execute query';
24377
+ sqlFetch.error_details = result;
24378
+ callback(sqlFetch);
24346
24379
  });
24347
24380
  }
24348
24381
  })
24349
24382
  .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);
24383
+ if (sqlFetch.state === 'pending') {
24384
+ sqlFetch.state = 'error';
24385
+ sqlFetch.error_message = 'failed to execute query';
24386
+ sqlFetch.error_details = error;
24355
24387
  }
24388
+ callback(sqlFetch);
24356
24389
  });
24357
24390
  }
24358
24391
 
24359
24392
  function maybeFetchResult () {
24360
- const params = new URLSearchParams(window.location.search);
24393
+ const url = new URL(window.location);
24394
+ const params = url.searchParams;
24361
24395
  const sql = params.get('sql');
24362
24396
  const file = params.get('file');
24363
24397
  const selection = params.get('selection');
24364
- const run = !params.has('run') || !['0', 'false'].includes(params.get('run').toLowerCase());
24398
+ const run = ['1', 'true'].includes(params.get('run')?.toLowerCase());
24365
24399
 
24366
24400
  if (params.has('file') && params.has('sql')) {
24367
24401
  // TODO: show an error.
24368
24402
  throw new Error('You can only specify a file or sql, not both.')
24369
24403
  }
24370
24404
 
24371
- const request = {
24405
+ const sqlFetch = {
24372
24406
  fetchController: new AbortController(),
24373
24407
  state: 'pending',
24374
24408
  sql,
@@ -24381,10 +24415,10 @@
24381
24415
  if (!fileDetails) {
24382
24416
  throw new Error(`no such file: ${params.get('file')}`)
24383
24417
  }
24384
- request.file = file;
24385
- request.sql = fileDetails.contents;
24418
+ sqlFetch.file = file;
24419
+ sqlFetch.sql = fileDetails.contents;
24386
24420
  } else if (params.has('sql')) {
24387
- request.sql = sql;
24421
+ sqlFetch.sql = sql;
24388
24422
  }
24389
24423
 
24390
24424
  const existingRequest = window.sqlFetch;
@@ -24406,11 +24440,13 @@
24406
24440
  clearResult();
24407
24441
 
24408
24442
  if (params.has('sql') || params.has('file')) {
24409
- setValue(request.sql);
24443
+ setValue(sqlFetch.sql);
24410
24444
  if (run) {
24411
- window.sqlFetch = request;
24412
- displaySqlFetch(request);
24413
- fetchSql(request, selection, displaySqlFetch);
24445
+ url.searchParams.delete('run');
24446
+ window.history.replaceState({}, '', url);
24447
+ window.sqlFetch = sqlFetch;
24448
+ displaySqlFetch(sqlFetch);
24449
+ fetchSql(sqlFetch, selection, displaySqlFetch);
24414
24450
  }
24415
24451
  }
24416
24452
  if (params.has('selection')) {
@@ -24420,17 +24456,22 @@
24420
24456
  }
24421
24457
 
24422
24458
  function displaySqlFetchInResultTab (fetch) {
24423
- const fetchSqlBoxElement = document.getElementById('fetch-sql-box');
24424
- const resultBoxElement = document.getElementById('result-box');
24425
24459
  if (fetch.state === 'pending') {
24426
24460
  clearResultBox();
24427
- resultBoxElement.style.display = 'none';
24428
- fetchSqlBoxElement.style.display = 'flex';
24461
+ document.getElementById('cancel-button').style.display = 'flex';
24462
+ document.getElementById('result-box').style.display = 'none';
24463
+ document.getElementById('fetch-sql-box').style.display = 'flex';
24429
24464
  return
24430
24465
  }
24431
24466
 
24432
- resultBoxElement.style.display = 'flex';
24433
- fetchSqlBoxElement.style.display = 'none';
24467
+ document.getElementById('cancel-button').style.display = 'none';
24468
+ document.getElementById('fetch-sql-box').style.display = 'none';
24469
+ document.getElementById('result-box').style.display = 'flex';
24470
+
24471
+ if (fetch.state === 'aborted') {
24472
+ clearResultBox();
24473
+ return
24474
+ }
24434
24475
 
24435
24476
  if (fetch.state === 'error') {
24436
24477
  clearResultBox();
@@ -24458,7 +24499,7 @@
24458
24499
  theadElement.appendChild(headerElement);
24459
24500
  tableElement.appendChild(theadElement);
24460
24501
  tableElement.appendChild(tbodyElement);
24461
- resultBoxElement.appendChild(tableElement);
24502
+ document.getElementById('result-box').appendChild(tableElement);
24462
24503
 
24463
24504
  fetch.result.columns.forEach(column => {
24464
24505
  const template = document.createElement('template');
@@ -24504,17 +24545,22 @@
24504
24545
  }
24505
24546
 
24506
24547
  function displaySqlFetchInGraphTab (fetch) {
24507
- const graphBoxElement = document.getElementById('graph-box');
24508
- const fetchSqlBoxElement = document.getElementById('fetch-sql-box');
24509
24548
  if (fetch.state === 'pending') {
24510
24549
  clearGraphBox();
24511
- graphBoxElement.style.display = 'none';
24512
- fetchSqlBoxElement.style.display = 'flex';
24550
+ document.getElementById('cancel-button').style.display = 'flex';
24551
+ document.getElementById('graph-box').style.display = 'none';
24552
+ document.getElementById('fetch-sql-box').style.display = 'flex';
24513
24553
  return
24514
24554
  }
24515
24555
 
24516
- graphBoxElement.style.display = 'flex';
24517
- fetchSqlBoxElement.style.display = 'none';
24556
+ document.getElementById('cancel-button').style.display = 'none';
24557
+ document.getElementById('fetch-sql-box').style.display = 'none';
24558
+ document.getElementById('graph-box').style.display = 'flex';
24559
+
24560
+ if (fetch.state === 'aborted') {
24561
+ clearGraphBox();
24562
+ return
24563
+ }
24518
24564
 
24519
24565
  if (fetch.state === 'error') {
24520
24566
  clearGraphBox();
@@ -24553,7 +24599,7 @@
24553
24599
  dataTable.addRow(rowValues);
24554
24600
  });
24555
24601
 
24556
- const chart = new google.visualization.LineChart(graphBoxElement);
24602
+ const chart = new google.visualization.LineChart(document.getElementById('graph-box'));
24557
24603
  const options = {
24558
24604
  hAxis: {
24559
24605
  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.27
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