ar-octopus 0.3.4 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,35 +1,64 @@
1
1
  require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
2
 
3
3
  describe Octopus do
4
- describe "#config method" do
4
+ describe "#config" do
5
5
  it "should load shards.yml file to start working" do
6
- Octopus.config().should be_kind_of(Hash)
6
+ Octopus.config().should be_kind_of(HashWithIndifferentAccess)
7
+ end
8
+
9
+ describe "when config file doesn't exist" do
10
+ before(:each) do
11
+ Octopus.stub!(:directory).and_return('/tmp')
12
+ Octopus.instance_variable_set(:@config, nil)
13
+ end
14
+
15
+ it "should return an empty HashWithIndifferentAccess" do
16
+ Octopus.config().should == HashWithIndifferentAccess.new
17
+ end
7
18
  end
8
19
  end
9
20
 
10
- describe "#directory method" do
21
+ describe "#directory" do
11
22
  it "should return the directory that contains the shards.yml file" do
12
23
  Octopus.directory().should == File.expand_path(File.dirname(__FILE__) + "/../")
13
24
  end
14
25
  end
15
26
 
16
- describe "#env method" do
27
+ describe "#env" do
17
28
  it "should return 'production' when is outside of a rails application" do
18
29
  Octopus.env().should == 'octopus'
19
30
  end
20
31
  end
21
-
22
- describe "#setup method" do
32
+
33
+
34
+ describe "#shards=" do
35
+ after(:each) do
36
+ Octopus.instance_variable_set(:@config, nil)
37
+ Thread.current[:connection_proxy] = Octopus::Proxy.new(Octopus.config())
38
+ end
39
+
40
+ it "should permit users to configure shards on initializer files, instead of on a yml file." do
41
+ lambda { User.using(:crazy_shard).create!(:name => "Joaquim") }.should raise_error
42
+
43
+ Octopus.setup do |config|
44
+ config.shards = {:crazy_shard => {:adapter => "mysql2", :database => "octopus_shard5", :username => "root", :password => ""}}
45
+ end
46
+
47
+ lambda { User.using(:crazy_shard).create!(:name => "Joaquim") }.should_not raise_error
48
+ end
49
+ end
50
+
51
+ describe "#setup" do
23
52
  it "should have the default octopus environment as production" do
24
53
  Octopus.environments.should == ["production"]
25
54
  end
26
-
55
+
27
56
  it "should allow the user to configure the octopus environments" do
28
57
  Octopus.setup do |config|
29
58
  config.environments = [:production, :staging]
30
59
  end
31
-
32
- Octopus.environments.should == ['production', 'staging']
60
+
61
+ Octopus.environments.should == ['production', 'staging']
33
62
 
34
63
  Octopus.setup do |config|
35
64
  config.environments = [:production]
@@ -3,45 +3,75 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
3
3
  describe Octopus::Proxy do
4
4
  let(:proxy) { Octopus::Proxy.new(Octopus.config()) }
5
5
 
6
- describe "creating a new instance" do
6
+ describe "creating a new instance" do
7
7
  it "should initialize all shards and groups" do
8
- proxy.instance_variable_get(:@shards).keys.to_set.should == [:postgresql_shard, :alone_shard, :aug2011, :canada, :brazil, :aug2009, :russia, :aug2010, :master, :sqlite_shard].to_set
9
- proxy.instance_variable_get(:@groups).should == {:country_shards=>[:canada, :brazil, :russia], :history_shards=>[:aug2009, :aug2010, :aug2011]}
8
+ proxy.instance_variable_get(:@shards).keys.to_set.should == ["canada", "brazil", "master", "sqlite_shard", "russia", "alone_shard", "aug2009", "postgresql_shard", "aug2010", "aug2011"].to_set
9
+ proxy.instance_variable_get(:@groups).should == {"country_shards" => [:canada, :brazil, :russia], "history_shards" => [:aug2009, :aug2010, :aug2011]}
10
10
  end
11
11
 
12
12
  it "should initialize the block attribute as false" do
13
13
  proxy.block.should be_false
14
- end
14
+ end
15
15
 
16
16
  it "should initialize replicated attribute as false" do
17
- proxy.instance_variable_get(:@replicated).should be_false
17
+ proxy.instance_variable_get(:@replicated).should be_false
18
18
  end
19
-
19
+
20
20
  it "should not verify connections for default" do
21
21
  proxy.instance_variable_get(:@verify_connection).should be_false
22
22
  end
23
-
23
+
24
24
  it "should work with thiking sphinx" do
