sqlui 0.1.10 → 0.1.11
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.version +1 -0
- data/app/server.rb +90 -0
- data/{lib → app}/sqlui.rb +0 -0
- data/bin/sqlui +3 -0
- metadata +57 -14
- data/resources/sqlui.css +0 -242
- data/resources/sqlui.html +0 -60
- data/resources/sqlui.js +0 -24458
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7a45f24e10141554fd6a6e0422bc9494202ace1c83d2dfb2977acdadb1263cd8
|
4
|
+
data.tar.gz: 13a28196b6be684a3e49268545b4c53177c29d3b36d19f66a7cba04c3604a04b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6c439cb823273e3cc7f4cfb40def589ab63ac146ff15a2509c0ea4527aad9e396ae78e67c078ac2e493dab1dcbc3764b632d8a8572d315474a9cfd475ea3a635
|
7
|
+
data.tar.gz: 0a3a2402c9b0b5ca1a3878e0fd2269b4d23df93305a85ccef5c8255b269faee7efbafddf99fd3872f3821232324ec4b066f6be2f518d194304f986df7f7cab95
|
data/.version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.11
|
data/app/server.rb
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'erb'
|
2
|
+
require 'json'
|
3
|
+
require 'mysql2'
|
4
|
+
require 'sinatra/base'
|
5
|
+
require_relative 'sqlui'
|
6
|
+
require 'yaml'
|
7
|
+
|
8
|
+
if ARGV.include?('-v') || ARGV.include?('--version')
|
9
|
+
puts File.read('.version')
|
10
|
+
exit
|
11
|
+
end
|
12
|
+
|
13
|
+
raise 'you must specify a configuration file' unless ARGV.size == 1
|
14
|
+
raise "configuration file does not exist" unless File.exist?(ARGV[0])
|
15
|
+
|
16
|
+
class Server < Sinatra::Base
|
17
|
+
set :logging, true
|
18
|
+
set :bind, '0.0.0.0'
|
19
|
+
set :port, Integer(ENV['PORT'])
|
20
|
+
|
21
|
+
class Client
|
22
|
+
def initialize(params)
|
23
|
+
@params = params
|
24
|
+
end
|
25
|
+
|
26
|
+
def query(sql)
|
27
|
+
client = Thread.current.thread_variable_get(:client)
|
28
|
+
unless client
|
29
|
+
client = Mysql2::Client.new(@params)
|
30
|
+
Thread.current.thread_variable_set(:client, client)
|
31
|
+
end
|
32
|
+
client.query(sql)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
config = YAML.load(ERB.new(File.read(ARGV[0])).result)
|
37
|
+
saved_path = config['saved_path']
|
38
|
+
client_map = config['databases'].values.map do |config|
|
39
|
+
client_params = {
|
40
|
+
host: config['db_host'],
|
41
|
+
port: config['db_port'] || 3306,
|
42
|
+
username: config['db_username'],
|
43
|
+
password: config['db_password'],
|
44
|
+
database: config['db_database'],
|
45
|
+
read_timeout: 10, # seconds
|
46
|
+
write_timeout: 0, # seconds
|
47
|
+
connect_timeout: 5 # seconds
|
48
|
+
}
|
49
|
+
client = Client.new(client_params)
|
50
|
+
[
|
51
|
+
config['path'],
|
52
|
+
::SQLUI.new(
|
53
|
+
client: client,
|
54
|
+
table_schema: config['db_database'],
|
55
|
+
name: config['name'],
|
56
|
+
saved_path: File.join(saved_path, config['path'])
|
57
|
+
)
|
58
|
+
]
|
59
|
+
end.to_h
|
60
|
+
|
61
|
+
get '/-/health' do
|
62
|
+
status 200
|
63
|
+
body 'OK'
|
64
|
+
end
|
65
|
+
|
66
|
+
get '/db/?' do
|
67
|
+
erb :databases, :locals => {:databases => databases}
|
68
|
+
end
|
69
|
+
|
70
|
+
get '/db/:database' do
|
71
|
+
redirect "/db/#{params[:database]}/app", 301
|
72
|
+
end
|
73
|
+
|
74
|
+
get '/db/:database/:route' do
|
75
|
+
response = client_map[params[:database]].get(params)
|
76
|
+
status response[:status]
|
77
|
+
headers "Content-Type": response[:content_type]
|
78
|
+
body response[:body]
|
79
|
+
end
|
80
|
+
|
81
|
+
post '/db/:database/:route' do
|
82
|
+
post_body = JSON.parse(request.body.read)
|
83
|
+
response = client_map[params[:database]].post(params.merge(post_body))
|
84
|
+
status response[:status]
|
85
|
+
headers "Content-Type": response[:content_type]
|
86
|
+
body response[:body]
|
87
|
+
end
|
88
|
+
|
89
|
+
run!
|
90
|
+
end
|
data/{lib → app}/sqlui.rb
RENAMED
File without changes
|
data/bin/sqlui
ADDED
metadata
CHANGED
@@ -1,23 +1,51 @@
|
|
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.11
|
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-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: mysql2
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: puma
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '6.0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '6.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: sinatra
|
15
43
|
requirement: !ruby/object:Gem::Requirement
|
16
44
|
requirements:
|
17
45
|
- - "~>"
|
18
46
|
- !ruby/object:Gem::Version
|
19
47
|
version: '3.0'
|
20
|
-
type: :
|
48
|
+
type: :runtime
|
21
49
|
prerelease: false
|
22
50
|
version_requirements: !ruby/object:Gem::Requirement
|
23
51
|
requirements:
|
@@ -25,7 +53,21 @@ dependencies:
|
|
25
53
|
- !ruby/object:Gem::Version
|
26
54
|
version: '3.0'
|
27
55
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
56
|
+
name: puma
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '6.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '6.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec-core
|
29
71
|
requirement: !ruby/object:Gem::Requirement
|
30
72
|
requirements:
|
31
73
|
- - "~>"
|
@@ -39,7 +81,7 @@ dependencies:
|
|
39
81
|
- !ruby/object:Gem::Version
|
40
82
|
version: '3.0'
|
41
83
|
- !ruby/object:Gem::Dependency
|
42
|
-
name: rspec-
|
84
|
+
name: rspec-expectations
|
43
85
|
requirement: !ruby/object:Gem::Requirement
|
44
86
|
requirements:
|
45
87
|
- - "~>"
|
@@ -53,19 +95,19 @@ dependencies:
|
|
53
95
|
- !ruby/object:Gem::Version
|
54
96
|
version: '3.0'
|
55
97
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
98
|
+
name: rspec-mocks
|
57
99
|
requirement: !ruby/object:Gem::Requirement
|
58
100
|
requirements:
|
59
101
|
- - "~>"
|
60
102
|
- !ruby/object:Gem::Version
|
61
|
-
version: '
|
103
|
+
version: '3.0'
|
62
104
|
type: :development
|
63
105
|
prerelease: false
|
64
106
|
version_requirements: !ruby/object:Gem::Requirement
|
65
107
|
requirements:
|
66
108
|
- - "~>"
|
67
109
|
- !ruby/object:Gem::Version
|
68
|
-
version: '
|
110
|
+
version: '3.0'
|
69
111
|
- !ruby/object:Gem::Dependency
|
70
112
|
name: sinatra
|
71
113
|
requirement: !ruby/object:Gem::Requirement
|
@@ -82,14 +124,15 @@ dependencies:
|
|
82
124
|
version: '3.0'
|
83
125
|
description: A SQL UI.
|
84
126
|
email: nicholasdower@gmail.com
|
85
|
-
executables:
|
127
|
+
executables:
|
128
|
+
- sqlui
|
86
129
|
extensions: []
|
87
130
|
extra_rdoc_files: []
|
88
131
|
files:
|
89
|
-
-
|
90
|
-
-
|
91
|
-
-
|
92
|
-
-
|
132
|
+
- ".version"
|
133
|
+
- app/server.rb
|
134
|
+
- app/sqlui.rb
|
135
|
+
- bin/sqlui
|
93
136
|
homepage: https://github.com/nicholasdower/sqlui
|
94
137
|
licenses:
|
95
138
|
- MIT
|
data/resources/sqlui.css
DELETED
@@ -1,242 +0,0 @@
|
|
1
|
-
body {
|
2
|
-
font-size: 16px;
|
3
|
-
margin: 0;
|
4
|
-
}
|
5
|
-
|
6
|
-
.main-box {
|
7
|
-
display: flex;
|
8
|
-
flex-direction: column;
|
9
|
-
flex: 1;
|
10
|
-
margin: 0;
|
11
|
-
height: 100%;
|
12
|
-
min-height: 100%;
|
13
|
-
}
|
14
|
-
|
15
|
-
.header {
|
16
|
-
display: flex;
|
17
|
-
flex: 1;
|
18
|
-
align-items: center;
|
19
|
-
justify-content: start;
|
20
|
-
padding-left: 5px;
|
21
|
-
color: #333;
|
22
|
-
font-weight: bold;
|
23
|
-
}
|
24
|
-
|
25
|
-
.tabs-box {
|
26
|
-
display: flex;
|
27
|
-
flex-direction: row;
|
28
|
-
border-bottom: 1px solid #ddd;
|
29
|
-
height: 36px;
|
30
|
-
font-size: 16px;
|
31
|
-
font-family: Helvetica;
|
32
|
-
}
|
33
|
-
|
34
|
-
.tab-button, .selected-tab-button {
|
35
|
-
border: none;
|
36
|
-
outline: none;
|
37
|
-
cursor: pointer;
|
38
|
-
width: 150px;
|
39
|
-
padding: 2px;
|
40
|
-
margin: 0px;
|
41
|
-
display: flex;
|
42
|
-
justify-content: center;
|
43
|
-
background-color: #fff;
|
44
|
-
}
|
45
|
-
|
46
|
-
.tab-button {
|
47
|
-
color: #888;
|
48
|
-
}
|
49
|
-
|
50
|
-
.tab-button:hover {
|
51
|
-
color: #333;
|
52
|
-
}
|
53
|
-
|
54
|
-
.selected-tab-button {
|
55
|
-
color: #333;
|
56
|
-
font-weight: bold;
|
57
|
-
}
|
58
|
-
|
59
|
-
.tab-content-element {
|
60
|
-
display: none;
|
61
|
-
}
|
62
|
-
|
63
|
-
.query-box {
|
64
|
-
display: flex;
|
65
|
-
flex-direction: column;
|
66
|
-
}
|
67
|
-
|
68
|
-
.query {
|
69
|
-
display: flex;
|
70
|
-
flex: 1;
|
71
|
-
}
|
72
|
-
|
73
|
-
.submit-box {
|
74
|
-
display: flex;
|
75
|
-
border-top: 1px solid #ddd;
|
76
|
-
height: 36px;
|
77
|
-
justify-content: right;
|
78
|
-
}
|
79
|
-
|
80
|
-
.status {
|
81
|
-
display: flex;
|
82
|
-
justify-content: center;
|
83
|
-
align-content: center;
|
84
|
-
flex-direction: column;
|
85
|
-
font-family: Helvetica;
|
86
|
-
}
|
87
|
-
|
88
|
-
.result-box, .saved-box, .graph-box, .structure-box {
|
89
|
-
flex: 1;
|
90
|
-
overflow: auto;
|
91
|
-
display: flex;
|
92
|
-
flex-direction: column;
|
93
|
-
}
|
94
|
-
|
95
|
-
.graph-box, .result-box {
|
96
|
-
border-top: 1px solid #ddd;
|
97
|
-
}
|
98
|
-
|
99
|
-
.graph-box {
|
100
|
-
padding: 20px;
|
101
|
-
}
|
102
|
-
|
103
|
-
table {
|
104
|
-
font-family: monospace;
|
105
|
-
flex: 1;
|
106
|
-
border-spacing: 0px;
|
107
|
-
display: flex;
|
108
|
-
width: 100%;
|
109
|
-
}
|
110
|
-
|
111
|
-
table td:last-child, table th:last-child {
|
112
|
-
width: 100%;
|
113
|
-
border-right: none !important;
|
114
|
-
}
|
115
|
-
|
116
|
-
td, th {
|
117
|
-
padding: 5px 20px 5px 5px;
|
118
|
-
font-weight: normal;
|
119
|
-
white-space: nowrap;
|
120
|
-
max-width: 500px;
|
121
|
-
overflow: hidden;
|
122
|
-
text-overflow: ellipsis;
|
123
|
-
}
|
124
|
-
|
125
|
-
td {
|
126
|
-
text-align: right;
|
127
|
-
}
|
128
|
-
|
129
|
-
th {
|
130
|
-
text-align: left;
|
131
|
-
font-weight: bold;
|
132
|
-
border-bottom: 1px solid #ddd;
|
133
|
-
border-right: 1px solid #ddd;
|
134
|
-
}
|
135
|
-
|
136
|
-
table {
|
137
|
-
display: block;
|
138
|
-
}
|
139
|
-
|
140
|
-
thead {
|
141
|
-
padding: 0px;
|
142
|
-
background-color: #fff;
|
143
|
-
position: -webkit-sticky;
|
144
|
-
position: sticky;
|
145
|
-
top: 0px;
|
146
|
-
z-index: 100;
|
147
|
-
table-layout:fixed;
|
148
|
-
}
|
149
|
-
|
150
|
-
.highlighted-row {
|
151
|
-
background: #eee;
|
152
|
-
}
|
153
|
-
|
154
|
-
.status-box {
|
155
|
-
padding: 5px;
|
156
|
-
display: flex;
|
157
|
-
flex-direction: rows;
|
158
|
-
justify-content: space-between;
|
159
|
-
border-top: 1px solid #ddd;
|
160
|
-
height: 30px;
|
161
|
-
}
|
162
|
-
|
163
|
-
.CodeMirror pre.CodeMirror-placeholder {
|
164
|
-
color: #999;
|
165
|
-
}
|
166
|
-
|
167
|
-
.tabs-box {
|
168
|
-
display: flex;
|
169
|
-
}
|
170
|
-
|
171
|
-
.saved-box {
|
172
|
-
font-family: Helvetica;
|
173
|
-
}
|
174
|
-
|
175
|
-
.saved-box h1 {
|
176
|
-
margin: 0px;
|
177
|
-
padding-left: 10px;
|
178
|
-
padding-right: 10px;
|
179
|
-
padding-top: 10px;
|
180
|
-
padding-bottom: 10px;
|
181
|
-
font-size: 16px;
|
182
|
-
font-weight: bold;
|
183
|
-
}
|
184
|
-
|
185
|
-
.saved-box div:first-child {
|
186
|
-
border-top: none !important;
|
187
|
-
}
|
188
|
-
|
189
|
-
.saved-box p {
|
190
|
-
margin: 0px;
|
191
|
-
padding-left: 20px;
|
192
|
-
padding-bottom: 20px;
|
193
|
-
}
|
194
|
-
|
195
|
-
.saved-box div {
|
196
|
-
cursor: pointer;
|
197
|
-
border-top: 1px solid #eeeeee;
|
198
|
-
}
|
199
|
-
|
200
|
-
.saved-box div:hover {
|
201
|
-
background: #eee;
|
202
|
-
}
|
203
|
-
|
204
|
-
.submit-button {
|
205
|
-
cursor: pointer;
|
206
|
-
margin-right: 10px;
|
207
|
-
}
|
208
|
-
|
209
|
-
.cm-editor.cm-focused {
|
210
|
-
outline: none !important;
|
211
|
-
}
|
212
|
-
|
213
|
-
.schemas, .tables {
|
214
|
-
border: none;
|
215
|
-
display: flex;
|
216
|
-
min-width: 200px;
|
217
|
-
}
|
218
|
-
|
219
|
-
.table-info {
|
220
|
-
display: grid;
|
221
|
-
grid-template-columns: 1;
|
222
|
-
grid-template-rows: 0.5fr 0.5fr;
|
223
|
-
justify-items: stretch;
|
224
|
-
flex: 1;
|
225
|
-
}
|
226
|
-
|
227
|
-
.columns {
|
228
|
-
border-bottom: 1px solid #ddd;
|
229
|
-
overflow: auto;
|
230
|
-
grid-column: 1;
|
231
|
-
grid-row: 1;
|
232
|
-
}
|
233
|
-
|
234
|
-
.indexes {
|
235
|
-
overflow: auto;
|
236
|
-
grid-column: 1;
|
237
|
-
grid-row: 2;
|
238
|
-
}
|
239
|
-
|
240
|
-
select {
|
241
|
-
outline: none;
|
242
|
-
}
|
data/resources/sqlui.html
DELETED
@@ -1,60 +0,0 @@
|
|
1
|
-
<head>
|
2
|
-
|
3
|
-
<title>SQLUI</title>
|
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 class="main-box">
|
12
|
-
<div class="tabs-box">
|
13
|
-
<div id="header" class="header">SQLUI</div>
|
14
|
-
<input id="query-tab-button" class="tab-button" type="button" value="Query" onclick="sqlui.selectTab('query')"></input>
|
15
|
-
<input id="graph-tab-button" class="tab-button" type="button" value="Graph" onclick="sqlui.selectTab('graph')"></input>
|
16
|
-
<input id="saved-tab-button" class="tab-button" type="button" value="Saved" onclick="sqlui.selectTab('saved')"></input>
|
17
|
-
<input id="structure-tab-button" class="tab-button" type="button" value="Structure" onclick="sqlui.selectTab('structure')"></input>
|
18
|
-
</div>
|
19
|
-
|
20
|
-
<div id="query-box" class="query-box tab-content-element graph-element query-element" style="display: none;">
|
21
|
-
<div id="query"></div>
|
22
|
-
</div>
|
23
|
-
|
24
|
-
<!--
|
25
|
-
<div id="submit-box" class="submit-box tab-content-element graph-element query-element" style="display: none;">
|
26
|
-
<input id="submit-button" class="submit-button" type="button" value="submit" onclick="submit();"></input>
|
27
|
-
</div>
|
28
|
-
-->
|
29
|
-
|
30
|
-
<div id="result-box" class="result-box tab-content-element query-element" style="display: none;">
|
31
|
-
</div>
|
32
|
-
|
33
|
-
<div id="graph-box" class="graph-box tab-content-element graph-element" style="display: none;">
|
34
|
-
</div>
|
35
|
-
|
36
|
-
<div id="saved-box" class="saved-box tab-content-element saved-element" style="display: none;">
|
37
|
-
</div>
|
38
|
-
|
39
|
-
<div id="structure-box" class="structure-box tab-content-element structure-element" style="display: none;">
|
40
|
-
<div style="display: flex; flex: 1; flex-direction: row; align-items: stretch;">
|
41
|
-
<select id="schemas" class="schemas" size="4">
|
42
|
-
</select>
|
43
|
-
<select id="tables" class="tables" size="4">
|
44
|
-
</select>
|
45
|
-
<div id="table-info" class="table-info">
|
46
|
-
<div id="columns" class="columns">
|
47
|
-
</div>
|
48
|
-
<div id="indexes" class="indexes">
|
49
|
-
</div>
|
50
|
-
</div>
|
51
|
-
</div>
|
52
|
-
</div>
|
53
|
-
|
54
|
-
<div id="status-box" class="status-box">
|
55
|
-
<div id="query-status" class="status tab-content-element query-element"></div>
|
56
|
-
<div id="graph-status" class="status tab-content-element graph-element"></div>
|
57
|
-
<div id="saved-status" class="status tab-content-element saved-element"></div>
|
58
|
-
</div>
|
59
|
-
</div>
|
60
|
-
</body>
|