sqlui 0.1.25 → 0.1.27

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: 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