25
- proxy.instance_variable_get(:@config).should == {:adapter=>"mysql", :password=>"", :database=>"octopus_shard1", :username=>"root"}
25
+ proxy.instance_variable_get(:@config).should == {:adapter=>"mysql2", :password=>"", :database=>"octopus_shard1", :username=>"root", :flags=>2}
26
+ end
27
+
28
+ it 'should create a set with all adapters, to ensure that is needed to clean the table name.' do
29
+ adapters = proxy.instance_variable_get(:@adapters)
30
+ adapters.should be_kind_of(Set)
31
+ adapters.to_a.should == ["sqlite3", "mysql2", "postgresql"]
32
+ end
33
+
34
+ it 'should respond correctly to respond_to?(:pk_and_sequence_for)' do
35
+ proxy.respond_to?(:pk_and_sequence_for).should be_true
36
+ end
37
+
38
+ it 'should respond correctly to respond_to?(:primary_key)' do
39
+ proxy.respond_to?(:primary_key).should be_true
40
+ end
41
+
42
+ describe "#should_clean_table_name?" do
43
+ it 'should return true when you have a environment with multiple database types' do
44
+ proxy.should_clean_table_name?.should be_true
45
+ end
46
+
47
+ context "when using a environment with a single table name" do
48
+ before(:each) do
49
+ set_octopus_env("production_replicated")
50
+ end
51
+
52
+ it 'should return false' do
53
+ proxy.should_clean_table_name?.should be_false
54
+ end
55
+ end
26
56
  end
27
57
 
28
58
  describe "should raise error if you have duplicated shard names" do
29
59
  before(:each) do
30
- set_octopus_env("production_raise_error")
60
+ set_octopus_env("production_raise_error")
31
61
  end
32
62
 
33
63
  it "should raise the error" do
34
- lambda { proxy }.should raise_error("You have duplicated shard names!")
64
+ lambda { proxy }.should raise_error("You have duplicated shard names!")
35
65
  end
36
66
  end
37
67
 
38
68
  describe "should initialize just the master when you don't have a shards.yml file" do
39
69
  before(:each) do
40
- set_octopus_env("crazy_environment")
70
+ set_octopus_env("crazy_environment")
41
71
  end
42
72
 
43
73
  it "should initialize just the master shard" do
44
- proxy.instance_variable_get(:@shards).keys.should == [:master]
74
+ proxy.instance_variable_get(:@shards).keys.should == ["master"]
45
75
  end
46
76
 
47
77
  it "should not initialize the groups variable" do
@@ -56,7 +86,7 @@ describe Octopus::Proxy do
56
86
 
57
87
  describe "when you have a replicated environment" do
58
88
  before(:each) do
59
- set_octopus_env("production_replicated")
89
+ set_octopus_env("production_replicated")
60
90
  end
61
91
 
62
92
  it "should have the replicated attribute as true" do
@@ -81,24 +111,24 @@ describe Octopus::Proxy do
81
111
 
82
112
  proxy.instance_variable_get(:@replicated).should be_true
83
113
  proxy.instance_variable_get(:@verify_connection).should be_true
84
- Octopus.environments.should == ["staging", "production"]
114
+ Octopus.environments.should == ["staging", "production"]
85
115
  end
86
116
 
87
117
  it "should initialize correctly the shards for the staging environment" do
88
118
  Rails.stub!(:env).and_return('staging')
89
119
 
90
- proxy.instance_variable_get(:@shards).keys.to_set.should == Set.new([:slave1, :slave2, :master])
120
+ proxy.instance_variable_get(:@shards).keys.to_set.should == Set.new(["slave1", "slave2", "master"])
91
121
  end
92
122
 
93
123
  it "should initialize correctly the shards for the production environment" do
94
124
  Rails.stub!(:env).and_return('production')
95
125
 
96
- proxy.instance_variable_get(:@shards).keys.to_set.should == Set.new([:slave3, :slave4, :master])
126
+ proxy.instance_variable_get(:@shards).keys.to_set.should == Set.new(["slave3", "slave4", "master"])
97
127
  end
98
128
 
99
129
  describe "using the master connection" do
100
130
  before(:each) do
101
- Rails.stub!(:env).and_return('development')
131
+ Rails.stub!(:env).and_return('development')
102
132
  end
103
133
 
104
134
  it "should use the master connection" do
@@ -113,9 +143,9 @@ describe Octopus::Proxy do
113
143
 
114
144
  user.name = "New Thiago"
