Class: RR::Session
- Inherits:
-
Object
- Object
- RR::Session
- Defined in:
- lib/rubyrep/session.rb
Overview
This class represents a rubyrep session. Creates and holds expensive objects like e. g. database connections.
Instance Attribute Summary collapse
-
#configuration ⇒ Object
The Configuration object provided to the initializer.
-
#proxies ⇒ Object
Hash to hold under either :left or :right the according Drb / direct DatabaseProxy.
Instance Method Summary collapse
-
#configured_table_pairs(included_table_specs = []) ⇒ Object
Returns an array of table pairs of the configured tables.
-
#connect_database(database) ⇒ Object
Set up the (proxied or direct) database connections to the specified database.
-
#corresponding_table(db_arm, table) ⇒ Object
Returns the corresponding table in the other database.
-
#database_unreachable?(database) ⇒ Boolean
Returns
true
if the specified database connection is not alive. -
#disconnect_database(database) ⇒ Object
Disconnnects the specified database *
database
: the target database (either :left
or :right
). -
#disconnect_databases ⇒ Object
Disconnects both database connections.
-
#initialize(config = Initializer::configuration) ⇒ Session
constructor
Creates a new rubyrep session with the provided Configuration.
-
#left ⇒ Object
Returns the “left” ActiveRecord / proxy database connection.
-
#left=(connection) ⇒ Object
Stores the “left” ActiveRecord /proxy database connection.
-
#manual_primary_keys(db_arm) ⇒ Object
Creates a hash of manual primary key names as can be specified with the Configuration options :
primary_key_names
or :auto_key_limit
. -
#proxied? ⇒ Boolean
Returns
true
if proxy connections are used. -
#refresh(options = {}) ⇒ Object
Refreshes both database connections *
options
: A options hash with the following settings * :forced
: iftrue
, always establish a new database connection. -
#refresh_database_connection(database, options) ⇒ Object
Refreshes the specified database connection.
-
#right ⇒ Object
Returns the “right” ActiveRecord / proxy database connection.
-
#right=(connection) ⇒ Object
Stores the “right” ActiveRecord / proxy database connection.
-
#sort_table_pairs(table_pairs) ⇒ Object
Orders the array of table pairs as per primary key / foreign key relations of the tables.
Constructor Details
#initialize(config = Initializer::configuration) ⇒ Session
Creates a new rubyrep session with the provided Configuration
220 221 222 223 224 225 226 227 228 |
# File 'lib/rubyrep/session.rb', line 220 def initialize(config = Initializer::configuration) @connections = {:left => nil, :right => nil} @proxies = {:left => nil, :right => nil} # Keep the database configuration for future reference self.configuration = config refresh end |
Instance Attribute Details
#configuration ⇒ Object
The Configuration object provided to the initializer
10 11 12 |
# File 'lib/rubyrep/session.rb', line 10 def configuration @configuration end |
#proxies ⇒ Object
Hash to hold under either :left or :right the according Drb / direct DatabaseProxy
33 34 35 |
# File 'lib/rubyrep/session.rb', line 33 def proxies @proxies end |
Instance Method Details
#configured_table_pairs(included_table_specs = []) ⇒ Object
Returns an array of table pairs of the configured tables. Refer to TableSpecResolver#resolve for a detailed description of the return value. If included_table_specs
is provided (that is: not an empty array), it will be used instead of the configured table specs.
97 98 99 100 101 |
# File 'lib/rubyrep/session.rb', line 97 def configured_table_pairs(included_table_specs = []) resolver = TableSpecResolver.new self included_table_specs = configuration.included_table_specs if included_table_specs.empty? resolver.resolve included_table_specs, configuration.excluded_table_specs end |
#connect_database(database) ⇒ Object
Set up the (proxied or direct) database connections to the specified database.
-
database
: the target database (either :left
or :right
)
197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 |
# File 'lib/rubyrep/session.rb', line 197 def connect_database(database) if configuration.left == configuration.right and database == :right # If both database configurations point to the same database # then don't create the database connection twice. # Assumes that the left database is always connected before the right one. self.right = self.left else # Connect the database / proxy arm_config = configuration.send database if arm_config.include? :proxy_host drb_url = "druby://#{arm_config[:proxy_host]}:#{arm_config[:proxy_port]}" @proxies[database] = DRbObject.new nil, drb_url else # Create fake proxy @proxies[database] = DatabaseProxy.new end @connections[database] = @proxies[database].create_session arm_config send(database).manual_primary_keys = manual_primary_keys(database) end end |
#corresponding_table(db_arm, table) ⇒ Object
Returns the corresponding table in the other database.
-
db_arm
: database of the given table (either :left
or :right
) -
table
: name of the table
If no corresponding table can be found, return the given table. Rationale: Support the case where a table was dropped from the configuration but there were still some unreplicated changes left.
73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/rubyrep/session.rb', line 73 def corresponding_table(db_arm, table) unless @table_map @table_map = {:left => {}, :right => {}} resolver = TableSpecResolver.new self table_pairs = resolver.resolve configuration.included_table_specs, [], false table_pairs.each do |table_pair| @table_map[:left][table_pair[:left]] = table_pair[:right] @table_map[:right][table_pair[:right]] = table_pair[:left] end end @table_map[db_arm][table] || table end |
#database_unreachable?(database) ⇒ Boolean
Returns true
if the specified database connection is not alive.
-
database
: target database (either:left
or :right
)
124 125 126 127 128 129 130 131 132 133 134 |
# File 'lib/rubyrep/session.rb', line 124 def database_unreachable?(database) unreachable = true Thread.new do begin if send(database) && send(database).select_one("select 1+1 as x")['x'].to_i == 2 unreachable = false # database is actually reachable end end rescue nil end.join configuration.[:database_connection_timeout] unreachable end |
#disconnect_database(database) ⇒ Object
Disconnnects the specified database
-
database
: the target database (either :left
or :right
)
145 146 147 148 149 150 151 152 |
# File 'lib/rubyrep/session.rb', line 145 def disconnect_database(database) proxy, connection = @proxies[database], @connections[database] @proxies[database] = nil @connections[database] = nil if proxy proxy.destroy_session(connection) end end |
#disconnect_databases ⇒ Object
Disconnects both database connections
137 138 139 140 141 |
# File 'lib/rubyrep/session.rb', line 137 def disconnect_databases [:left, :right].each do |database| disconnect_database(database) end end |
#left ⇒ Object
Returns the “left” ActiveRecord / proxy database connection
13 14 15 |
# File 'lib/rubyrep/session.rb', line 13 def left @connections[:left] end |
#left=(connection) ⇒ Object
Stores the “left” ActiveRecord /proxy database connection
18 19 20 |
# File 'lib/rubyrep/session.rb', line 18 def left=(connection) @connections[:left] = connection end |
#manual_primary_keys(db_arm) ⇒ Object
Creates a hash of manual primary key names as can be specified with the Configuration options :primary_key_names
or :auto_key_limit
.
-
+db_arm: should be either :left or :right
Returns the identified manual primary keys. This is a hash with
-
key: table_name
-
value: array of primary key names
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/rubyrep/session.rb', line 42 def manual_primary_keys(db_arm) manual_primary_keys = {} resolver = TableSpecResolver.new self table_pairs = resolver.resolve configuration.included_table_specs, [], false table_pairs.each do |table_pair| = configuration.(table_pair[:left]) key_names = [:key] if key_names == nil and [:auto_key_limit] > 0 if left.primary_key_names(table_pair[:left], :raw => true).empty? column_names = left.column_names(table_pair[:left]) if column_names.size <= [:auto_key_limit] key_names = column_names end end end if key_names table_name = table_pair[db_arm] manual_primary_keys[table_name] = [key_names].flatten end end manual_primary_keys end |
#proxied? ⇒ Boolean
Returns true
if proxy connections are used
87 88 89 90 |
# File 'lib/rubyrep/session.rb', line 87 def proxied? [configuration.left, configuration.right].any? \ {|arm_config| arm_config.include? :proxy_host} end |
#refresh(options = {}) ⇒ Object
Refreshes both database connections
-
options
: A options hash with the following settings-
:
forced
: iftrue
, always establish a new database connection
-
157 158 159 |
# File 'lib/rubyrep/session.rb', line 157 def refresh( = {}) [:left, :right].each {|database| refresh_database_connection database, } end |
#refresh_database_connection(database, options) ⇒ Object
Refreshes the specified database connection. (I. e. reestablish if not active anymore.)
-
database
: target database (either :left
or :right
) -
options
: A options hash with the following settings-
:
forced
: iftrue
, always establish a new database connection
-
166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 |
# File 'lib/rubyrep/session.rb', line 166 def refresh_database_connection(database, ) if [:forced] or database_unreachable?(database) # step 1: disconnect both database connection (if still possible) begin Thread.new do disconnect_database database rescue nil end.join configuration.[:database_connection_timeout] end connect_exception = nil # step 2: try to reconnect the database Thread.new do begin connect_database database rescue Exception => e # save exception so it can be rethrown outside of the thread connect_exception = e end end.join configuration.[:database_connection_timeout] raise connect_exception if connect_exception # step 3: verify if database connections actually work (to detect silent connection failures) if database_unreachable?(database) raise "no connection to '#{database}' database" end end end |
#right ⇒ Object
Returns the “right” ActiveRecord / proxy database connection
23 24 25 |
# File 'lib/rubyrep/session.rb', line 23 def right @connections[:right] end |
#right=(connection) ⇒ Object
Stores the “right” ActiveRecord / proxy database connection
28 29 30 |
# File 'lib/rubyrep/session.rb', line 28 def right=(connection) @connections[:right] = connection end |
#sort_table_pairs(table_pairs) ⇒ Object
Orders the array of table pairs as per primary key / foreign key relations of the tables. Returns the result. Only sorts if the configuration has set option :table_ordering
. Refer to TableSpecResolver#resolve for a detailed description of the parameter and return value.
108 109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/rubyrep/session.rb', line 108 def sort_table_pairs(table_pairs) if configuration.[:table_ordering] left_tables = table_pairs.map {|table_pair| table_pair[:left]} sorted_left_tables = TableSorter.new(self, left_tables).sort sorted_left_tables.map do |left_table| table_pairs.find do |table_pair| table_pair[:left] == left_table end end else table_pairs end end |