sqlui 0.1.31 → 0.1.32
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/server.rb +7 -8
- data/app/views/databases.erb +1 -0
- data/client/resources/sqlui.html +57 -56
- data/client/resources/sqlui.js +158 -113
- 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: 7e17fe02caa80d2ea8ff8a7fc85ed11f4127526aeaec4c80f99de5b2dc23c9fc
|
4
|
+
data.tar.gz: 03b85e9805bf65329a48ba2f25712982e73e52c6beacffe0f561f75097827194
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c93782f85fc36265a469a249446f60417463e8051af9f54b401d501090c03ce5b226deb0a1999148e4bcdd2ca89ccc15f906c4d8705e305da069cdd49844f5a1
|
7
|
+
data.tar.gz: 50f397871d5262dc1a9d7a555a5e3d233cf4d4e8b747200a8723905f0ef07bda390319353ebafa15b3a58f25849a82406b3c0f09131d7d4a8c303563f7a22f7a
|
data/.version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.32
|
data/app/server.rb
CHANGED
@@ -40,14 +40,14 @@ class Server < Sinatra::Base
|
|
40
40
|
get "#{database.url_path}/sqlui.css" do
|
41
41
|
@css ||= File.read(File.join(resources_dir, 'sqlui.css'))
|
42
42
|
status 200
|
43
|
-
headers 'Content-Type' => 'text/css'
|
43
|
+
headers 'Content-Type' => 'text/css; charset=utf-8'
|
44
44
|
body @css
|
45
45
|
end
|
46
46
|
|
47
47
|
get "#{database.url_path}/sqlui.js" do
|
48
48
|
@js ||= File.read(File.join(resources_dir, 'sqlui.js'))
|
49
49
|
status 200
|
50
|
-
headers 'Content-Type' => 'text/javascript'
|
50
|
+
headers 'Content-Type' => 'text/javascript; charset=utf-8'
|
51
51
|
body @js
|
52
52
|
end
|
53
53
|
|
@@ -76,7 +76,7 @@ class Server < Sinatra::Base
|
|
76
76
|
}
|
77
77
|
end
|
78
78
|
status 200
|
79
|
-
headers 'Content-Type' => 'application/json'
|
79
|
+
headers 'Content-Type' => 'application/json; charset=utf-8'
|
80
80
|
body metadata.to_json
|
81
81
|
end
|
82
82
|
|
@@ -117,23 +117,22 @@ class Server < Sinatra::Base
|
|
117
117
|
result[:query] = full_sql
|
118
118
|
|
119
119
|
status 200
|
120
|
-
headers 'Content-Type' => 'application/json'
|
120
|
+
headers 'Content-Type' => 'application/json; charset=utf-8'
|
121
121
|
body result.to_json
|
122
122
|
end
|
123
123
|
|
124
124
|
get(%r{#{Regexp.escape(database.url_path)}/(query|graph|structure|saved)}) do
|
125
125
|
@html ||= File.read(File.join(resources_dir, 'sqlui.html'))
|
126
126
|
status 200
|
127
|
-
headers 'Content-Type' => 'text/html'
|
127
|
+
headers 'Content-Type' => 'text/html; charset=utf-8'
|
128
128
|
body @html
|
129
129
|
end
|
130
130
|
end
|
131
131
|
|
132
132
|
error do |e|
|
133
133
|
status 500
|
134
|
-
headers 'Content-Type' => 'application/json'
|
134
|
+
headers 'Content-Type' => 'application/json; charset=utf-8'
|
135
135
|
message = e.message.lines.first&.strip || 'unexpected error'
|
136
|
-
message = "#{message[0..80]}…" if message.length > 80
|
137
136
|
result = {
|
138
137
|
error: message,
|
139
138
|
stacktrace: e.backtrace.map { |b| b }.join("\n")
|
@@ -148,7 +147,7 @@ class Server < Sinatra::Base
|
|
148
147
|
|
149
148
|
def client_error(message, stacktrace: nil)
|
150
149
|
status(400)
|
151
|
-
headers 'Content-Type' => 'application/json'
|
150
|
+
headers 'Content-Type' => 'application/json; charset=utf-8'
|
152
151
|
body({ error: message, stacktrace: stacktrace }.compact.to_json)
|
153
152
|
end
|
154
153
|
|
data/app/views/databases.erb
CHANGED
data/client/resources/sqlui.html
CHANGED
@@ -1,70 +1,71 @@
|
|
1
|
-
<
|
1
|
+
<html lang="en">
|
2
|
+
<head>
|
3
|
+
<meta charset="utf-8">
|
4
|
+
<title>SQLUI</title>
|
5
|
+
<script src="sqlui.js"></script>
|
6
|
+
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
|
7
|
+
<link rel="stylesheet" href="sqlui.css">
|
8
|
+
</head>
|
2
9
|
|
3
|
-
<
|
4
|
-
|
5
|
-
<script src="sqlui.js"></script>
|
6
|
-
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
|
7
|
-
<link rel="stylesheet" href="sqlui.css">
|
8
|
-
</head>
|
9
|
-
|
10
|
-
<body>
|
11
|
-
<div id="loading-box" class="loading-box">
|
12
|
-
</div>
|
13
|
-
|
14
|
-
<div id="main-box" class="main-box" style="display:none">
|
15
|
-
<div class="tabs-box">
|
16
|
-
<h1 class="header"><a id="header-link">SQLUI</a></h1>
|
17
|
-
<h1 id="server-name" class="server-name"></h1>
|
18
|
-
<a id="query-tab-button" class="tab-button">Query</a>
|
19
|
-
<a id="graph-tab-button" class="tab-button">Graph</a>
|
20
|
-
<a id="saved-tab-button" class="tab-button">Saved</a>
|
21
|
-
<a id="structure-tab-button" class="tab-button">Structure</a>
|
10
|
+
<body>
|
11
|
+
<div id="loading-box" class="loading-box">
|
22
12
|
</div>
|
23
13
|
|
24
|
-
<div id="
|
25
|
-
<div
|
26
|
-
|
14
|
+
<div id="main-box" class="main-box" style="display:none">
|
15
|
+
<div class="tabs-box">
|
16
|
+
<h1 class="header"><a id="header-link">SQLUI</a></h1>
|
17
|
+
<h1 id="server-name" class="server-name"></h1>
|
18
|
+
<a id="query-tab-button" class="tab-button">Query</a>
|
19
|
+
<a id="graph-tab-button" class="tab-button">Graph</a>
|
20
|
+
<a id="saved-tab-button" class="tab-button">Saved</a>
|
21
|
+
<a id="structure-tab-button" class="tab-button">Structure</a>
|
22
|
+
</div>
|
27
23
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
<input id="submit-current-button" class="submit-button" type="button" value="run selection (ctrl-enter)"></input>
|
32
|
-
<input id="submit-all-button" class="submit-button" type="button" value="run (ctrl-shift-enter)"></input>
|
33
|
-
</div>
|
24
|
+
<div id="query-box" class="query-box tab-content-element graph-element query-element" style="display: none;">
|
25
|
+
<div id="query" class="query"></div>
|
26
|
+
</div>
|
34
27
|
|
35
|
-
|
36
|
-
|
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>
|
31
|
+
<input id="submit-current-button" class="submit-button" type="button" value="run selection (ctrl-enter)"></input>
|
32
|
+
<input id="submit-all-button" class="submit-button" type="button" value="run (ctrl-shift-enter)"></input>
|
33
|
+
</div>
|
37
34
|
|
38
|
-
|
39
|
-
|
35
|
+
<div id="result-box" class="result-box tab-content-element query-element" style="display: none;">
|
36
|
+
</div>
|
40
37
|
|
41
|
-
|
42
|
-
|
43
|
-
<p id="result-time" class="result-time"></p>
|
44
|
-
</div>
|
38
|
+
<div id="graph-box" class="graph-box tab-content-element graph-element" style="display: none;">
|
39
|
+
</div>
|
45
40
|
|
46
|
-
|
47
|
-
|
41
|
+
<div id="fetch-sql-box" class="fetch-sql-box tab-content-element graph-element query-element" style="display: none;">
|
42
|
+
<div id="result-loader" class="loader"></div>
|
43
|
+
<p id="result-time" class="result-time"></p>
|
44
|
+
</div>
|
48
45
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
<
|
54
|
-
|
55
|
-
|
56
|
-
<
|
57
|
-
</
|
58
|
-
<div id="
|
46
|
+
<div id="saved-box" class="saved-box tab-content-element saved-element" style="display: none;">
|
47
|
+
</div>
|
48
|
+
|
49
|
+
<div id="structure-box" class="structure-box tab-content-element structure-element" style="display: none;">
|
50
|
+
<div style="display: flex; flex: 1; flex-direction: row; align-items: stretch;">
|
51
|
+
<select id="schemas" class="schemas" size="4">
|
52
|
+
</select>
|
53
|
+
<select id="tables" class="tables" size="4">
|
54
|
+
</select>
|
55
|
+
<div id="table-info" class="table-info">
|
56
|
+
<div id="columns" class="columns">
|
57
|
+
</div>
|
58
|
+
<div id="indexes" class="indexes">
|
59
|
+
</div>
|
59
60
|
</div>
|
60
61
|
</div>
|
61
62
|
</div>
|
62
|
-
</div>
|
63
63
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
64
|
+
<div id="status-box" class="status-box">
|
65
|
+
<div id="result-status" class="status tab-content-element query-element"></div>
|
66
|
+
<div id="graph-status" class="status tab-content-element graph-element"></div>
|
67
|
+
<div id="saved-status" class="status tab-content-element saved-element"></div>
|
68
|
+
</div>
|
68
69
|
</div>
|
69
|
-
</
|
70
|
-
</
|
70
|
+
</body>
|
71
|
+
</html>
|
data/client/resources/sqlui.js
CHANGED
@@ -15413,8 +15413,13 @@
|
|
15413
15413
|
The [language data](https://codemirror.net/6/docs/ref/#state.EditorState.languageDataAt) facet
|
15414
15414
|
used for this language.
|
15415
15415
|
*/
|
15416
|
-
data, parser, extraExtensions = []
|
15416
|
+
data, parser, extraExtensions = [],
|
15417
|
+
/**
|
15418
|
+
A language name.
|
15419
|
+
*/
|
15420
|
+
name = "") {
|
15417
15421
|
this.data = data;
|
15422
|
+
this.name = name;
|
15418
15423
|
// Kludge to define EditorState.tree as a debugging helper,
|
15419
15424
|
// without the EditorState package actually knowing about
|
15420
15425
|
// languages and lezer trees.
|
@@ -15502,8 +15507,8 @@
|
|
15502
15507
|
parsers.
|
15503
15508
|
*/
|
15504
15509
|
class LRLanguage extends Language {
|
15505
|
-
constructor(data, parser) {
|
15506
|
-
super(data, parser);
|
15510
|
+
constructor(data, parser, name) {
|
15511
|
+
super(data, parser, [], name);
|
15507
15512
|
this.parser = parser;
|
15508
15513
|
}
|
15509
15514
|
/**
|
@@ -15513,14 +15518,14 @@
|
|
15513
15518
|
let data = defineLanguageFacet(spec.languageData);
|
15514
15519
|
return new LRLanguage(data, spec.parser.configure({
|
15515
15520
|
props: [languageDataProp.add(type => type.isTop ? data : undefined)]
|
15516
|
-
}));
|
15521
|
+
}), spec.name);
|
15517
15522
|
}
|
15518
15523
|
/**
|
15519
15524
|
Create a new instance of this language with a reconfigured
|
15520
|
-
version of its parser.
|
15525
|
+
version of its parser and optionally a new name.
|
15521
15526
|
*/
|
15522
|
-
configure(options) {
|
15523
|
-
return new LRLanguage(this.data, this.parser.configure(options));
|
15527
|
+
configure(options, name) {
|
15528
|
+
return new LRLanguage(this.data, this.parser.configure(options), name || this.name);
|
15524
15529
|
}
|
15525
15530
|
get allowsNesting() { return this.parser.hasWrappers(); }
|
15526
15531
|
}
|
@@ -15821,14 +15826,14 @@
|
|
15821
15826
|
// state updates with parse work beyond the viewport.
|
15822
15827
|
let upto = this.context.treeLen == tr.startState.doc.length ? undefined
|
15823
15828
|
: Math.max(tr.changes.mapPos(this.context.treeLen), newCx.viewport.to);
|
15824
|
-
if (!newCx.work(20 /* Apply */, upto))
|
15829
|
+
if (!newCx.work(20 /* Work.Apply */, upto))
|
15825
15830
|
newCx.takeTree();
|
15826
15831
|
return new LanguageState(newCx);
|
15827
15832
|
}
|
15828
15833
|
static init(state) {
|
15829
|
-
let vpTo = Math.min(3000 /* InitViewport */, state.doc.length);
|
15834
|
+
let vpTo = Math.min(3000 /* Work.InitViewport */, state.doc.length);
|
15830
15835
|
let parseState = ParseContext.create(state.facet(language).parser, state, { from: 0, to: vpTo });
|
15831
|
-
if (!parseState.work(20 /* Apply */, vpTo))
|
15836
|
+
if (!parseState.work(20 /* Work.Apply */, vpTo))
|
15832
15837
|
parseState.takeTree();
|
15833
15838
|
return new LanguageState(parseState);
|
15834
15839
|
}
|
@@ -15845,14 +15850,14 @@
|
|
15845
15850
|
}
|
15846
15851
|
});
|
15847
15852
|
let requestIdle = (callback) => {
|
15848
|
-
let timeout = setTimeout(() => callback(), 500 /* MaxPause */);
|
15853
|
+
let timeout = setTimeout(() => callback(), 500 /* Work.MaxPause */);
|
15849
15854
|
return () => clearTimeout(timeout);
|
15850
15855
|
};
|
15851
15856
|
if (typeof requestIdleCallback != "undefined")
|
15852
15857
|
requestIdle = (callback) => {
|
15853
15858
|
let idle = -1, timeout = setTimeout(() => {
|
15854
|
-
idle = requestIdleCallback(callback, { timeout: 500 /* MaxPause */ - 100 /* MinPause */ });
|
15855
|
-
}, 100 /* MinPause */);
|
15859
|
+
idle = requestIdleCallback(callback, { timeout: 500 /* Work.MaxPause */ - 100 /* Work.MinPause */ });
|
15860
|
+
}, 100 /* Work.MinPause */);
|
15856
15861
|
return () => idle < 0 ? clearTimeout(timeout) : cancelIdleCallback(idle);
|
15857
15862
|
};
|
15858
15863
|
const isInputPending = typeof navigator != "undefined" && ((_a = navigator.scheduling) === null || _a === void 0 ? void 0 : _a.isInputPending)
|
@@ -15875,7 +15880,7 @@
|
|
15875
15880
|
this.scheduleWork();
|
15876
15881
|
if (update.docChanged) {
|
15877
15882
|
if (this.view.hasFocus)
|
15878
|
-
this.chunkBudget += 50 /* ChangeBonus */;
|
15883
|
+
this.chunkBudget += 50 /* Work.ChangeBonus */;
|
15879
15884
|
this.scheduleWork();
|
15880
15885
|
}
|
15881
15886
|
this.checkAsyncSchedule(cx);
|
@@ -15891,19 +15896,19 @@
|
|
15891
15896
|
this.working = null;
|
15892
15897
|
let now = Date.now();
|
15893
15898
|
if (this.chunkEnd < now && (this.chunkEnd < 0 || this.view.hasFocus)) { // Start a new chunk
|
15894
|
-
this.chunkEnd = now + 30000 /* ChunkTime */;
|
15895
|
-
this.chunkBudget = 3000 /* ChunkBudget */;
|
15899
|
+
this.chunkEnd = now + 30000 /* Work.ChunkTime */;
|
15900
|
+
this.chunkBudget = 3000 /* Work.ChunkBudget */;
|
15896
15901
|
}
|
15897
15902
|
if (this.chunkBudget <= 0)
|
15898
15903
|
return; // No more budget
|
15899
15904
|
let { state, viewport: { to: vpTo } } = this.view, field = state.field(Language.state);
|
15900
|
-
if (field.tree == field.context.tree && field.context.isDone(vpTo + 100000 /* MaxParseAhead */))
|
15905
|
+
if (field.tree == field.context.tree && field.context.isDone(vpTo + 100000 /* Work.MaxParseAhead */))
|
15901
15906
|
return;
|
15902
|
-
let endTime = Date.now() + Math.min(this.chunkBudget, 100 /* Slice */, deadline && !isInputPending ? Math.max(25 /* MinSlice */, deadline.timeRemaining() - 5) : 1e9);
|
15907
|
+
let endTime = Date.now() + Math.min(this.chunkBudget, 100 /* Work.Slice */, deadline && !isInputPending ? Math.max(25 /* Work.MinSlice */, deadline.timeRemaining() - 5) : 1e9);
|
15903
15908
|
let viewportFirst = field.context.treeLen < vpTo && state.doc.length > vpTo + 1000;
|
15904
15909
|
let done = field.context.work(() => {
|
15905
15910
|
return isInputPending && isInputPending() || Date.now() > endTime;
|
15906
|
-
}, vpTo + (viewportFirst ? 0 : 100000 /* MaxParseAhead */));
|
15911
|
+
}, vpTo + (viewportFirst ? 0 : 100000 /* Work.MaxParseAhead */));
|
15907
15912
|
this.chunkBudget -= Date.now() - now;
|
15908
15913
|
if (done || this.chunkBudget <= 0) {
|
15909
15914
|
field.context.takeTree();
|
@@ -15941,7 +15946,14 @@
|
|
15941
15946
|
*/
|
15942
15947
|
const language = /*@__PURE__*/Facet.define({
|
15943
15948
|
combine(languages) { return languages.length ? languages[0] : null; },
|
15944
|
-
enables: [
|
15949
|
+
enables: language => [
|
15950
|
+
Language.state,
|
15951
|
+
parseWorker,
|
15952
|
+
EditorView.contentAttributes.compute([language], state => {
|
15953
|
+
let lang = state.facet(language);
|
15954
|
+
return lang && lang.name ? { "data-language": lang.name } : {};
|
15955
|
+
})
|
15956
|
+
]
|
15945
15957
|
});
|
15946
15958
|
/**
|
15947
15959
|
This class bundles a [language](https://codemirror.net/6/docs/ref/#language.Language) with an
|
@@ -15974,8 +15986,10 @@
|
|
15974
15986
|
|
15975
15987
|
/**
|
15976
15988
|
Facet that defines a way to provide a function that computes the
|
15977
|
-
appropriate indentation depth
|
15978
|
-
`
|
15989
|
+
appropriate indentation depth, as a column number (see
|
15990
|
+
[`indentString`](https://codemirror.net/6/docs/ref/#language.indentString)), at the start of a given
|
15991
|
+
line, or `null` to indicate no appropriate indentation could be
|
15992
|
+
determined.
|
15979
15993
|
*/
|
15980
15994
|
const indentService = /*@__PURE__*/Facet.define();
|
15981
15995
|
/**
|
@@ -16020,12 +16034,13 @@
|
|
16020
16034
|
return result;
|
16021
16035
|
}
|
16022
16036
|
/**
|
16023
|
-
Get the indentation at the given position.
|
16024
|
-
[indent services](https://codemirror.net/6/docs/ref/#language.indentService)
|
16025
|
-
and if none of those return an indentation,
|
16026
|
-
syntax tree for the [indent node
|
16027
|
-
and use that if found. Returns a
|
16028
|
-
be determined, and null
|
16037
|
+
Get the indentation, as a column number, at the given position.
|
16038
|
+
Will first consult any [indent services](https://codemirror.net/6/docs/ref/#language.indentService)
|
16039
|
+
that are registered, and if none of those return an indentation,
|
16040
|
+
this will check the syntax tree for the [indent node
|
16041
|
+
prop](https://codemirror.net/6/docs/ref/#language.indentNodeProp) and use that if found. Returns a
|
16042
|
+
number when an indentation could be determined, and null
|
16043
|
+
otherwise.
|
16029
16044
|
*/
|
16030
16045
|
function getIndentation(context, pos) {
|
16031
16046
|
if (context instanceof EditorState)
|
@@ -16135,8 +16150,9 @@
|
|
16135
16150
|
/**
|
16136
16151
|
A syntax tree node prop used to associate indentation strategies
|
16137
16152
|
with node types. Such a strategy is a function from an indentation
|
16138
|
-
context to a column number
|
16139
|
-
|
16153
|
+
context to a column number (see also
|
16154
|
+
[`indentString`](https://codemirror.net/6/docs/ref/#language.indentString)) or null, where null
|
16155
|
+
indicates that no definitive indentation can be determined.
|
16140
16156
|
*/
|
16141
16157
|
const indentNodeProp = /*@__PURE__*/new NodeProp();
|
16142
16158
|
// Compute the indentation for a given position from the syntax tree.
|
@@ -16692,7 +16708,12 @@
|
|
16692
16708
|
[tags](https://lezer.codemirror.net/docs/ref#highlight.Tag).
|
16693
16709
|
*/
|
16694
16710
|
class HighlightStyle {
|
16695
|
-
constructor(
|
16711
|
+
constructor(
|
16712
|
+
/**
|
16713
|
+
The tag styles used to create this highlight style.
|
16714
|
+
*/
|
16715
|
+
specs, options) {
|
16716
|
+
this.specs = specs;
|
16696
16717
|
let modSpec;
|
16697
16718
|
function def(spec) {
|
16698
16719
|
let cls = StyleModule.newName();
|
@@ -16703,7 +16724,7 @@
|
|
16703
16724
|
const scopeOpt = options.scope;
|
16704
16725
|
this.scope = scopeOpt instanceof Language ? (type) => type.prop(languageDataProp) == scopeOpt.data
|
16705
16726
|
: scopeOpt ? (type) => type == scopeOpt : undefined;
|
16706
|
-
this.style = tagHighlighter(
|
16727
|
+
this.style = tagHighlighter(specs.map(style => ({
|
16707
16728
|
tag: style.tag,
|
16708
16729
|
class: style.class || def(Object.assign({}, style, { tag: null }))
|
16709
16730
|
})), {
|
@@ -21577,74 +21598,6 @@
|
|
21577
21598
|
}
|
21578
21599
|
});
|
21579
21600
|
|
21580
|
-
// (The superfluous function calls around the list of extensions work
|
21581
|
-
// around current limitations in tree-shaking software.)
|
21582
|
-
/**
|
21583
|
-
This is an extension value that just pulls together a number of
|
21584
|
-
extensions that you might want in a basic editor. It is meant as a
|
21585
|
-
convenient helper to quickly set up CodeMirror without installing
|
21586
|
-
and importing a lot of separate packages.
|
21587
|
-
|
21588
|
-
Specifically, it includes...
|
21589
|
-
|
21590
|
-
- [the default command bindings](https://codemirror.net/6/docs/ref/#commands.defaultKeymap)
|
21591
|
-
- [line numbers](https://codemirror.net/6/docs/ref/#view.lineNumbers)
|
21592
|
-
- [special character highlighting](https://codemirror.net/6/docs/ref/#view.highlightSpecialChars)
|
21593
|
-
- [the undo history](https://codemirror.net/6/docs/ref/#commands.history)
|
21594
|
-
- [a fold gutter](https://codemirror.net/6/docs/ref/#language.foldGutter)
|
21595
|
-
- [custom selection drawing](https://codemirror.net/6/docs/ref/#view.drawSelection)
|
21596
|
-
- [drop cursor](https://codemirror.net/6/docs/ref/#view.dropCursor)
|
21597
|
-
- [multiple selections](https://codemirror.net/6/docs/ref/#state.EditorState^allowMultipleSelections)
|
21598
|
-
- [reindentation on input](https://codemirror.net/6/docs/ref/#language.indentOnInput)
|
21599
|
-
- [the default highlight style](https://codemirror.net/6/docs/ref/#language.defaultHighlightStyle) (as fallback)
|
21600
|
-
- [bracket matching](https://codemirror.net/6/docs/ref/#language.bracketMatching)
|
21601
|
-
- [bracket closing](https://codemirror.net/6/docs/ref/#autocomplete.closeBrackets)
|
21602
|
-
- [autocompletion](https://codemirror.net/6/docs/ref/#autocomplete.autocompletion)
|
21603
|
-
- [rectangular selection](https://codemirror.net/6/docs/ref/#view.rectangularSelection) and [crosshair cursor](https://codemirror.net/6/docs/ref/#view.crosshairCursor)
|
21604
|
-
- [active line highlighting](https://codemirror.net/6/docs/ref/#view.highlightActiveLine)
|
21605
|
-
- [active line gutter highlighting](https://codemirror.net/6/docs/ref/#view.highlightActiveLineGutter)
|
21606
|
-
- [selection match highlighting](https://codemirror.net/6/docs/ref/#search.highlightSelectionMatches)
|
21607
|
-
- [search](https://codemirror.net/6/docs/ref/#search.searchKeymap)
|
21608
|
-
- [linting](https://codemirror.net/6/docs/ref/#lint.lintKeymap)
|
21609
|
-
|
21610
|
-
(You'll probably want to add some language package to your setup
|
21611
|
-
too.)
|
21612
|
-
|
21613
|
-
This extension does not allow customization. The idea is that,
|
21614
|
-
once you decide you want to configure your editor more precisely,
|
21615
|
-
you take this package's source (which is just a bunch of imports
|
21616
|
-
and an array literal), copy it into your own code, and adjust it
|
21617
|
-
as desired.
|
21618
|
-
*/
|
21619
|
-
const basicSetup = /*@__PURE__*/(() => [
|
21620
|
-
lineNumbers(),
|
21621
|
-
highlightActiveLineGutter(),
|
21622
|
-
highlightSpecialChars(),
|
21623
|
-
history(),
|
21624
|
-
foldGutter(),
|
21625
|
-
drawSelection(),
|
21626
|
-
dropCursor(),
|
21627
|
-
EditorState.allowMultipleSelections.of(true),
|
21628
|
-
indentOnInput(),
|
21629
|
-
syntaxHighlighting(defaultHighlightStyle, { fallback: true }),
|
21630
|
-
bracketMatching(),
|
21631
|
-
closeBrackets(),
|
21632
|
-
autocompletion(),
|
21633
|
-
rectangularSelection(),
|
21634
|
-
crosshairCursor(),
|
21635
|
-
highlightActiveLine(),
|
21636
|
-
highlightSelectionMatches(),
|
21637
|
-
keymap.of([
|
21638
|
-
...closeBracketsKeymap,
|
21639
|
-
...defaultKeymap,
|
21640
|
-
...searchKeymap,
|
21641
|
-
...historyKeymap,
|
21642
|
-
...foldKeymap,
|
21643
|
-
...completionKeymap,
|
21644
|
-
...lintKeymap
|
21645
|
-
])
|
21646
|
-
])();
|
21647
|
-
|
21648
21601
|
/// A parse stack. These are used internally by the parser to track
|
21649
21602
|
/// parsing progress. They also provide some properties and methods
|
21650
21603
|
/// that external code such as a tokenizer can use to get information
|
@@ -23847,6 +23800,25 @@
|
|
23847
23800
|
The standard SQL dialect.
|
23848
23801
|
*/
|
23849
23802
|
const StandardSQL = /*@__PURE__*/SQLDialect.define({});
|
23803
|
+
const MySQLKeywords = "accessible algorithm analyze asensitive authors auto_increment autocommit avg avg_row_length binlog btree cache catalog_name chain change changed checkpoint checksum class_origin client_statistics coalesce code collations columns comment committed completion concurrent consistent contains contributors convert database databases day_hour day_microsecond day_minute day_second delay_key_write delayed delimiter des_key_file dev_pop dev_samp deviance directory disable discard distinctrow div dual dumpfile enable enclosed ends engine engines enum errors escaped even event events every explain extended fast field fields flush force found_rows fulltext grants handler hash high_priority hosts hour_microsecond hour_minute hour_second ignore ignore_server_ids import index index_statistics infile innodb insensitive insert_method install invoker iterate keys kill linear lines list load lock logs low_priority master master_heartbeat_period master_ssl_verify_server_cert masters max max_rows maxvalue message_text middleint migrate min min_rows minute_microsecond minute_second mod mode modify mutex mysql_errno no_write_to_binlog offline offset one online optimize optionally outfile pack_keys parser partition partitions password phase plugin plugins prev processlist profile profiles purge query quick range read_write rebuild recover regexp relaylog remove rename reorganize repair repeatable replace require resume rlike row_format rtree schedule schema_name schemas second_microsecond security sensitive separator serializable server share show slave slow snapshot soname spatial sql_big_result sql_buffer_result sql_cache sql_calc_found_rows sql_no_cache sql_small_result ssl starting starts std stddev stddev_pop stddev_samp storage straight_join subclass_origin sum suspend table_name table_statistics tables tablespace terminated triggers truncate uncommitted uninstall unlock upgrade use use_frm user_resources user_statistics utc_date utc_time utc_timestamp variables views warnings xa xor year_month zerofill";
|
23804
|
+
const MySQLTypes = SQLTypes + "bool blob long longblob longtext medium mediumblob mediumint mediumtext tinyblob tinyint tinytext text bigint int1 int2 int3 int4 int8 float4 float8 varbinary varcharacter precision datetime unsigned signed";
|
23805
|
+
const MySQLBuiltin = "charset clear edit ego help nopager notee nowarning pager print prompt quit rehash source status system tee";
|
23806
|
+
/**
|
23807
|
+
[MySQL](https://dev.mysql.com/) dialect.
|
23808
|
+
*/
|
23809
|
+
const MySQL = /*@__PURE__*/SQLDialect.define({
|
23810
|
+
operatorChars: "*+-%<>!=&|^",
|
23811
|
+
charSetCasts: true,
|
23812
|
+
doubleQuotedStrings: true,
|
23813
|
+
unquotedBitLiterals: true,
|
23814
|
+
hashComments: true,
|
23815
|
+
spaceAfterDashes: true,
|
23816
|
+
specialVar: "@?",
|
23817
|
+
identifierQuotes: "`",
|
23818
|
+
keywords: SQLKeywords + "group_concat " + MySQLKeywords,
|
23819
|
+
types: MySQLTypes,
|
23820
|
+
builtin: MySQLBuiltin
|
23821
|
+
});
|
23850
23822
|
|
23851
23823
|
/* global google */
|
23852
23824
|
|
@@ -23873,20 +23845,83 @@
|
|
23873
23845
|
clearResult();
|
23874
23846
|
});
|
23875
23847
|
|
23848
|
+
const isMac = navigator.userAgent.includes('Mac');
|
23849
|
+
document.getElementById('submit-current-button').value = `run selection (${isMac ? '⌘' : 'Ctrl'}-Shift-Enter)`;
|
23850
|
+
document.getElementById('submit-all-button').value = `run (${isMac ? '⌘' : 'Ctrl'}-Shift-Enter)`;
|
23851
|
+
|
23876
23852
|
const fixedHeightEditor = EditorView.theme({
|
23877
|
-
'.cm-scroller': {
|
23853
|
+
'.cm-scroller': {
|
23854
|
+
height: '200px',
|
23855
|
+
overflow: 'auto',
|
23856
|
+
resize: 'vertical'
|
23857
|
+
}
|
23858
|
+
});
|
23859
|
+
const schemas = Object.entries(window.metadata.schemas);
|
23860
|
+
const editorSchema = {};
|
23861
|
+
schemas.forEach(([schemaName, schema]) => {
|
23862
|
+
Object.entries(schema.tables).forEach(([tableName, table]) => {
|
23863
|
+
const qualifiedTableName = schemas.length === 1 ? tableName : `${schemaName}.${tableName}`;
|
23864
|
+
editorSchema[qualifiedTableName] = Object.keys(table.columns);
|
23865
|
+
});
|
23866
|
+
});
|
23867
|
+
// I prefer to use Cmd-Enter/Ctrl-Enter to submit the query. Here I am replacing the default mapping.
|
23868
|
+
// See https://codemirror.net/docs/ref/#commands.defaultKeymap
|
23869
|
+
// See https://github.com/codemirror/commands/blob/6aa9989f38fe3c7dbc9b72c5015a3db97370c07a/src/commands.ts#L891
|
23870
|
+
const customDefaultKeymap = defaultKeymap.map(keymap => {
|
23871
|
+
if (keymap.key === 'Mod-Enter') {
|
23872
|
+
keymap.key = 'Shift-Enter';
|
23873
|
+
}
|
23874
|
+
return keymap
|
23878
23875
|
});
|
23876
|
+
const editorKeymap = keymap.of([
|
23877
|
+
{
|
23878
|
+
key: 'Cmd-Enter',
|
23879
|
+
run: onSubmit,
|
23880
|
+
preventDefault: true,
|
23881
|
+
shift: onShiftSubmit
|
23882
|
+
},
|
23883
|
+
{
|
23884
|
+
key: 'Ctrl-Enter',
|
23885
|
+
run: onSubmit,
|
23886
|
+
preventDefault: true,
|
23887
|
+
shift: onShiftSubmit
|
23888
|
+
},
|
23889
|
+
...closeBracketsKeymap,
|
23890
|
+
...customDefaultKeymap,
|
23891
|
+
...searchKeymap,
|
23892
|
+
...historyKeymap,
|
23893
|
+
...foldKeymap,
|
23894
|
+
...completionKeymap,
|
23895
|
+
...lintKeymap
|
23896
|
+
]);
|
23879
23897
|
window.editorView = new EditorView({
|
23880
23898
|
state: EditorState.create({
|
23881
23899
|
extensions: [
|
23882
|
-
|
23883
|
-
|
23884
|
-
|
23885
|
-
|
23886
|
-
|
23887
|
-
|
23900
|
+
lineNumbers(),
|
23901
|
+
highlightActiveLineGutter(),
|
23902
|
+
highlightSpecialChars(),
|
23903
|
+
history(),
|
23904
|
+
foldGutter(),
|
23905
|
+
drawSelection(),
|
23906
|
+
dropCursor(),
|
23907
|
+
EditorState.allowMultipleSelections.of(true),
|
23908
|
+
indentOnInput(),
|
23909
|
+
syntaxHighlighting(defaultHighlightStyle, { fallback: true }),
|
23910
|
+
bracketMatching(),
|
23911
|
+
closeBrackets(),
|
23912
|
+
autocompletion(),
|
23913
|
+
rectangularSelection(),
|
23914
|
+
crosshairCursor(),
|
23915
|
+
highlightActiveLine(),
|
23916
|
+
highlightSelectionMatches(),
|
23917
|
+
editorKeymap,
|
23918
|
+
sql({
|
23919
|
+
dialect: MySQL,
|
23920
|
+
upperCaseKeywords: true,
|
23921
|
+
schema: editorSchema
|
23922
|
+
}),
|
23888
23923
|
fixedHeightEditor,
|
23889
|
-
placeholder('
|
23924
|
+
placeholder('Let\'s query!')
|
23890
23925
|
]
|
23891
23926
|
}),
|
23892
23927
|
parent
|
@@ -23914,7 +23949,12 @@
|
|
23914
23949
|
anchor = Math.min(parseInt(selection), window.editorView.state.doc.length);
|
23915
23950
|
head = anchor;
|
23916
23951
|
}
|
23917
|
-
window.editorView.dispatch({
|
23952
|
+
window.editorView.dispatch({
|
23953
|
+
selection: {
|
23954
|
+
anchor,
|
23955
|
+
head
|
23956
|
+
}
|
23957
|
+
});
|
23918
23958
|
}
|
23919
23959
|
|
23920
23960
|
function focus () {
|
@@ -24341,7 +24381,9 @@
|
|
24341
24381
|
if (window.sqlFetch === sqlFetch) {
|
24342
24382
|
if (sqlFetch.state === 'pending' || sqlFetch.spinner === 'always') {
|
24343
24383
|
displaySqlFetch(sqlFetch);
|
24344
|
-
setTimeout(() => {
|
24384
|
+
setTimeout(() => {
|
24385
|
+
updateResultTime(sqlFetch);
|
24386
|
+
}, 500);
|
24345
24387
|
}
|
24346
24388
|
}
|
24347
24389
|
}
|
@@ -24592,12 +24634,15 @@
|
|
24592
24634
|
|
24593
24635
|
function displaySqlFetchError (statusElementId, message, details) {
|
24594
24636
|
const statusElement = document.getElementById(statusElementId);
|
24637
|
+
let statusMessage = 'error: ' + message;
|
24638
|
+
if (statusMessage.length > 90) {
|
24639
|
+
statusMessage = statusMessage.substring(0, 90) + '…';
|
24640
|
+
}
|
24595
24641
|
if (details) {
|
24596
24642
|
console.log(`${message}\n${details}`);
|
24597
|
-
|
24598
|
-
} else {
|
24599
|
-
statusElement.innerText = `error: ${message}`;
|
24643
|
+
statusMessage += ' (check console)';
|
24600
24644
|
}
|
24645
|
+
statusElement.innerText = statusMessage;
|
24601
24646
|
}
|
24602
24647
|
|
24603
24648
|
function clearSpinner () {
|
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.32
|
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-11-
|
11
|
+
date: 2022-11-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: mysql2
|