115
145
  user.save()
116
-
146
+
117
147
  User.using(:russia).find_by_name("New Thiago").should == user
118
- User.find_by_name("New Thiago").should == user
148
+ User.find_by_name("New Thiago").should == user
119
149
  end
120
150
 
121
151
  it "should work when using blocks" do
@@ -125,7 +155,7 @@ describe Octopus::Proxy do
125
155
 
126
156
  User.find_by_name("Thiago").should == @user
127
157
  end
128
-
158
+
129
159
  it "should work with associations" do
130
160
  u = Client.create!(:name => "Thiago")
131
161
  i = Item.create(:name => "Item")
@@ -144,29 +174,29 @@ describe Octopus::Proxy do
144
174
  describe "returning the correct connection" do
145
175
  describe "should return the shard name" do
146
176
  it "when current_shard is empty" do
147
- proxy.shard_name.should == :master
177
+ proxy.shard_name.should == :master
148
178
  end
149
179
 
150
180
  it "when current_shard is a single shard" do
151
181
  proxy.current_shard = :canada
152
- proxy.shard_name.should == :canada
182
+ proxy.shard_name.should == :canada
153
183
  end
154
184
 
155
185
  it "when current_shard is more than one shard" do
156
186
  proxy.current_shard = [:russia, :brazil]
157
- proxy.shard_name.should == :russia
187
+ proxy.shard_name.should == :russia
158
188
  end
159
189
  end
160
190
 
161
191
  describe "should return the connection based on shard_name" do
162
192
  it "when current_shard is empty" do
163
- proxy.select_connection().should == proxy.instance_variable_get(:@shards)[:master].connection()
193
+ proxy.select_connection().should == proxy.instance_variable_get(:@shards)[:master].connection()
164
194
  end
165
195
 
166
196
  it "when current_shard is a single shard" do
167
197
  proxy.current_shard = :canada
168
- proxy.select_connection().should == proxy.instance_variable_get(:@shards)[:canada].connection()
198
+ proxy.select_connection().should == proxy.instance_variable_get(:@shards)[:canada].connection()
169
199
  end
170
200
  end
171
201
  end
172
- end
202
+ end
@@ -68,5 +68,18 @@ describe "when the database is replicated and the entire application is replicat
68
68
  k.errors.should == {:name=>["has already been taken"]}
69
69
  end
70
70
  end
71
+
72
+ it "should reset current shard if slave throws an exception" do
73
+
74
+ using_environment :production_fully_replicated do
75
+ Cat.create!(:name => "Slave Cat")
76
+ Cat.connection.current_shard.should eql(:master)
77
+ begin
78
+ Cat.find(:all, :conditions => 'rubbish = true')
79
+ rescue
80
+ end
81
+ Cat.connection.current_shard.should eql(:master)
82
+ end
83
+ end
71
84
  end
72
85
 
@@ -16,4 +16,4 @@ describe Octopus::ScopeProxy do
16
16
  it "should raise a exception when trying to send a query to a shard that don't exists" do
17
17
  lambda { User.using(:dont_exists).all }.should raise_exception("Nonexistent Shard Name: dont_exists")
18
18
  end
19
- end
19
+ end
@@ -30,4 +30,4 @@ describe "when the database is not entire sharded" do
30
30
 
31
31
  Cat.count.should == 1
32
32
  end
33
- end
33
+ end
@@ -1,7 +1,8 @@
1
1
  def clean_all_shards()
2
- ActiveRecord::Base.using(:master).connection.instance_variable_get(:@shards).keys.each do |shard_symbol|
3
- ['schema_migrations', 'users', 'clients', 'cats', 'items', 'keyboards', 'computers', 'permissions_roles', 'roles', 'permissions', 'assignments', 'projects', 'programmers'].each do |tables|
4
- ActiveRecord::Base.using(shard_symbol).connection.execute("DELETE FROM #{tables};")
2
+ @@shards ||= ActiveRecord::Base.using(:master).connection.instance_variable_get(:@shards).keys
3
+ @@shards.each do |shard_symbol|
4
+ ['schema_migrations', 'users', 'clients', 'cats', 'items', 'keyboards', 'computers', 'permissions_roles', 'roles', 'permissions', 'assignments', 'projects', 'programmers', "yummy"].each do |tables|
5
+ ActiveRecord::Base.using(shard_symbol).connection.execute("DELETE FROM #{tables}")
5
6
  end
6
7
  end
7
8
  end
@@ -33,4 +34,4 @@ end
33
34
  def set_octopus_env(env)
