sqlui 0.1.19 → 0.1.20

Sign up to get free protection for your applications and to get access to all the features.
data/app/sqlui.rb ADDED
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'sqlui_config'
4
+ require_relative 'server'
5
+
6
+ # Main entry point.
7
+ class Sqlui
8
+ MAX_ROWS = 1_000
9
+
10
+ def initialize(config_file)
11
+ raise 'you must specify a configuration file' unless config_file
12
+ raise 'configuration file does not exist' unless File.exist?(config_file)
13
+
14
+ @config = SqluiConfig.new(config_file)
15
+ @resources_dir = File.join(File.expand_path('..', File.dirname(__FILE__)), 'client', 'resources')
16
+
17
+ # Connect to each database to verify each can be connected to.
18
+ @config.database_configs.each { |database| database.with_client { |client| client } }
19
+ end
20
+
21
+ def run
22
+ Server.init_and_run(@config, @resources_dir)
23
+ end
24
+
25
+ def self.from_command_line(args)
26
+ if args.include?('-v') || args.include?('--version')
27
+ puts File.read('.version')
28
+ exit
29
+ end
30
+
31
+ raise 'you must specify a configuration file' unless args.size == 1
32
+ raise 'configuration file does not exist' unless File.exist?(args[0])
33
+
34
+ Sqlui.new(args[0])
35
+ end
36
+ end
data/app/sqlui_config.rb CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  require 'yaml'
4
4
  require_relative 'database_config'
5
+ require_relative 'args'
5
6
 
6
7
  # App config including database configs.
7
8
  class SqluiConfig
@@ -10,40 +11,34 @@ class SqluiConfig
10
11
  def initialize(filename)
11
12
  config = YAML.safe_load(ERB.new(File.read(filename)).result)
12
13
  deep_symbolize!(config)
13
- @name = fetch_non_empty_string(config, :name).strip
14
- @list_url_path = fetch_non_empty_string(config, :list_url_path).strip
14
+ @name = Args.fetch_non_empty_string(config, :name).strip
15
+ @list_url_path = Args.fetch_non_empty_string(config, :list_url_path).strip
15
16
  raise ArgumentError, 'list_url_path should start with a /' unless @list_url_path.start_with?('/')
16
17
  if @list_url_path.length > 1 && @list_url_path.end_with?('/')
17
18
  raise ArgumentError, 'list_url_path should not end with a /'
18
19
  end
19
20
 
20
- databases = config[:databases]
21
- if databases.nil? || !databases.is_a?(Hash) || databases.empty?
22
- raise ArgumentError, 'required parameter databases missing'
23
- end
24
-
21
+ databases = Args.fetch_non_empty_hash(config, :databases)
25
22
  @database_configs = databases.map do |_, current|
26
23
  DatabaseConfig.new(current)
27
24
  end
28
25
  end
29
26
 
30
27
  def database_config_for(url_path:)
31
- @database_configs.find { |database| database.url_path == url_path } || raise("no config found for path #{url_path}")
28
+ config = @database_configs.find { |database| database.url_path == url_path }
29
+ raise ArgumentError, "no config found for path #{url_path}" unless config
30
+
31
+ config
32
32
  end
33
33
 
34
34
  private
35
35
 
36
- def fetch_non_empty_string(hash, key)
37
- value = hash[key]
38
- raise ArgumentError, "required parameter #{key} missing" if value.nil? || !value.is_a?(String) || value.strip.empty?
39
-
40
- value.strip
41
- end
42
-
43
36
  def deep_symbolize!(object)
44
- return unless object.is_a? Hash
37
+ return object unless object.is_a? Hash
45
38
 
46
39
  object.transform_keys!(&:to_sym)
47
40
  object.each_value { |child| deep_symbolize!(child) }
41
+
42
+ object
48
43
  end
49
44
  end
