misha-ar-octopus 0.8.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (157) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +11 -0
  3. data/.rspec +2 -0
  4. data/.rubocop.yml +46 -0
  5. data/.rubocop_todo.yml +56 -0
  6. data/.ruby-version +1 -0
  7. data/.travis.yml +18 -0
  8. data/Appraisals +16 -0
  9. data/Gemfile +4 -0
  10. data/README.mkdn +242 -0
  11. data/Rakefile +172 -0
  12. data/TODO.txt +7 -0
  13. data/ar-octopus.gemspec +42 -0
  14. data/gemfiles/rails32.gemfile +7 -0
  15. data/gemfiles/rails4.gemfile +7 -0
  16. data/gemfiles/rails41.gemfile +7 -0
  17. data/gemfiles/rails42.gemfile +7 -0
  18. data/init.rb +1 -0
  19. data/lib/ar-octopus.rb +1 -0
  20. data/lib/octopus.rb +181 -0
  21. data/lib/octopus/abstract_adapter.rb +35 -0
  22. data/lib/octopus/association.rb +13 -0
  23. data/lib/octopus/association_shard_tracking.rb +114 -0
  24. data/lib/octopus/collection_association.rb +11 -0
  25. data/lib/octopus/collection_proxy.rb +16 -0
  26. data/lib/octopus/exception.rb +4 -0
  27. data/lib/octopus/has_and_belongs_to_many_association.rb +9 -0
  28. data/lib/octopus/load_balancing.rb +4 -0
  29. data/lib/octopus/load_balancing/round_robin.rb +20 -0
  30. data/lib/octopus/log_subscriber.rb +22 -0
  31. data/lib/octopus/migration.rb +168 -0
  32. data/lib/octopus/model.rb +210 -0
  33. data/lib/octopus/persistence.rb +39 -0
  34. data/lib/octopus/proxy.rb +534 -0
  35. data/lib/octopus/railtie.rb +11 -0
  36. data/lib/octopus/relation_proxy.rb +35 -0
  37. data/lib/octopus/scope_proxy.rb +61 -0
  38. data/lib/octopus/shard_tracking.rb +41 -0
  39. data/lib/octopus/shard_tracking/attribute.rb +22 -0
  40. data/lib/octopus/shard_tracking/dynamic.rb +11 -0
  41. data/lib/octopus/singular_association.rb +9 -0
  42. data/lib/octopus/slave_group.rb +13 -0
  43. data/lib/octopus/version.rb +3 -0
  44. data/lib/tasks/octopus.rake +16 -0
  45. data/rails/init.rb +1 -0
  46. data/sample_app/.gitignore +4 -0
  47. data/sample_app/.rspec +1 -0
  48. data/sample_app/Gemfile +20 -0
  49. data/sample_app/README +3 -0
  50. data/sample_app/README.rdoc +261 -0
  51. data/sample_app/Rakefile +7 -0
  52. data/sample_app/app/assets/images/rails.png +0 -0
  53. data/sample_app/app/assets/javascripts/application.js +15 -0
  54. data/sample_app/app/assets/stylesheets/application.css +13 -0
  55. data/sample_app/app/controllers/application_controller.rb +4 -0
  56. data/sample_app/app/helpers/application_helper.rb +2 -0
  57. data/sample_app/app/mailers/.gitkeep +0 -0
  58. data/sample_app/app/models/.gitkeep +0 -0
  59. data/sample_app/app/models/item.rb +3 -0
  60. data/sample_app/app/models/user.rb +3 -0
  61. data/sample_app/app/views/layouts/application.html.erb +14 -0
  62. data/sample_app/autotest/discover.rb +2 -0
  63. data/sample_app/config.ru +4 -0
  64. data/sample_app/config/application.rb +62 -0
  65. data/sample_app/config/boot.rb +6 -0
  66. data/sample_app/config/cucumber.yml +8 -0
  67. data/sample_app/config/database.yml +28 -0
  68. data/sample_app/config/environment.rb +5 -0
  69. data/sample_app/config/environments/development.rb +37 -0
  70. data/sample_app/config/environments/production.rb +67 -0
  71. data/sample_app/config/environments/test.rb +37 -0
  72. data/sample_app/config/initializers/backtrace_silencers.rb +7 -0
  73. data/sample_app/config/initializers/inflections.rb +15 -0
  74. data/sample_app/config/initializers/mime_types.rb +5 -0
  75. data/sample_app/config/initializers/secret_token.rb +7 -0
  76. data/sample_app/config/initializers/session_store.rb +8 -0
  77. data/sample_app/config/initializers/wrap_parameters.rb +14 -0
  78. data/sample_app/config/locales/en.yml +5 -0
  79. data/sample_app/config/routes.rb +58 -0
  80. data/sample_app/config/shards.yml +28 -0
  81. data/sample_app/db/migrate/20100720172715_create_users.rb +15 -0
  82. data/sample_app/db/migrate/20100720172730_create_items.rb +16 -0
  83. data/sample_app/db/migrate/20100720210335_create_sample_users.rb +11 -0
  84. data/sample_app/db/schema.rb +29 -0
  85. data/sample_app/db/seeds.rb +16 -0
  86. data/sample_app/doc/README_FOR_APP +2 -0
  87. data/sample_app/features/migrate.feature +45 -0
  88. data/sample_app/features/seed.feature +15 -0
  89. data/sample_app/features/step_definitions/seeds_steps.rb +13 -0
  90. data/sample_app/features/step_definitions/web_steps.rb +218 -0
  91. data/sample_app/features/support/database.rb +13 -0
  92. data/sample_app/features/support/env.rb +57 -0
  93. data/sample_app/features/support/paths.rb +33 -0
  94. data/sample_app/lib/assets/.gitkeep +0 -0
  95. data/sample_app/lib/tasks/.gitkeep +0 -0
  96. data/sample_app/lib/tasks/cucumber.rake +64 -0
  97. data/sample_app/log/.gitkeep +0 -0
  98. data/sample_app/public/404.html +26 -0
  99. data/sample_app/public/422.html +26 -0
  100. data/sample_app/public/500.html +26 -0
  101. data/sample_app/public/favicon.ico +0 -0
  102. data/sample_app/public/images/rails.png +0 -0
  103. data/sample_app/public/index.html +279 -0
  104. data/sample_app/public/javascripts/application.js +2 -0
  105. data/sample_app/public/javascripts/controls.js +965 -0
  106. data/sample_app/public/javascripts/dragdrop.js +974 -0
  107. data/sample_app/public/javascripts/effects.js +1123 -0
  108. data/sample_app/public/javascripts/prototype.js +4874 -0
  109. data/sample_app/public/javascripts/rails.js +118 -0
  110. data/sample_app/public/robots.txt +5 -0
  111. data/sample_app/public/stylesheets/.gitkeep +0 -0
  112. data/sample_app/script/cucumber +10 -0
  113. data/sample_app/script/rails +6 -0
  114. data/sample_app/spec/models/item_spec.rb +5 -0
  115. data/sample_app/spec/models/user_spec.rb +5 -0
  116. data/sample_app/spec/spec_helper.rb +27 -0
  117. data/sample_app/vendor/assets/javascripts/.gitkeep +0 -0
  118. data/sample_app/vendor/assets/stylesheets/.gitkeep +0 -0
  119. data/sample_app/vendor/plugins/.gitkeep +0 -0
  120. data/spec/config/shards.yml +217 -0
  121. data/spec/migrations/10_create_users_using_replication.rb +9 -0
  122. data/spec/migrations/11_add_field_in_all_slaves.rb +11 -0
  123. data/spec/migrations/12_create_users_using_block.rb +23 -0
  124. data/spec/migrations/13_create_users_using_block_and_using.rb +15 -0
  125. data/spec/migrations/14_create_users_on_shards_of_a_group_with_versions.rb +11 -0
  126. data/spec/migrations/15_create_user_on_shards_of_default_group_with_versions.rb +9 -0
  127. data/spec/migrations/1_create_users_on_master.rb +9 -0
  128. data/spec/migrations/2_create_users_on_canada.rb +11 -0
  129. data/spec/migrations/3_create_users_on_both_shards.rb +11 -0
  130. data/spec/migrations/4_create_users_on_shards_of_a_group.rb +11 -0
  131. data/spec/migrations/5_create_users_on_multiples_groups.rb +11 -0
  132. data/spec/migrations/6_raise_exception_with_invalid_shard_name.rb +11 -0
  133. data/spec/migrations/7_raise_exception_with_invalid_multiple_shard_names.rb +11 -0
  134. data/spec/migrations/8_raise_exception_with_invalid_group_name.rb +11 -0
  135. data/spec/migrations/9_raise_exception_with_multiple_invalid_group_names.rb +11 -0
  136. data/spec/octopus/association_shard_tracking_spec.rb +714 -0
  137. data/spec/octopus/collection_proxy_spec.rb +16 -0
  138. data/spec/octopus/log_subscriber_spec.rb +19 -0
  139. data/spec/octopus/migration_spec.rb +115 -0
  140. data/spec/octopus/model_spec.rb +693 -0
  141. data/spec/octopus/octopus_spec.rb +123 -0
  142. data/spec/octopus/proxy_spec.rb +307 -0
  143. data/spec/octopus/relation_proxy_spec.rb +93 -0
  144. data/spec/octopus/replicated_slave_grouped_spec.rb +91 -0
  145. data/spec/octopus/replication_spec.rb +137 -0
  146. data/spec/octopus/scope_proxy_spec.rb +63 -0
  147. data/spec/octopus/sharded_replicated_slave_grouped_spec.rb +55 -0
  148. data/spec/octopus/sharded_spec.rb +33 -0
  149. data/spec/spec_helper.rb +16 -0
  150. data/spec/support/active_record/connection_adapters/modify_config_adapter.rb +15 -0
  151. data/spec/support/database_connection.rb +4 -0
  152. data/spec/support/database_models.rb +118 -0
  153. data/spec/support/octopus_helper.rb +55 -0
  154. data/spec/support/query_count.rb +17 -0
  155. data/spec/support/shared_contexts.rb +18 -0
  156. data/spec/tasks/octopus.rake_spec.rb +32 -0
  157. metadata +388 -0
