connection_manager 0.3.11 → 1.0.1

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.
data/Gemfile CHANGED
@@ -1,3 +1,2 @@
1
1
  source "http://rubygems.org"
2
-
3
2
  gemspec
data/README.md CHANGED
@@ -24,7 +24,7 @@ ConnectionManager is available through [Rubygems](https://rubygems.org/gems/conn
24
24
 
25
25
  $ gem install connection_manager
26
26
 
27
- ## Rails 3 setup (No Rails 2 at this time)
27
+ ## Rails 3/4 setup (No Rails 2 at this time)
28
28
 
29
29
  Add connection_manager to you gemfile:
30
30
 
@@ -8,8 +8,8 @@ Gem::Specification.new do |s|
8
8
  s.authors = ["Joshua Mckinney"]
9
9
  s.email = ["joshmckin@gmail.com"]
10
10
  s.homepage = ""
11
- s.summary = %q{Simplifies connecting to Muliple and Replication databases with rails and active_record}
12
- s.description = %q{Simplifies connecting to Muliple and Replication databases with rails and active_record}
11
+ s.summary = %q{Simplifies connecting to Multiple and Replication databases with rails and active_record}
12
+ s.description = %q{Simplifies connecting to Multiple and Replication databases with rails and active_record}
13
13
 
14
14
  s.rubyforge_project = "connection_manager"
15
15
 
@@ -17,12 +17,12 @@ Gem::Specification.new do |s|
17
17
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
18
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
19
  s.require_paths = ["lib"]
20
- s.add_runtime_dependency 'activerecord', '~> 3.0'
20
+ s.add_runtime_dependency 'activerecord', '>= 3.0', '<= 4.0'
21
21
  s.add_development_dependency 'rspec'
22
22
  s.add_development_dependency 'autotest'
23
23
  s.add_development_dependency 'mocha'
24
24
  s.add_development_dependency 'factory_girl'
25
- s.add_development_dependency 'activesupport', '~> 3.0'
25
+ s.add_development_dependency 'activesupport', '>= 3.0', '<= 4.0'
26
26
 
27
27
  if(defined? RUBY_ENGINE and 'jruby' == RUBY_ENGINE)
28
28
  s.add_development_dependency 'jruby-openssl'
@@ -10,6 +10,8 @@ module ConnectionManager
10
10
  require 'connection_manager/shards'
11
11
  require 'connection_manager/replication'
12
12
  require 'connection_manager/patches/cross_schema_patch'
13
+ require 'connection_manager/patches/reflections_patch'
14
+ require 'connection_manager/patches/query_methods_patch'
13
15
  require 'connection_manager/connection_manager_railtie' if defined?(Rails)
14
16
 
15
17
  ActiveRecord::ConnectionAdapters::AbstractAdapter.send(:include,(ConnectionManager::AbstractAdapterHelper))
@@ -5,12 +5,12 @@ if ActiveRecord::VERSION::MAJOR == 3 && ActiveRecord::VERSION::MINOR <= 2
5
5
  module ActiveRecord
6
6
  module ConnectionAdapters
7
7
  class Mysql2Adapter < ((ActiveRecord::VERSION::MAJOR == 3 && ActiveRecord::VERSION::MINOR == 2) ? AbstractMysqlAdapter : AbstractAdapter)
8
-
8
+
9
9
  # Force all tables to be cached for the life connection
10
10
  def cached_tables
11
11
  @cached_tables ||= {}
12
12
  end
13
-
13
+
14
14
  def tables(name = nil, database = nil, like =nil)
15
15
  return cached_tables[database] if cached_tables[database] && like.nil?
16
16
  cached_tables[database] ||= []
@@ -21,9 +21,9 @@ if ActiveRecord::VERSION::MAJOR == 3 && ActiveRecord::VERSION::MINOR <= 2
21
21
  result = execute(sql, 'SCHEMA')
22
22
  cached_tables[database] = (cached_tables[database] | result.collect { |field| field[0] }).compact
23
23
  end
24
-
24
+
25
25
  alias :new_tables :tables
26
-
26
+
27
27
  def table_exists?(name)
28
28
  return false unless name
29
29
  name = name.to_s
@@ -37,4 +37,4 @@ if ActiveRecord::VERSION::MAJOR == 3 && ActiveRecord::VERSION::MINOR <= 2
37
37
  end
38
38
  end
39
39
  end
40
- end
40
+ end
@@ -0,0 +1,15 @@
1
+ module ActiveRecord
2
+ module QueryMethods
3
+ private
4
+ # For some reason on .include or a custom join
5
+ # Arel drops the table name prefix on slave classes
6
+ def build_select(arel, selects)
7
+ unless selects.empty?
8
+ @implicit_readonly = false
9
+ arel.project(*selects)
10
+ else
11
+ arel.project("#{quoted_table_name}.*")
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,19 @@
1
+ if ActiveRecord::VERSION::MAJOR == 4 && ActiveRecord::VERSION::MINOR <= 0
2
+ # Sometimes for some reason the quoted_table_name instance methods
3
+ # drops the schema. If the quoted table name does not include a '.'
4
+ # want to retrieve the quoted_table_name from the class and reset
5
+ module ActiveRecord
6
+ # = Active Record Reflection
7
+ module Reflection # :nodoc:
8
+ class AssociationReflection < MacroReflection
9
+ def table_name
10
+ @table_name = klass.table_name
11
+ end
12
+
13
+ def quoted_table_name
14
+ @quoted_table_name = klass.quoted_table_name
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -25,7 +25,8 @@ module ConnectionManager
25
25
 
26
26
  # Modifies the dup class to use the connection class connection.
27
27
  # We want to use the current class table name, but the connection
28
- # class database as the prefix. We also want the superclass method to
28
+ # class database as the prefix, useful when shards but normally
29
+ # should be the same. We also want the superclass method to
29
30
  # return the connection class as AR sometimes uses the the superclass
30
31
  # connection
31
32
  def build_dup_class(connection_class_name)
@@ -1,3 +1,3 @@
1
1
  module ConnectionManager
2
- VERSION = "0.3.11"
2
+ VERSION = "1.0.1"
3
3
  end
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
  describe ConnectionManager::Replication do
3
-
3
+
4
4
  describe '#database_name' do
5
5
  it "should return the name of the database the model is using" do
6
6
  Fruit.current_database_name.should eql('cm_test')
@@ -12,45 +12,61 @@ describe ConnectionManager::Replication do
12
12
  Fruit.connection.stubs(:replication_keys).returns([])
13
13
  lambda { Fruit.replicated }.should raise_error
14
14
  end
15
-
15
+
16
16
  it "should not raise an exception if no connections are empty, but connection.replication_keys are not blank" do
17
- Fruit.connection.stubs(:replication_keys).returns([:slave_1_cm_test])
17
+ Fruit.connection.stubs(:replication_keys).returns([:slave_1_cm_test])
18
18
  lambda { Fruit.replicated }.should_not raise_error
19
19
  end
20
-
20
+
21
21
  context "the methods created from #replicated" do
22
22
  it "should create a method with the name given for the :name option" do
23
23
  Fruit.replicated(:name => 'foozle')
24
24
  Fruit.respond_to?(:foozle).should be_true
25
25
  end
26
-
26
+
27
27
  it "should create a method in ActiveRecord::QueryMethods with the name given for the :name option" do
28
28
  f = FactoryGirl.create(:fruit)
29
29
  Fruit.replicated(:name => 'fizzle')
30
30
  ActiveRecord::QueryMethods.instance_methods.include?(:fizzle).should be_true
31
31
  Fruit.where(:id => f.id).fizzle.first.should_not eql(Fruit.where(:id => f.id).first)
32
32
  end
33
-
33
+
34
34
  it "should return an ActiveRecord::Relation" do
35
35
  Fruit.replicated(:name => 'slaves')
36
36
  Fruit.slaves.should be_kind_of(ActiveRecord::Relation)
37
37
  end
38
-
38
+
39
39
  it "should have a different connection" do
40
40
  Fruit.replicated
41
41
  Fruit.slaves.connection.config.should_not eql(Fruit.connection.config)
42
42
  end
43
-
43
+
44
+ it "should work" do
45
+ Fruit.replicated
46
+ Fruit.slaves.joins(:region).joins("LEFT OUTER JOIN `fruit_baskets` ON `fruit_baskets`.`fruit_id` = `cm_test`.`fruits`.`id`").to_sql.should eql(Fruit.joins(:region).joins("LEFT OUTER JOIN `fruit_baskets` ON `fruit_baskets`.`fruit_id` = `cm_test`.`fruits`.`id`").to_sql)
47
+ end
48
+
44
49
  it "should produce the same query string" do
45
50
  Fruit.replicated
46
51
  Fruit.slaves.joins(:region).to_sql.should eql(Fruit.joins(:region).to_sql)
47
52
  Fruit.slaves.joins(:fruit_baskets).to_sql.should eql(Fruit.joins(:fruit_baskets).to_sql)
48
- Fruit.slaves.joins(:region).joins("LEFT OUTER JOIN `fruit_baskets` ON `fruit_baskets`.`fruit_id` = `cm_test`.`fruits`.`id`").to_sql.should eql(Fruit.joins(:region).joins("LEFT OUTER JOIN `fruit_baskets` ON `fruit_baskets`.`fruit_id` = `cm_test`.`fruits`.`id`").to_sql)
49
53
  Fruit.slaves.includes(:fruit_baskets).to_sql.should eql(Fruit.includes(:fruit_baskets).to_sql)
50
54
  Fruit.slaves.includes(:region).to_sql.should eql(Fruit.includes(:region).to_sql)
51
55
  end
56
+
57
+ context '#slaves' do
58
+ it "should have the same quoted_table_name" do
59
+ Fruit.replicated
60
+
61
+ Fruit.slaves.quoted_table_name.should eql(Fruit.quoted_table_name)
62
+ end
63
+ it "should have the same table_name_prefix"do
64
+ Fruit.replicated
65
+ Fruit.slaves.table_name_prefix.should eql(Fruit.table_name_prefix)
66
+ end
67
+ end
52
68
  end
53
-
69
+
54
70
  context "the objects return from a query" do
55
71
  # The default connection is the original connection for the model
56
72
  it "should have the connection as the replication" do
@@ -58,10 +74,10 @@ describe ConnectionManager::Replication do
58
74
  FactoryGirl.create(:fruit)
59
75
  Fruit.slaves.first.connection.config.should eql(Fruit.slaves.connection.config)
60
76
  Fruit.slaves.first.should_not be_nil
61
- end
77
+ end
62
78
  end
63
79
  end
64
-
80
+
65
81
  describe'#replicated?' do
66
82
  it "should be false if not replicated" do
67
83
  Fruit.replicated?.should be_false
@@ -71,34 +87,34 @@ describe ConnectionManager::Replication do
71
87
  Fruit.replicated?.should be_true
72
88
  end
73
89
  end
74
-
75
-
90
+
91
+
76
92
 
77
93
  #ConnectionManager::Connections.build_connection_classes(:env => 'test')
78
94
  class CmFooSlaveConnection < ActiveRecord::Base
79
95
  establish_managed_connection(:slave_1_cm_test)
80
96
  end
81
-
97
+
82
98
  class CmUserConnection < ActiveRecord::Base
83
99
  establish_managed_connection(:cm_user_test)
84
100
  end
85
-
101
+
86
102
  class SlaveCmUserConnection < ActiveRecord::Base
87
103
  establish_managed_connection(:slave_1_cm_user_test)
88
104
  end
89
-
105
+
90
106
  class User < CmUserConnection
91
107
  has_many :foos
92
108
  has_many(:foo_slaves, :class_name => "Foo::Slaves")
93
109
  replicated('SlaveCmUserConnection')
94
-
110
+
95
111
  end
96
-
112
+
97
113
  class Foo < ActiveRecord::Base
98
114
  belongs_to :user
99
115
  replicated("CmFooSlaveConnection")
100
116
  end
101
-
117
+
102
118
  context "eager loading (#includes)" do
103
119
  before :each do
104
120
  @user = User.new(:name => "Testing")
@@ -106,38 +122,37 @@ describe ConnectionManager::Replication do
106
122
  @foo = Foo.new(:user_id => @user.id)
107
123
  @foo.save
108
124
  end
109
-
125
+
110
126
  # We'd like this to happen magically some day. Possible in 3.2
111
127
  it "should eager load with replication instances" #do
112
- # user = User.slaves.includes(:foos).where(:id => @user.id).first
113
- # user.foos.first.should_not be_kind_of(Foo)
114
- # end
115
-
128
+ # user = User.slaves.includes(:foos).where(:id => @user.id).first
129
+ # user.foos.first.should_not be_kind_of(Foo)
130
+ # end
131
+
116
132
  context "specifically defined replication association" do
117
133
  it "should eager load with replication instances" do
118
134
  user = User.slaves.includes(:foo_slaves).where(:id => @user.id).first
119
135
  user.foo_slaves.first.should_not be_kind_of(Foo)
120
136
  end
121
- end
137
+ end
122
138
  end
123
- context "cross database joins" do
139
+ context "cross database joins" do
124
140
  before :each do
125
141
  @user = User.new(:name => "Testing")
126
142
  @user.save
127
143
  @foo = Foo.new(:user_id => @user.id)
128
144
  @foo.save
129
145
  end
130
-
146
+
131
147
  it "should work" do
132
- @user.foos.blank?.should be_false
148
+ @user.foos.blank?.should be_false
133
149
  found = Foo.select('users.name AS user_name').joins(:user).where(:id => @foo.id).first
134
150
  found.user_name.blank?.should be_false
135
151
  end
136
-
152
+
137
153
  it "should work with replication" do
138
154
  found = Foo.slaves.select('foos.*, users.name AS user_name').joins(:user).where(:id => @foo.id).first
139
155
  found.user.blank?.should be_false
140
156
  end
141
- end
157
+ end
142
158
  end
143
-
@@ -23,18 +23,18 @@ describe ConnectionManager::Shards do
23
23
 
24
24
  it "should not matter how the where statement is formated" do
25
25
  fruit = FactoryGirl.create(:fruit)
26
- a = Fruit.shards do |shard|
26
+ afruit = Fruit.shards do |shard|
27
27
  shard.where(:id => fruit.id).first
28
28
  end
29
- b = Fruit.shards do |shard|
29
+
30
+ bfruit = Fruit.shards do |shard|
30
31
  shard.where(['id = ?', fruit.id]).first
31
32
  end
32
33
 
33
- c = Fruit.shards do |shard|
34
+ cfruit = Fruit.shards do |shard|
34
35
  shard.where('id = ?', fruit.id).first
35
36
  end
36
-
37
- (a == b && b == c).should be_true
37
+ (afruit == bfruit && bfruit == cfruit).should be_true
38
38
  end
39
39
  end
40
40
  end
@@ -10,7 +10,7 @@ describe ConnectionManager::Using do
10
10
 
11
11
  it "should add sub class to current class with the name of the connection" do
12
12
  Fruit.send(:fetch_duplicate_class,"CmFooSlaveConnection")
13
- lambda { "Fruit::CmFooSlaveConnectionDup".constantize}.should_not raise_error(NameError)
13
+ lambda { "Fruit::CmFooSlaveConnectionDup".constantize}.should_not raise_error
14
14
  end
15
15
 
16
16
  describe '#using' do
@@ -20,11 +20,11 @@ RSpec.configure do |config|
20
20
  config.mock_with :mocha
21
21
  # Loads database.yml and establishes primary connection
22
22
  # Create tables when tests are completed
23
- config.before(:all) {
23
+ config.before(:suite) {
24
24
  require 'helpers/models_spec_helper.rb'
25
25
  }
26
26
  # Drops tables when tests are completed
27
- config.after(:all){
27
+ config.after(:suite){
28
28
  TestDB.clean
29
29
  }
30
30
  # Make sure every test is isolated.
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.3.11
4
+ version: 1.0.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,24 +9,30 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-02-04 00:00:00.000000000 Z
12
+ date: 2013-10-24 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activerecord
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
- - - ~>
19
+ - - ! '>='
20
20
  - !ruby/object:Gem::Version
21
21
  version: '3.0'
22
+ - - <=
23
+ - !ruby/object:Gem::Version
24
+ version: '4.0'
22
25
  type: :runtime
23
26
  prerelease: false
24
27
  version_requirements: !ruby/object:Gem::Requirement
25
28
  none: false
26
29
  requirements:
27
- - - ~>
30
+ - - ! '>='
28
31
  - !ruby/object:Gem::Version
29
32
  version: '3.0'
33
+ - - <=
34
+ - !ruby/object:Gem::Version
35
+ version: '4.0'
30
36
  - !ruby/object:Gem::Dependency
31
37
  name: rspec
32
38
  requirement: !ruby/object:Gem::Requirement
@@ -96,17 +102,23 @@ dependencies:
96
102
  requirement: !ruby/object:Gem::Requirement
97
103
  none: false
98
104
  requirements:
99
- - - ~>
105
+ - - ! '>='
100
106
  - !ruby/object:Gem::Version
101
107
  version: '3.0'
108
+ - - <=
109
+ - !ruby/object:Gem::Version
110
+ version: '4.0'
102
111
  type: :development
103
112
  prerelease: false
104
113
  version_requirements: !ruby/object:Gem::Requirement
105
114
  none: false
106
115
  requirements:
107
- - - ~>
116
+ - - ! '>='
108
117
  - !ruby/object:Gem::Version
109
118
  version: '3.0'
119
+ - - <=
120
+ - !ruby/object:Gem::Version
121
+ version: '4.0'
110
122
  - !ruby/object:Gem::Dependency
111
123
  name: mysql2
112
124
  requirement: !ruby/object:Gem::Requirement
@@ -123,7 +135,7 @@ dependencies:
123
135
  - - ! '>='
124
136
  - !ruby/object:Gem::Version
125
137
  version: '0'
126
- description: Simplifies connecting to Muliple and Replication databases with rails
138
+ description: Simplifies connecting to Multiple and Replication databases with rails
127
139
  and active_record
128
140
  email:
129
141
  - joshmckin@gmail.com
@@ -144,6 +156,8 @@ files:
144
156
  - lib/connection_manager/helpers/abstract_adapter_helper.rb
145
157
  - lib/connection_manager/helpers/connection_helpers.rb
146
158
  - lib/connection_manager/patches/cross_schema_patch.rb
159
+ - lib/connection_manager/patches/query_methods_patch.rb
160
+ - lib/connection_manager/patches/reflections_patch.rb
147
161
  - lib/connection_manager/replication.rb
148
162
  - lib/connection_manager/shards.rb
149
163
  - lib/connection_manager/using.rb
@@ -184,7 +198,7 @@ rubyforge_project: connection_manager
184
198
  rubygems_version: 1.8.25
185
199
  signing_key:
186
200
  specification_version: 3
187
- summary: Simplifies connecting to Muliple and Replication databases with rails and
201
+ summary: Simplifies connecting to Multiple and Replication databases with rails and
188
202
  active_record
189
203
  test_files:
190
204
  - spec/factories.rb