data/bin/sqlui CHANGED
@@ -1,4 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
- require_relative '../app/server'
4
+ require_relative '../app/sqlui'
5
+
6
+ Sqlui.from_command_line(ARGV).run
@@ -1,242 +1,263 @@
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
- }
1
+ body {
2
+ margin: 0;
3
+ }
4
+
5
+ .loading-box {
6
+ font-family: monospace;
7
+ display: flex;
8
+ flex-direction: column;
9
+ flex: 1;
10
+ margin: 0;
11
+ height: 100%;
12
+ min-height: 100%;
13
+ align-items: start;
14
+ justify-content: start;
15
+ padding: 10px;
16
+ }
17
+
18
+ .main-box {
19
+ display: flex;
20
+ flex-direction: column;
21
+ flex: 1;
22
+ margin: 0;
23
+ height: 100%;
24
+ min-height: 100%;
25
+ }
26
+
27
+ .header, .server-name {
28
+ display: flex;
29
+ align-items: center;
30
+ justify-content: start;
31
+ color: #333;
32
+ }
33
+
34
+ .header {
35
+ font-weight: bold;
36
+ padding-left: 5px;
37
+ }
38
+
39
+ .server-name {
40
+ flex: 1;
41
+ padding-left: 15px;
42
+ }
43
+
44
+ .tabs-box {
45
+ display: flex;
46
+ flex-direction: row;
47
+ border-bottom: 1px solid #ddd;
48
+ height: 36px;
49
+ font-family: Helvetica;
50
+ }
51
+
52
+ .tab-button, .selected-tab-button {
53
+ border: none;
54
+ outline: none;
55
+ cursor: pointer;
56
+ width: 150px;
57
+ padding: 2px;
58
+ margin: 0px;
59
+ display: flex;
60
+ justify-content: center;
61
+ background-color: #fff;
62
+ }
63
+
64
+ .tab-button {
65
+ color: #888;
66
+ }
67
+
68
+ .tab-button:hover {
69
+ color: #333;
70
+ }
71
+
72
+ .selected-tab-button {
73
+ color: #333;
74
+ font-weight: bold;
75
+ }
76
+
77
+ .tab-content-element {
78
+ display: none;
79
+ }
80
+
81
+ .query-box {
82
+ display: flex;
83
+ flex-direction: column;
84
+ }
85
+
86
+ .query {
87
+ display: flex;
88
+ flex: 1;
89
+ }
90
+
91
+ .submit-box {
92
+ display: flex;
93
+ border-top: 1px solid #ddd;
94
+ justify-content: right;
95
+ }
96
+
97
+ .submit-button {
98
+ cursor: pointer;
99
+ margin: 5px;
100
+ border: 1px solid #888;
101
+ background: none;
102
+ padding: 5px;
103
+ }
104
+
105
+ .status {
106
+ display: flex;
107
+ justify-content: center;
108
+ align-content: center;
109
+ flex-direction: column;
110
+ font-family: Helvetica;
111
+ white-space: nowrap;
112
+ overflow: hidden;
113
+ }
114
+
115
+ .result-box, .saved-box, .graph-box, .structure-box {
116
+ flex: 1;
117
+ overflow: auto;
118
+ display: flex;
119
+ flex-direction: column;
120
+ }
121
+
122
+ .graph-box, .result-box {
123
+ border-top: 1px solid #ddd;
124
+ }
125
+
126
+ .graph-box {
127
+ padding: 20px;
128
+ }
129
+
130
+ table {
131
+ font-family: monospace;
132
+ flex: 1;
133
+ border-spacing: 0px;
134
+ display: flex;
135
+ width: 100%;
136
+ }
137
+
138
+ table td:last-child, table th:last-child {
139
+ width: 100%;
140
+ border-right: none !important;
141
+ }
142
+
143
+ td, th {
144
+ padding: 5px 20px 5px 5px;
145
+ font-weight: normal;
146
+ white-space: nowrap;
147
+ max-width: 500px;
148
+ overflow: hidden;
149
+ text-overflow: ellipsis;
150
+ }
151
+
152
+ td {
153
+ text-align: right;
154
+ }
155
+
156
+ th {
157
+ text-align: left;
158
+ font-weight: bold;
159
+ border-bottom: 1px solid #ddd;
160
+ border-right: 1px solid #ddd;
161
+ }
162
+
163
+ table {
164
+ display: block;
165
+ }
166
+
167
+ thead {
168
+ padding: 0px;
169
+ background-color: #fff;
170
+ position: -webkit-sticky;
171
+ position: sticky;
172
+ top: 0px;
173
+ z-index: 100;
174
+ table-layout: fixed;
175
+ }
176
+
177
+ .highlighted-row {
178
+ background: #eee;
179
+ }
180
+
181
+ .status-box {
182
+ padding: 5px;
183
+ display: flex;
184
+ flex-direction: rows;
185
+ justify-content: space-between;
186
+ border-top: 1px solid #ddd;
187
+ height: 30px;
188
+ }
189
+
190
+ .CodeMirror pre.CodeMirror-placeholder {
191
+ color: #999;
192
+ }
193
+
194
+ .tabs-box {
195
+ display: flex;
196
+ }
197
+
198
+ .saved-box {
199
+ font-family: Helvetica;
200
+ }
201
+
202
+ .saved-box h1 {
203
+ margin: 0px;
204
+ padding-left: 10px;
205
+ padding-right: 10px;
206
+ padding-top: 10px;
207
+ padding-bottom: 10px;
208
+ font-weight: bold;
209
+ }
210
+
211
+ .saved-box div:first-child {
212
+ border-top: none !important;
213
+ }
214
+
215
+ .saved-box p {
216
+ margin: 0px;
217
+ padding-left: 20px;
218
+ padding-bottom: 20px;
219
+ }
220
+
221
+ .saved-box div {
222
+ cursor: pointer;
223
+ border-top: 1px solid #eeeeee;
224
+ }
225
+
226
+ .saved-box div:hover {
227
+ background: #eee;
228
+ }
229
+
230
+ .cm-editor.cm-focused {
231
+ outline: none !important;
232
+ }
233
+
234
+ .schemas, .tables {
235
+ border: none;
236
+ display: flex;
237
+ min-width: 200px;
238
+ }
239
+
240
+ .table-info {
241
+ display: grid;
242
+ grid-template-columns: 1;
243
+ grid-template-rows: 0.5fr 0.5fr;
244
+ justify-items: stretch;
245
+ flex: 1;
246
+ }
247
+
248
+ .columns {
249
+ border-bottom: 1px solid #ddd;
250
+ overflow: auto;
251
+ grid-column: 1;
252
+ grid-row: 1;
253
+ }
254
+
255
+ .indexes {
256
+ overflow: auto;
257
+ grid-column: 1;
258
+ grid-row: 2;
259
+ }
260
+
261
+ select {
262
+ outline: none;
263
+ }
@@ -8,9 +8,13 @@
8
8
  </head>