@@ -0,0 +1,15 @@
1
+ class CreateUsersUsingBlockAndUsing < ActiveRecord::Migration
2
+ using(:brazil)
3
+
4
+ def self.up
5
+ Octopus.using(:canada) do
6
+ User.create!(:name => 'Canada')
7
+ end
8
+
9
+ User.create!(:name => 'Brazil')
10
+ end
11
+
12
+ def self.down
13
+ User.delete_all
14
+ end
15
+ end
@@ -0,0 +1,11 @@
1
+ class CreateUsersOnShardsOfAGroupWithVersions < ActiveRecord::Migration
2
+ using_group(:country_shards)
3
+
4
+ def self.up
5
+ User.create!(:name => 'Group')
6
+ end
7
+
8
+ def self.down
9
+ User.delete_all
10
+ end
11
+ end
@@ -0,0 +1,9 @@
1
+ class CreateUserOnShardsOfDefaultGroupWithVersions < ActiveRecord::Migration
2
+ def self.up
3
+ User.create!(:name => 'Default Group')
4
+ end
5
+
6
+ def self.down
7
+ User.delete_all
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ class CreateUsersOnMaster < ActiveRecord::Migration
2
+ def self.up
3
+ User.create!(:name => 'Master')
4
+ end
5
+
6
+ def self.down
7
+ User.delete_all
8
+ end
9
+ end
@@ -0,0 +1,11 @@
1
+ class CreateUsersOnCanada < ActiveRecord::Migration
2
+ using(:canada)
3
+
4
+ def self.up
5
+ User.create!(:name => 'Sharding')
6
+ end
7
+
8
+ def self.down
9
+ User.delete_all
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ class CreateUsersOnBothShards < ActiveRecord::Migration
2
+ using(:brazil, :canada)
3
+
4
+ def self.up
5
+ User.create!(:name => 'Both')
6
+ end
7
+
8
+ def self.down
9
+ User.delete_all
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ class CreateUsersOnShardsOfAGroup < ActiveRecord::Migration
2
+ using_group(:country_shards)
3
+
4
+ def self.up
5
+ User.create!(:name => 'Group')
6
+ end
7
+
8
+ def self.down
9
+ User.delete_all
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ class CreateUsersOnMultiplesGroups < ActiveRecord::Migration
2
+ using_group('country_shards', 'history_shards')
3
+
4
+ def self.up
5
+ User.create!(:name => 'MultipleGroup')
6
+ end
7
+
8
+ def self.down
9
+ User.delete_all
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ class RaiseExceptionWithInvalidShardName < ActiveRecord::Migration
2
+ using(:amazing_shard)
3
+
4
+ def self.up
5
+ User.create!(:name => 'Error')
6
+ end
7
+
8
+ def self.down
9
+ User.delete_all
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ class RaiseExceptionWithInvalidMultipleShardNames < ActiveRecord::Migration
2
+ using(:brazil, :invalid_shard)
3
+
4
+ def self.up
5
+ User.create!(:name => 'Error')
6
+ end
7
+
8
+ def self.down
9
+ User.delete_all
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ class RaiseExceptionWithInvalidGroupName < ActiveRecord::Migration
2
+ using_group(:invalid_group)
3
+
4
+ def self.up
5
+ User.create!(:name => 'Error')
6
+ end
7
+
8
+ def self.down
9
+ User.delete_all
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ class RaiseExceptionWithMultipleInvalidGroupNames < ActiveRecord::Migration
2
+ using_group(:country_shards, :invalid_group)
3
+
4
+ def self.up
5
+ User.create!(:name => 'Error')
6
+ end
7
+
8
+ def self.down
9
+ User.delete_all
10
+ end
11
+ end
@@ -0,0 +1,714 @@
1
+ require 'spec_helper'
2
+
3
+ describe Octopus::AssociationShardTracking, :shards => [:brazil, :master, :canada] do
4
+ describe 'when you have a 1 x 1 relationship' do
5
+ before(:each) do
6
+ @computer_brazil = Computer.using(:brazil).create!(:name => 'Computer Brazil')
7
+ @computer_master = Computer.create!(:name => 'Computer Brazil')
8
+ @keyboard_brazil = Keyboard.using(:brazil).create!(:name => 'Keyboard Brazil', :computer => @computer_brazil)
9
+ @keyboard_master = Keyboard.create!(:name => 'Keyboard Master', :computer => @computer_master)
10
+ end
11
+
12
+ it 'should find the models' do
13
+ expect(@keyboard_master.computer).to eq(@computer_master)
14
+ expect(@keyboard_brazil.computer).to eq(@computer_brazil)
15
+ end
16
+
17
+ it 'should read correctly the relationed model' do
18
+ new_computer_brazil = Computer.using(:brazil).create!(:name => 'New Computer Brazil')
19
+ _new_computer_hello = Computer.create!(:name => 'New Computer Brazil')
20
+ @keyboard_brazil.computer = new_computer_brazil
21
+ @keyboard_brazil.save
22
+ @keyboard_brazil.reload
23
+ expect(@keyboard_brazil.computer_id).to eq(new_computer_brazil.id)
24
+ expect(@keyboard_brazil.computer).to eq(new_computer_brazil)
25
+ new_computer_brazil.save
26
+ new_computer_brazil.reload
27
+ expect(new_computer_brazil.keyboard).to eq(@keyboard_brazil)
28
+ end
29
+
30
+ it 'should work when using #build_computer or #build_keyboard' do
31
+ c = Computer.using(:brazil).create!(:name => 'Computer Brazil')
32
+ k = c.build_keyboard(:name => 'Building keyboard')
33
+ c.save
34
+ k.save
35
+ expect(c.keyboard).to eq(k)
36
+ expect(k.computer_id).to eq(c.id)
37
+ expect(k.computer).to eq(c)
38
+ end
39
+
40
+ it 'should work when using #create_computer or #create_keyboard' do
41
+ c = Computer.using(:brazil).create!(:name => 'Computer Brazil')
42
+ k = c.create_keyboard(:name => 'Building keyboard')
43
+ c.save
44
+ k.save
45
+ expect(c.keyboard).to eq(k)
46
+ expect(k.computer_id).to eq(c.id)
47
+ expect(k.computer).to eq(c)
48
+ end
49
+
50
+ it 'should include models' do
51
+ c = Computer.using(:brazil).create!(:name => 'Computer Brazil')
52
+ k = c.create_keyboard(:name => 'Building keyboard')
53
+ c.save
54
+ k.save
55
+
56
+ expect(Computer.using(:brazil).includes(:keyboard).find(c.id)).to eq(c)
57
+ end
58
+ end
59
+
60
+ describe 'when you have a N x N relationship' do
61
+ before(:each) do
62
+ @brazil_role = Role.using(:brazil).create!(:name => 'Brazil Role')
63
+ @master_role = Role.create!(:name => 'Master Role')
64
+ @permission_brazil = Permission.using(:brazil).create!(:name => 'Brazil Permission')
65
+ @permission_master = Permission.using(:master).create!(:name => 'Master Permission')
66
+ @brazil_role.permissions << @permission_brazil
67
+ @brazil_role.save
68
+ Client.using(:master).create!(:name => 'teste')
69
+ end
70
+
71
+ it 'should find all models in the specified shard' do
72
+ expect(@brazil_role.permission_ids).to eq([@permission_brazil.id])
73
+ expect(@brazil_role.permissions).to eq([@permission_brazil])
74
+
75
+ expect(@brazil_role.permissions.first).to eq(@permission_brazil)
76
+ expect(@brazil_role.permissions.last).to eq(@permission_brazil)
77
+ end
78
+
79
+ it 'should finds the client that the item belongs' do
80
+ expect(@permission_brazil.role_ids).to eq([@brazil_role.id])
81
+ expect(@permission_brazil.roles).to eq([@brazil_role])
82
+
83
+ expect(@permission_brazil.roles.first).to eq(@brazil_role)
84
+ expect(@permission_brazil.roles.last).to eq(@brazil_role)
85
+ end
86
+
87
+ it 'should update the attribute for the item' do
88
+ new_brazil_role = Role.using(:brazil).create!(:name => 'new Role')
89
+ @permission_brazil.roles = [new_brazil_role]
90
+ expect(@permission_brazil.roles).to eq([new_brazil_role])
91
+ @permission_brazil.save
92
+ @permission_brazil.reload
93
+ expect(@permission_brazil.role_ids).to eq([new_brazil_role.id])
94
+ expect(@permission_brazil.roles).to eq([new_brazil_role])
95
+ end
96
+
97
+ it 'should works for build method' do
98
+ new_brazil_role = Role.using(:brazil).create!(:name => 'Brazil Role')
99
+ c = new_brazil_role.permissions.create(:name => 'new Permission')
100
+ c.save
101
+ new_brazil_role.save
102
+ expect(c.roles).to eq([new_brazil_role])
103
+ expect(new_brazil_role.permissions).to eq([c])
104
+ end
105
+
106
+ describe 'it should works when using' do
107
+ before(:each) do
108
+ @permission_brazil_2 = Permission.using(:brazil).create!(:name => 'Brazil Item 2')
109
+ @role = Role.using(:brazil).create!(:name => 'testes')
110
+ end
111
+
112
+ it 'update_attributes' do
113
+ @permission_brazil_2.update_attributes(:role_ids => [@role.id])
114
+ expect(@permission_brazil_2.roles.to_set).to eq([@role].to_set)
115
+ end
116
+
117
+ it 'update_attribute' do
118
+ @permission_brazil_2.update_attribute(:role_ids, [@role.id])
119
+ expect(@permission_brazil_2.roles.to_set).to eq([@role].to_set)
120
+ end
121
+
122
+ it '<<' do
123
+ @permission_brazil_2.roles << @role
124
+ @role.save
125
+ @permission_brazil_2.save
126
+ @permission_brazil_2.reload
127
+ expect(@permission_brazil_2.roles.to_set).to eq([@role].to_set)
128
+ end
129
+
130
+ it 'build' do
131
+ role = @permission_brazil_2.roles.build(:name => 'Builded Role')
132
+ @permission_brazil_2.save
133
+ expect(@permission_brazil_2.roles.to_set).to eq([role].to_set)
134
+ end
135
+
136
+ it 'create' do
137
+ role = @permission_brazil_2.roles.create(:name => 'Builded Role')
138
+ expect(@permission_brazil_2.roles.to_set).to eq([role].to_set)
139
+ end
140
+
141
+ it 'create' do
142
+ role = @permission_brazil_2.roles.create!(:name => 'Builded Role')
143
+ expect(@permission_brazil_2.roles.to_set).to eq([role].to_set)
144
+ end
145
+
146
+ it 'count' do
147
+ expect(@permission_brazil_2.roles.count).to eq(0)
148
+ _role = @permission_brazil_2.roles.create(:name => 'Builded Role')
149
+ expect(@permission_brazil_2.roles.count).to eq(1)
150
+ _role = @permission_brazil_2.roles.create(:name => 'Builded Role')
151
+ expect(@permission_brazil_2.roles.count).to eq(2)
152
+ end
153
+
154
+ it 'size' do
155
+ expect(@permission_brazil_2.roles.size).to eq(0)
156
+ _role = @permission_brazil_2.roles.create(:name => 'Builded Role')
157
+ expect(@permission_brazil_2.roles.size).to eq(1)
158
+ _role = @permission_brazil_2.roles.create(:name => 'Builded Role')
159
+ expect(@permission_brazil_2.roles.size).to eq(2)
160
+ end
161
+
162
+ it 'length' do
163
+ expect(@permission_brazil_2.roles.length).to eq(0)
164
+ _role = @permission_brazil_2.roles.create(:name => 'Builded Role')
165
+ expect(@permission_brazil_2.roles.length).to eq(1)
166
+ _role = @permission_brazil_2.roles.create(:name => 'Builded Role')
167
+ expect(@permission_brazil_2.roles.length).to eq(2)
168
+ end
169
+
170
+ it 'empty?' do
171
+ expect(@permission_brazil_2.roles.empty?).to be true
172
+ _role = @permission_brazil_2.roles.create(:name => 'Builded Role')
173
+ expect(@permission_brazil_2.roles.empty?).to be false
174
+ end
175
+
176
+ it 'delete_all' do
177
+ _role = @permission_brazil_2.roles.create(:name => 'Builded Role')
178
+ expect(@permission_brazil_2.roles.empty?).to be false
179
+ @permission_brazil_2.roles.delete_all
180
+ expect(@permission_brazil_2.roles.empty?).to be true
181
+ end
182
+
183
+ it 'destroy_all' do
184
+ _role = @permission_brazil_2.roles.create(:name => 'Builded Role')
185
+ expect(@permission_brazil_2.roles.empty?).to be false
186
+ @permission_brazil_2.roles.destroy_all
187
+ expect(@permission_brazil_2.roles.empty?).to be true
188
+ end
189
+
190
+ it 'find' do
191
+ role = @permission_brazil_2.roles.create(:name => 'Builded Role')
192
+ expect(@permission_brazil_2.roles.first).to eq(role)
193
+ @permission_brazil_2.roles.destroy_all
194
+ expect(@permission_brazil_2.roles.first).to be_nil
195
+ end
196
+
197
+ it 'exists?' do
198
+ role = @permission_brazil_2.roles.create(:name => 'Builded Role')
199
+ expect(@permission_brazil_2.roles.exists?(role)).to be true
200
+ @permission_brazil_2.roles.destroy_all
201
+ expect(@permission_brazil_2.roles.exists?(role)).to be false
202
+ end
203
+
204
+ it 'clear' do
205
+ _rol = @permission_brazil_2.roles.create(:name => 'Builded Role')
206
+ expect(@permission_brazil_2.roles.empty?).to be false
207
+ @permission_brazil_2.roles.clear
208
+ expect(@permission_brazil_2.roles.empty?).to be true
209
+ end
210
+
211
+ it 'delete' do
212
+ role = @permission_brazil_2.roles.create(:name => 'Builded Role')
213
+ expect(@permission_brazil_2.roles.empty?).to be false
214
+ @permission_brazil_2.roles.delete(role)
215
+ @permission_brazil_2.reload
216
+ @role.reload
217
+ expect(@role.permissions).to eq([])
218
+ expect(@permission_brazil_2.roles).to eq([])
219
+ end
220
+ end
221
+ end
222
+
223
+ describe 'when you have has_many :through' do
224
+ before(:each) do
225
+ @programmer = Programmer.using(:brazil).create!(:name => 'Thiago')
226
+ @project = Project.using(:brazil).create!(:name => 'RubySoc')
227
+ @project2 = Project.using(:brazil).create!(:name => 'Cobol Application')
228
+ @programmer.projects << @project
229
+ @programmer.save
230
+ Project.using(:master).create!(:name => 'Project Master')
231
+ end
232
+
233
+ it 'should find all models in the specified shard' do
234
+ expect(@programmer.project_ids).to eq([@project.id])
235
+ expect(@programmer.projects).to eq([@project])
236
+
237
+ expect(@programmer.projects.first).to eq(@project)
238
+ expect(@programmer.projects.last).to eq(@project)
239
+ end
240
+
241
+ it 'should update the attribute for the item' do
242
+ new_brazil_programmer = Programmer.using(:brazil).create!(:name => 'Joao')
243
+ @project.programmers = [new_brazil_programmer]
244
+ expect(@project.programmers).to eq([new_brazil_programmer])
245
+ @project.save
246
+ @project.reload
247
+ expect(@project.programmer_ids).to eq([new_brazil_programmer.id])
248
+ expect(@project.programmers).to eq([new_brazil_programmer])
249
+ end
250
+
251
+ it 'should works for create method' do
252
+ new_brazil_programmer = Programmer.using(:brazil).create!(:name => 'Joao')
253
+ c = new_brazil_programmer.projects.create(:name => 'new Project')
254
+ c.save
255
+ new_brazil_programmer.save
256
+ expect(c.programmers).to eq([new_brazil_programmer])
257
+ expect(new_brazil_programmer.projects).to eq([c])
258
+ end
259
+
260
+ describe 'it should works when using' do
261
+ before(:each) do
262
+ @new_brazil_programmer = Programmer.using(:brazil).create!(:name => 'Jose')
263
+ @project = Project.using(:brazil).create!(:name => 'VB Application :-(')
264
+ end
265
+
266
+ it 'update_attributes' do
267
+ @new_brazil_programmer.update_attributes(:project_ids => [@project.id])
268
+ expect(@new_brazil_programmer.projects.to_set).to eq([@project].to_set)
269
+ end
270
+
271
+ it 'update_attribute' do
272
+ @new_brazil_programmer.update_attribute(:project_ids, [@project.id])
273
+ expect(@new_brazil_programmer.projects.to_set).to eq([@project].to_set)
274
+ end
275
+
276
+ it '<<' do
277
+ @new_brazil_programmer.projects << @project
278
+ @project.save
279
+ @new_brazil_programmer.save
280
+ @new_brazil_programmer.reload
281
+ expect(@new_brazil_programmer.projects.to_set).to eq([@project].to_set)
282
+ end
283
+
284
+ it 'build' do
285
+ role = @new_brazil_programmer.projects.build(:name => 'New VB App :-/')
286
+ @new_brazil_programmer.save
287
+ expect(@new_brazil_programmer.projects.to_set).to eq([role].to_set)
288
+ end
289
+
290
+ it 'create' do
291
+ role = @new_brazil_programmer.projects.create(:name => 'New VB App :-/')
292
+ expect(@new_brazil_programmer.projects.to_set).to eq([role].to_set)
293
+ end
294
+
295
+ it 'create' do
296
+ role = @new_brazil_programmer.projects.create!(:name => 'New VB App :-/')
297
+ expect(@new_brazil_programmer.projects.to_set).to eq([role].to_set)
298
+ end
299
+
300
+ it 'count' do
301
+ expect(@new_brazil_programmer.projects.count).to eq(0)
302
+ _role = @new_brazil_programmer.projects.create(:name => 'New VB App :-/')
303
+ expect(@new_brazil_programmer.projects.count).to eq(1)
304
+ _role = @new_brazil_programmer.projects.create(:name => 'New VB App :-/')
305
+ expect(@new_brazil_programmer.projects.count).to eq(2)
306
+ end
307
+
308
+ it 'size' do
309
+ expect(@new_brazil_programmer.projects.size).to eq(0)
310
+ _role = @new_brazil_programmer.projects.create(:name => 'New VB App :-/')
311
+ expect(@new_brazil_programmer.projects.size).to eq(1)
312
+ _role = @new_brazil_programmer.projects.create(:name => 'New VB App :-/')
313
+ expect(@new_brazil_programmer.projects.size).to eq(2)
314
+ end
315
+
316
+ it 'length' do
317
+ expect(@new_brazil_programmer.projects.length).to eq(0)
318
+ _role = @new_brazil_programmer.projects.create(:name => 'New VB App :-/')
319
+ expect(@new_brazil_programmer.projects.length).to eq(1)
320
+ _role = @new_brazil_programmer.projects.create(:name => 'New VB App :-/')
321
+ expect(@new_brazil_programmer.projects.length).to eq(2)
322
+ end
323
+
324
+ it 'empty?' do
325
+ expect(@new_brazil_programmer.projects.empty?).to be true
326
+ _role = @new_brazil_programmer.projects.create(:name => 'New VB App :-/')
327
+ expect(@new_brazil_programmer.projects.empty?).to be false
328
+ end
329
+
330
+ it 'delete_all' do
331
+ _role = @new_brazil_programmer.projects.create(:name => 'New VB App :-/')
332
+ expect(@new_brazil_programmer.projects.empty?).to be false
333
+ @new_brazil_programmer.projects.delete_all
334
+ expect(@new_brazil_programmer.projects.empty?).to be true
335
+ end
336
+
337
+ it 'destroy_all' do
338
+ _role = @new_brazil_programmer.projects.create(:name => 'New VB App :-/')
339
+ expect(@new_brazil_programmer.projects.empty?).to be false
340
+ @new_brazil_programmer.projects.destroy_all
341
+ expect(@new_brazil_programmer.projects.empty?).to be true
342
+ end
343
+
344
+ it 'find' do
345
+ role = @new_brazil_programmer.projects.create(:name => 'New VB App :-/')
346
+ expect(@new_brazil_programmer.projects.first).to eq(role)
347
+ @new_brazil_programmer.projects.destroy_all
348
+ expect(@new_brazil_programmer.projects.first).to be_nil
349
+ end
350
+
351
+ it 'exists?' do
352
+ role = @new_brazil_programmer.projects.create(:name => 'New VB App :-/')
353
+ expect(@new_brazil_programmer.projects.exists?(role)).to be true
354
+ @new_brazil_programmer.projects.destroy_all
355
+ expect(@new_brazil_programmer.projects.exists?(role)).to be false
356
+ end
357
+
358
+ it 'clear' do
359
+ _role = @new_brazil_programmer.projects.create(:name => 'New VB App :-/')
360
+ expect(@new_brazil_programmer.projects.empty?).to be false
361
+ @new_brazil_programmer.projects.clear
362
+ expect(@new_brazil_programmer.projects.empty?).to be true
363
+ end
364
+
365
+ it 'delete' do
366
+ role = @new_brazil_programmer.projects.create(:name => 'New VB App :-/')
367
+ expect(@new_brazil_programmer.projects.empty?).to be false
368
+ @new_brazil_programmer.projects.delete(role)
369
+ @new_brazil_programmer.reload
370
+ @project.reload
371
+ expect(@project.programmers).to eq([])
372
+ expect(@new_brazil_programmer.projects).to eq([])
373
+ end
374
+ end
375
+ end
376
+
377
+ describe 'when you have a 1 x N relationship' do
378
+ before(:each) do
379
+ @brazil_client = Client.using(:brazil).create!(:name => 'Brazil Client')
380
+ @master_client = Client.create!(:name => 'Master Client')
381
+ @item_brazil = Item.using(:brazil).create!(:name => 'Brazil Item', :client => @brazil_client)
382
+ @item_master = Item.create!(:name => 'Master Item', :client => @master_client)
383
+ @brazil_client = Client.using(:brazil).find_by_name('Brazil Client')
384
+ Client.using(:master).create!(:name => 'teste')
385
+ end
386
+
387
+ it 'should find all models in the specified shard' do
388
+ expect(@brazil_client.item_ids).to eq([@item_brazil.id])
389
+ expect(@brazil_client.items).to eq([@item_brazil])
390
+
391
+ expect(@brazil_client.items.last).to eq(@item_brazil)
392
+ expect(@brazil_client.items.first).to eq(@item_brazil)
393
+ end
394
+
395
+ it 'should finds the client that the item belongs' do
396
+ expect(@item_brazil.client).to eq(@brazil_client)
397
+ end
398
+
399
+ it 'should raise error if you try to add a record from a different shard' do
400
+ expect do
401
+ @brazil_client.items << Item.using(:canada).create!(:name => 'New User')
402
+ end.to raise_error('Association Error: Records are from different shards')
403
+ end
404
+
405
+ it 'should update the attribute for the item' do
406
+ new_brazil_client = Client.using(:brazil).create!(:name => 'new Client')
407
+ @item_brazil.client = new_brazil_client
408
+ expect(@item_brazil.client).to eq(new_brazil_client)
409
+ @item_brazil.save
410
+ @item_brazil.reload
411
+ expect(@item_brazil.client_id).to eq(new_brazil_client.id)
412
+ expect(@item_brazil.client).to eq(new_brazil_client)
413
+ end
414
+
415
+ it 'should works for build method' do
416
+ item2 = Item.using(:brazil).create!(:name => 'Brazil Item')
417
+ c = item2.create_client(:name => 'new Client')
418
+ c.save
419
+ item2.save
420
+ expect(item2.client).to eq(c)
421
+ expect(c.items).to eq([item2])
422
+ end
423
+
424
+ context 'when calling methods on a collection generated by an association' do
425
+ let(:collection) { @brazil_client.items }
426
+ before :each do
427
+ @brazil_client.items.create(:name => 'Brazil Item #2')
428
+ end
429
+
430
+ it "can call collection indexes directly without resetting the collection's current_shard" do
431
+ last_item = collection[1]
432
+ expect(collection.length).to eq(2)
433
+ expect(collection).to eq([collection[0], last_item])
434
+ end
435
+
436
+ it "can call methods on the collection without resetting the collection's current_shard" do
437
+ last_item = collection[collection.size - 1]
438
+ expect(collection.length).to eq(2)
439
+ expect(collection).to eq([collection[0], last_item])
440
+ end
441
+ end
442
+
443
+ describe 'it should works when using' do
444
+ before(:each) do
445
+ @item_brazil_2 = Item.using(:brazil).create!(:name => 'Brazil Item 2')
446
+ expect(@brazil_client.items.to_set).to eq([@item_brazil].to_set)
447
+ end
448
+
449
+ it 'update_attributes' do
450
+ @brazil_client.update_attributes(:item_ids => [@item_brazil_2.id, @item_brazil.id])
451
+ expect(@brazil_client.items.to_set).to eq([@item_brazil, @item_brazil_2].to_set)
452
+ end
453
+
454
+ it 'update_attribute' do
455
+ @brazil_client.update_attribute(:item_ids, [@item_brazil_2.id, @item_brazil.id])
456
+ expect(@brazil_client.items.to_set).to eq([@item_brazil, @item_brazil_2].to_set)
457
+ end
458
+
459
+ it '<<' do
460
+ @brazil_client.items << @item_brazil_2
461
+ expect(@brazil_client.items.to_set).to eq([@item_brazil, @item_brazil_2].to_set)
462
+ end
463
+
464
+ it 'all' do
465
+ item = @brazil_client.items.build(:name => 'Builded Item')
466
+ item.save
467
+ i = @brazil_client.items
468
+ expect(i.to_set).to eq([@item_brazil, item].to_set)
469
+ expect(i.reload.all.to_set).to eq([@item_brazil, item].to_set)
470
+ end
471
+
472
+ it 'build' do
473
+ item = @brazil_client.items.build(:name => 'Builded Item')
474
+ item.save
475
+ expect(@brazil_client.items.to_set).to eq([@item_brazil, item].to_set)
476
+ end
477
+
478
+ it 'create' do
479
+ item = @brazil_client.items.create(:name => 'Builded Item')
480
+ expect(@brazil_client.items.to_set).to eq([@item_brazil, item].to_set)
481
+ end
482
+
483
+ it 'count' do
484
+ expect(@brazil_client.items.count).to eq(1)
485
+ _itm = @brazil_client.items.create(:name => 'Builded Item')
486
+ expect(@brazil_client.items.count).to eq(2)
487
+ end
488
+
489
+ it 'size' do
490
+ expect(@brazil_client.items.size).to eq(1)
491
+ _itm = @brazil_client.items.create(:name => 'Builded Item')
492
+ expect(@brazil_client.items.size).to eq(2)
493
+ end
494
+
495
+ it 'create!' do
496
+ item = @brazil_client.items.create!(:name => 'Builded Item')
497
+ expect(@brazil_client.items.to_set).to eq([@item_brazil, item].to_set)
498
+ end
499
+
500
+ it 'length' do
501
+ expect(@brazil_client.items.length).to eq(1)
502
+ _itm = @brazil_client.items.create(:name => 'Builded Item')
503
+ expect(@brazil_client.items.length).to eq(2)
504
+ end
505
+
506
+ it 'empty?' do
507
+ expect(@brazil_client.items.empty?).to be false
508
+ c = Client.create!(:name => 'Client1')
509
+ expect(c.items.empty?).to be true
510
+ end
511
+
512
+ it 'delete' do
513
+ expect(@brazil_client.items.empty?).to be false
514
+ @brazil_client.items.delete(@item_brazil)
515
+ @brazil_client.reload
516
+ @item_brazil.reload
517
+ expect(@item_brazil.client).to be_nil
518
+ expect(@brazil_client.items).to eq([])
519
+ expect(@brazil_client.items.empty?).to be true
520
+ end
521
+
522
+ it 'delete_all' do
523
+ expect(@brazil_client.items.empty?).to be false
524
+ @brazil_client.items.delete_all
525
+ expect(@brazil_client.items.empty?).to be true
526
+ end
527
+
528
+ it 'destroy_all' do
529
+ expect(@brazil_client.items.empty?).to be false
530
+ @brazil_client.items.destroy_all
531
+ expect(@brazil_client.items.empty?).to be true
532
+ end
533
+
534
+ it 'find' do
535
+ expect(@brazil_client.items.first).to eq(@item_brazil)
536
+ @brazil_client.items.destroy_all
537
+ expect(@brazil_client.items.first).to be_nil
538
+ end
539
+
540
+ it 'exists?' do
541
+ expect(@brazil_client.items.exists?(@item_brazil)).to be true
542
+ @brazil_client.items.destroy_all
543
+ expect(@brazil_client.items.exists?(@item_brazil)).to be false
544
+ end
545
+
546
+ it 'uniq' do
547
+ expect(@brazil_client.items.uniq).to eq([@item_brazil])
548
+ end
549
+
550
+ it 'clear' do
551
+ expect(@brazil_client.items.empty?).to be false
552
+ @brazil_client.items.clear
553
+ expect(@brazil_client.items.empty?).to be true
554
+ end
555
+ end
556
+ end
557
+
558
+ describe 'when you have a 1 x N polymorphic relationship' do
559
+ before(:each) do
560
+ @brazil_client = Client.using(:brazil).create!(:name => 'Brazil Client')
561
+ @master_client = Client.create!(:name => 'Master Client')
562
+ @comment_brazil = Comment.using(:brazil).create!(:name => 'Brazil Comment', :commentable => @brazil_client)
563
+ @comment_master = Comment.create!(:name => 'Master Comment', :commentable => @master_client)
564
+ @brazil_client = Client.using(:brazil).find_by_name('Brazil Client')
565
+ Client.using(:master).create!(:name => 'teste')
566
+ end
567
+
568
+ it 'should find all models in the specified shard' do
569
+ expect(@brazil_client.comment_ids).to eq([@comment_brazil.id])
570
+ expect(@brazil_client.comments).to eq([@comment_brazil])
571
+ end
572
+
573
+ it 'should finds the client that the comment belongs' do
574
+ expect(@comment_brazil.commentable).to eq(@brazil_client)
575
+ end
576
+
577
+ it 'should update the attribute for the comment' do
578
+ new_brazil_client = Client.using(:brazil).create!(:name => 'new Client')
579
+ @comment_brazil.commentable = new_brazil_client
580
+ expect(@comment_brazil.commentable).to eq(new_brazil_client)
581
+ @comment_brazil.save
582
+ @comment_brazil.reload
583
+ expect(@comment_brazil.commentable_id).to eq(new_brazil_client.id)
584
+ expect(@comment_brazil.commentable).to eq(new_brazil_client)
585
+ end
586
+
587
+ describe 'it should works when using' do
588
+ before(:each) do
589
+ @comment_brazil_2 = Comment.using(:brazil).create!(:name => 'Brazil Comment 2')
590
+ expect(@brazil_client.comments.to_set).to eq([@comment_brazil].to_set)
591
+ end
592
+
593
+ it 'update_attributes' do
594
+ @brazil_client.update_attributes(:comment_ids => [@comment_brazil_2.id, @comment_brazil.id])
595
+ expect(@brazil_client.comments.to_set).to eq([@comment_brazil, @comment_brazil_2].to_set)
596
+ end
597
+
598
+ it 'update_attribute' do
599
+ @brazil_client.update_attribute(:comment_ids, [@comment_brazil_2.id, @comment_brazil.id])
600
+ expect(@brazil_client.comments.to_set).to eq([@comment_brazil, @comment_brazil_2].to_set)
601
+ end
602
+
603
+ it '<<' do
604
+ @brazil_client.comments << @comment_brazil_2
605
+ expect(@brazil_client.comments.to_set).to eq([@comment_brazil, @comment_brazil_2].to_set)
606
+ end
607
+
608
+ it 'all' do
609
+ comment = @brazil_client.comments.build(:name => 'Builded Comment')
610
+ comment.save
611
+ c = @brazil_client.comments
612
+ expect(c.to_set).to eq([@comment_brazil, comment].to_set)
613
+ expect(c.reload.all.to_set).to eq([@comment_brazil, comment].to_set)
614
+ end
615
+
616
+ it 'build' do
617
+ comment = @brazil_client.comments.build(:name => 'Builded Comment')
618
+ comment.save
619
+ expect(@brazil_client.comments.to_set).to eq([@comment_brazil, comment].to_set)
620
+ end
621
+
622
+ it 'create' do
623
+ comment = @brazil_client.comments.create(:name => 'Builded Comment')
624
+ expect(@brazil_client.comments.to_set).to eq([@comment_brazil, comment].to_set)
625
+ end
626
+
627
+ it 'count' do
628
+ expect(@brazil_client.comments.count).to eq(1)
629
+ _cmt = @brazil_client.comments.create(:name => 'Builded Comment')
630
+ expect(@brazil_client.comments.count).to eq(2)
631
+ end
632
+
633
+ it 'group + count' do
634
+ expect(@brazil_client.comments.group(:id).count.length).to eq(1)
635
+ _cmt = @brazil_client.comments.create(:name => 'Builded Comment')
636
+ expect(@brazil_client.comments.group(:id).count.length).to eq(2)
637
+ end
638
+
639
+ it 'size' do
640
+ expect(@brazil_client.comments.size).to eq(1)
641
+ _cmt = @brazil_client.comments.create(:name => 'Builded Comment')
642
+ expect(@brazil_client.comments.size).to eq(2)
643
+ end
644
+
645
+ it 'create!' do
646
+ comment = @brazil_client.comments.create!(:name => 'Builded Comment')
647
+ expect(@brazil_client.comments.to_set).to eq([@comment_brazil, comment].to_set)
648
+ end
649
+
650
+ it 'length' do
651
+ expect(@brazil_client.comments.length).to eq(1)
652
+ _cmt = @brazil_client.comments.create(:name => 'Builded Comment')
653
+ expect(@brazil_client.comments.length).to eq(2)
654
+ end
655
+
656
+ it 'empty?' do
657
+ expect(@brazil_client.comments.empty?).to be false
658
+ c = Client.create!(:name => 'Client1')
659
+ expect(c.comments.empty?).to be true
660
+ end
661
+
662
+ it 'delete' do
663
+ expect(@brazil_client.comments.empty?).to be false
664
+ @brazil_client.comments.delete(@comment_brazil)
665
+ @brazil_client.reload
666
+ @comment_brazil.reload
667
+ expect(@comment_brazil.commentable).to be_nil
668
+ expect(@brazil_client.comments).to eq([])
669
+ expect(@brazil_client.comments.empty?).to be true
670
+ end
671
+
672
+ it 'delete_all' do
673
+ expect(@brazil_client.comments.empty?).to be false
674
+ @brazil_client.comments.delete_all
675
+ expect(@brazil_client.comments.empty?).to be true
676
+ end
677
+
678
+ it 'destroy_all' do
679
+ expect(@brazil_client.comments.empty?).to be false
680
+ @brazil_client.comments.destroy_all
681
+ expect(@brazil_client.comments.empty?).to be true
682
+ end
683
+
684
+ it 'find' do
685
+ expect(@brazil_client.comments.first).to eq(@comment_brazil)
686
+ @brazil_client.comments.destroy_all
687
+ expect(@brazil_client.comments.first).to be_nil
688
+ end
689
+
690
+ it 'exists?' do
691
+ expect(@brazil_client.comments.exists?(@comment_brazil)).to be true
692
+ @brazil_client.comments.destroy_all
693
+ expect(@brazil_client.comments.exists?(@comment_brazil)).to be false
694
+ end
695
+
696
+ it 'uniq' do
697
+ expect(@brazil_client.comments.uniq).to eq([@comment_brazil])
698
+ end
699
+
700
+ it 'clear' do
701
+ expect(@brazil_client.comments.empty?).to be false
702
+ @brazil_client.comments.clear
703
+ expect(@brazil_client.comments.empty?).to be true
704
+ end
705
+ end
706
+ end
707
+
708
+ it 'block' do
709
+ @brazil_role = Role.using(:brazil).create!(:name => 'Brazil Role')
710
+ expect(@brazil_role.permissions.build(:name => 'ok').name).to eq('ok')
711
+ expect(@brazil_role.permissions.create(:name => 'ok').name).to eq('ok')
712
+ expect(@brazil_role.permissions.create!(:name => 'ok').name).to eq('ok')
713
+ end
714
+ end