sqlui 0.1.55 → 0.1.57
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 +4 -4
- data/.release-version +1 -1
- data/app/server.rb +37 -25
- data/app/sql_parser.rb +4 -0
- data/app/sqlui.rb +2 -2
- data/app/views/sqlui.erb +2 -0
- data/client/resources/sqlui.css +5 -10
- data/client/resources/sqlui.js +209 -157
- 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: be280a4fa679ca8aa39ad6dfd93705c85b87b54993cf4ea601fa6260978ae349
|
4
|
+
data.tar.gz: db66920d0dd4c222bc5f4626046d7305be478afb11a816fb5c450a09d97b7f2b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0f436e784f0ac4b187805ed276323a9e712a9f0aee3e5beb504971956abd5588e8e044a9495618e4be82f018b0c20d88f50a37d3d379fc6e2d08e6a962000a43
|
7
|
+
data.tar.gz: ed51e6754f145b23d184542bdbc97c76bbcd52d3bc17c0bbebb7c2adb0534486c097e9af379c453b2c16b6b850fbd7252f9b03e43df71962771e1e29f99d9a4a
|
data/.release-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.57
|
data/app/server.rb
CHANGED
@@ -138,13 +138,13 @@ class Server < Sinatra::Base
|
|
138
138
|
break client_error('missing sql') unless params[:sql]
|
139
139
|
|
140
140
|
variables = params[:variables] || {}
|
141
|
-
|
141
|
+
queries = find_selected_queries(params[:sql], params[:selection])
|
142
142
|
|
143
143
|
status 200
|
144
144
|
headers 'Content-Type' => 'application/json; charset=utf-8'
|
145
145
|
|
146
146
|
database.with_client do |client|
|
147
|
-
query_result = execute_query(client, variables,
|
147
|
+
query_result = execute_query(client, variables, queries)
|
148
148
|
stream do |out|
|
149
149
|
if query_result
|
150
150
|
json = <<~RES.chomp
|
@@ -159,7 +159,7 @@ class Server < Sinatra::Base
|
|
159
159
|
out << json
|
160
160
|
bytes = json.bytesize
|
161
161
|
query_result.each_with_index do |row, i|
|
162
|
-
json = "#{i.zero? ? '' : ','}\n #{row.to_json}"
|
162
|
+
json = "#{i.zero? ? '' : ','}\n #{row.map { |v| big_decimal_to_float(v) }.to_json}"
|
163
163
|
bytes += json.bytesize
|
164
164
|
break if i == Sqlui::MAX_ROWS || bytes > Sqlui::MAX_BYTES
|
165
165
|
|
@@ -191,7 +191,7 @@ class Server < Sinatra::Base
|
|
191
191
|
|
192
192
|
sql = Base64.decode64(params[:sql]).force_encoding('UTF-8')
|
193
193
|
variables = params.map { |k, v| k[0] == '_' ? [k, v] : nil }.compact.to_h
|
194
|
-
|
194
|
+
queries = find_selected_queries(sql, params[:selection])
|
195
195
|
|
196
196
|
content_type 'application/csv; charset=utf-8'
|
197
197
|
headers 'Cache-Control' => 'no-cache'
|
@@ -199,11 +199,11 @@ class Server < Sinatra::Base
|
|
199
199
|
status 200
|
200
200
|
|
201
201
|
database.with_client do |client|
|
202
|
-
query_result = execute_query(client, variables,
|
202
|
+
query_result = execute_query(client, variables, queries)
|
203
203
|
stream do |out|
|
204
204
|
out << CSV::Row.new(query_result.fields, query_result.fields, header_row: true).to_s.strip
|
205
205
|
query_result.each do |row|
|
206
|
-
out << "\n#{CSV::Row.new(query_result.fields, row).to_s.strip}"
|
206
|
+
out << "\n#{CSV::Row.new(query_result.fields, row.map { |v| big_decimal_to_float(v) }).to_s.strip}"
|
207
207
|
end
|
208
208
|
end
|
209
209
|
end
|
@@ -250,33 +250,45 @@ class Server < Sinatra::Base
|
|
250
250
|
body({ error: message, stacktrace: stacktrace }.compact.to_json)
|
251
251
|
end
|
252
252
|
|
253
|
-
def
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
end
|
253
|
+
def find_selected_queries(full_sql, selection)
|
254
|
+
if selection
|
255
|
+
if selection.include?('-')
|
256
|
+
# sort because the selection could be in either direction
|
257
|
+
selection = selection.split('-').map { |v| Integer(v) }.sort
|
258
|
+
else
|
259
|
+
selection = Integer(selection)
|
260
|
+
selection = [selection, selection]
|
261
|
+
end
|
263
262
|
|
264
|
-
|
265
|
-
|
263
|
+
if selection[0] == selection[1]
|
264
|
+
[SqlParser.find_statement_at_cursor(full_sql, selection[0])]
|
265
|
+
else
|
266
|
+
SqlParser.split(full_sql[selection[0], selection[1]])
|
267
|
+
end
|
266
268
|
else
|
267
|
-
full_sql
|
269
|
+
SqlParser.split(full_sql)
|
268
270
|
end
|
269
271
|
end
|
270
272
|
|
271
|
-
def execute_query(client, variables,
|
273
|
+
def execute_query(client, variables, queries)
|
272
274
|
variables.each do |name, value|
|
273
275
|
client.query("SET @#{name} = #{value};")
|
274
276
|
end
|
275
|
-
queries = if sql.include?(';')
|
276
|
-
sql.split(/(?<=;)/).map(&:strip).reject(&:empty?)
|
277
|
-
else
|
278
|
-
[sql]
|
279
|
-
end
|
280
277
|
queries.map { |current| client.query(current) }.last
|
281
278
|
end
|
279
|
+
|
280
|
+
def big_decimal_to_float(maybe_big_decimal)
|
281
|
+
# TODO: This BigDecimal thing needs some thought.
|
282
|
+
if maybe_big_decimal.is_a?(BigDecimal)
|
283
|
+
big_decimal_string = maybe_big_decimal.to_s('F')
|
284
|
+
float = maybe_big_decimal.to_f
|
285
|
+
if big_decimal_string == float.to_s
|
286
|
+
float
|
287
|
+
else
|
288
|
+
big_decimal_string
|
289
|
+
end
|
290
|
+
else
|
291
|
+
maybe_big_decimal
|
292
|
+
end
|
293
|
+
end
|
282
294
|
end
|
data/app/sql_parser.rb
CHANGED
data/app/sqlui.rb
CHANGED
@@ -6,8 +6,8 @@ require_relative 'version'
|
|
6
6
|
|
7
7
|
# Main entry point.
|
8
8
|
class Sqlui
|
9
|
-
MAX_ROWS =
|
10
|
-
MAX_BYTES = 10 * 1_024 * 1_024
|
9
|
+
MAX_ROWS = 50_000
|
10
|
+
MAX_BYTES = 10 * 1_024 * 1_024 # 10 MB
|
11
11
|
|
12
12
|
def initialize(config_file)
|
13
13
|
raise 'you must specify a configuration file' unless config_file
|
data/app/views/sqlui.erb
CHANGED
@@ -100,8 +100,10 @@
|
|
100
100
|
<div style="flex: 1;"></div>
|
101
101
|
<div id="pagination-box" class="tab-content-element">
|
102
102
|
<div id="page-count-box"></div>
|
103
|
+
<input id="first-button" class="pagination-button" type="button" value="First" />
|
103
104
|
<input id="prev-button" class="pagination-button" type="button" value="Prev" />
|
104
105
|
<input id="next-button" class="pagination-button" type="button" value="Next" />
|
106
|
+
<input id="last-button" class="pagination-button" type="button" value="Last" />
|
105
107
|
</div>
|
106
108
|
</div>
|
107
109
|
</div>
|
data/client/resources/sqlui.css
CHANGED
@@ -282,8 +282,6 @@ table {
|
|
282
282
|
border-spacing: 0;
|
283
283
|
color: #333;
|
284
284
|
font-size: 18px;
|
285
|
-
width: 100%;
|
286
|
-
table-layout: auto; /* Will be overridden if a column is resized. */
|
287
285
|
}
|
288
286
|
|
289
287
|
table td:last-child, table th:last-child {
|
@@ -296,6 +294,10 @@ td, th {
|
|
296
294
|
max-width: 500px;
|
297
295
|
}
|
298
296
|
|
297
|
+
td:last-child, th:last-child {
|
298
|
+
max-width: none;
|
299
|
+
}
|
300
|
+
|
299
301
|
td {
|
300
302
|
overflow: hidden;
|
301
303
|
text-overflow: ellipsis;
|
@@ -491,15 +493,8 @@ select {
|
|
491
493
|
font-size: 16px;
|
492
494
|
}
|
493
495
|
|
494
|
-
#next-button {
|
495
|
-
|
496
|
-
}
|
497
|
-
|
498
|
-
#prev-button {
|
499
|
-
margin: 0 10px;
|
500
|
-
}
|
501
|
-
|
502
496
|
.pagination-button {
|
497
|
+
margin: 0 10px;
|
503
498
|
cursor: pointer;
|
504
499
|
background: none;
|
505
500
|
color: #333;
|
data/client/resources/sqlui.js
CHANGED
@@ -24295,180 +24295,215 @@
|
|
24295
24295
|
return match ? match[1] : identifier
|
24296
24296
|
}
|
24297
24297
|
|
24298
|
-
|
24299
|
-
|
24300
|
-
|
24301
|
-
|
24302
|
-
|
24303
|
-
|
24304
|
-
|
24305
|
-
|
24298
|
+
class Drag {
|
24299
|
+
tableElement = null
|
24300
|
+
scrolled = null
|
24301
|
+
scrollOffset = null
|
24302
|
+
containerOffset = null
|
24303
|
+
containerWidth = null
|
24304
|
+
thElement = null
|
24305
|
+
colElement = null
|
24306
|
+
otherColsWidth = null
|
24307
|
+
lastColElement = null
|
24308
|
+
}
|
24309
|
+
|
24310
|
+
let drag = new Drag();
|
24306
24311
|
|
24307
24312
|
document.addEventListener('mousedown', (event) => {
|
24308
|
-
if (event.target.classList.contains('col-resizer'))
|
24309
|
-
|
24310
|
-
|
24311
|
-
|
24312
|
-
|
24313
|
-
|
24314
|
-
|
24315
|
-
const theadElement = trElement.parentElement;
|
24316
|
-
drag.tableElement = theadElement.parentElement;
|
24317
|
-
drag.containerElement = drag.tableElement.parentElement;
|
24318
|
-
drag.thElement = thElement;
|
24319
|
-
drag.colElement = document.getElementById(event.target.dataset.colId);
|
24320
|
-
|
24321
|
-
const colElements = Array.from(drag.colElement.parentElement.childNodes);
|
24322
|
-
drag.lastColElement = colElements[colElements.length - 1];
|
24323
|
-
drag.otherColWidths = [];
|
24324
|
-
for (let i = 0; i < colElements.length - 1; i++) {
|
24325
|
-
if (colElements[i] !== drag.colElement) {
|
24326
|
-
drag.otherColWidths.push(colElements[i].getBoundingClientRect().width);
|
24327
|
-
}
|
24328
|
-
}
|
24329
|
-
colElements.forEach((element) => {
|
24330
|
-
element.style.width = `${element.getBoundingClientRect().width}px`;
|
24331
|
-
});
|
24332
|
-
drag.tableElement.style.tableLayout = 'fixed';
|
24313
|
+
if (!event.target.classList.contains('col-resizer')) return
|
24314
|
+
|
24315
|
+
drag = new Drag();
|
24316
|
+
event.preventDefault();
|
24317
|
+
const thElement = event.target.parentElement.parentElement;
|
24318
|
+
if (thElement.tagName.toLowerCase() !== 'th') {
|
24319
|
+
throw new Error(`expected th element, found: ${thElement}`)
|
24333
24320
|
}
|
24321
|
+
const trElement = thElement.parentElement;
|
24322
|
+
const theadElement = trElement.parentElement;
|
24323
|
+
const tableElement = theadElement.parentElement;
|
24324
|
+
const containerElement = tableElement.parentElement;
|
24325
|
+
drag.tableElement = tableElement;
|
24326
|
+
drag.containerWidth = containerElement.clientWidth;
|
24327
|
+
drag.scrollOffset = containerElement.scrollLeft;
|
24328
|
+
drag.scrolled = drag.scrollOffset > 0;
|
24329
|
+
drag.containerOffset = containerElement.offsetLeft;
|
24330
|
+
drag.thElement = thElement;
|
24331
|
+
drag.colElement = tableElement.querySelector(`col[data-col-id=${event.target.dataset.colId}]`);
|
24332
|
+
|
24333
|
+
const colElements = Array.from(drag.colElement.parentElement.childNodes);
|
24334
|
+
drag.lastColElement = colElements[colElements.length - 1];
|
24335
|
+
drag.otherColsWidth = 0;
|
24336
|
+
for (let i = 0; i < colElements.length; i++) {
|
24337
|
+
if (colElements[i] !== drag.colElement && i !== (colElements.length - 1)) {
|
24338
|
+
drag.otherColsWidth += colElements[i].getBoundingClientRect().width;
|
24339
|
+
}
|
24340
|
+
colElements[i].style.width = `${colElements[i].getBoundingClientRect().width}px`;
|
24341
|
+
}
|
24342
|
+
tableElement.style.tableLayout = 'fixed';
|
24343
|
+
tableElement.style.width = `${tableElement.getBoundingClientRect().width}px`;
|
24334
24344
|
});
|
24335
24345
|
|
24336
24346
|
document.addEventListener('mouseup', (event) => {
|
24337
|
-
drag
|
24338
|
-
drag.tableElement = null;
|
24339
|
-
drag.thElement = null;
|
24340
|
-
drag.colElement = null;
|
24341
|
-
drag.otherColWidths = null;
|
24342
|
-
drag.lastColElement = null;
|
24347
|
+
drag = new Drag();
|
24343
24348
|
});
|
24344
24349
|
|
24345
24350
|
document.addEventListener('mousemove', (event) => {
|
24346
|
-
if (drag.colElement)
|
24347
|
-
|
24348
|
-
|
24349
|
-
|
24350
|
-
|
24351
|
-
|
24352
|
-
|
24353
|
-
|
24354
|
-
|
24355
|
-
drag.
|
24356
|
-
|
24357
|
-
|
24358
|
-
let remainingWidth;
|
24359
|
-
if (scrolled) {
|
24360
|
-
remainingWidth = (scrollOffset + drag.containerElement.clientWidth) - runningWidth;
|
24361
|
-
} else {
|
24362
|
-
remainingWidth = Math.max(10, drag.containerElement.clientWidth - runningWidth);
|
24363
|
-
}
|
24364
|
-
drag.lastColElement.style.width = `${remainingWidth}px`;
|
24365
|
-
runningWidth += remainingWidth;
|
24366
|
-
drag.tableElement.style.width = `${runningWidth}px`;
|
24351
|
+
if (!drag.colElement) return
|
24352
|
+
|
24353
|
+
const newColumnWidth = Math.max(0, drag.scrollOffset + (event.clientX - drag.containerOffset) - drag.thElement.offsetLeft);
|
24354
|
+
if (newColumnWidth < drag.colElement.getBoundingClientRect().width && newColumnWidth < 30) return
|
24355
|
+
|
24356
|
+
drag.colElement.style.width = `${newColumnWidth}px`;
|
24357
|
+
drag.tableElement.columnsWidth = newColumnWidth + drag.otherColsWidth;
|
24358
|
+
let lastColWidth;
|
24359
|
+
if (drag.scrolled) {
|
24360
|
+
lastColWidth = (drag.scrollOffset + drag.containerWidth) - (drag.tableElement.columnsWidth);
|
24361
|
+
} else {
|
24362
|
+
lastColWidth = Math.max(10, drag.containerWidth - (drag.tableElement.columnsWidth));
|
24367
24363
|
}
|
24364
|
+
drag.lastColElement.style.width = lastColWidth + 'px';
|
24365
|
+
drag.tableElement.style.width = (drag.otherColsWidth + newColumnWidth + lastColWidth) + 'px';
|
24368
24366
|
});
|
24369
24367
|
|
24370
|
-
|
24371
|
-
|
24372
|
-
|
24373
|
-
if (!rows) throw new Error('missing table rows')
|
24374
|
-
if (!id) throw new Error('missing table id')
|
24368
|
+
class ResizeTable extends HTMLTableElement {
|
24369
|
+
constructor (columns, rows, cellRenderer) {
|
24370
|
+
super();
|
24375
24371
|
|
24376
|
-
|
24377
|
-
|
24378
|
-
if (id) tableElement.id = id;
|
24372
|
+
this.columns = columns;
|
24373
|
+
this.cellRenderer = cellRenderer;
|
24379
24374
|
|
24380
|
-
|
24381
|
-
|
24375
|
+
this.style.tableLayout = 'auto';
|
24376
|
+
this.style.width = '100%';
|
24382
24377
|
|
24383
|
-
|
24384
|
-
|
24378
|
+
const colgroupElement = document.createElement('colgroup');
|
24379
|
+
this.appendChild(colgroupElement);
|
24385
24380
|
|
24386
|
-
|
24387
|
-
|
24381
|
+
const theadElement = document.createElement('thead');
|
24382
|
+
this.appendChild(theadElement);
|
24388
24383
|
|
24389
|
-
|
24390
|
-
|
24391
|
-
const headerElement = document.createElement('th');
|
24392
|
-
headerTrElement.appendChild(headerElement);
|
24384
|
+
const headerTrElement = document.createElement('tr');
|
24385
|
+
theadElement.appendChild(headerTrElement);
|
24393
24386
|
|
24394
|
-
|
24395
|
-
|
24396
|
-
|
24387
|
+
if (columns.length > 0) {
|
24388
|
+
const colElements = [];
|
24389
|
+
columns.forEach(function (column, index) {
|
24390
|
+
const headerElement = document.createElement('th');
|
24391
|
+
headerTrElement.appendChild(headerElement);
|
24397
24392
|
|
24398
|
-
|
24399
|
-
|
24400
|
-
|
24393
|
+
const contentWrapperElement = document.createElement('div');
|
24394
|
+
contentWrapperElement.classList.add('col-content-wrapper');
|
24395
|
+
headerElement.appendChild(contentWrapperElement);
|
24401
24396
|
|
24402
|
-
|
24403
|
-
|
24404
|
-
|
24405
|
-
nonLastColElements.push(colElement);
|
24397
|
+
const nameElement = document.createElement('div');
|
24398
|
+
nameElement.classList.add('col-name');
|
24399
|
+
contentWrapperElement.appendChild(nameElement);
|
24406
24400
|
|
24407
|
-
|
24408
|
-
|
24409
|
-
|
24410
|
-
|
24401
|
+
const colElement = document.createElement('col');
|
24402
|
+
colElement.dataset.colId = `col-${index}`;
|
24403
|
+
colgroupElement.appendChild(colElement);
|
24404
|
+
colElements.push(colElement);
|
24411
24405
|
|
24412
|
-
|
24413
|
-
|
24414
|
-
|
24415
|
-
|
24416
|
-
|
24417
|
-
|
24418
|
-
function resize () {
|
24419
|
-
let runningWidth = 0;
|
24420
|
-
const colElements = Array.from(tableElement.getElementsByTagName('col'));
|
24421
|
-
nonLastColElements.forEach((element, index) => {
|
24422
|
-
runningWidth += element.getBoundingClientRect().width;
|
24406
|
+
const resizerElement = document.createElement('div');
|
24407
|
+
resizerElement.classList.add('col-resizer');
|
24408
|
+
resizerElement.dataset.colId = colElement.dataset.colId;
|
24409
|
+
contentWrapperElement.appendChild(resizerElement);
|
24410
|
+
|
24411
|
+
nameElement.innerText = column;
|
24423
24412
|
});
|
24424
|
-
const remainingWidth = Math.max(10, containerElement.clientWidth - runningWidth);
|
24425
|
-
colElements[colElements.length - 1].style.width = `${remainingWidth}px`;
|
24426
|
-
runningWidth += remainingWidth;
|
24427
|
-
tableElement.style.width = `${runningWidth}px`;
|
24428
|
-
}
|
24429
24413
|
|
24430
|
-
|
24431
|
-
|
24414
|
+
headerTrElement.appendChild(document.createElement('th'));
|
24415
|
+
const lastColElement = document.createElement('col');
|
24416
|
+
lastColElement.style.width = '100%';
|
24417
|
+
colElements.push(lastColElement);
|
24432
24418
|
|
24433
|
-
|
24434
|
-
|
24435
|
-
|
24436
|
-
|
24437
|
-
|
24438
|
-
|
24439
|
-
|
24440
|
-
|
24441
|
-
colgroupElement.appendChild(lastColElement);
|
24419
|
+
const containerMutationObserver = new MutationObserver(function (mutationList, observer) {
|
24420
|
+
mutationList.forEach(function (mutation) {
|
24421
|
+
if (this.parentElement) {
|
24422
|
+
if (this.parentElement !== mutation.target) {
|
24423
|
+
throw new Error('Unexpected table parent')
|
24424
|
+
}
|
24425
|
+
return
|
24426
|
+
}
|
24442
24427
|
|
24443
|
-
|
24444
|
-
|
24445
|
-
|
24428
|
+
if (observer.resizeObserver) {
|
24429
|
+
observer.resizeObserver.unobserve(mutation.target);
|
24430
|
+
observer.resizeObserver = null;
|
24431
|
+
}
|
24432
|
+
observer.disconnect();
|
24433
|
+
}.bind(this));
|
24434
|
+
}.bind(this));
|
24446
24435
|
|
24447
|
-
|
24448
|
-
|
24449
|
-
|
24436
|
+
const tableResizeObserver = new ResizeObserver(function () {
|
24437
|
+
if (!this.parentElement) {
|
24438
|
+
this.observingContainer = false;
|
24439
|
+
return
|
24440
|
+
}
|
24441
|
+
if (this.observingContainer) {
|
24442
|
+
return
|
24443
|
+
}
|
24444
|
+
this.observingContainer = true;
|
24450
24445
|
|
24451
|
-
|
24452
|
-
|
24453
|
-
|
24454
|
-
|
24455
|
-
|
24446
|
+
const containerResizeObserver = new ResizeObserver(function () {
|
24447
|
+
if (this.style.tableLayout === 'auto') return
|
24448
|
+
if (this.parentElement.scrollLeft > 0) return
|
24449
|
+
if (!this.columnsWidth) throw new Error('columnsWidth not set')
|
24450
|
+
|
24451
|
+
const remainingWidth = Math.max(10, this.parentElement.clientWidth - this.columnsWidth);
|
24452
|
+
colElements.slice(-1)[0].style.width = `${remainingWidth}px`;
|
24453
|
+
this.style.width = `${this.columnsWidth + remainingWidth}px`;
|
24454
|
+
}.bind(this));
|
24455
|
+
containerResizeObserver.observe(this.parentElement);
|
24456
|
+
|
24457
|
+
containerMutationObserver.resizeObserver = containerResizeObserver;
|
24458
|
+
containerMutationObserver.containerElement = this.parentElement;
|
24459
|
+
console.log('observing');
|
24460
|
+
console.log(this.parentElement);
|
24461
|
+
containerMutationObserver.observe(this.parentElement, { childList: true });
|
24462
|
+
}.bind(this));
|
24463
|
+
tableResizeObserver.observe(this);
|
24464
|
+
|
24465
|
+
colgroupElement.appendChild(lastColElement);
|
24466
|
+
|
24467
|
+
this.updateTableBody(rows, cellRenderer);
|
24456
24468
|
}
|
24457
|
-
|
24458
|
-
|
24459
|
-
|
24460
|
-
|
24461
|
-
|
24462
|
-
|
24463
|
-
|
24464
|
-
|
24465
|
-
|
24469
|
+
}
|
24470
|
+
|
24471
|
+
updateTableBody (rows, cellRenderer) {
|
24472
|
+
this.style.tableLayout = 'auto';
|
24473
|
+
|
24474
|
+
if (this.tbodyElement) this.removeChild(this.tbodyElement);
|
24475
|
+
const tbodyElement = document.createElement('tbody');
|
24476
|
+
this.appendChild(tbodyElement);
|
24477
|
+
this.tbodyElement = tbodyElement;
|
24478
|
+
|
24479
|
+
let highlight = false;
|
24480
|
+
rows.forEach(function (row) {
|
24481
|
+
const rowElement = document.createElement('tr');
|
24482
|
+
if (highlight) {
|
24483
|
+
rowElement.classList.add('highlighted-row');
|
24466
24484
|
}
|
24485
|
+
highlight = !highlight;
|
24486
|
+
tbodyElement.appendChild(rowElement);
|
24487
|
+
row.forEach(function (value, index) {
|
24488
|
+
if (cellRenderer) {
|
24489
|
+
cellRenderer(rowElement, index, value);
|
24490
|
+
} else {
|
24491
|
+
const cellElement = document.createElement('td');
|
24492
|
+
cellElement.innerText = value;
|
24493
|
+
rowElement.appendChild(cellElement);
|
24494
|
+
}
|
24495
|
+
});
|
24496
|
+
rowElement.appendChild(document.createElement('td'));
|
24467
24497
|
});
|
24468
|
-
|
24469
|
-
|
24498
|
+
}
|
24499
|
+
|
24500
|
+
getTableBody () {
|
24501
|
+
return this.tbodyElement
|
24502
|
+
}
|
24470
24503
|
}
|
24471
24504
|
|
24505
|
+
customElements.define('resize-table', ResizeTable, { extends: 'table' });
|
24506
|
+
|
24472
24507
|
/* global google */
|
24473
24508
|
|
24474
24509
|
const PAGE_SIZE = 500;
|
@@ -24538,6 +24573,10 @@
|
|
24538
24573
|
copyTextToClipboard(toTsv(window.sqlFetch.result.columns, window.sqlFetch.result.rows));
|
24539
24574
|
}
|
24540
24575
|
});
|
24576
|
+
addClickListener(document.getElementById('first-button'), (event) => {
|
24577
|
+
window.sqlFetch.page = 0;
|
24578
|
+
displaySqlFetch(window.sqlFetch);
|
24579
|
+
});
|
24541
24580
|
addClickListener(document.getElementById('prev-button'), (event) => {
|
24542
24581
|
window.sqlFetch.page -= 1;
|
24543
24582
|
displaySqlFetch(window.sqlFetch);
|
@@ -24546,6 +24585,10 @@
|
|
24546
24585
|
window.sqlFetch.page += 1;
|
24547
24586
|
displaySqlFetch(window.sqlFetch);
|
24548
24587
|
});
|
24588
|
+
addClickListener(document.getElementById('last-button'), (event) => {
|
24589
|
+
window.sqlFetch.page = window.sqlFetch.pageCount - 1;
|
24590
|
+
displaySqlFetch(window.sqlFetch);
|
24591
|
+
});
|
24549
24592
|
addClickListener(document.getElementById('submit-dropdown-button-download-csv'), () => {
|
24550
24593
|
if (!window.sqlFetch?.result) return
|
24551
24594
|
|
@@ -24694,6 +24737,8 @@
|
|
24694
24737
|
selected.style.display = 'none';
|
24695
24738
|
});
|
24696
24739
|
|
24740
|
+
setStatus('');
|
24741
|
+
|
24697
24742
|
switch (window.tab) {
|
24698
24743
|
case 'query':
|
24699
24744
|
selectResultTab(internal);
|
@@ -24799,7 +24844,7 @@
|
|
24799
24844
|
cellElement.innerText = value;
|
24800
24845
|
rowElement.appendChild(cellElement);
|
24801
24846
|
};
|
24802
|
-
|
24847
|
+
columnsElement.appendChild(new ResizeTable(columns, rows, cellRenderer));
|
24803
24848
|
}
|
24804
24849
|
|
24805
24850
|
const indexEntries = Object.entries(table.indexes);
|
@@ -24825,7 +24870,7 @@
|
|
24825
24870
|
cellElement.innerText = value;
|
24826
24871
|
rowElement.appendChild(cellElement);
|
24827
24872
|
};
|
24828
|
-
|
24873
|
+
indexesElement.appendChild(new ResizeTable(columns, rows, cellRenderer));
|
24829
24874
|
}
|
24830
24875
|
});
|
24831
24876
|
window.structureLoaded = true;
|
@@ -25274,28 +25319,25 @@
|
|
25274
25319
|
|
25275
25320
|
displaySqlFetchResultStatus(fetch);
|
25276
25321
|
|
25277
|
-
const resultBody = document.querySelector('table[id="result-table"] > tbody');
|
25278
25322
|
const pageStart = fetch.page * fetch.pageSize;
|
25279
25323
|
const rows = fetch.result.rows.slice(pageStart, pageStart + fetch.pageSize);
|
25280
|
-
|
25324
|
+
|
25325
|
+
let tableElement = document.getElementById('result-table');
|
25326
|
+
if (tableElement) {
|
25327
|
+
const resultBody = tableElement.getTableBody();
|
25281
25328
|
if (resultBody.dataset.page === fetch.page) {
|
25282
25329
|
// Results already displayed.
|
25283
25330
|
return
|
25284
25331
|
}
|
25285
|
-
|
25286
|
-
createTableBody(rows, document.getElementById('result-table'), resultCellRenderer);
|
25332
|
+
tableElement.updateTableBody(rows, resultCellRenderer);
|
25287
25333
|
} else {
|
25288
25334
|
clearResultBox();
|
25289
|
-
|
25290
|
-
|
25291
|
-
|
25292
|
-
|
25293
|
-
'result-table',
|
25294
|
-
resultCellRenderer);
|
25335
|
+
const resultBoxElement = document.getElementById('result-box');
|
25336
|
+
tableElement = new ResizeTable(fetch.result.columns, rows, resultCellRenderer);
|
25337
|
+
tableElement.id = 'result-table';
|
25338
|
+
resultBoxElement.appendChild(tableElement);
|
25295
25339
|
}
|
25296
|
-
|
25297
|
-
.querySelector('table[id="result-table"] > tbody')
|
25298
|
-
.setAttribute('data-page', fetch.page);
|
25340
|
+
tableElement.setAttribute('data-page', fetch.page);
|
25299
25341
|
}
|
25300
25342
|
|
25301
25343
|
function disableDownloadButtons () {
|
@@ -25451,7 +25493,7 @@
|
|
25451
25493
|
}
|
25452
25494
|
|
25453
25495
|
if (result.total_rows > result.rows.length) {
|
25454
|
-
message += ` (truncated to ${result.rows.length})`;
|
25496
|
+
message += ` (truncated to ${result.rows.length.toLocaleString()})`;
|
25455
25497
|
}
|
25456
25498
|
setStatus(message);
|
25457
25499
|
|
@@ -25463,6 +25505,16 @@
|
|
25463
25505
|
document.getElementById('next-button').disabled = sqlFetch.page + 1 === sqlFetch.pageCount;
|
25464
25506
|
document.getElementById('prev-button').disabled = sqlFetch.page === 0;
|
25465
25507
|
}
|
25508
|
+
|
25509
|
+
if (sqlFetch.pageCount > 2) {
|
25510
|
+
document.getElementById('first-button').style.display = 'flex';
|
25511
|
+
document.getElementById('last-button').style.display = 'flex';
|
25512
|
+
document.getElementById('first-button').disabled = sqlFetch.page === 0;
|
25513
|
+
document.getElementById('last-button').disabled = sqlFetch.page === sqlFetch.pageCount - 1;
|
25514
|
+
} else {
|
25515
|
+
document.getElementById('last-button').style.display = 'none';
|
25516
|
+
document.getElementById('first-button').style.display = 'none';
|
25517
|
+
}
|
25466
25518
|
}
|
25467
25519
|
|
25468
25520
|
window.addEventListener('popstate', function (event) {
|
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.57
|
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-12-
|
11
|
+
date: 2022-12-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: airbrake
|