sqlui 0.1.19 → 0.1.20
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/.version +1 -1
- data/app/args.rb +33 -0
- data/app/database_config.rb +7 -7
- data/app/database_metadata.rb +116 -0
- data/app/deep.rb +58 -0
- data/app/mysql_types.rb +33 -0
- data/app/server.rb +124 -218
- data/app/sqlui.rb +36 -0
- data/app/sqlui_config.rb +11 -16
- data/bin/sqlui +3 -1
- data/client/resources/sqlui.css +263 -242
- data/client/resources/sqlui.html +8 -5
- data/client/resources/sqlui.js +166 -81
- metadata +7 -2
data/client/resources/sqlui.js
CHANGED
@@ -4150,7 +4150,7 @@ var sqlui = (function (exports) {
|
|
4150
4150
|
return name
|
4151
4151
|
}
|
4152
4152
|
|
4153
|
-
function getSelection(root) {
|
4153
|
+
function getSelection$1(root) {
|
4154
4154
|
let target;
|
4155
4155
|
// Browsers differ on whether shadow roots have a getSelection
|
4156
4156
|
// method. If it exists, use that, otherwise, call it on the
|
@@ -6773,7 +6773,7 @@ var sqlui = (function (exports) {
|
|
6773
6773
|
this.dom.blur();
|
6774
6774
|
this.dom.focus({ preventScroll: true });
|
6775
6775
|
}
|
6776
|
-
let rawSel = getSelection(this.view.root);
|
6776
|
+
let rawSel = getSelection$1(this.view.root);
|
6777
6777
|
if (!rawSel) ;
|
6778
6778
|
else if (main.empty) {
|
6779
6779
|
// Work around https://bugzilla.mozilla.org/show_bug.cgi?id=1612076
|
@@ -6822,7 +6822,7 @@ var sqlui = (function (exports) {
|
|
6822
6822
|
if (this.compositionDeco.size)
|
6823
6823
|
return;
|
6824
6824
|
let cursor = this.view.state.selection.main;
|
6825
|
-
let sel = getSelection(this.view.root);
|
6825
|
+
let sel = getSelection$1(this.view.root);
|
6826
6826
|
if (!sel || !cursor.empty || !cursor.assoc || !sel.modify)
|
6827
6827
|
return;
|
6828
6828
|
let line = LineView.find(this, cursor.head);
|
@@ -7763,7 +7763,7 @@ var sqlui = (function (exports) {
|
|
7763
7763
|
return false;
|
7764
7764
|
// On boundary clicks, check whether the coordinates are inside the
|
7765
7765
|
// selection's client rectangles
|
7766
|
-
let sel = getSelection(view.root);
|
7766
|
+
let sel = getSelection$1(view.root);
|
7767
7767
|
if (!sel || sel.rangeCount == 0)
|
7768
7768
|
return true;
|
7769
7769
|
let rects = sel.getRangeAt(0).getClientRects();
|
@@ -9998,7 +9998,7 @@ var sqlui = (function (exports) {
|
|
9998
9998
|
// https://github.com/codemirror/dev/issues/414
|
9999
9999
|
let range = browser.safari && view.root.nodeType == 11 &&
|
10000
10000
|
deepActiveElement(this.dom.ownerDocument) == this.dom &&
|
10001
|
-
safariSelectionRangeHack(this.view) || getSelection(view.root);
|
10001
|
+
safariSelectionRangeHack(this.view) || getSelection$1(view.root);
|
10002
10002
|
if (!range || this.selectionRange.eq(range))
|
10003
10003
|
return false;
|
10004
10004
|
let local = hasSelection(this.dom, range);
|
@@ -23850,7 +23850,7 @@ var sqlui = (function (exports) {
|
|
23850
23850
|
|
23851
23851
|
/* global google */
|
23852
23852
|
|
23853
|
-
function init (parent, onSubmit) {
|
23853
|
+
function init (parent, onSubmit, onShiftSubmit) {
|
23854
23854
|
const fixedHeightEditor = EditorView.theme({
|
23855
23855
|
'.cm-scroller': { height: '200px', overflow: 'auto', resize: 'vertical' }
|
23856
23856
|
});
|
@@ -23858,7 +23858,7 @@ var sqlui = (function (exports) {
|
|
23858
23858
|
state: EditorState.create({
|
23859
23859
|
extensions: [
|
23860
23860
|
keymap.of([
|
23861
|
-
{ key: 'Ctrl-Enter', run: onSubmit, preventDefault: true },
|
23861
|
+
{ key: 'Ctrl-Enter', run: onSubmit, preventDefault: true, shift: onShiftSubmit },
|
23862
23862
|
...defaultKeymap
|
23863
23863
|
]),
|
23864
23864
|
basicSetup,
|
@@ -23871,12 +23871,19 @@ var sqlui = (function (exports) {
|
|
23871
23871
|
});
|
23872
23872
|
}
|
23873
23873
|
|
23874
|
-
function
|
23875
|
-
return window.editorView.state.selection.main.
|
23874
|
+
function getSelection () {
|
23875
|
+
return [window.editorView.state.selection.main.from, window.editorView.state.selection.main.to]
|
23876
23876
|
}
|
23877
23877
|
|
23878
|
-
function
|
23879
|
-
window.editorView.dispatch(
|
23878
|
+
function setSelection (selection) {
|
23879
|
+
window.editorView.dispatch(
|
23880
|
+
{
|
23881
|
+
selection: {
|
23882
|
+
anchor: Math.min(selection[0], window.editorView.state.doc.length),
|
23883
|
+
head: Math.min(selection[1], window.editorView.state.doc.length)
|
23884
|
+
}
|
23885
|
+
}
|
23886
|
+
);
|
23880
23887
|
}
|
23881
23888
|
|
23882
23889
|
function focus () {
|
@@ -24067,7 +24074,9 @@ var sqlui = (function (exports) {
|
|
24067
24074
|
headerElement.innerText = columnName;
|
24068
24075
|
headerTrElement.appendChild(headerElement);
|
24069
24076
|
});
|
24070
|
-
|
24077
|
+
if (columns.length > 0) {
|
24078
|
+
headerTrElement.appendChild(document.createElement('th'));
|
24079
|
+
}
|
24071
24080
|
let highlight = false;
|
24072
24081
|
rows.forEach(function (row) {
|
24073
24082
|
const rowElement = document.createElement('tr');
|
@@ -24093,12 +24102,12 @@ var sqlui = (function (exports) {
|
|
24093
24102
|
|
24094
24103
|
google.charts.load('current', { packages: ['corechart', 'line'] });
|
24095
24104
|
google.charts.setOnLoadCallback(function () {
|
24096
|
-
loadQueryOrGraphTab(loadGraphResult);
|
24105
|
+
loadQueryOrGraphTab(loadGraphResult, queryErrorCallback('graph-status'));
|
24097
24106
|
});
|
24098
24107
|
|
24099
|
-
const
|
24108
|
+
const selection = getSelection();
|
24100
24109
|
focus();
|
24101
|
-
|
24110
|
+
setSelection(selection);
|
24102
24111
|
}
|
24103
24112
|
|
24104
24113
|
function selectQueryTab () {
|
@@ -24106,11 +24115,23 @@ var sqlui = (function (exports) {
|
|
24106
24115
|
selected.style.display = 'flex';
|
24107
24116
|
});
|
24108
24117
|
|
24109
|
-
const
|
24118
|
+
const selection = getSelection();
|
24110
24119
|
focus();
|
24111
|
-
|
24120
|
+
setSelection(selection);
|
24121
|
+
|
24122
|
+
loadQueryOrGraphTab(loadQueryResult, queryErrorCallback('query-status'));
|
24123
|
+
}
|
24112
24124
|
|
24113
|
-
|
24125
|
+
function queryErrorCallback (statusElementId) {
|
24126
|
+
const statusElement = document.getElementById(statusElementId);
|
24127
|
+
return function (message, error) {
|
24128
|
+
if (error) {
|
24129
|
+
console.log(`${message}\n${error}`);
|
24130
|
+
statusElement.innerText = `error: ${message} (check console)`;
|
24131
|
+
} else {
|
24132
|
+
statusElement.innerText = `error: ${message}`;
|
24133
|
+
}
|
24134
|
+
}
|
24114
24135
|
}
|
24115
24136
|
|
24116
24137
|
function selectSavedTab () {
|
@@ -24157,9 +24178,21 @@ var sqlui = (function (exports) {
|
|
24157
24178
|
window.savedLoaded = true;
|
24158
24179
|
}
|
24159
24180
|
|
24160
|
-
function
|
24181
|
+
function submitAll () {
|
24182
|
+
submit(null);
|
24183
|
+
}
|
24184
|
+
|
24185
|
+
function submitCurrent () {
|
24186
|
+
submit(getSelection());
|
24187
|
+
}
|
24188
|
+
|
24189
|
+
function submit (selection) {
|
24161
24190
|
const url = new URL(window.location);
|
24162
|
-
|
24191
|
+
if (selection) {
|
24192
|
+
url.searchParams.set('selection', selection.join(':'));
|
24193
|
+
} else {
|
24194
|
+
url.searchParams.delete('selection');
|
24195
|
+
}
|
24163
24196
|
|
24164
24197
|
let sql = getValue().trim();
|
24165
24198
|
sql = sql === '' ? null : sql;
|
@@ -24218,7 +24251,7 @@ var sqlui = (function (exports) {
|
|
24218
24251
|
}
|
24219
24252
|
}
|
24220
24253
|
|
24221
|
-
function fetchSql (sql,
|
24254
|
+
function fetchSql (sql, selection, successCallback, errorCallback) {
|
24222
24255
|
fetch('query', {
|
24223
24256
|
headers: {
|
24224
24257
|
Accept: 'application/json',
|
@@ -24227,40 +24260,69 @@ var sqlui = (function (exports) {
|
|
24227
24260
|
method: 'POST',
|
24228
24261
|
body: JSON.stringify({
|
24229
24262
|
sql,
|
24230
|
-
|
24263
|
+
selection
|
24231
24264
|
})
|
24232
24265
|
})
|
24233
|
-
.then((response) =>
|
24234
|
-
|
24266
|
+
.then((response) => {
|
24267
|
+
const contentType = response.headers.get('content-type');
|
24268
|
+
if (contentType && contentType.indexOf('application/json') !== -1) {
|
24269
|
+
response.json().then((result) => {
|
24270
|
+
if (result?.query) {
|
24271
|
+
successCallback(result);
|
24272
|
+
} else if (result?.error) {
|
24273
|
+
errorCallback(result.error, result.stacktrace);
|
24274
|
+
} else if (result) {
|
24275
|
+
errorCallback('failed to execute query', result.toString());
|
24276
|
+
} else {
|
24277
|
+
errorCallback('failed to execute query');
|
24278
|
+
}
|
24279
|
+
});
|
24280
|
+
} else {
|
24281
|
+
response.text().then((result) => {
|
24282
|
+
errorCallback('failed to execute query', result);
|
24283
|
+
});
|
24284
|
+
}
|
24285
|
+
})
|
24286
|
+
.catch(function (error) {
|
24287
|
+
errorCallback('failed to execute query', error.stack);
|
24288
|
+
});
|
24235
24289
|
}
|
24236
24290
|
|
24237
|
-
function fetchFile (name,
|
24291
|
+
function fetchFile (name, successCallback, errorCallback) {
|
24238
24292
|
fetch(`query_file?file=${name}`, {
|
24239
24293
|
headers: {
|
24240
24294
|
Accept: 'application/json'
|
24241
24295
|
},
|
24242
24296
|
method: 'GET'
|
24243
24297
|
})
|
24244
|
-
.then((response) =>
|
24245
|
-
|
24246
|
-
|
24247
|
-
|
24248
|
-
|
24249
|
-
|
24250
|
-
|
24251
|
-
|
24252
|
-
|
24253
|
-
|
24254
|
-
|
24255
|
-
|
24256
|
-
|
24298
|
+
.then((response) => {
|
24299
|
+
const contentType = response.headers.get('content-type');
|
24300
|
+
if (contentType && contentType.indexOf('application/json') !== -1) {
|
24301
|
+
response.json().then((result) => {
|
24302
|
+
if (result?.query) {
|
24303
|
+
successCallback(result);
|
24304
|
+
} else if (result?.error) {
|
24305
|
+
errorCallback(result.error, result.stacktrace);
|
24306
|
+
} else if (result) {
|
24307
|
+
errorCallback('failed to load file ', result.toString());
|
24308
|
+
} else {
|
24309
|
+
errorCallback('failed to load file');
|
24310
|
+
}
|
24311
|
+
});
|
24312
|
+
} else {
|
24313
|
+
errorCallback('failed to load file', response.toString());
|
24314
|
+
}
|
24315
|
+
})
|
24316
|
+
.catch(function (error) {
|
24317
|
+
errorCallback('failed to load file', error.stack);
|
24318
|
+
});
|
24257
24319
|
}
|
24258
24320
|
|
24259
|
-
function loadQueryOrGraphTab (callback) {
|
24321
|
+
function loadQueryOrGraphTab (callback, errorCallback) {
|
24260
24322
|
const params = new URLSearchParams(window.location.search);
|
24261
24323
|
const sql = params.get('sql');
|
24262
24324
|
const file = params.get('file');
|
24263
|
-
const
|
24325
|
+
const selection = params.has('selection') ? params.get('selection') : null;
|
24264
24326
|
|
24265
24327
|
if (params.has('sql') && window.result && sql === window.result.query) {
|
24266
24328
|
callback();
|
@@ -24270,7 +24332,7 @@ var sqlui = (function (exports) {
|
|
24270
24332
|
return
|
24271
24333
|
}
|
24272
24334
|
|
24273
|
-
if (params.has('file') && params.has('sql') &&
|
24335
|
+
if (params.has('file') && params.has('sql') && selection === window.result.selection) {
|
24274
24336
|
// TODO: show an error.
|
24275
24337
|
throw new Error('You can only specify a file or sql, not both.')
|
24276
24338
|
}
|
@@ -24279,24 +24341,21 @@ var sqlui = (function (exports) {
|
|
24279
24341
|
|
24280
24342
|
if (params.has('sql')) {
|
24281
24343
|
setValue(sql);
|
24282
|
-
|
24283
|
-
fetchSql(params.get('sql'), cursor, function (result) {
|
24344
|
+
fetchSql(params.get('sql'), selection, function (result) {
|
24284
24345
|
window.result = result;
|
24285
24346
|
callback();
|
24286
|
-
});
|
24347
|
+
}, errorCallback);
|
24287
24348
|
} else if (params.has('file')) {
|
24288
24349
|
setValue('');
|
24289
24350
|
fetchFile(file, function (result) {
|
24290
24351
|
window.result = result;
|
24291
|
-
|
24292
|
-
setValue(result.query);
|
24293
|
-
}
|
24352
|
+
setValue(result.query);
|
24294
24353
|
callback();
|
24295
|
-
});
|
24354
|
+
}, errorCallback);
|
24296
24355
|
}
|
24297
|
-
if (params.has('
|
24356
|
+
if (params.has('selection')) {
|
24298
24357
|
focus();
|
24299
|
-
|
24358
|
+
setSelection(params.get('selection').split(':'));
|
24300
24359
|
}
|
24301
24360
|
}
|
24302
24361
|
|
@@ -24308,9 +24367,9 @@ var sqlui = (function (exports) {
|
|
24308
24367
|
|
24309
24368
|
setQueryStatus(window.result);
|
24310
24369
|
|
24311
|
-
if (!window.result.rows) {
|
24312
|
-
|
24313
|
-
}
|
24370
|
+
// if (!window.result.rows) {
|
24371
|
+
// return
|
24372
|
+
// }
|
24314
24373
|
|
24315
24374
|
const tableElement = document.createElement('table');
|
24316
24375
|
const theadElement = document.createElement('thead');
|
@@ -24326,7 +24385,9 @@ var sqlui = (function (exports) {
|
|
24326
24385
|
template.innerHTML = `<th class="cell">${column}</th>`;
|
24327
24386
|
headerElement.appendChild(template.content.firstChild);
|
24328
24387
|
});
|
24329
|
-
|
24388
|
+
if (window.result.columns.length > 0) {
|
24389
|
+
headerElement.appendChild(document.createElement('th'));
|
24390
|
+
}
|
24330
24391
|
let highlight = false;
|
24331
24392
|
window.result.rows.forEach(function (row) {
|
24332
24393
|
const rowElement = document.createElement('tr');
|
@@ -24362,8 +24423,11 @@ var sqlui = (function (exports) {
|
|
24362
24423
|
|
24363
24424
|
window.result.rows.forEach((row) => {
|
24364
24425
|
const rowValues = row.map((value, index) => {
|
24365
|
-
if (window.result.column_types[index] === 'date') {
|
24426
|
+
if (window.result.column_types[index] === 'date' || window.result.column_types[index] === 'datetime') {
|
24366
24427
|
return new Date(value)
|
24428
|
+
} else if (window.result.column_types[index] === 'timeofday') {
|
24429
|
+
// TODO: This should be hour, minute, second, milliseconds
|
24430
|
+
return [0, 0, 0, 0]
|
24367
24431
|
} else {
|
24368
24432
|
return value
|
24369
24433
|
}
|
@@ -24387,13 +24451,6 @@ var sqlui = (function (exports) {
|
|
24387
24451
|
|
24388
24452
|
function setGraphStatus (result) {
|
24389
24453
|
const statusElement = document.getElementById('graph-status');
|
24390
|
-
if (!result.rows) {
|
24391
|
-
// TODO use a popup
|
24392
|
-
console.log('error parsing graph result');
|
24393
|
-
console.log(JSON.stringify(result, null, 2));
|
24394
|
-
statusElement.innerText = 'error, check console';
|
24395
|
-
return
|
24396
|
-
}
|
24397
24454
|
|
24398
24455
|
if (result.total_rows === 1) {
|
24399
24456
|
statusElement.innerText = `${result.total_rows} row`;
|
@@ -24408,13 +24465,6 @@ var sqlui = (function (exports) {
|
|
24408
24465
|
|
24409
24466
|
function setQueryStatus (result) {
|
24410
24467
|
const statusElement = document.getElementById('query-status');
|
24411
|
-
if (!result.rows) {
|
24412
|
-
// TODO use a popup
|
24413
|
-
console.log('error parsing query result');
|
24414
|
-
console.log(JSON.stringify(result, null, 2));
|
24415
|
-
statusElement.innerText = 'error, check console';
|
24416
|
-
return
|
24417
|
-
}
|
24418
24468
|
|
24419
24469
|
if (result.total_rows === 1) {
|
24420
24470
|
statusElement.innerText = `${result.total_rows} row`;
|
@@ -24447,23 +24497,58 @@ var sqlui = (function (exports) {
|
|
24447
24497
|
}
|
24448
24498
|
|
24449
24499
|
window.onload = function () {
|
24450
|
-
|
24451
|
-
|
24452
|
-
|
24453
|
-
|
24454
|
-
|
24455
|
-
|
24456
|
-
|
24457
|
-
|
24500
|
+
fetch('metadata', {
|
24501
|
+
headers: {
|
24502
|
+
Accept: 'application/json'
|
24503
|
+
},
|
24504
|
+
method: 'GET'
|
24505
|
+
})
|
24506
|
+
.then((response) => {
|
24507
|
+
const contentType = response.headers.get('content-type');
|
24508
|
+
if (contentType && contentType.indexOf('application/json') !== -1) {
|
24509
|
+
return response.json().then((result) => {
|
24510
|
+
if (result.error) {
|
24511
|
+
let error = `<pre>${result.error}`;
|
24512
|
+
if (result.stacktrace) {
|
24513
|
+
error += '\n' + result.stacktrace + '</pre>';
|
24514
|
+
}
|
24515
|
+
document.getElementById('loading-box').innerHTML = error;
|
24516
|
+
} else if (!result.server) {
|
24517
|
+
document.getElementById('loading-box').innerHTML = `
|
24518
|
+
<pre>
|
24519
|
+
error loading metadata, response:
|
24520
|
+
${JSON.stringify(result)}
|
24521
|
+
</pre>
|
24522
|
+
`;
|
24523
|
+
} else {
|
24524
|
+
window.metadata = result;
|
24525
|
+
document.getElementById('loading-box').style.display = 'none';
|
24526
|
+
document.getElementById('main-box').style.display = 'flex';
|
24527
|
+
document.getElementById('server-name').innerText = result.server;
|
24528
|
+
const queryElement = document.getElementById('query');
|
24458
24529
|
|
24459
|
-
|
24460
|
-
|
24530
|
+
init(queryElement, submitCurrent, submitAll);
|
24531
|
+
route();
|
24532
|
+
}
|
24533
|
+
})
|
24534
|
+
} else {
|
24535
|
+
console.log(response);
|
24536
|
+
document.getElementById('loading-box').style.display = 'flex';
|
24537
|
+
document.getElementById('main-box').style.display = 'none';
|
24538
|
+
document.getElementById('loading-box').innerHTML = `<pre>${response}</pre>`;
|
24539
|
+
}
|
24540
|
+
})
|
24541
|
+
.catch(function (error) {
|
24542
|
+
console.log(error);
|
24543
|
+
document.getElementById('loading-box').style.display = 'flex';
|
24544
|
+
document.getElementById('main-box').style.display = 'none';
|
24545
|
+
document.getElementById('loading-box').innerHTML = `<pre>${error.stack}</pre>`;
|
24461
24546
|
});
|
24462
|
-
route();
|
24463
|
-
});
|
24464
24547
|
};
|
24465
24548
|
|
24466
24549
|
exports.selectTab = selectTab;
|
24550
|
+
exports.submitAll = submitAll;
|
24551
|
+
exports.submitCurrent = submitCurrent;
|
24467
24552
|
|
24468
24553
|
return exports;
|
24469
24554
|
|
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.20
|
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-
|
11
|
+
date: 2022-10-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: mysql2
|
@@ -158,10 +158,15 @@ extensions: []
|
|
158
158
|
extra_rdoc_files: []
|
159
159
|
files:
|
160
160
|
- ".version"
|
161
|
+
- app/args.rb
|
161
162
|
- app/database_config.rb
|
163
|
+
- app/database_metadata.rb
|
164
|
+
- app/deep.rb
|
162
165
|
- app/environment.rb
|
166
|
+
- app/mysql_types.rb
|
163
167
|
- app/server.rb
|
164
168
|
- app/sql_parser.rb
|
169
|
+
- app/sqlui.rb
|
165
170
|
- app/sqlui_config.rb
|
166
171
|
- app/views/databases.erb
|
167
172
|
- bin/sqlui
|