ar-octopus 0.3.4 → 0.4.0

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