Class: RR::Session

Inherits:
Object
  • Object
show all
Defined in:
lib/rubyrep/session.rb,
lib/rubyrep/logged_change.rb

Overview

This class represents a rubyrep session. Creates and holds expensive objects like e. g. database connections.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config = Initializer::configuration) ⇒ Session

Creates a new rubyrep session with the provided Configuration



153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
# File 'lib/rubyrep/session.rb', line 153

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

  # Determine method of connection (either 'proxy_connect' or 'db_connect'
  connection_method = proxied? ? :proxy_connect : :db_connect
  
  # Connect the left database / proxy
  self.send connection_method, :left, configuration
  left.manual_primary_keys = manual_primary_keys(:left)
  
  # If both database configurations point to the same database
  # then don't create the database connection twice
  if configuration.left == configuration.right
    self.right = self.left
  else
    self.send connection_method, :right, configuration
    right.manual_primary_keys = manual_primary_keys(:right)
  end  
end

Instance Attribute Details

#configurationObject

The Configuration object provided to the initializer



10
11
12
# File 'lib/rubyrep/session.rb', line 10

def configuration
  @configuration
end

#proxiesObject

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

#change_loader(database) ⇒ Object

Returns the LoggedChangeLoader of the specified database.

  • database: either :left or :right



7
8
9
10
11
12
13
# File 'lib/rubyrep/logged_change.rb', line 7

def change_loader(database)
  @change_loaders ||= {}
  unless change_loader = @change_loaders[database]
    change_loader = @change_loaders[database] = LoggedChangeLoader.new(self, database)
  end
  change_loader
end

#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.



122
123
124
125
126
# File 'lib/rubyrep/session.rb', line 122

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

#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

#db_connect(db_arm, config) ⇒ Object

Does the actual work of establishing a database connection

db_arm

should be either :left or :right

config

the rubyrep Configuration



89
90
91
92
93
# File 'lib/rubyrep/session.rb', line 89

def db_connect(db_arm, config)
  arm_config = config.send db_arm
  @proxies[db_arm] = DatabaseProxy.new
  @connections[db_arm] = @proxies[db_arm].create_session arm_config
end

#leftObject

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|
    options = configuration.options_for_table(table_pair[:left])
    key_names = options[:key]
    if key_names == nil and options[: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 <= options[: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

True if proxy connections are used

Returns:

  • (Boolean)


112
113
114
115
# File 'lib/rubyrep/session.rb', line 112

def proxied?
  [configuration.left, configuration.right].any? \
    {|arm_config| arm_config.include? :proxy_host}
end

#proxy_connect(db_arm, config) ⇒ Object

Does the actual work of establishing a proxy connection

db_arm

should be either :left or :right

config

the rubyrep Configuration



98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/rubyrep/session.rb', line 98

def proxy_connect(db_arm, config)
  arm_config = config.send db_arm
  if arm_config.include? :proxy_host 
    drb_url = "druby://#{arm_config[:proxy_host]}:#{arm_config[:proxy_port]}"
    @proxies[db_arm] = DRbObject.new nil, drb_url
  else
    # If one connection goes through a proxy, so has the other one.
    # So if necessary, create a "fake" proxy
    @proxies[db_arm] = DatabaseProxy.new
  end
  @connections[db_arm] = @proxies[db_arm].create_session arm_config
end

#refreshObject

Refreshes (reestablish if no more active) the database connections.



148
149
150
# File 'lib/rubyrep/session.rb', line 148

def refresh
  [:left, :right].each {|database| send(database).refresh}
end

#reload_changesObject

Forces an update of the change log cache



16
17
18
19
# File 'lib/rubyrep/logged_change.rb', line 16

def reload_changes
  change_loader(:left).update :forced => true
  change_loader(:right).update :forced => true
end

#rightObject

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.



133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/rubyrep/session.rb', line 133

def sort_table_pairs(table_pairs)
  if configuration.options[: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