9
9
 
10
10
  <body>
11
- <div class="main-box">
11
+ <div id="loading-box" class="loading-box">
12
+ </div>
13
+
14
+ <div id="main-box" class="main-box" style="display:none">
12
15
  <div class="tabs-box">
13
- <div id="header" class="header">SQLUI</div>
16
+ <div class="header">SQLUI</div>
17
+ <div id="server-name" class="server-name"></div>
14
18
  <input id="query-tab-button" class="tab-button" type="button" value="Query" onclick="sqlui.selectTab('query')"></input>
15
19
  <input id="graph-tab-button" class="tab-button" type="button" value="Graph" onclick="sqlui.selectTab('graph')"></input>
16
20
  <input id="saved-tab-button" class="tab-button" type="button" value="Saved" onclick="sqlui.selectTab('saved')"></input>
@@ -21,11 +25,10 @@
21
25
  <div id="query"></div>
22
26
  </div>
23
27
 
24
- <!--
25
28
  <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>
29
+ <input id="submit-all-button" class="submit-button" type="button" value="execute (ctrl-shift-enter)" onclick="sqlui.submitAll();"></input>
30
+ <input id="submit-current-button" class="submit-button" type="button" value="execute selection (ctrl-enter)" onclick="sqlui.submitCurrent();"></input>
27
31
  </div>
28
- -->
29
32
 
30
33
  <div id="result-box" class="result-box tab-content-element query-element" style="display: none;">
31
34
  </div>