sqlui 0.1.55 → 0.1.57
Sign up to get free protection for your applications and to get access to all the features.
- 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
|