db-gui 0.2.3 → 0.4.0
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/CHANGELOG.md +12 -0
- data/README.md +8 -2
- data/VERSION +1 -1
- data/app/db-gui.rb +5 -0
- data/app/db_gui/model/db.rb +80 -35
- data/app/db_gui/presenter/db_presenter.rb +83 -0
- data/app/db_gui/view/db_command_form.rb +29 -8
- data/app/db_gui/view/db_command_result_table.rb +9 -9
- data/app/db_gui/view/db_config_form.rb +54 -13
- data/app/db_gui/view/db_gui_application.rb +7 -7
- data/app/db_gui/view/db_gui_menu_bar.rb +32 -12
- metadata +4 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 75e15d34f7435b0c8d0d66b67cc8138b7935c88dad827a9ed2cc3575e9a83b00
|
|
4
|
+
data.tar.gz: 7f19a38c51c2e91423e7c95d7aa631410208f3a9134e6e011c916b827949e6ba
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ef5768eb5582be26fb0d2c3089c33bc6d905982981978361713ec764134952d0a0abb246494a6a5c17fe1cd27cff176acb3a719e0e547b5e28e59e6b43e4f4aa
|
|
7
|
+
data.tar.gz: a77221ceb7131f2c0d14b28e1ec3465f740f9c678e0e9936579766019efd9abca519ba0132c609f1a2acbe116ddbc49270df5008c67c1a061335bfbe53d0a39a
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
+
## 0.4.0
|
|
4
|
+
|
|
5
|
+
- Remember all DB commands in a history dropdown
|
|
6
|
+
- Remove currently selected DB command from DB command history dropdown
|
|
7
|
+
- Clear DB command history dropdown
|
|
8
|
+
|
|
9
|
+
## 0.3.0
|
|
10
|
+
|
|
11
|
+
- Support the ability to save/load multiple databases (DB configs)
|
|
12
|
+
- Add more resiliency against errors when copying table or record data via menu items
|
|
13
|
+
|
|
3
14
|
## 0.2.3
|
|
4
15
|
|
|
5
16
|
- Edit -> Copy Table (with query & headers) menu item to copy table data with query (e.g. SQL) & headers as a formatted string to the clipboard
|
|
@@ -8,6 +19,7 @@
|
|
|
8
19
|
|
|
9
20
|
- Edit -> Copy Table (with headers) menu item to copy table data with headers as a formatted string to the clipboard
|
|
10
21
|
- Edit -> Copy Selected Row (with headers) menu item to copy selected row data with headers as a formatted string to the clipboard
|
|
22
|
+
- Query -> Run menu item to run query
|
|
11
23
|
|
|
12
24
|
## 0.2.1
|
|
13
25
|
|
data/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# DB GUI (Database Graphical User Interface) 0.
|
|
1
|
+
# DB GUI (Database Graphical User Interface) 0.4.0
|
|
2
2
|
## [<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer/master/images/glimmer-logo-hi-res.png" height=40 /> Glimmer DSL for LibUI Application](https://github.com/AndyObtiva/glimmer-dsl-libui)
|
|
3
3
|
[](http://badge.fury.io/rb/db-gui)
|
|
4
4
|
|
|
@@ -8,11 +8,15 @@ It currently supports PostgreSQL as a start, with the potential of supporting ma
|
|
|
8
8
|
|
|
9
9
|

|
|
10
10
|
|
|
11
|
+

|
|
12
|
+
|
|
13
|
+

|
|
14
|
+
|
|
11
15
|
## Setup
|
|
12
16
|
|
|
13
17
|
Run:
|
|
14
18
|
```
|
|
15
|
-
gem install db-gui -v0.
|
|
19
|
+
gem install db-gui -v0.4.0
|
|
16
20
|
```
|
|
17
21
|
|
|
18
22
|
## Usage
|
|
@@ -26,6 +30,8 @@ Or, run one of the aliases: `db-ui` / `dbgui` / `db-gui`
|
|
|
26
30
|
|
|
27
31
|
Note that it stores the last connection details under `~/.db_gui`, and will auto-connect using that configuration on startup for extra convenience (in the future, there is the potential to support multiple connection configurations).
|
|
28
32
|
|
|
33
|
+
It remembers DB command history in a dropdown above the DB command text area.
|
|
34
|
+
|
|
29
35
|
### Menu Items
|
|
30
36
|
|
|
31
37
|
**Edit -> Copy Table**
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.4.0
|
data/app/db-gui.rb
CHANGED
|
@@ -13,6 +13,11 @@ class DbGui
|
|
|
13
13
|
APP_ROOT = File.expand_path('../..', __FILE__)
|
|
14
14
|
VERSION = File.read(File.join(APP_ROOT, 'VERSION'))
|
|
15
15
|
LICENSE = File.read(File.join(APP_ROOT, 'LICENSE.txt'))
|
|
16
|
+
DIR_DB_GUI = File.expand_path(File.join('~', '.db_gui'))
|
|
17
|
+
FileUtils.rm(DIR_DB_GUI) if File.file?(DIR_DB_GUI)
|
|
18
|
+
FileUtils.mkdir_p(DIR_DB_GUI)
|
|
19
|
+
FILE_DB_CONFIGS = File.expand_path(File.join(DIR_DB_GUI, '.db_config'))
|
|
20
|
+
FILE_DB_COMMANDS = File.expand_path(File.join(DIR_DB_GUI, '.db_commands'))
|
|
16
21
|
end
|
|
17
22
|
|
|
18
23
|
require 'db_gui/view/db_gui_application.rb'
|
data/app/db_gui/model/db.rb
CHANGED
|
@@ -4,31 +4,64 @@ require 'clipboard'
|
|
|
4
4
|
|
|
5
5
|
class DbGui
|
|
6
6
|
module Model
|
|
7
|
-
Db = Struct.new(:host, :port, :dbname, :username, :password, :db_command_timeout, keyword_init: true) do
|
|
8
|
-
|
|
9
|
-
FileUtils.rm(DIR_DB_GUI) if File.file?(DIR_DB_GUI)
|
|
10
|
-
FileUtils.mkdir_p(DIR_DB_GUI)
|
|
11
|
-
FILE_DB_CONFIGS = File.expand_path(File.join(DIR_DB_GUI, '.db_configs'))
|
|
12
|
-
FILE_DB_COMMANDS = File.expand_path(File.join(DIR_DB_GUI, '.db_commands'))
|
|
7
|
+
Db = Struct.new(:name, :host, :port, :dbname, :username, :password, :db_command_timeout, keyword_init: true) do
|
|
8
|
+
|
|
13
9
|
COUNT_RETRIES = ENV.fetch('DB_COMMAND_COUNT_RETRIES', 7)
|
|
14
10
|
REGEX_ROW_COUNT = /^\((\d+) row/
|
|
15
11
|
ERROR_PREFIX = 'ERROR:'
|
|
16
12
|
NEW_LINE = OS.windows? ? "\r\n" : "\n"
|
|
13
|
+
DB_COMMAND_TIMEOUT_DEFAULT = 300
|
|
17
14
|
|
|
15
|
+
attr_accessor :deleteable
|
|
16
|
+
alias deleteable? deleteable
|
|
18
17
|
attr_accessor :connected
|
|
19
18
|
alias connected? connected
|
|
20
19
|
attr_accessor :db_command_result
|
|
20
|
+
attr_accessor :db_commands
|
|
21
21
|
attr_accessor :db_command
|
|
22
22
|
attr_accessor :db_command_result_selection
|
|
23
23
|
|
|
24
24
|
def initialize
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
load_db_commands
|
|
26
|
+
reset
|
|
27
|
+
to_h.keys.each do |attribute|
|
|
28
|
+
Glimmer::DataBinding::Observer.proc do |value|
|
|
29
|
+
notify_observers(:saveable)
|
|
30
|
+
end.observe(self, attribute)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def reset
|
|
35
|
+
self.name = Db::NAME_NEW
|
|
36
|
+
self.host = nil
|
|
27
37
|
self.port ||= 5432 # PostgreSQL default port
|
|
38
|
+
self.dbname = nil
|
|
39
|
+
self.username = nil
|
|
40
|
+
self.password = nil
|
|
28
41
|
self.db_command_result = ''
|
|
29
|
-
self.db_command_timeout ||= ENV.fetch('DB_COMMAND_TIMEOUT_IN_MILLISECONDS',
|
|
42
|
+
self.db_command_timeout ||= ENV.fetch('DB_COMMAND_TIMEOUT_IN_MILLISECONDS', DB_COMMAND_TIMEOUT_DEFAULT).to_i
|
|
30
43
|
self.db_command_result_selection = 0
|
|
31
|
-
|
|
44
|
+
self.db_commands ||= ['']
|
|
45
|
+
self.db_command ||= ''
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def db_commands
|
|
49
|
+
if @db_commands == []
|
|
50
|
+
@db_commands = ['']
|
|
51
|
+
end
|
|
52
|
+
@db_commands
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def new?
|
|
56
|
+
name === Db::NAME_NEW
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def saveable
|
|
60
|
+
!new?
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def deleteable
|
|
64
|
+
!new?
|
|
32
65
|
end
|
|
33
66
|
|
|
34
67
|
def toggle_connection
|
|
@@ -42,7 +75,6 @@ class DbGui
|
|
|
42
75
|
def connect
|
|
43
76
|
io
|
|
44
77
|
self.connected = true
|
|
45
|
-
save_db_config
|
|
46
78
|
end
|
|
47
79
|
|
|
48
80
|
def disconnect
|
|
@@ -77,9 +109,23 @@ class DbGui
|
|
|
77
109
|
end
|
|
78
110
|
|
|
79
111
|
def run_db_command
|
|
112
|
+
reset_db_command_timeout
|
|
80
113
|
run_io_command(db_command)
|
|
81
|
-
|
|
82
|
-
|
|
114
|
+
save_db_commands
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def clear_db_commands
|
|
118
|
+
self.db_commands = ['']
|
|
119
|
+
self.db_command = ''
|
|
120
|
+
save_db_commands(add_current: false)
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def remove_db_command
|
|
124
|
+
current_db_command = db_command
|
|
125
|
+
self.db_commands = self.db_commands - [current_db_command.to_s.strip]
|
|
126
|
+
self.db_command = ''
|
|
127
|
+
self.db_command = self.db_commands.last || ''
|
|
128
|
+
save_db_commands(add_current: false)
|
|
83
129
|
end
|
|
84
130
|
|
|
85
131
|
def db_command_result_count
|
|
@@ -127,7 +173,7 @@ class DbGui
|
|
|
127
173
|
rows ||= db_command_result_rows
|
|
128
174
|
rows = rows.dup
|
|
129
175
|
rows.prepend(db_command_result_headers) if include_headers
|
|
130
|
-
column_max_lengths = row_column_max_lengths(rows)
|
|
176
|
+
column_max_lengths = row_column_max_lengths(rows)
|
|
131
177
|
formatted_string = rows.map do |row|
|
|
132
178
|
row.each_with_index.map do |data, column_index|
|
|
133
179
|
data.ljust(column_max_lengths[column_index])
|
|
@@ -162,34 +208,30 @@ class DbGui
|
|
|
162
208
|
@line = nil
|
|
163
209
|
end
|
|
164
210
|
|
|
165
|
-
def
|
|
166
|
-
|
|
167
|
-
db_configs_array = [db_config_hash] # TODO in the future, support storing multiple DB configs
|
|
168
|
-
db_configs_file_content = YAML.dump(db_configs_array)
|
|
169
|
-
File.write(FILE_DB_CONFIGS, db_configs_file_content)
|
|
211
|
+
def reset_db_command_timeout
|
|
212
|
+
self.db_command_timeout = DB_COMMAND_TIMEOUT_DEFAULT
|
|
170
213
|
end
|
|
171
214
|
|
|
172
|
-
def
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
215
|
+
def save_db_commands(add_current: true)
|
|
216
|
+
return if db_command_result_error?
|
|
217
|
+
new_command = db_command.to_s.strip
|
|
218
|
+
self.db_commands ||= []
|
|
219
|
+
db_command_exists_in_db_commands = db_commands.find { |command| new_command == command.to_s.strip }
|
|
220
|
+
if add_current && !db_command_exists_in_db_commands
|
|
221
|
+
new_db_commands = db_commands + [new_command]
|
|
222
|
+
self.db_commands = new_db_commands.reject { |command| command.to_s.strip.empty? }
|
|
178
223
|
end
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
def save_db_command
|
|
184
|
-
db_commands_array = [db_command] # TODO in the future, support storing multiple DB configs
|
|
185
|
-
db_commands_file_content = YAML.dump(db_commands_array)
|
|
224
|
+
self.db_command = ''
|
|
225
|
+
self.db_command = new_command
|
|
226
|
+
db_commands_file_content = YAML.dump(db_command:, db_commands:)
|
|
186
227
|
File.write(FILE_DB_COMMANDS, db_commands_file_content)
|
|
187
228
|
end
|
|
188
229
|
|
|
189
|
-
def
|
|
230
|
+
def load_db_commands
|
|
190
231
|
db_commands_file_content = File.read(FILE_DB_COMMANDS)
|
|
191
|
-
|
|
192
|
-
self.
|
|
232
|
+
db_commands_config = YAML.load(db_commands_file_content)
|
|
233
|
+
self.db_commands = db_commands_config[:db_commands]
|
|
234
|
+
self.db_command = db_commands_config[:db_command]
|
|
193
235
|
rescue => e
|
|
194
236
|
puts "No database commands stored yet. #{e.message}"
|
|
195
237
|
end
|
|
@@ -212,6 +254,8 @@ class DbGui
|
|
|
212
254
|
def compute_db_command_result_count_headers_rows
|
|
213
255
|
count = 0
|
|
214
256
|
headers = rows = []
|
|
257
|
+
# TODO db_command_result.lines has an issue in case the data in the DB in a certain row contains \n
|
|
258
|
+
# Try to bisect data more correctly, maybe by looking at \n one by one
|
|
215
259
|
db_command_result_lines = db_command_result.lines.reject { |line| line == "\n" }
|
|
216
260
|
if db_command_result_lines.any?
|
|
217
261
|
headers = db_command_result_lines.first.split('|').map(&:strip)
|
|
@@ -238,5 +282,6 @@ class DbGui
|
|
|
238
282
|
column_max_lengths
|
|
239
283
|
end
|
|
240
284
|
end
|
|
285
|
+
Db::NAME_NEW = '(New Config)'
|
|
241
286
|
end
|
|
242
287
|
end
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
require 'glimmer/data_binding/observable_model'
|
|
2
|
+
require 'db_gui/model/db'
|
|
3
|
+
|
|
4
|
+
class DbGui
|
|
5
|
+
module Presenter
|
|
6
|
+
class DbPresenter
|
|
7
|
+
include Glimmer::DataBinding::ObservableModel
|
|
8
|
+
|
|
9
|
+
attr_accessor :dbs, :selected_db, :new_db
|
|
10
|
+
|
|
11
|
+
def initialize
|
|
12
|
+
@new_db = Model::Db.new
|
|
13
|
+
@dbs = [@new_db]
|
|
14
|
+
@selected_db = @new_db
|
|
15
|
+
load_db_config
|
|
16
|
+
selected_db.connect
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def newable
|
|
20
|
+
selected_db != new_db
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def selected_db_name
|
|
24
|
+
selected_db.name
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def selected_db_name=(db_name)
|
|
28
|
+
self.selected_db = dbs.find { |db| db.name == db_name }
|
|
29
|
+
notify_observers(:newable)
|
|
30
|
+
save_config
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def save
|
|
34
|
+
if selected_db == new_db && selected_db.name != Model::Db::NAME_NEW
|
|
35
|
+
saved_db = new_db.clone
|
|
36
|
+
new_db.reset
|
|
37
|
+
dbs << saved_db # this will trigger an update to the combobox items
|
|
38
|
+
self.selected_db_name = saved_db.name
|
|
39
|
+
else
|
|
40
|
+
notify_observers(:dbs)
|
|
41
|
+
self.selected_db_name = selected_db.name
|
|
42
|
+
end
|
|
43
|
+
save_config
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def new
|
|
47
|
+
self.selected_db_name = new_db.name
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def delete
|
|
51
|
+
dbs.delete(selected_db)
|
|
52
|
+
self.selected_db_name = new_db.name
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def save_config
|
|
56
|
+
dbs_attributes = dbs.reject {|db| db.name == Model::Db::NAME_NEW }.map(&:to_h)
|
|
57
|
+
selected_db_name
|
|
58
|
+
db_config = {
|
|
59
|
+
selected_db_name:,
|
|
60
|
+
dbs: dbs_attributes,
|
|
61
|
+
}
|
|
62
|
+
db_config_yaml = YAML.dump(db_config)
|
|
63
|
+
File.write(FILE_DB_CONFIGS, db_config_yaml)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def load_db_config
|
|
67
|
+
db_config_yaml = File.read(FILE_DB_CONFIGS)
|
|
68
|
+
db_config = YAML.load(db_config_yaml)
|
|
69
|
+
db_config[:dbs].each do |db_config|
|
|
70
|
+
db = Model::Db.new
|
|
71
|
+
db_config.each do |attribute, value|
|
|
72
|
+
db.send("#{attribute}=", value)
|
|
73
|
+
end
|
|
74
|
+
self.dbs << db
|
|
75
|
+
end
|
|
76
|
+
self.selected_db_name = db_config[:selected_db_name]
|
|
77
|
+
rescue => e
|
|
78
|
+
puts "No database configurations stored yet. #{e.message}"
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
@@ -7,37 +7,58 @@ class DbGui
|
|
|
7
7
|
|
|
8
8
|
TIMEOUT_MAX_IN_MILLISECONDS = (ENV['TIMEOUT_MAX_IN_MILLISECONDS'] || 60*60*1000).to_i
|
|
9
9
|
|
|
10
|
-
option :
|
|
10
|
+
option :db_presenter
|
|
11
11
|
|
|
12
12
|
body {
|
|
13
13
|
vertical_box {
|
|
14
|
+
horizontal_box {
|
|
15
|
+
stretchy false
|
|
16
|
+
combobox {
|
|
17
|
+
items <= [db_presenter, 'selected_db.db_commands']
|
|
18
|
+
selected_item <=> [db_presenter, 'selected_db.db_command']
|
|
19
|
+
enabled <= [db_presenter, 'selected_db.db_commands', on_read: -> (value) { value != [''] }]
|
|
20
|
+
}
|
|
21
|
+
button('Remove') {
|
|
22
|
+
stretchy false
|
|
23
|
+
on_clicked do
|
|
24
|
+
db_presenter.selected_db.remove_db_command
|
|
25
|
+
end
|
|
26
|
+
}
|
|
27
|
+
button('Clear') {
|
|
28
|
+
stretchy false
|
|
29
|
+
on_clicked do
|
|
30
|
+
db_presenter.selected_db.clear_db_commands
|
|
31
|
+
end
|
|
32
|
+
}
|
|
33
|
+
}
|
|
14
34
|
non_wrapping_multiline_entry {
|
|
15
|
-
text <=> [
|
|
35
|
+
text <=> [db_presenter, 'selected_db.db_command']
|
|
16
36
|
}
|
|
17
|
-
|
|
18
37
|
horizontal_box {
|
|
19
38
|
stretchy false
|
|
20
39
|
|
|
21
40
|
button('Run') {
|
|
41
|
+
enabled <= [db_presenter, 'selected_db.db_command', on_read: -> (command) { !command.to_s.strip.empty? }]
|
|
42
|
+
|
|
22
43
|
on_clicked do
|
|
23
|
-
|
|
44
|
+
db_presenter.selected_db.run_db_command
|
|
24
45
|
end
|
|
25
46
|
}
|
|
26
|
-
|
|
47
|
+
|
|
27
48
|
label('Timeout (msec): ') {
|
|
28
49
|
stretchy false
|
|
29
50
|
}
|
|
30
51
|
spinbox(0, TIMEOUT_MAX_IN_MILLISECONDS) {
|
|
31
52
|
stretchy false
|
|
32
|
-
value <=> [
|
|
53
|
+
value <=> [db_presenter, 'selected_db.db_command_timeout', on_read: :to_i]
|
|
33
54
|
}
|
|
34
55
|
|
|
35
|
-
label('
|
|
56
|
+
label('Rows: ') {
|
|
36
57
|
stretchy false
|
|
37
58
|
}
|
|
38
59
|
label {
|
|
39
60
|
stretchy false
|
|
40
|
-
text <= [
|
|
61
|
+
text <= [db_presenter, 'selected_db.db_command_result_count', computed_by: 'selected_db.db_command_result', on_read: :to_s]
|
|
41
62
|
}
|
|
42
63
|
}
|
|
43
64
|
}
|
|
@@ -5,25 +5,25 @@ class DbGui
|
|
|
5
5
|
class DbCommandResultTable
|
|
6
6
|
include Glimmer::LibUI::CustomControl
|
|
7
7
|
|
|
8
|
-
option :
|
|
8
|
+
option :db_presenter
|
|
9
9
|
|
|
10
10
|
body {
|
|
11
11
|
vertical_box {
|
|
12
|
-
content(
|
|
13
|
-
if
|
|
14
|
-
label(
|
|
15
|
-
elsif
|
|
12
|
+
content(db_presenter, 'selected_db.db_command_result') {
|
|
13
|
+
if db_presenter.selected_db.db_command_result_error?
|
|
14
|
+
label(db_presenter.selected_db.db_command_result)
|
|
15
|
+
elsif db_presenter.selected_db.db_command_result_count > 0
|
|
16
16
|
table {
|
|
17
|
-
|
|
17
|
+
db_presenter.selected_db.db_command_result_headers.each do |header|
|
|
18
18
|
text_column(header)
|
|
19
19
|
end
|
|
20
20
|
|
|
21
|
-
cell_rows
|
|
21
|
+
cell_rows db_presenter.selected_db.db_command_result_rows
|
|
22
22
|
selection_mode :one
|
|
23
|
-
selection
|
|
23
|
+
selection db_presenter.selected_db.db_command_result_selection
|
|
24
24
|
|
|
25
25
|
on_selection_changed do |t, selection, added_selection, removed_selection|
|
|
26
|
-
|
|
26
|
+
db_presenter.selected_db.db_command_result_selection = selection
|
|
27
27
|
end
|
|
28
28
|
}
|
|
29
29
|
else
|
|
@@ -5,48 +5,89 @@ class DbGui
|
|
|
5
5
|
class DbConfigForm
|
|
6
6
|
include Glimmer::LibUI::CustomControl
|
|
7
7
|
|
|
8
|
-
option :
|
|
8
|
+
option :db_presenter
|
|
9
9
|
|
|
10
10
|
body {
|
|
11
11
|
vertical_box {
|
|
12
12
|
form {
|
|
13
|
+
combobox {
|
|
14
|
+
label 'Selected Config:'
|
|
15
|
+
items <= [db_presenter, :dbs, on_read: ->(dbs) { dbs.map(&:name) }]
|
|
16
|
+
selected_item <=> [db_presenter, :selected_db_name]
|
|
17
|
+
enabled <= [db_presenter, 'selected_db.connected', on_read: :!]
|
|
18
|
+
}
|
|
19
|
+
|
|
13
20
|
entry {
|
|
14
21
|
label 'Host:'
|
|
15
|
-
text <=> [
|
|
16
|
-
enabled <= [
|
|
22
|
+
text <=> [db_presenter, 'selected_db.host']
|
|
23
|
+
enabled <= [db_presenter, 'selected_db.connected', on_read: :!]
|
|
17
24
|
}
|
|
18
25
|
|
|
19
26
|
spinbox(0, 1_000_000) {
|
|
20
27
|
label 'Port:'
|
|
21
|
-
value <=> [
|
|
22
|
-
enabled <= [
|
|
28
|
+
value <=> [db_presenter, 'selected_db.port']
|
|
29
|
+
enabled <= [db_presenter, 'selected_db.connected', on_read: :!]
|
|
23
30
|
}
|
|
24
31
|
|
|
25
32
|
entry {
|
|
26
33
|
label 'Database Name:'
|
|
27
|
-
text <=> [
|
|
28
|
-
enabled <= [
|
|
34
|
+
text <=> [db_presenter, 'selected_db.dbname']
|
|
35
|
+
enabled <= [db_presenter, 'selected_db.connected', on_read: :!]
|
|
29
36
|
}
|
|
30
37
|
|
|
31
38
|
entry {
|
|
32
39
|
label 'Username:'
|
|
33
|
-
text <=> [
|
|
34
|
-
enabled <= [
|
|
40
|
+
text <=> [db_presenter, 'selected_db.username']
|
|
41
|
+
enabled <= [db_presenter, 'selected_db.connected', on_read: :!]
|
|
35
42
|
}
|
|
36
43
|
|
|
37
44
|
password_entry {
|
|
38
45
|
label 'Password:'
|
|
39
|
-
text <=> [
|
|
40
|
-
enabled <= [
|
|
46
|
+
text <=> [db_presenter, 'selected_db.password']
|
|
47
|
+
enabled <= [db_presenter, 'selected_db.connected', on_read: :!]
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
horizontal_box {
|
|
51
|
+
entry {
|
|
52
|
+
text <=> [db_presenter, 'selected_db.name']
|
|
53
|
+
enabled <= [db_presenter, 'selected_db.connected', on_read: :!]
|
|
54
|
+
}
|
|
55
|
+
button {
|
|
56
|
+
stretchy false
|
|
57
|
+
text 'Save'
|
|
58
|
+
enabled <= [db_presenter, 'selected_db.saveable']
|
|
59
|
+
|
|
60
|
+
on_clicked do
|
|
61
|
+
db_presenter.save
|
|
62
|
+
end
|
|
63
|
+
}
|
|
64
|
+
button {
|
|
65
|
+
stretchy false
|
|
66
|
+
text 'Delete'
|
|
67
|
+
enabled <= [db_presenter, 'selected_db.deleteable']
|
|
68
|
+
|
|
69
|
+
on_clicked do
|
|
70
|
+
db_presenter.delete
|
|
71
|
+
end
|
|
72
|
+
}
|
|
73
|
+
button {
|
|
74
|
+
stretchy false
|
|
75
|
+
text 'New'
|
|
76
|
+
enabled <= [db_presenter, 'newable']
|
|
77
|
+
|
|
78
|
+
on_clicked do
|
|
79
|
+
db_presenter.new
|
|
80
|
+
end
|
|
81
|
+
}
|
|
41
82
|
}
|
|
42
83
|
}
|
|
43
84
|
|
|
44
85
|
button {
|
|
45
86
|
stretchy false
|
|
46
|
-
text <= [
|
|
87
|
+
text <= [db_presenter, 'selected_db.connected', on_read: -> (connected) { connected ? 'Disconnect (currently connected)' : 'Connect (currently disconnected)' }]
|
|
47
88
|
|
|
48
89
|
on_clicked do
|
|
49
|
-
|
|
90
|
+
db_presenter.selected_db.toggle_connection
|
|
50
91
|
end
|
|
51
92
|
}
|
|
52
93
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
require 'db_gui/
|
|
1
|
+
require 'db_gui/presenter/db_presenter'
|
|
2
2
|
|
|
3
3
|
require 'db_gui/view/db_gui_menu_bar'
|
|
4
4
|
require 'db_gui/view/db_config_form'
|
|
@@ -10,11 +10,11 @@ class DbGui
|
|
|
10
10
|
class DbGuiApplication
|
|
11
11
|
include Glimmer::LibUI::Application
|
|
12
12
|
|
|
13
|
-
attr_reader :
|
|
13
|
+
attr_reader :db_presenter
|
|
14
14
|
|
|
15
15
|
before_body do
|
|
16
|
-
@
|
|
17
|
-
db_gui_menu_bar(
|
|
16
|
+
@db_presenter = Presenter::DbPresenter.new
|
|
17
|
+
db_gui_menu_bar(db_presenter:)
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
body {
|
|
@@ -25,13 +25,13 @@ class DbGui
|
|
|
25
25
|
margined true
|
|
26
26
|
|
|
27
27
|
vertical_box {
|
|
28
|
-
db_config_form(
|
|
28
|
+
db_config_form(db_presenter:) {
|
|
29
29
|
stretchy false
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
db_command_form(
|
|
32
|
+
db_command_form(db_presenter:)
|
|
33
33
|
|
|
34
|
-
db_command_result_table(
|
|
34
|
+
db_command_result_table(db_presenter:)
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
37
|
}
|
|
@@ -3,55 +3,75 @@ class DbGui
|
|
|
3
3
|
class DbGuiMenuBar
|
|
4
4
|
include Glimmer::LibUI::CustomControl
|
|
5
5
|
|
|
6
|
-
option :
|
|
6
|
+
option :db_presenter
|
|
7
7
|
|
|
8
8
|
body {
|
|
9
9
|
menu('Query') {
|
|
10
10
|
menu_item('Run') {
|
|
11
11
|
on_clicked do
|
|
12
|
-
|
|
12
|
+
db_presenter.selected_db.run_db_command
|
|
13
13
|
end
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
menu('Edit') {
|
|
18
18
|
menu_item('Copy Table') {
|
|
19
|
-
enabled <= [
|
|
19
|
+
enabled <= [db_presenter, 'selected_db.db_command_result_rows', computed_by: 'selected_db.db_command_result', on_read: -> (data) { !data.empty? }]
|
|
20
20
|
|
|
21
21
|
on_clicked do
|
|
22
|
-
|
|
22
|
+
begin
|
|
23
|
+
db_presenter.selected_db.copy_table
|
|
24
|
+
rescue => e
|
|
25
|
+
puts "Encountered an error copying table: #{e.full_message}"
|
|
26
|
+
end
|
|
23
27
|
end
|
|
24
28
|
}
|
|
25
29
|
|
|
26
30
|
menu_item('Copy Table (with headers)') {
|
|
27
|
-
enabled <= [
|
|
31
|
+
enabled <= [db_presenter, 'selected_db.db_command_result_rows', computed_by: 'selected_db.db_command_result', on_read: -> (data) { !data.empty? }]
|
|
28
32
|
|
|
29
33
|
on_clicked do
|
|
30
|
-
|
|
34
|
+
begin
|
|
35
|
+
db_presenter.selected_db.copy_table_with_headers
|
|
36
|
+
rescue => e
|
|
37
|
+
puts "Encountered an error copying table (with headers): #{e.full_message}"
|
|
38
|
+
end
|
|
31
39
|
end
|
|
32
40
|
}
|
|
33
41
|
|
|
34
42
|
menu_item('Copy Table (with query & headers)') {
|
|
35
|
-
enabled <= [
|
|
43
|
+
enabled <= [db_presenter, 'selected_db.db_command_result_rows', computed_by: 'selected_db.db_command_result', on_read: -> (data) { !data.empty? }]
|
|
36
44
|
|
|
37
45
|
on_clicked do
|
|
38
|
-
|
|
46
|
+
begin
|
|
47
|
+
db_presenter.selected_db.copy_table_with_query_and_headers
|
|
48
|
+
rescue => e
|
|
49
|
+
puts "Encountered an error copying table (with query & headers): #{e.full_message}"
|
|
50
|
+
end
|
|
39
51
|
end
|
|
40
52
|
}
|
|
41
53
|
|
|
42
54
|
menu_item('Copy Selected Row') {
|
|
43
|
-
enabled <= [
|
|
55
|
+
enabled <= [db_presenter, 'selected_db.db_command_result_rows', computed_by: 'selected_db.db_command_result', on_read: -> (data) { !data.empty? }]
|
|
44
56
|
|
|
45
57
|
on_clicked do
|
|
46
|
-
|
|
58
|
+
begin
|
|
59
|
+
db_presenter.selected_db.copy_selected_row
|
|
60
|
+
rescue => e
|
|
61
|
+
puts "Encountered an error copying selected row: #{e.full_message}"
|
|
62
|
+
end
|
|
47
63
|
end
|
|
48
64
|
}
|
|
49
65
|
|
|
50
66
|
menu_item('Copy Selected Row (with headers)') {
|
|
51
|
-
enabled <= [
|
|
67
|
+
enabled <= [db_presenter, 'selected_db.db_command_result_rows', computed_by: 'selected_db.db_command_result', on_read: -> (data) { !data.empty? }]
|
|
52
68
|
|
|
53
69
|
on_clicked do
|
|
54
|
-
|
|
70
|
+
begin
|
|
71
|
+
db_presenter.selected_db.copy_selected_row_with_headers
|
|
72
|
+
rescue => e
|
|
73
|
+
puts "Encountered an error copying selected row (with headers): #{e.full_message}"
|
|
74
|
+
end
|
|
55
75
|
end
|
|
56
76
|
}
|
|
57
77
|
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: db-gui
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Andy Maleh
|
|
@@ -15,14 +15,14 @@ dependencies:
|
|
|
15
15
|
requirements:
|
|
16
16
|
- - "~>"
|
|
17
17
|
- !ruby/object:Gem::Version
|
|
18
|
-
version: 0.
|
|
18
|
+
version: 0.13.1
|
|
19
19
|
type: :runtime
|
|
20
20
|
prerelease: false
|
|
21
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
22
22
|
requirements:
|
|
23
23
|
- - "~>"
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
|
-
version: 0.
|
|
25
|
+
version: 0.13.1
|
|
26
26
|
- !ruby/object:Gem::Dependency
|
|
27
27
|
name: clipboard
|
|
28
28
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -100,6 +100,7 @@ files:
|
|
|
100
100
|
- app/db-gui.rb
|
|
101
101
|
- app/db_gui/launch.rb
|
|
102
102
|
- app/db_gui/model/db.rb
|
|
103
|
+
- app/db_gui/presenter/db_presenter.rb
|
|
103
104
|
- app/db_gui/view/db_command_form.rb
|
|
104
105
|
- app/db_gui/view/db_command_result_table.rb
|
|
105
106
|
- app/db_gui/view/db_config_form.rb
|