34
35
  Octopus.instance_variable_set(:@config, nil)
35
36
  Octopus.stub!(:env).and_return(env)
36
- end
37
+ end
data/spec/spec_helper.rb CHANGED
@@ -17,8 +17,4 @@ RSpec.configure do |config|
17
17
  require "database_models"
18
18
  clean_all_shards()
19
19
  end
20
-
21
- config.after(:each) do
22
- clean_all_shards()
23
- end
24
- end
20
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ar-octopus
3
3
  version: !ruby/object:Gem::Version
4
- hash: 27
5
- prerelease: false
4
+ hash: 15
5
+ prerelease:
6
6
  segments:
7
7
  - 0
8
- - 3
9
8
  - 4
10
- version: 0.3.4
9
+ - 0
10
+ version: 0.4.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Thiago Pradi
@@ -16,14 +16,44 @@ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2011-01-09 00:00:00 -02:00
19
+ date: 2011-07-03 00:00:00 -03:00
20
20
  default_executable:
21
21
  dependencies:
22
22
  - !ruby/object:Gem::Dependency
23
23
  prerelease: false
24
- type: :development
25
- name: rspec
26
24
  version_requirements: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - "="
28
+ - !ruby/object:Gem::Version
29
+ hash: 11
30
+ segments:
31
+ - 3
32
+ - 0
33
+ - 6
34
+ version: 3.0.6
35
+ type: :runtime
36
+ requirement: *id001
37
+ name: activerecord
38
+ - !ruby/object:Gem::Dependency
39
+ prerelease: false
40
+ version_requirements: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - "="
44
+ - !ruby/object:Gem::Version
45
+ hash: 11
46
+ segments:
47
+ - 3
48
+ - 0
49
+ - 6
50
+ version: 3.0.6
51
+ type: :runtime
52
+ requirement: *id002
53
+ name: actionpack
54
+ - !ruby/object:Gem::Dependency
55
+ prerelease: false
56
+ version_requirements: &id003 !ruby/object:Gem::Requirement
27
57
  none: false
28
58
  requirements:
29
59
  - - ">="
@@ -36,28 +66,26 @@ dependencies:
36
66
  - beta
37
67
  - 19
38
68
  version: 2.0.0.beta.19
39
- requirement: *id001
69
+ type: :development
70
+ requirement: *id003
71
+ name: rspec
40
72
  - !ruby/object:Gem::Dependency
41
73
  prerelease: false
42
- type: :development
43
- name: mysql
44
- version_requirements: &id002 !ruby/object:Gem::Requirement
74
+ version_requirements: &id004 !ruby/object:Gem::Requirement
45
75
  none: false
46
76
  requirements:
47
77
  - - ">="
48
78
  - !ruby/object:Gem::Version
49
- hash: 45
79
+ hash: 3
50
80
  segments:
51
- - 2
52
- - 8
53
- - 1
54
- version: 2.8.1
55
- requirement: *id002
81
+ - 0
82
+ version: "0"
83
+ type: :development
84
+ requirement: *id004
85
+ name: mysql2
56
86
  - !ruby/object:Gem::Dependency
57
87
  prerelease: false
58
- type: :development
59
- name: pg
60
- version_requirements: &id003 !ruby/object:Gem::Requirement
88
+ version_requirements: &id005 !ruby/object:Gem::Requirement
61
89
  none: false
62
90
  requirements:
63
91
  - - ">="
@@ -68,12 +96,12 @@ dependencies:
68
96
  - 9
69
97
  - 0
70
98
  version: 0.9.0
71
- requirement: *id003
99
+ type: :development
100
+ requirement: *id005
101
+ name: pg
72
102
  - !ruby/object:Gem::Dependency
73
103
  prerelease: false
74
- type: :development
75
- name: sqlite3-ruby
76
- version_requirements: &id004 !ruby/object:Gem::Requirement
104
+ version_requirements: &id006 !ruby/object:Gem::Requirement
77
105
  none: false
78
106
  requirements:
79
107
  - - ">="
@@ -84,12 +112,12 @@ dependencies:
84
112
  - 3
85
113
  - 1
86
114
  version: 1.3.1
87
- requirement: *id004
115
+ type: :development
116
+ requirement: *id006
117
+ name: sqlite3-ruby
88
118
  - !ruby/object:Gem::Dependency
89
119
  prerelease: false
