connection_manager 0.1.4 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- connection_manager (0.1.4)
4
+ connection_manager (0.2.0)
5
5
  activerecord (~> 3.0)
6
6
 
7
7
  GEM
@@ -39,7 +39,7 @@ GEM
39
39
  rspec-expectations (2.7.0)
40
40
  diff-lcs (~> 1.1.2)
41
41
  rspec-mocks (2.7.0)
42
- sqlite3 (1.3.4)
42
+ sqlite3 (1.3.5)
43
43
  tzinfo (0.3.31)
44
44
 
45
45
  PLATFORMS
data/README.md CHANGED
@@ -119,7 +119,7 @@ available slave connections each time it is called using a different connection
119
119
  User.slave.where(['created_at BETWEEN ? and ?',Time.now - 5.days, Time.now]).all => returns results from slave_2_user_data_development
120
120
 
121
121
  ## TODO's
122
- * sharding
122
+ * sharding - IN 2.0 AS BETA
123
123
 
124
124
  ## Other activerecord Connection gems
125
125
  * [Octopus](https://github.com/tchandy/octopus)
@@ -26,4 +26,3 @@ module ConnectionManager
26
26
  end
27
27
  end
28
28
  end
29
- ActiveRecord::Base.extend(ConnectionManager::Associations)
@@ -3,7 +3,7 @@ module ConnectionManager
3
3
  class << self
4
4
  @connection_keys
5
5
  @all
6
- @replication_connections
6
+ @secondary_connections
7
7
  @env
8
8
 
9
9
  def env
@@ -16,7 +16,7 @@ module ConnectionManager
16
16
  end
17
17
 
18
18
  # Get the current environment if defined
19
- # Check for Rails, check for RACK_ENV, fail back to 'development'
19
+ # Check for Rails, check for RACK_ENV, default to 'development'
20
20
  def fetch_env
21
21
  return Rails.env if defined?(Rails)
22
22
  return RACK_ENV if defined?(RACK_ENV)
@@ -36,23 +36,23 @@ module ConnectionManager
36
36
  end
37
37
 
38
38
  # Holds connections
39
- def replication_connections
40
- @replication_connections ||= {}
39
+ def secondary_connections
40
+ @secondary_connections ||= {}
41
41
  end
42
42
 
43
43
  # Returns the database value given a connection key from the database.yml
44
44
  def database_name_from_yml(name_from_yml)
45
- ActiveRecord::Base.configurations[name_from_yml]['database']
45
+ clean_db_name(ActiveRecord::Base.configurations[name_from_yml]['database'])
46
46
  end
47
-
48
- def clean_sqlite_db_name(name)
47
+
48
+ def clean_sqlite_db_name(name,remove_env=true)
49
49
  new_name = "#{name}".gsub(/(\.sqlite3$)/,'')
50
50
  new_name = new_name.split("/").last
51
- new_name.gsub!(Regexp.new("(\_#{env}$)"),'')
51
+ new_name.gsub!(Regexp.new("(\_#{env}$)"),'') if remove_env
52
52
  new_name
53
53
  end
54
54
 
55
- def clean_bd_name(name)
55
+ def clean_db_name(name)
56
56
  new_name = "#{name}".gsub(Regexp.new("#{env}$"),'')
57
57
  if new_name.blank?
58
58
  new_name = "#{database_name_from_yml(name)}"
@@ -64,27 +64,27 @@ module ConnectionManager
64
64
  # Given an connection key name from the database.yml, returns the string
65
65
  # equivelent of the class name for that entry.
66
66
  def connection_class_name(name_from_yml)
67
- new_class_name = clean_bd_name(name_from_yml)
67
+ new_class_name = clean_db_name(name_from_yml)
68
68
  new_class_name = new_class_name.gsub(/\_/,' ').titleize.gsub(/ /,'')
69
69
  new_class_name << "Connection"
70
70
  new_class_name
71
71
  end
72
72
 
73
- def replication_key(name_from_yml)
74
- rep_name = clean_bd_name(name_from_yml)
73
+ def secondary_key(name_from_yml)
74
+ rep_name = clean_db_name(name_from_yml)
75
75
  rep_name.gsub!(/(\_)+(\d+)/,'')
76
76
  rep_name.to_sym
77
77
  end
78
78
 
79
- def add_replication_connection(name_from_yml,new_connection)
80
- key = replication_key(name_from_yml)
81
- replication_connections[key] ||= []
82
- replication_connections[key] << new_connection
83
- replication_connections
79
+ def add_secondary_connection(name_from_yml,new_connection)
80
+ key = secondary_key(name_from_yml)
81
+ secondary_connections[key] ||= []
82
+ secondary_connections[key] << new_connection
83
+ secondary_connections
84
84
  end
85
85
 
86
- def connections_for_replication(rep_collection_key)
87
- replication_connections[(rep_collection_key.gsub(Regexp.new("(\_#{env}$)"),'')).to_sym]
86
+ def available_secondary_connections(rep_collection_key)
87
+ secondary_connections[(rep_collection_key.gsub(Regexp.new("(\_#{env}$)"),'')).to_sym]
88
88
  end
89
89
 
90
90
  # Sets class instance attributes, then builds connection classes, while populating
@@ -95,7 +95,7 @@ module ConnectionManager
95
95
  end
96
96
  connection_keys.each do |connection|
97
97
  new_connection = connection_class_name(connection)
98
- add_replication_connection(connection,new_connection)
98
+ add_secondary_connection(connection,new_connection)
99
99
  build_connection_class(new_connection,connection)
100
100
  end
101
101
  all
@@ -104,12 +104,13 @@ module ConnectionManager
104
104
  # Addes a conneciton subclass to Connections using the supplied
105
105
  # class name and connection key from database.yml
106
106
  def build_connection_class(class_name,connection_key)
107
- class_eval <<-STR, __FILE__, __LINE__
108
- class #{class_name} < ActiveRecord::Base
107
+ klass = Class.new(ActiveRecord::Base) do
109
108
  self.abstract_class = true
110
- establish_connection("#{connection_key}")
111
109
  end
112
- STR
110
+ new_connection_class = Object.const_set(class_name, klass)
111
+ new_connection_class.establish_connection(connection_key)
112
+
113
+ (const_set class_name, new_connection_class)
113
114
  all << class_name
114
115
  end
115
116
  end
@@ -0,0 +1,57 @@
1
+ require 'active_record'
2
+ module ConnectionManager
3
+ class MethodRecorder
4
+ attr_accessor :classes_to_call
5
+
6
+ def initialize(classes_to_call=[])
7
+ self.classes_to_call = classes_to_call
8
+ end
9
+
10
+ # A place to store our methods and thier variables
11
+ def recordings
12
+ @recordings ||= {}
13
+ end
14
+
15
+ def execute_recordings
16
+ results = []
17
+ classes_to_call.each do |class_to_call|
18
+ called = nil
19
+ recordings.each do |name,args|
20
+ args = args[0] if [Array, Hash].include?args[0].class
21
+ if called.nil?
22
+ if args.blank?
23
+ called = class_to_call.send(name.to_sym)
24
+ else
25
+ called = class_to_call.send(name.to_sym, args)
26
+ end
27
+ else
28
+ if args.blank?
29
+ called = called.send(name.to_sym)
30
+ else
31
+ called = called.send(name.to_sym, args)
32
+ end
33
+ end
34
+ end
35
+ if called.is_a?(Array)
36
+ results = (results | called)
37
+ else
38
+ results << called
39
+ end
40
+ end
41
+ results
42
+ end
43
+
44
+ # Create recorder classes for methods that might be called on a ActiveRecord
45
+ # model in the process of building a query
46
+ (ActiveRecord::FinderMethods.instance_methods | ActiveRecord::QueryMethods.instance_methods).each do |method|
47
+ define_method(method) do |*args|
48
+ recordings[method] = args
49
+ self
50
+ end
51
+ end
52
+
53
+ def execute
54
+ execute_recordings
55
+ end
56
+ end
57
+ end
@@ -1,11 +1,11 @@
1
1
  module ConnectionManager
2
- module ReplicationBuilder
2
+ module SecondaryConnectionBuilder
3
3
 
4
4
  def database_name
5
5
  "#{connection.instance_variable_get(:@config)[:database].to_s}"
6
6
  end
7
7
 
8
- def replication_association_options(method,association,class_name,options={})
8
+ def secondary_association_options(method,association,class_name,options={})
9
9
  new_options = {}.merge(options)
10
10
  if new_options[:class_name].blank?
11
11
  new_options[:class_name] = "#{association.to_s.singularize.classify}::#{class_name}"
@@ -19,14 +19,14 @@ module ConnectionManager
19
19
  new_options
20
20
  end
21
21
 
22
- def build_replication_associations(class_name)
22
+ def build_secondary_associations(class_name)
23
23
  str = ""
24
24
  defined_associations.each do |method,defs|
25
25
  unless defs.blank?
26
26
  defs.each do |association,options|
27
27
  options = {} if options.blank?
28
28
  unless options[:no_readonly] || options[:class_name].to_s.match("::#{class_name}")
29
- str << "#{method.to_s} :#{association}, #{replication_association_options(method,association,class_name,options)};"
29
+ str << "#{method.to_s} :#{association}, #{secondary_association_options(method,association,class_name,options)};"
30
30
  end
31
31
  end
32
32
  end
@@ -34,28 +34,36 @@ module ConnectionManager
34
34
  str
35
35
  end
36
36
 
37
- def replication_connection_classes(options)
37
+ def secondary_connection_classes(options)
38
38
  if options[:using] && options[:using].is_a?(Array)
39
39
  connection_classes = options[:using].collect{|c| Connections.connection_class_name(c)}
40
40
  else
41
41
  rep_name = "#{options[:name].to_s}_#{Connections.clean_sqlite_db_name(database_name)}"
42
- connection_classes = Connections.connections_for_replication(rep_name)
42
+ connection_classes = Connections.available_secondary_connections(rep_name)
43
43
  end
44
44
  connection_classes
45
45
  end
46
-
47
46
 
47
+ def replicated(*settings)
48
+ options = {:name => "slave", :readonly => true, :replication => true}.merge(settings.extract_options!)
49
+ build_secondary_connections(options)
50
+ end
51
+
52
+ def sharded(*settings)
53
+ options = {:name => "shard", :readonly => false, :shards => true}.merge(settings.extract_options!)
54
+ build_secondary_connections(options)
55
+ end
56
+
48
57
  # Adds subclass with the class name of the type provided in the options, which
49
58
  # defaults to 'slave' if blank, that uses the connection from a connection class.
50
59
  # If :database option is blank?, replicated will assume the database.yml has
51
60
  # slave connections defined as: slave_database_name_test or slave_1_database_name_test,
52
- # where slave_1 is the replication instance, 'database_name' is the actual
61
+ # where slave_1 is the secondary instance, 'database_name' is the actual
53
62
  # name of the database and '_test' is the Rails environment
54
- def replicated(*settings)
55
- options = {:name => "slave", :readonly => true}.merge(settings.extract_options!)
56
- connection_classes = replication_connection_classes(options)
63
+ def build_secondary_connections(options={})
64
+ connection_classes = secondary_connection_classes(options)
57
65
  if connection_classes.blank?
58
- raise ArgumentError, " a replication connection was not found. Check your database.yml."
66
+ raise ArgumentError, " a secondary connection was not found. Check your database.yml."
59
67
  else
60
68
  connection_methods = []
61
69
  connection_classes.each do |c|
@@ -64,32 +72,34 @@ module ConnectionManager
64
72
  method_name = method_name.insert(method_name.index(/\d/),"_")
65
73
  class_name = method_name.classify
66
74
  connection_methods << method_name.to_sym
67
- build_replication_class(class_name,c,options)
68
- build_single_replication_method(method_name,class_name)
75
+ build_secondary_class(class_name,c,options)
76
+ build_single_secondary_method(method_name,class_name)
77
+ set_table_name_for_joins
69
78
  end
70
79
  end
71
- build_full_replication_method(options,connection_methods)
72
-
80
+
81
+ build_slaves_method(connection_methods) if options[:replication]
82
+ build_shards_method(connection_methods) if options[:shards]
73
83
  end
74
84
 
75
85
  # Creats a subclass that inherets from the model. The default model_name
76
86
  # class method is overriden to return the super's name, which ensures rails
77
- # helpers like link_to called on a replication stance generate a url for the
78
- # master database. If options include readonly, build_replication_class also
87
+ # helpers like link_to called on a secondary stance generate a url for the
88
+ # master database. If options include readonly, build_secondary_class also
79
89
  # overrides the rails "readonly?" method to ensure saves are prevented.
80
- # Replication class can be called directly for operaitons.
90
+ # secondary class can be called directly for operaitons.
81
91
  # Usage:
82
92
  # User::Slave1.where(:id => 1).first => returns results from slave_1 database
83
- # User::Slave2.where(:id => 2).first => returns results from slave_1 database
84
- def build_replication_class(class_name,connection_name,options)
93
+ # User::Slave2.where(:id => 2).first => returns results from slave_2 database
94
+ # User::Shard1.where(:id => 2).first => returns results from slave_1 database
95
+ def build_secondary_class(class_name,connection_name,options)
85
96
  class_eval <<-STR, __FILE__, __LINE__
86
97
  class #{class_name} < self
87
- #{build_replication_associations(class_name)}
98
+ #{build_secondary_associations(class_name)}
88
99
  class << self
89
100
  def connection
90
101
  Connections::#{connection_name}.connection
91
102
  end
92
-
93
103
  def model_name
94
104
  ActiveModel::Name.new(#{name})
95
105
  end
@@ -99,11 +109,15 @@ module ConnectionManager
99
109
  STR
100
110
  end
101
111
 
102
- # Adds as class method to call a specific replication conneciton.
112
+ def set_table_name_for_joins
113
+ self.table_name_prefix = "#{database_name}." unless database_name.match(/\.sqlite3$/)
114
+ end
115
+
116
+ # Adds as class method to call a specific secondary conneciton.
103
117
  # Usage:
104
118
  # User.slave_1.where(:id => 2).first => returns results from slave_1 database
105
119
  # User.slave_2.where(:id => 2).first => returns results from slave_2 database
106
- def build_single_replication_method(method_name,class_name)
120
+ def build_single_secondary_method(method_name,class_name)
107
121
  class_eval <<-STR, __FILE__, __LINE__
108
122
  class << self
109
123
  def #{method_name}
@@ -117,21 +131,36 @@ module ConnectionManager
117
131
  # on each call.
118
132
  # Usage:
119
133
  # User.slave.where(:id => 2).first => can return results from slave_1 or slave_2
120
- def build_full_replication_method(options,connection_methods)
134
+ def build_slaves_method(connection_methods)
121
135
  class_eval <<-STR, __FILE__, __LINE__
122
136
  @connection_methods = #{connection_methods}
123
137
  class << self
124
- def #{options[:name].to_s}
138
+ def slaves
125
139
  current = @connection_methods.shift
126
140
  @connection_methods << current
127
141
  send(current)
128
142
  end
143
+ alias :slave :slaves
129
144
  def connection_methods
130
145
  @connection_methods
131
146
  end
132
147
  end
133
148
  STR
134
149
  end
150
+
151
+ # add a class method that shifts through available connections methods
152
+ # on each call.
153
+ # Usage:
154
+ # User.shards.where(:id => 2).first => can return results from slave_1 or slave_2
155
+ def build_shards_method(connection_methods)
156
+ class_eval <<-STR, __FILE__, __LINE__
157
+ @shard_connection_methods = #{connection_methods}
158
+ class << self
159
+ def shards
160
+ ConnectionManager::MethodRecorder.new(@shard_connection_methods)
161
+ end
162
+ end
163
+ STR
164
+ end
135
165
  end
136
- end
137
- ActiveRecord::Base.extend(ConnectionManager::ReplicationBuilder)
166
+ end
@@ -1,4 +1,4 @@
1
1
  module ConnectionManager
2
- VERSION = "0.1.4"
2
+ VERSION = "0.2.0"
3
3
  end
4
4
 
@@ -4,7 +4,12 @@ module ConnectionManager
4
4
  require 'active_record'
5
5
  require 'connection_manager/connections'
6
6
  require 'connection_manager/associations'
7
- require 'connection_manager/replication_builder'
8
- require 'connection_manager/connection_manager_railtie.rb' if defined?(Rails)
7
+ require 'connection_manager/secondary_connection_builder'
8
+ require 'connection_manager/method_recorder'
9
+ require 'connection_manager/connection_manager_railtie.rb' if defined?(Rails)
10
+
11
+ ActiveRecord::Base.extend(ConnectionManager::Associations)
12
+ ActiveRecord::Base.extend(ConnectionManager::SecondaryConnectionBuilder)
13
+
9
14
  end
10
15
 
data/spec/database.yml CHANGED
@@ -17,4 +17,10 @@ slave_2_cm_test:
17
17
  adapter: sqlite3
18
18
  database: spec/cm_test.sqlite3
19
19
  pool: 5
20
- timeout: 5000
20
+ timeout: 5000
21
+
22
+ shard_1_cm_test:
23
+ adapter: sqlite3
24
+ database: spec/legacy_cm_test.sqlite3
25
+ pool: 5
26
+ timeout: 5000
@@ -2,11 +2,11 @@ require 'spec_helper'
2
2
 
3
3
  # Tests for associations build form replication.
4
4
 
5
- describe ConnectionManager::ReplicationBuilder do
5
+ describe ConnectionManager::SecondaryConnectionBuilder do
6
6
  before(:all) do
7
7
  # Make sure connections recreated in other tests do not presist to current
8
8
  ConnectionManager::Connections.all.clear
9
- ConnectionManager::Connections.replication_connections.clear
9
+ ConnectionManager::Connections.secondary_connections.clear
10
10
 
11
11
  #Initialize
12
12
  ConnectionManager::Connections.initialize(:env => 'test')
@@ -44,8 +44,7 @@ describe ConnectionManager::ReplicationBuilder do
44
44
  context "slave" do
45
45
  context('belongs_to') do
46
46
  it "should return the same belongs to object as master" do
47
- fruit = Factory.create(:fruit)
48
-
47
+ fruit = Factory.create(:fruit)
49
48
  slave_fruit = Fruit.slave.where(:id => fruit.id).first
50
49
  slave_fruit.region.id.should eql(fruit.region.id)
51
50
  end
@@ -1,15 +1,16 @@
1
1
  require 'spec_helper'
2
-
3
2
  class Foo < ActiveRecord::Base
4
3
  belongs_to :that
5
4
  has_many :foo_bars
6
5
  has_many :bars, :through => :foo_bars
7
6
  has_one :noob
8
7
  end
8
+
9
9
  class Bar < ActiveRecord::Base
10
10
  has_many :foo_bars
11
11
  has_many :foos, :through => :foo_bars
12
12
  end
13
+
13
14
  describe ConnectionManager::Associations do
14
15
 
15
16
  it "should add associations as keys to @defined_associations" do
@@ -10,20 +10,20 @@ describe ConnectionManager::Connections do
10
10
  end
11
11
  end
12
12
 
13
- context '#clean_bd_name' do
13
+ context '#clean_db_name' do
14
14
  context "when name is not just the Rails.env" do
15
15
  it "should remove the Rails.env from the string" do
16
- ConnectionManager::Connections.clean_bd_name("my_database_test").should eql("my_database")
16
+ ConnectionManager::Connections.clean_db_name("my_database_test").should eql("my_database")
17
17
  end
18
18
  end
19
19
  context "when the name is only the Rails.env" do
20
20
  it "should use the name of the database and remove the Rails.env" do
21
21
  ConnectionManager::Connections.stubs(:database_name_from_yml).returns("my_database_test")
22
- ConnectionManager::Connections.clean_bd_name("test").should eql("my_database")
22
+ ConnectionManager::Connections.clean_db_name("test").should eql("my_database")
23
23
  end
24
24
  it "should account for sqlite3 database name" do
25
25
  ConnectionManager::Connections.stubs(:database_name_from_yml).returns("db/my_database_test.sqlite3")
26
- ConnectionManager::Connections.clean_bd_name("test").should eql("my_database")
26
+ ConnectionManager::Connections.clean_db_name("test").should eql("my_database")
27
27
  end
28
28
  end
29
29
  end
@@ -50,7 +50,7 @@ describe ConnectionManager::Connections do
50
50
  before(:all) do
51
51
  # Make sure connections recreated in other tests do not presist to tests tests
52
52
  ConnectionManager::Connections.all.clear
53
- ConnectionManager::Connections.replication_connections.clear
53
+ ConnectionManager::Connections.secondary_connections.clear
54
54
 
55
55
  #Initialize
56
56
  ConnectionManager::Connections.initialize(:env => 'test')
@@ -58,18 +58,18 @@ describe ConnectionManager::Connections do
58
58
 
59
59
  context '#all' do
60
60
  it "should return the database.yml entries for the current rails environment" do
61
- ConnectionManager::Connections.all.should eql(["CmConnection",
62
- "Slave1CmConnection", "Slave2CmConnection"])
61
+ ConnectionManager::Connections.all.should eql(["CmConnection",
62
+ "Slave1CmConnection", "Slave2CmConnection", "Shard1CmConnection"])
63
63
  end
64
64
  end
65
65
 
66
- context '#replication_connections' do
66
+ context '#secondary_connections' do
67
67
  it "should return a hash where the keys are the generic undescored names for all connections" do
68
- ConnectionManager::Connections.replication_connections.keys.
69
- should eql([:cm, :slave_cm])
68
+ ConnectionManager::Connections.secondary_connections.keys.
69
+ should eql([:cm, :slave_cm, :shard_cm])
70
70
  end
71
71
  it "should return a hash where the values are an array of connection class names as strings" do
72
- first_value = ConnectionManager::Connections.replication_connections.values.first
72
+ first_value = ConnectionManager::Connections.secondary_connections.values.first
73
73
  first_value.class.should eql(Array)
74
74
  defined?((ConnectionManager::Connections.class_eval(first_value[0]))).should be_true
75
75
  end
@@ -86,8 +86,7 @@ describe ConnectionManager::Connections do
86
86
  it "should have a super class of ActiveRecord::Base" do
87
87
  ConnectionManager::Connections::MyConnectionClass.superclass.should eql(ActiveRecord::Base)
88
88
  end
89
- end
90
-
89
+ end
91
90
  end
92
91
  end
93
92
 
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+
3
+ describe ConnectionManager::MethodRecorder do
4
+ before(:each) do
5
+ class Fruit < ActiveRecord::Base
6
+ #include ConnectionManager::MethodRecorder
7
+ def self.shards
8
+ ConnectionManager::MethodRecorder.new([self])
9
+ end
10
+ end
11
+ end
12
+ context 'shards'do
13
+ it "it should record methods" do
14
+ a = Fruit.shards.select('fruits.*').where(:id => 1).order('created_at').first
15
+ a.recordings.should eql({:select => ['fruits.*'], :where => [:id =>1], :order => ['created_at'], :first => []})
16
+ end
17
+
18
+ context '#execute' do
19
+ it "should return an array of results" do
20
+ a = Fruit.shards.first.execute
21
+ a.should be_a_kind_of(Array)
22
+ end
23
+ it "should execute the active record methods on the the provided class" do
24
+ fruit = Factory.create(:fruit)
25
+ class_to_call = Fruit
26
+ a = class_to_call.shards.where(:id => fruit.id).first.execute
27
+ a[0].should be_a_kind_of(class_to_call)
28
+ end
29
+
30
+ it "should not matter how the where statement is formated" do
31
+ fruit = Factory.create(:fruit)
32
+ a = Fruit.shards.where(:id => fruit.id).first.execute
33
+ b = Fruit.shards.where(['id = ?', fruit.id]).first.execute
34
+ c = Fruit.shards.where('id = ?', fruit.id).first.execute
35
+ (a == b && b == c).should be_true
36
+ end
37
+ end
38
+ end
39
+ end
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe ConnectionManager::ReplicationBuilder do
3
+ describe ConnectionManager::SecondaryConnectionBuilder do
4
4
 
5
5
  context '#database_name' do
6
6
  it "should return the name of the database the model is using" do
@@ -11,28 +11,28 @@ describe ConnectionManager::ReplicationBuilder do
11
11
  context '#other_association_options' do
12
12
 
13
13
  it "should add :class_name options set to the replication subclass if :class_name is blank" do
14
- options = Fruit.replication_association_options(:has_one, :plant, 'Slave')
14
+ options = Fruit.secondary_association_options(:has_one, :plant, 'Slave')
15
15
  options[:class_name].should eql("Plant::Slave")
16
16
  end
17
17
 
18
18
  it "should append :class_name with the replication subclass if :class_name is not bank" do
19
- options = Fruit.replication_association_options(:has_one, :plant, 'Slave', :class_name => 'Plant')
19
+ options = Fruit.secondary_association_options(:has_one, :plant, 'Slave', :class_name => 'Plant')
20
20
  options[:class_name].should eql("Plant::Slave")
21
21
  end
22
22
 
23
23
  context "has_one or has_many" do
24
24
  it "should add the :foreign_key if the :foreign_key options is not present" do
25
- options = Fruit.replication_association_options(:has_one, :plant, 'Slave')
25
+ options = Fruit.secondary_association_options(:has_one, :plant, 'Slave')
26
26
  options[:foreign_key].should eql('fruit_id')
27
- options = Fruit.replication_association_options(:has_many, :plant, 'Slave')
27
+ options = Fruit.secondary_association_options(:has_many, :plant, 'Slave')
28
28
  options[:foreign_key].should eql('fruit_id')
29
29
  end
30
30
  end
31
31
  end
32
32
 
33
- context '#replication_connection_classes' do
33
+ context '#secondary_connection_classes' do
34
34
  it "should return the :using array with the array elements classified and append with Connection" do
35
- Fruit.replication_connection_classes({:using => ['slave_1_test_db','slave_2_test_db']}).
35
+ Fruit.secondary_connection_classes({:using => ['slave_1_test_db','slave_2_test_db']}).
36
36
  should eql(["Slave1TestDbConnection", "Slave2TestDbConnection"])
37
37
  end
38
38
 
@@ -40,7 +40,7 @@ describe ConnectionManager::ReplicationBuilder do
40
40
 
41
41
  context '#replicated' do
42
42
  it "should raise an exception if no replication_connection_classes are found" do
43
- Fruit.stubs(:replication_connection_classes).returns([])
43
+ Fruit.stubs(:secondary_connection_classes).returns([])
44
44
  lambda { Fruit.replicated }.should raise_error
45
45
  end
46
46
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: connection_manager
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-12-10 00:00:00.000000000Z
12
+ date: 2011-12-27 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activerecord
16
- requirement: &70145637967540 !ruby/object:Gem::Requirement
16
+ requirement: &70148774706040 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '3.0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70145637967540
24
+ version_requirements: *70148774706040
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: sqlite3
27
- requirement: &70145637967120 !ruby/object:Gem::Requirement
27
+ requirement: &70148774705620 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *70145637967120
35
+ version_requirements: *70148774705620
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: rspec
38
- requirement: &70145637966660 !ruby/object:Gem::Requirement
38
+ requirement: &70148774705160 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *70145637966660
46
+ version_requirements: *70148774705160
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: autotest
49
- requirement: &70145637966240 !ruby/object:Gem::Requirement
49
+ requirement: &70148774704740 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: '0'
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *70145637966240
57
+ version_requirements: *70148774704740
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: mocha
60
- requirement: &70145637965820 !ruby/object:Gem::Requirement
60
+ requirement: &70148774704320 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: '0'
66
66
  type: :development
67
67
  prerelease: false
68
- version_requirements: *70145637965820
68
+ version_requirements: *70148774704320
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: factory_girl
71
- requirement: &70145637965400 !ruby/object:Gem::Requirement
71
+ requirement: &70148774703900 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ! '>='
@@ -76,7 +76,7 @@ dependencies:
76
76
  version: '0'
77
77
  type: :development
78
78
  prerelease: false
79
- version_requirements: *70145637965400
79
+ version_requirements: *70148774703900
80
80
  description: Simplifies connecting to Muliple and Replication databases with rails
81
81
  and active_record
82
82
  email:
@@ -97,16 +97,18 @@ files:
97
97
  - lib/connection_manager/associations.rb
98
98
  - lib/connection_manager/connection_manager_railtie.rb
99
99
  - lib/connection_manager/connections.rb
100
- - lib/connection_manager/replication_builder.rb
100
+ - lib/connection_manager/method_recorder.rb
101
+ - lib/connection_manager/secondary_connection_builder.rb
101
102
  - lib/connection_manager/version.rb
102
103
  - spec/database.yml
103
104
  - spec/factories.rb
104
105
  - spec/helpers/database_spec_helper.rb
105
106
  - spec/helpers/models_spec_helper.rb
106
- - spec/integration/replication_builder_spec.rb
107
+ - spec/integration/secondary_connection_builder_spec.rb
107
108
  - spec/lib/associations_spec.rb
108
109
  - spec/lib/connections_spec.rb
109
- - spec/lib/replication_builder_spec.rb
110
+ - spec/lib/method_recorder_spec.rb
111
+ - spec/lib/secondary_connection_builder_spec.rb
110
112
  - spec/spec.opts
111
113
  - spec/spec_helper.rb
112
114
  homepage: ''
@@ -139,9 +141,10 @@ test_files:
139
141
  - spec/factories.rb
140
142
  - spec/helpers/database_spec_helper.rb
141
143
  - spec/helpers/models_spec_helper.rb
142
- - spec/integration/replication_builder_spec.rb
144
+ - spec/integration/secondary_connection_builder_spec.rb
143
145
  - spec/lib/associations_spec.rb
144
146
  - spec/lib/connections_spec.rb
145
- - spec/lib/replication_builder_spec.rb
147
+ - spec/lib/method_recorder_spec.rb
148
+ - spec/lib/secondary_connection_builder_spec.rb
146
149
  - spec/spec.opts
147
150
  - spec/spec_helper.rb