db-gui 0.2.3 → 0.3.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 +6 -0
- data/README.md +2 -2
- data/VERSION +1 -1
- data/app/db-gui.rb +5 -0
- data/app/db_gui/model/db.rb +35 -30
- data/app/db_gui/presenter/db_presenter.rb +83 -0
- data/app/db_gui/view/db_command_form.rb +5 -5
- 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: 1a78c9674da527b498d11f7147b066c48d4b9de25f4ad3bffc6d3c7f908e7380
|
|
4
|
+
data.tar.gz: 7d8c82fae0cdc343a6ef2dae98a0b820cd73fa9c6c4c128f60d1ecc751429a0a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: '021209590135c5c94cea318db98b73362c944909d5da2e168544a8524c357f4382baef9776205575459fd0f32f26ec4b86be6de943ec9f04ab0a534574b103d8'
|
|
7
|
+
data.tar.gz: 5596987aded997443eff090340dcf0b407c335e84cf2194194ec30101493d96a0b662b61fb51cae55b67a493f17d443c171dd63cc37fdd2ceb8f14c6fad0c453
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
+
## 0.3.0
|
|
4
|
+
|
|
5
|
+
- Support the ability to save/load multiple databases (DB configs)
|
|
6
|
+
- Add more resiliency against errors when copying table or record data via menu items
|
|
7
|
+
|
|
3
8
|
## 0.2.3
|
|
4
9
|
|
|
5
10
|
- 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 +13,7 @@
|
|
|
8
13
|
|
|
9
14
|
- Edit -> Copy Table (with headers) menu item to copy table data with headers as a formatted string to the clipboard
|
|
10
15
|
- Edit -> Copy Selected Row (with headers) menu item to copy selected row data with headers as a formatted string to the clipboard
|
|
16
|
+
- Query -> Run menu item to run query
|
|
11
17
|
|
|
12
18
|
## 0.2.1
|
|
13
19
|
|
data/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# DB GUI (Database Graphical User Interface) 0.
|
|
1
|
+
# DB GUI (Database Graphical User Interface) 0.3.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
|
|
|
@@ -12,7 +12,7 @@ It currently supports PostgreSQL as a start, with the potential of supporting ma
|
|
|
12
12
|
|
|
13
13
|
Run:
|
|
14
14
|
```
|
|
15
|
-
gem install db-gui -v0.
|
|
15
|
+
gem install db-gui -v0.3.0
|
|
16
16
|
```
|
|
17
17
|
|
|
18
18
|
## Usage
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.3.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,17 +4,15 @@ 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"
|
|
17
13
|
|
|
14
|
+
attr_accessor :deleteable
|
|
15
|
+
alias deleteable? deleteable
|
|
18
16
|
attr_accessor :connected
|
|
19
17
|
alias connected? connected
|
|
20
18
|
attr_accessor :db_command_result
|
|
@@ -22,13 +20,37 @@ class DbGui
|
|
|
22
20
|
attr_accessor :db_command_result_selection
|
|
23
21
|
|
|
24
22
|
def initialize
|
|
25
|
-
load_db_config
|
|
26
23
|
load_db_command
|
|
24
|
+
reset
|
|
25
|
+
to_h.keys.each do |attribute|
|
|
26
|
+
Glimmer::DataBinding::Observer.proc do |value|
|
|
27
|
+
notify_observers(:saveable)
|
|
28
|
+
end.observe(self, attribute)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def reset
|
|
33
|
+
self.name = Db::NAME_NEW
|
|
34
|
+
self.host = nil
|
|
27
35
|
self.port ||= 5432 # PostgreSQL default port
|
|
36
|
+
self.dbname = nil
|
|
37
|
+
self.username = nil
|
|
38
|
+
self.password = nil
|
|
28
39
|
self.db_command_result = ''
|
|
29
40
|
self.db_command_timeout ||= ENV.fetch('DB_COMMAND_TIMEOUT_IN_MILLISECONDS', 300).to_i
|
|
30
41
|
self.db_command_result_selection = 0
|
|
31
|
-
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def new?
|
|
45
|
+
name === Db::NAME_NEW
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def saveable
|
|
49
|
+
!new?
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def deleteable
|
|
53
|
+
!new?
|
|
32
54
|
end
|
|
33
55
|
|
|
34
56
|
def toggle_connection
|
|
@@ -42,7 +64,6 @@ class DbGui
|
|
|
42
64
|
def connect
|
|
43
65
|
io
|
|
44
66
|
self.connected = true
|
|
45
|
-
save_db_config
|
|
46
67
|
end
|
|
47
68
|
|
|
48
69
|
def disconnect
|
|
@@ -78,7 +99,6 @@ class DbGui
|
|
|
78
99
|
|
|
79
100
|
def run_db_command
|
|
80
101
|
run_io_command(db_command)
|
|
81
|
-
save_db_config
|
|
82
102
|
save_db_command
|
|
83
103
|
end
|
|
84
104
|
|
|
@@ -127,7 +147,7 @@ class DbGui
|
|
|
127
147
|
rows ||= db_command_result_rows
|
|
128
148
|
rows = rows.dup
|
|
129
149
|
rows.prepend(db_command_result_headers) if include_headers
|
|
130
|
-
column_max_lengths = row_column_max_lengths(rows)
|
|
150
|
+
column_max_lengths = row_column_max_lengths(rows)
|
|
131
151
|
formatted_string = rows.map do |row|
|
|
132
152
|
row.each_with_index.map do |data, column_index|
|
|
133
153
|
data.ljust(column_max_lengths[column_index])
|
|
@@ -162,26 +182,8 @@ class DbGui
|
|
|
162
182
|
@line = nil
|
|
163
183
|
end
|
|
164
184
|
|
|
165
|
-
def save_db_config
|
|
166
|
-
db_config_hash = to_h
|
|
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)
|
|
170
|
-
end
|
|
171
|
-
|
|
172
|
-
def load_db_config
|
|
173
|
-
db_configs_file_content = File.read(FILE_DB_CONFIGS)
|
|
174
|
-
db_configs_array = [YAML.load(db_configs_file_content)].flatten
|
|
175
|
-
db_config_hash = db_configs_array.first # TODO in the future, support loading multiple DB configs
|
|
176
|
-
db_config_hash.each do |attribute, value|
|
|
177
|
-
self.send("#{attribute}=", value)
|
|
178
|
-
end
|
|
179
|
-
rescue => e
|
|
180
|
-
puts "No database configurations stored yet. #{e.message}"
|
|
181
|
-
end
|
|
182
|
-
|
|
183
185
|
def save_db_command
|
|
184
|
-
db_commands_array = [db_command] # TODO in the future, support storing multiple DB
|
|
186
|
+
db_commands_array = [db_command] # TODO in the future, support storing multiple DB commands
|
|
185
187
|
db_commands_file_content = YAML.dump(db_commands_array)
|
|
186
188
|
File.write(FILE_DB_COMMANDS, db_commands_file_content)
|
|
187
189
|
end
|
|
@@ -212,6 +214,8 @@ class DbGui
|
|
|
212
214
|
def compute_db_command_result_count_headers_rows
|
|
213
215
|
count = 0
|
|
214
216
|
headers = rows = []
|
|
217
|
+
# TODO db_command_result.lines has an issue in case the data in the DB in a certain row contains \n
|
|
218
|
+
# Try to bisect data more correctly, maybe by looking at \n one by one
|
|
215
219
|
db_command_result_lines = db_command_result.lines.reject { |line| line == "\n" }
|
|
216
220
|
if db_command_result_lines.any?
|
|
217
221
|
headers = db_command_result_lines.first.split('|').map(&:strip)
|
|
@@ -238,5 +242,6 @@ class DbGui
|
|
|
238
242
|
column_max_lengths
|
|
239
243
|
end
|
|
240
244
|
end
|
|
245
|
+
Db::NAME_NEW = '(New Config)'
|
|
241
246
|
end
|
|
242
247
|
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,12 +7,12 @@ 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
14
|
non_wrapping_multiline_entry {
|
|
15
|
-
text <=> [
|
|
15
|
+
text <=> [db_presenter, 'selected_db.db_command']
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
horizontal_box {
|
|
@@ -20,7 +20,7 @@ class DbGui
|
|
|
20
20
|
|
|
21
21
|
button('Run') {
|
|
22
22
|
on_clicked do
|
|
23
|
-
|
|
23
|
+
db_presenter.selected_db.run_db_command
|
|
24
24
|
end
|
|
25
25
|
}
|
|
26
26
|
|
|
@@ -29,7 +29,7 @@ class DbGui
|
|
|
29
29
|
}
|
|
30
30
|
spinbox(0, TIMEOUT_MAX_IN_MILLISECONDS) {
|
|
31
31
|
stretchy false
|
|
32
|
-
value <=> [
|
|
32
|
+
value <=> [db_presenter, 'selected_db.db_command_timeout', on_read: :to_i]
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
label('Row(s): ') {
|
|
@@ -37,7 +37,7 @@ class DbGui
|
|
|
37
37
|
}
|
|
38
38
|
label {
|
|
39
39
|
stretchy false
|
|
40
|
-
text <= [
|
|
40
|
+
text <= [db_presenter, 'selected_db.db_command_result_count', computed_by: 'selected_db.db_command_result', on_read: :to_s]
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
43
|
}
|
|
@@ -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 { |me|
|
|
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.3.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
|