Class: DbGui::Model::Db

Inherits:
Struct
  • Object
show all
Defined in:
app/db_gui/model/db.rb

Constant Summary collapse

COUNT_RETRIES =
ENV.fetch('DB_COMMAND_COUNT_RETRIES', 7)
REGEX_ROW_COUNT =
/^\((\d+) row/
ERROR_PREFIX =
'ERROR:'
NEW_LINE =
OS.windows? ? "\r\n" : "\n"
NAME_NEW =
'(New Config)'

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeDb

Returns a new instance of Db.



22
23
24
25
26
27
28
29
30
# File 'app/db_gui/model/db.rb', line 22

def initialize
  load_db_command
  reset
  to_h.keys.each do |attribute|
    Glimmer::DataBinding::Observer.proc do |value|
      notify_observers(:saveable)
    end.observe(self, attribute)
  end
end

Instance Attribute Details

#connectedObject Also known as: connected?

Returns the value of attribute connected.



16
17
18
# File 'app/db_gui/model/db.rb', line 16

def connected
  @connected
end

#db_commandObject

Returns the value of attribute db_command.



19
20
21
# File 'app/db_gui/model/db.rb', line 19

def db_command
  @db_command
end

#db_command_resultObject

Returns the value of attribute db_command_result.



18
19
20
# File 'app/db_gui/model/db.rb', line 18

def db_command_result
  @db_command_result
end

#db_command_result_selectionObject

Returns the value of attribute db_command_result_selection.



20
21
22
# File 'app/db_gui/model/db.rb', line 20

def db_command_result_selection
  @db_command_result_selection
end

#db_command_timeoutObject

Returns the value of attribute db_command_timeout

Returns:

  • (Object)

    the current value of db_command_timeout



7
8
9
# File 'app/db_gui/model/db.rb', line 7

def db_command_timeout
  @db_command_timeout
end

#dbnameObject

Returns the value of attribute dbname

Returns:

  • (Object)

    the current value of dbname



7
8
9
# File 'app/db_gui/model/db.rb', line 7

def dbname
  @dbname
end

#deleteableObject

Returns the value of attribute deleteable.



14
15
16
# File 'app/db_gui/model/db.rb', line 14

def deleteable
  @deleteable
end

#hostObject

Returns the value of attribute host

Returns:

  • (Object)

    the current value of host



7
8
9
# File 'app/db_gui/model/db.rb', line 7

def host
  @host
end

#nameObject

Returns the value of attribute name

Returns:

  • (Object)

    the current value of name



7
8
9
# File 'app/db_gui/model/db.rb', line 7

def name
  @name
end

#passwordObject

Returns the value of attribute password

Returns:

  • (Object)

    the current value of password



7
8
9
# File 'app/db_gui/model/db.rb', line 7

def password
  @password
end

#portObject

Returns the value of attribute port

Returns:

  • (Object)

    the current value of port



7
8
9
# File 'app/db_gui/model/db.rb', line 7

def port
  @port
end

#usernameObject

Returns the value of attribute username

Returns:

  • (Object)

    the current value of username



7
8
9
# File 'app/db_gui/model/db.rb', line 7

def username
  @username
end

Instance Method Details

#connectObject



64
65
66
67
# File 'app/db_gui/model/db.rb', line 64

def connect
  io
  self.connected = true
end

#copy_selected_rowObject



136
137
138
139
# File 'app/db_gui/model/db.rb', line 136

def copy_selected_row
  return if db_command_result_rows.empty?
  Clipboard.copy(formatted_selected_row_string)
end

#copy_selected_row_with_headersObject



141
142
143
144
# File 'app/db_gui/model/db.rb', line 141

def copy_selected_row_with_headers
  return if db_command_result_rows.empty?
  Clipboard.copy(formatted_selected_row_string(include_headers: true))
end

#copy_tableObject



121
122
123
124
# File 'app/db_gui/model/db.rb', line 121

def copy_table
  return if db_command_result_rows.empty?
  Clipboard.copy(formatted_table_string)
end

#copy_table_with_headersObject



126
127
128
129
# File 'app/db_gui/model/db.rb', line 126

def copy_table_with_headers
  return if db_command_result_rows.empty?
  Clipboard.copy(formatted_table_string(include_headers: true))
end

#copy_table_with_query_and_headersObject



131
132
133
134
# File 'app/db_gui/model/db.rb', line 131

def copy_table_with_query_and_headers
  return if db_command_result_rows.empty?
  Clipboard.copy(formatted_table_string(include_query: true, include_headers: true))
end

#db_command_result_countObject



105
106
107
# File 'app/db_gui/model/db.rb', line 105

def db_command_result_count
  db_command_result_count_headers_rows[0]
end

#db_command_result_error?Boolean

Returns:

  • (Boolean)


117
118
119
# File 'app/db_gui/model/db.rb', line 117

def db_command_result_error?
  db_command_result.to_s.strip.start_with?(ERROR_PREFIX)
end

#db_command_result_headersObject



109
110
111
# File 'app/db_gui/model/db.rb', line 109

def db_command_result_headers
  db_command_result_count_headers_rows[1]
end

#db_command_result_rowsObject



113
114
115
# File 'app/db_gui/model/db.rb', line 113

def db_command_result_rows
  db_command_result_count_headers_rows[2]
end

#deleteable?Object

Returns the value of attribute deleteable.



15
16
17
# File 'app/db_gui/model/db.rb', line 15

def deleteable
  @deleteable
end

#disconnectObject



69
70
71
72
73
# File 'app/db_gui/model/db.rb', line 69

def disconnect
  io.close
  @io = nil
  self.connected = false
end

#formatted_selected_row_string(include_headers: false) ⇒ Object



160
161
162
163
164
165
# File 'app/db_gui/model/db.rb', line 160

def formatted_selected_row_string(include_headers: false)
  selected_row = db_command_result_rows[db_command_result_selection]
  selected_row.join(' | ')
  rows = [selected_row]
  formatted_table_string(rows, include_headers:)
end

#formatted_table_string(rows = nil, include_query: false, include_headers: false) ⇒ Object



146
147
148
149
150
151
152
153
154
155
156
157
158
# File 'app/db_gui/model/db.rb', line 146

def formatted_table_string(rows = nil, include_query: false, include_headers: false)
  rows ||= db_command_result_rows
  rows = rows.dup
  rows.prepend(db_command_result_headers) if include_headers
  column_max_lengths = row_column_max_lengths(rows)
  formatted_string = rows.map do |row|
    row.each_with_index.map do |data, column_index|
      data.ljust(column_max_lengths[column_index])
    end.join(" | ")
  end.join(NEW_LINE)
  formatted_string.prepend("#{db_command}\n\n") if include_query
  formatted_string
end

#ioObject



75
76
77
78
# File 'app/db_gui/model/db.rb', line 75

def io
  db_connection_command = "PGPASSWORD=\"#{password}\" psql --host=#{host} --port=#{port} --username=#{username} --dbname=#{dbname}"
  @io ||= IO.popen(db_connection_command, 'r+', err: [:child, :out])
end

#new?Boolean

Returns:

  • (Boolean)


44
45
46
# File 'app/db_gui/model/db.rb', line 44

def new?
  name === Db::NAME_NEW
end

#resetObject



32
33
34
35
36
37
38
39
40
41
42
# File 'app/db_gui/model/db.rb', line 32

def reset
  self.name = Db::NAME_NEW
  self.host = nil
  self.port ||= 5432 # PostgreSQL default port
  self.dbname = nil
  self.username = nil
  self.password = nil
  self.db_command_result = ''
  self.db_command_timeout ||= ENV.fetch('DB_COMMAND_TIMEOUT_IN_MILLISECONDS', 300).to_i
  self.db_command_result_selection = 0
end

#run_db_commandObject



100
101
102
103
# File 'app/db_gui/model/db.rb', line 100

def run_db_command
  run_io_command(db_command)
  save_db_command
end

#run_io_command(command) ⇒ Object



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'app/db_gui/model/db.rb', line 80

def run_io_command(command)
  command = command.strip
  command = "#{command};" unless command.end_with?(';')
  @io_command_try ||= 0
  @io_command_try += 1
  io.puts(command)
  read_io_into_db_command_result
  @io_command_try = nil
rescue Timeout::Error, Errno::EPIPE => e
  puts e.message
  @io = nil
  if @io_command_try > COUNT_RETRIES
    @io_command_try = nil
  else
    self.db_command_timeout *= 2
    puts "Retrying DB Command...  {try: #{@io_command_try + 1}, db_command_timeout: #{db_command_timeout}}"
    run_io_command(command) unless db_command_result_error?
  end
end

#saveableObject



48
49
50
# File 'app/db_gui/model/db.rb', line 48

def saveable
  !new?
end

#toggle_connectionObject



56
57
58
59
60
61
62
# File 'app/db_gui/model/db.rb', line 56

def toggle_connection
  if connected?
    disconnect
  else
    connect
  end
end