90
- type: :development
91
- name: jeweler
92
- version_requirements: &id005 !ruby/object:Gem::Requirement
120
+ version_requirements: &id007 !ruby/object:Gem::Requirement
93
121
  none: false
94
122
  requirements:
95
123
  - - ">="
@@ -99,12 +127,12 @@ dependencies:
99
127
  - 1
100
128
  - 4
101
129
  version: "1.4"
102
- requirement: *id005
130
+ type: :development
131
+ requirement: *id007
132
+ name: jeweler
103
133
  - !ruby/object:Gem::Dependency
104
134
  prerelease: false
105
- type: :development
106
- name: actionpack
107
- version_requirements: &id006 !ruby/object:Gem::Requirement
135
+ version_requirements: &id008 !ruby/object:Gem::Requirement
108
136
  none: false
109
137
  requirements:
110
138
  - - ">="
@@ -114,12 +142,12 @@ dependencies:
114
142
  - 2
115
143
  - 3
116
144
  version: "2.3"
117
- requirement: *id006
145
+ type: :development
146
+ requirement: *id008
147
+ name: actionpack
118
148
  - !ruby/object:Gem::Dependency
119
149
  prerelease: false
120
- type: :runtime
121
- name: activerecord
122
- version_requirements: &id007 !ruby/object:Gem::Requirement
150
+ version_requirements: &id009 !ruby/object:Gem::Requirement
123
151
  none: false
124
152
  requirements:
125
153
  - - ">="
@@ -129,7 +157,9 @@ dependencies:
129
157
  - 2
130
158
  - 3
131
159
  version: "2.3"
132
- requirement: *id007
160
+ type: :runtime
161
+ requirement: *id009
162
+ name: activerecord
133
163
  description: This gem allows you to use sharded databases with ActiveRecord. this also provides a interface for replication and for running migrations with multiples shards.
134
164
  email: tchandy@gmail.com
135
165
  executables: []
@@ -139,7 +169,6 @@ extensions: []
139
169
  extra_rdoc_files:
140
170
  - README.mkdn
141
171
  files:
142
- - .gitignore
143
172
  - .rspec
144
173
  - Gemfile
145
174
  - Gemfile.lock
@@ -152,11 +181,13 @@ files:
152
181
  - lib/octopus/association.rb
153
182
  - lib/octopus/association_collection.rb
154
183
  - lib/octopus/has_and_belongs_to_many_association.rb
184
+ - lib/octopus/logger.rb
155
185
  - lib/octopus/migration.rb
156
186
  - lib/octopus/model.rb
157
187
  - lib/octopus/proxy.rb
158
188
  - lib/octopus/rails2/association.rb
159
189
  - lib/octopus/rails2/persistence.rb
190
+ - lib/octopus/rails3/arel.rb
160
191
  - lib/octopus/rails3/association.rb
161
192
  - lib/octopus/rails3/persistence.rb
162
193
  - lib/octopus/scope_proxy.rb
@@ -244,6 +275,7 @@ files:
244
275
  - spec/migrations/9_raise_exception_with_multiple_invalid_group_names.rb
245
276
  - spec/octopus/association_spec.rb
246
277
  - spec/octopus/controller_spec.rb
278
+ - spec/octopus/logger_spec.rb
247
279
  - spec/octopus/migration_spec.rb
248
280
  - spec/octopus/model_spec.rb
249
281
  - spec/octopus/octopus_spec.rb
@@ -258,8 +290,8 @@ homepage: http://github.com/tchandy/octopus
258
290
  licenses: []
259
291
 
260
292
  post_install_message:
261
- rdoc_options:
262
- - --charset=UTF-8
293
+ rdoc_options: []
294
+
263
295
  require_paths:
264
296
  - lib
265
297
  required_ruby_version: !ruby/object:Gem::Requirement
@@ -283,7 +315,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
283
315
  requirements: []
284
316
 
285
317
  rubyforge_project:
286
- rubygems_version: 1.3.7
318
+ rubygems_version: 1.4.2
287
319
  signing_key:
288
320
  specification_version: 3
289
321
  summary: Easy Database Sharding for ActiveRecord
@@ -305,6 +337,7 @@ test_files:
305
337
  - spec/migrations/9_raise_exception_with_multiple_invalid_group_names.rb
306
338
  - spec/octopus/association_spec.rb
307
339
  - spec/octopus/controller_spec.rb
340
+ - spec/octopus/logger_spec.rb
308
341
  - spec/octopus/migration_spec.rb
309
342
  - spec/octopus/model_spec.rb
310
343
  - spec/octopus/octopus_spec.rb