ar-octopus 0.8.5 → 0.10.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +1 -0
  3. data/.travis.yml +6 -9
  4. data/Appraisals +8 -8
  5. data/README.mkdn +47 -15
  6. data/Rakefile +1 -0
  7. data/ar-octopus.gemspec +9 -12
  8. data/gemfiles/rails42.gemfile +2 -2
  9. data/gemfiles/{rails32.gemfile → rails5.gemfile} +2 -2
  10. data/gemfiles/{rails4.gemfile → rails51.gemfile} +2 -2
  11. data/gemfiles/{rails41.gemfile → rails52.gemfile} +2 -2
  12. data/lib/octopus/abstract_adapter.rb +4 -10
  13. data/lib/octopus/association.rb +1 -0
  14. data/lib/octopus/association_shard_tracking.rb +41 -71
  15. data/lib/octopus/collection_association.rb +9 -3
  16. data/lib/octopus/exception.rb +4 -0
  17. data/lib/octopus/finder_methods.rb +8 -0
  18. data/lib/octopus/load_balancing/round_robin.rb +2 -1
  19. data/lib/octopus/log_subscriber.rb +6 -2
  20. data/lib/octopus/migration.rb +123 -55
  21. data/lib/octopus/model.rb +42 -27
  22. data/lib/octopus/persistence.rb +33 -27
  23. data/lib/octopus/proxy.rb +147 -272
  24. data/lib/octopus/proxy_config.rb +251 -0
  25. data/lib/octopus/query_cache_for_shards.rb +24 -0
  26. data/lib/octopus/railtie.rb +0 -2
  27. data/lib/octopus/relation_proxy.rb +36 -1
  28. data/lib/octopus/result_patch.rb +19 -0
  29. data/lib/octopus/scope_proxy.rb +12 -5
  30. data/lib/octopus/shard_tracking.rb +8 -3
  31. data/lib/octopus/slave_group.rb +3 -3
  32. data/lib/octopus/version.rb +1 -1
  33. data/lib/octopus.rb +71 -18
  34. data/spec/config/shards.yml +12 -0
  35. data/spec/migrations/10_create_users_using_replication.rb +1 -1
  36. data/spec/migrations/11_add_field_in_all_slaves.rb +1 -1
  37. data/spec/migrations/12_create_users_using_block.rb +1 -1
  38. data/spec/migrations/13_create_users_using_block_and_using.rb +1 -1
  39. data/spec/migrations/14_create_users_on_shards_of_a_group_with_versions.rb +1 -1
  40. data/spec/migrations/15_create_user_on_shards_of_default_group_with_versions.rb +1 -1
  41. data/spec/migrations/1_create_users_on_master.rb +1 -1
  42. data/spec/migrations/2_create_users_on_canada.rb +1 -1
  43. data/spec/migrations/3_create_users_on_both_shards.rb +1 -1
  44. data/spec/migrations/4_create_users_on_shards_of_a_group.rb +1 -1
  45. data/spec/migrations/5_create_users_on_multiples_groups.rb +1 -1
  46. data/spec/migrations/6_raise_exception_with_invalid_shard_name.rb +1 -1
  47. data/spec/migrations/7_raise_exception_with_invalid_multiple_shard_names.rb +1 -1
  48. data/spec/migrations/8_raise_exception_with_invalid_group_name.rb +1 -1
  49. data/spec/migrations/9_raise_exception_with_multiple_invalid_group_names.rb +1 -1
  50. data/spec/octopus/association_shard_tracking_spec.rb +344 -16
  51. data/spec/octopus/load_balancing/round_robin_spec.rb +15 -0
  52. data/spec/octopus/log_subscriber_spec.rb +1 -1
  53. data/spec/octopus/migration_spec.rb +45 -11
  54. data/spec/octopus/model_spec.rb +204 -16
  55. data/spec/octopus/octopus_spec.rb +2 -2
  56. data/spec/octopus/proxy_spec.rb +44 -40
  57. data/spec/octopus/query_cache_for_shards_spec.rb +40 -0
  58. data/spec/octopus/relation_proxy_spec.rb +71 -23
  59. data/spec/octopus/replicated_slave_grouped_spec.rb +27 -0
  60. data/spec/octopus/replication_spec.rb +72 -2
  61. data/spec/octopus/scope_proxy_spec.rb +41 -7
  62. data/spec/spec_helper.rb +2 -0
  63. data/spec/support/database_connection.rb +1 -1
  64. data/spec/support/database_models.rb +1 -1
  65. data/spec/support/octopus_helper.rb +14 -6
  66. data/spec/tasks/octopus.rake_spec.rb +1 -1
  67. metadata +40 -30
  68. data/.ruby-version +0 -1
  69. data/init.rb +0 -1
  70. data/lib/octopus/has_and_belongs_to_many_association.rb +0 -9
  71. data/rails/init.rb +0 -1
@@ -1,4 +1,4 @@
1
- class CreateUsersOnBothShards < ActiveRecord::Migration
1
+ class CreateUsersOnBothShards < BaseOctopusMigrationClass
2
2
  using(:brazil, :canada)
3
3
 
4
4
  def self.up
@@ -1,4 +1,4 @@
1
- class CreateUsersOnShardsOfAGroup < ActiveRecord::Migration
1
+ class CreateUsersOnShardsOfAGroup < BaseOctopusMigrationClass
2
2
  using_group(:country_shards)
3
3
 
4
4
  def self.up
@@ -1,4 +1,4 @@
1
- class CreateUsersOnMultiplesGroups < ActiveRecord::Migration
1
+ class CreateUsersOnMultiplesGroups < BaseOctopusMigrationClass
2
2
  using_group('country_shards', 'history_shards')
3
3
 
4
4
  def self.up
@@ -1,4 +1,4 @@
1
- class RaiseExceptionWithInvalidShardName < ActiveRecord::Migration
1
+ class RaiseExceptionWithInvalidShardName < BaseOctopusMigrationClass
2
2
  using(:amazing_shard)
3
3
 
4
4
  def self.up
@@ -1,4 +1,4 @@
1
- class RaiseExceptionWithInvalidMultipleShardNames < ActiveRecord::Migration
1
+ class RaiseExceptionWithInvalidMultipleShardNames < BaseOctopusMigrationClass
2
2
  using(:brazil, :invalid_shard)
3
3
 
4
4
  def self.up
@@ -1,4 +1,4 @@
1
- class RaiseExceptionWithInvalidGroupName < ActiveRecord::Migration
1
+ class RaiseExceptionWithInvalidGroupName < BaseOctopusMigrationClass
2
2
  using_group(:invalid_group)
3
3
 
4
4
  def self.up
@@ -1,4 +1,4 @@
1
- class RaiseExceptionWithMultipleInvalidGroupNames < ActiveRecord::Migration
1
+ class RaiseExceptionWithMultipleInvalidGroupNames < BaseOctopusMigrationClass
2
2
  using_group(:country_shards, :invalid_group)
3
3
 
4
4
  def self.up
@@ -73,6 +73,7 @@ describe Octopus::AssociationShardTracking, :shards => [:brazil, :master, :canad
73
73
  expect(@brazil_role.permissions).to eq([@permission_brazil])
74
74
 
75
75
  expect(@brazil_role.permissions.first).to eq(@permission_brazil)
76
+ expect(@brazil_role.permissions.first!).to eq(@permission_brazil)
76
77
  expect(@brazil_role.permissions.last).to eq(@permission_brazil)
77
78
  end
78
79
 
@@ -81,6 +82,7 @@ describe Octopus::AssociationShardTracking, :shards => [:brazil, :master, :canad
81
82
  expect(@permission_brazil.roles).to eq([@brazil_role])
82
83
 
83
84
  expect(@permission_brazil.roles.first).to eq(@brazil_role)
85
+ expect(@permission_brazil.roles.first!).to eq(@brazil_role)
84
86
  expect(@permission_brazil.roles.last).to eq(@brazil_role)
85
87
  end
86
88
 
@@ -94,7 +96,7 @@ describe Octopus::AssociationShardTracking, :shards => [:brazil, :master, :canad
94
96
  expect(@permission_brazil.roles).to eq([new_brazil_role])
95
97
  end
96
98
 
97
- it 'should works for build method' do
99
+ it 'should work for build method' do
98
100
  new_brazil_role = Role.using(:brazil).create!(:name => 'Brazil Role')
99
101
  c = new_brazil_role.permissions.create(:name => 'new Permission')
100
102
  c.save
@@ -103,7 +105,7 @@ describe Octopus::AssociationShardTracking, :shards => [:brazil, :master, :canad
103
105
  expect(new_brazil_role.permissions).to eq([c])
104
106
  end
105
107
 
106
- describe 'it should works when using' do
108
+ describe 'it should work when using' do
107
109
  before(:each) do
108
110
  @permission_brazil_2 = Permission.using(:brazil).create!(:name => 'Brazil Item 2')
109
111
  @role = Role.using(:brazil).create!(:name => 'testes')
@@ -194,11 +196,97 @@ describe Octopus::AssociationShardTracking, :shards => [:brazil, :master, :canad
194
196
  expect(@permission_brazil_2.roles.first).to be_nil
195
197
  end
196
198
 
199
+ it 'where' do
200
+ role = @permission_brazil_2.roles.create(:name => 'Builded Role')
201
+ expect(@permission_brazil_2.roles.where('1=1')).to eq([role])
202
+ @permission_brazil_2.roles.destroy_all
203
+ expect(@permission_brazil_2.roles.where('1=1')).to be_empty
204
+ end
205
+
206
+ it 'map' do
207
+ role = @permission_brazil_2.roles.create(:name => 'Builded Role')
208
+ expect(@permission_brazil_2.roles.map(&:id)).to eq([role.id])
209
+ @permission_brazil_2.roles.destroy_all
210
+ expect(@permission_brazil_2.roles.map(&:id)).to be_empty
211
+ end
212
+
213
+ it 'where + map' do
214
+ role = @permission_brazil_2.roles.create(:name => 'Builded Role')
215
+ expect(@permission_brazil_2.roles.where('1=1').map(&:id)).to eq([role.id])
216
+ @permission_brazil_2.roles.destroy_all
217
+ expect(@permission_brazil_2.roles.where('1=1').map(&:id)).to be_empty
218
+ end
219
+
220
+ # each_with_index is not listed in active_record/relation/delegation.rb
221
+ it 'where + each_with_index + map (enum method chain)' do
222
+ role = @permission_brazil_2.roles.create(:name => 'Builded Role')
223
+ expect(@permission_brazil_2.roles.where('1=1').each_with_index.map { |r, i| [r.id, i]}).to eq([[role.id, 0]])
224
+ @permission_brazil_2.roles.destroy_all
225
+ expect(@permission_brazil_2.roles.where('1=1').each_with_index.map { |r, i| [r.id, i]}).to be_empty
226
+ end
227
+
228
+ # sum & index_by is specialized in active_support/core_ext/enumerable.rb
229
+ it 'where + sum' do
230
+ role = @permission_brazil_2.roles.create(:name => 'Builded Role')
231
+ expect(@permission_brazil_2.roles.where('1=1').sum(&:id)).to eq(role.id)
232
+ @permission_brazil_2.roles.destroy_all
233
+ expect(@permission_brazil_2.roles.where('1=1').sum(&:id)).to eq(0)
234
+ end
235
+
236
+ it 'where + index_by' do
237
+ role = @permission_brazil_2.roles.create(:name => 'Builded Role')
238
+ expect(@permission_brazil_2.roles.where('1=1').index_by(&:id)).to eq(role.id => role)
239
+ @permission_brazil_2.roles.destroy_all
240
+ expect(@permission_brazil_2.roles.where('1=1').index_by(&:id)).to be_empty
241
+ end
242
+
243
+ it 'where + find' do
244
+ role = @permission_brazil_2.roles.create(:name => 'Builded Role')
245
+ expect(@permission_brazil_2.roles.where('1=1').find([role.id])).to eq([role])
246
+ @permission_brazil_2.roles.destroy_all
247
+ expect { @permission_brazil_2.roles.where('1=1').find([role.id]) }.to raise_error ActiveRecord::RecordNotFound
248
+ end
249
+
250
+ it 'where + find with block' do
251
+ role = @permission_brazil_2.roles.create(:name => 'Builded Role')
252
+ expect(@permission_brazil_2.roles.where('1=1').find { |r| r.id == role.id }).to eq(role)
253
+ @permission_brazil_2.roles.destroy_all
254
+ expect(@permission_brazil_2.roles.where('1=1').find { |r| r.id == role.id }).to be_nil
255
+ end
256
+
257
+ it 'where + select' do
258
+ role = @permission_brazil_2.roles.create(:name => 'Builded Role')
259
+ expect(@permission_brazil_2.roles.where('1=1').select(:name).first.name).to eq(role.name)
260
+ @permission_brazil_2.roles.destroy_all
261
+ expect(@permission_brazil_2.roles.where('1=1').select(:name)).to be_empty
262
+ end
263
+
264
+ it 'where + select with block' do
265
+ role = @permission_brazil_2.roles.create(:name => 'Builded Role')
266
+ expect(@permission_brazil_2.roles.where('1=1').select { |r| r.id == role.id }).to eq([role])
267
+ @permission_brazil_2.roles.destroy_all
268
+ expect(@permission_brazil_2.roles.where('1=1').select { |r| r.id == role.id }).to be_empty
269
+ end
270
+
271
+ it 'where + any?' do
272
+ role = @permission_brazil_2.roles.create(:name => 'Builded Role')
273
+ expect(@permission_brazil_2.roles.where('1=1').any?).to be true
274
+ @permission_brazil_2.roles.destroy_all
275
+ expect(@permission_brazil_2.roles.where('1=1').any?).to be false
276
+ end
277
+
278
+ it 'where + any? with block' do
279
+ role = @permission_brazil_2.roles.create(:name => 'Builded Role')
280
+ expect(@permission_brazil_2.roles.where('1=1').any? { |r| r.id == role.id }).to be true
281
+ @permission_brazil_2.roles.destroy_all
282
+ expect(@permission_brazil_2.roles.where('1=1').any? { |r| r.id == role.id }).to be false
283
+ end
284
+
197
285
  it 'exists?' do
198
286
  role = @permission_brazil_2.roles.create(:name => 'Builded Role')
199
- expect(@permission_brazil_2.roles.exists?(role)).to be true
287
+ expect(@permission_brazil_2.roles.exists?(role.id)).to be true
200
288
  @permission_brazil_2.roles.destroy_all
201
- expect(@permission_brazil_2.roles.exists?(role)).to be false
289
+ expect(@permission_brazil_2.roles.exists?(role.id)).to be false
202
290
  end
203
291
 
204
292
  it 'clear' do
@@ -248,7 +336,7 @@ describe Octopus::AssociationShardTracking, :shards => [:brazil, :master, :canad
248
336
  expect(@project.programmers).to eq([new_brazil_programmer])
249
337
  end
250
338
 
251
- it 'should works for create method' do
339
+ it 'should work for create method' do
252
340
  new_brazil_programmer = Programmer.using(:brazil).create!(:name => 'Joao')
253
341
  c = new_brazil_programmer.projects.create(:name => 'new Project')
254
342
  c.save
@@ -257,7 +345,7 @@ describe Octopus::AssociationShardTracking, :shards => [:brazil, :master, :canad
257
345
  expect(new_brazil_programmer.projects).to eq([c])
258
346
  end
259
347
 
260
- describe 'it should works when using' do
348
+ describe 'it should work when using' do
261
349
  before(:each) do
262
350
  @new_brazil_programmer = Programmer.using(:brazil).create!(:name => 'Jose')
263
351
  @project = Project.using(:brazil).create!(:name => 'VB Application :-(')
@@ -348,11 +436,95 @@ describe Octopus::AssociationShardTracking, :shards => [:brazil, :master, :canad
348
436
  expect(@new_brazil_programmer.projects.first).to be_nil
349
437
  end
350
438
 
439
+ it 'where' do
440
+ role = @new_brazil_programmer.projects.create(:name => 'New VB App :-/')
441
+ expect(@new_brazil_programmer.projects.where('1=1')).to eq([role])
442
+ @new_brazil_programmer.projects.destroy_all
443
+ expect(@new_brazil_programmer.projects.where('1=1')).to be_empty
444
+ end
445
+
446
+ it 'map' do
447
+ role = @new_brazil_programmer.projects.create(:name => 'New VB App :-/')
448
+ expect(@new_brazil_programmer.projects.map(&:id)).to eq([role.id])
449
+ @new_brazil_programmer.projects.destroy_all
450
+ expect(@new_brazil_programmer.projects.map(&:id)).to be_empty
451
+ end
452
+
453
+ it 'where + map' do
454
+ role = @new_brazil_programmer.projects.create(:name => 'New VB App :-/')
455
+ expect(@new_brazil_programmer.projects.where('1=1').map(&:id)).to eq([role.id])
456
+ @new_brazil_programmer.projects.destroy_all
457
+ expect(@new_brazil_programmer.projects.where('1=1').map(&:id)).to be_empty
458
+ end
459
+
460
+ it 'where + each_with_index + map (enum method chain)' do
461
+ role = @new_brazil_programmer.projects.create(:name => 'New VB App :-/')
462
+ expect(@new_brazil_programmer.projects.where('1=1').each_with_index.map { |r, i| [r.id, i] }).to eq([[role.id, 0]])
463
+ @new_brazil_programmer.projects.destroy_all
464
+ expect(@new_brazil_programmer.projects.where('1=1').each_with_index.map { |r, i| [r.id, i] }).to be_empty
465
+ end
466
+
467
+ it 'where + sum' do
468
+ role = @new_brazil_programmer.projects.create(:name => 'New VB App :-/')
469
+ expect(@new_brazil_programmer.projects.where('1=1').sum(&:id)).to eq(role.id)
470
+ @new_brazil_programmer.projects.destroy_all
471
+ expect(@new_brazil_programmer.projects.where('1=1').sum(&:id)).to eq(0)
472
+ end
473
+
474
+ it 'where + index_by' do
475
+ role = @new_brazil_programmer.projects.create(:name => 'New VB App :-/')
476
+ expect(@new_brazil_programmer.projects.where('1=1').index_by(&:id)).to eq(role.id => role)
477
+ @new_brazil_programmer.projects.destroy_all
478
+ expect(@new_brazil_programmer.projects.where('1=1').index_by(&:id)).to be_empty
479
+ end
480
+
481
+ it 'where + find' do
482
+ role = @new_brazil_programmer.projects.create(:name => 'New VB App :-/')
483
+ expect(@new_brazil_programmer.projects.where('1=1').find(role.id)).to eq(role)
484
+ @new_brazil_programmer.projects.destroy_all
485
+ expect { @new_brazil_programmer.projects.where('1=1').find(role.id) }.to raise_error ActiveRecord::RecordNotFound
486
+ end
487
+
488
+ it 'where + find with block' do
489
+ role = @new_brazil_programmer.projects.create(:name => 'New VB App :-/')
490
+ expect(@new_brazil_programmer.projects.where('1=1').find { |r| r.id == role.id }).to eq(role)
491
+ @new_brazil_programmer.projects.destroy_all
492
+ expect(@new_brazil_programmer.projects.where('1=1').find { |r| r.id == role.id }).to be_nil
493
+ end
494
+
495
+ it 'where + select' do
496
+ role = @new_brazil_programmer.projects.create(:name => 'New VB App :-/')
497
+ expect(@new_brazil_programmer.projects.where('1=1').select(:name).first.name).to eq(role.name)
498
+ @new_brazil_programmer.projects.destroy_all
499
+ expect(@new_brazil_programmer.projects.where('1=1').select(:name)).to be_empty
500
+ end
501
+
502
+ it 'where + select with block' do
503
+ role = @new_brazil_programmer.projects.create(:name => 'New VB App :-/')
504
+ expect(@new_brazil_programmer.projects.where('1=1').select { |r| r.id == role.id }).to eq([role])
505
+ @new_brazil_programmer.projects.destroy_all
506
+ expect(@new_brazil_programmer.projects.where('1=1').select { |r| r.id == role.id }).to be_empty
507
+ end
508
+
509
+ it 'where + any?' do
510
+ role = @new_brazil_programmer.projects.create(:name => 'New VB App :-/')
511
+ expect(@new_brazil_programmer.projects.where('1=1').any?).to be true
512
+ @new_brazil_programmer.projects.destroy_all
513
+ expect(@new_brazil_programmer.projects.where('1=1').any?).to be false
514
+ end
515
+
516
+ it 'where + any? with block' do
517
+ role = @new_brazil_programmer.projects.create(:name => 'New VB App :-/')
518
+ expect(@new_brazil_programmer.projects.where('1=1').any? { |r| r.id == role.id }).to be true
519
+ @new_brazil_programmer.projects.destroy_all
520
+ expect(@new_brazil_programmer.projects.where('1=1').any? { |r| r.id == role.id }).to be false
521
+ end
522
+
351
523
  it 'exists?' do
352
524
  role = @new_brazil_programmer.projects.create(:name => 'New VB App :-/')
353
- expect(@new_brazil_programmer.projects.exists?(role)).to be true
525
+ expect(@new_brazil_programmer.projects.exists?(role.id)).to be true
354
526
  @new_brazil_programmer.projects.destroy_all
355
- expect(@new_brazil_programmer.projects.exists?(role)).to be false
527
+ expect(@new_brazil_programmer.projects.exists?(role.id)).to be false
356
528
  end
357
529
 
358
530
  it 'clear' do
@@ -399,7 +571,13 @@ describe Octopus::AssociationShardTracking, :shards => [:brazil, :master, :canad
399
571
  it 'should raise error if you try to add a record from a different shard' do
400
572
  expect do
401
573
  @brazil_client.items << Item.using(:canada).create!(:name => 'New User')
402
- end.to raise_error('Association Error: Records are from different shards')
574
+ end.to raise_error(Octopus::AssociationShardTracking::MismatchedShards)
575
+ end
576
+
577
+ it 'should make difference if the shard is a symbol or a string for raising Octopus::AssociationShardTracking::MismatchedShards' do
578
+ expect do
579
+ @brazil_client.items << Item.using('brazil').create!(:name => 'New Brazil Item')
580
+ end.not_to raise_error
403
581
  end
404
582
 
405
583
  it 'should update the attribute for the item' do
@@ -412,7 +590,7 @@ describe Octopus::AssociationShardTracking, :shards => [:brazil, :master, :canad
412
590
  expect(@item_brazil.client).to eq(new_brazil_client)
413
591
  end
414
592
 
415
- it 'should works for build method' do
593
+ it 'should work for build method' do
416
594
  item2 = Item.using(:brazil).create!(:name => 'Brazil Item')
417
595
  c = item2.create_client(:name => 'new Client')
418
596
  c.save
@@ -440,7 +618,7 @@ describe Octopus::AssociationShardTracking, :shards => [:brazil, :master, :canad
440
618
  end
441
619
  end
442
620
 
443
- describe 'it should works when using' do
621
+ describe 'it should work when using' do
444
622
  before(:each) do
445
623
  @item_brazil_2 = Item.using(:brazil).create!(:name => 'Brazil Item 2')
446
624
  expect(@brazil_client.items.to_set).to eq([@item_brazil].to_set)
@@ -537,10 +715,82 @@ describe Octopus::AssociationShardTracking, :shards => [:brazil, :master, :canad
537
715
  expect(@brazil_client.items.first).to be_nil
538
716
  end
539
717
 
718
+ it 'where' do
719
+ expect(@brazil_client.items.where('1=1')).to eq([@item_brazil])
720
+ @brazil_client.items.destroy_all
721
+ expect(@brazil_client.items.where('1=1')).to be_empty
722
+ end
723
+
724
+ it 'map' do
725
+ expect(@brazil_client.items.map(&:id)).to eq([@item_brazil.id])
726
+ @brazil_client.items.destroy_all
727
+ expect(@brazil_client.items.map(&:id)).to be_empty
728
+ end
729
+
730
+ it 'where + map' do
731
+ expect(@brazil_client.items.where('1=1').map(&:id)).to eq([@item_brazil.id])
732
+ @brazil_client.items.destroy_all
733
+ expect(@brazil_client.items.where('1=1').map(&:id)).to be_empty
734
+ end
735
+
736
+ it 'where + each_with_index + map (enum method chain)' do
737
+ expect(@brazil_client.items.where('1=1').each_with_index.map { |r, i| [r.id, i]}).to eq([[@item_brazil.id, 0]])
738
+ @brazil_client.items.destroy_all
739
+ expect(@brazil_client.items.where('1=1').each_with_index.map { |r, i| [r.id, i]}).to be_empty
740
+ end
741
+
742
+ it 'where + sum' do
743
+ expect(@brazil_client.items.where('1=1').sum(&:id)).to eq(@item_brazil.id)
744
+ @brazil_client.items.destroy_all
745
+ expect(@brazil_client.items.where('1=1').sum(&:id)).to eq(0)
746
+ end
747
+
748
+ it 'where + index_by' do
749
+ expect(@brazil_client.items.where('1=1').index_by(&:id)).to eq(@item_brazil.id => @item_brazil)
750
+ @brazil_client.items.destroy_all
751
+ expect(@brazil_client.items.where('1=1').index_by(&:id)).to be_empty
752
+ end
753
+
754
+ it 'where + find' do
755
+ expect(@brazil_client.items.where('1=1').find(@item_brazil.id)).to eq(@item_brazil)
756
+ @brazil_client.items.destroy_all
757
+ expect { @brazil_client.items.where('1=1').find(@item_brazil.id) }.to raise_error ActiveRecord::RecordNotFound
758
+ end
759
+
760
+ it 'where + find with block' do
761
+ expect(@brazil_client.items.where('1=1').find { |i| i.id == @item_brazil.id }).to eq(@item_brazil)
762
+ @brazil_client.items.destroy_all
763
+ expect(@brazil_client.items.where('1=1').find { |i| i.id == @item_brazil.id }).to be_nil
764
+ end
765
+
766
+ it 'where + select' do
767
+ expect(@brazil_client.items.where('1=1').select(:name).first.name).to eq(@item_brazil.name)
768
+ @brazil_client.items.destroy_all
769
+ expect(@brazil_client.items.where('1=1').select(:name)).to be_empty
770
+ end
771
+
772
+ it 'where + select with block' do
773
+ expect(@brazil_client.items.where('1=1').select { |i| i.id == @item_brazil.id }).to eq([@item_brazil])
774
+ @brazil_client.items.destroy_all
775
+ expect(@brazil_client.items.where('1=1').select { |i| i.id == @item_brazil.id }).to be_empty
776
+ end
777
+
778
+ it 'where + any?' do
779
+ expect(@brazil_client.items.where('1=1').any?).to be true
780
+ @brazil_client.items.destroy_all
781
+ expect(@brazil_client.items.where('1=1').any?).to be false
782
+ end
783
+
784
+ it 'where + any? with block' do
785
+ expect(@brazil_client.items.where('1=1').any? { |i| i.id == @item_brazil.id }).to be true
786
+ @brazil_client.items.destroy_all
787
+ expect(@brazil_client.items.where('1=1').any? { |i| i.id == @item_brazil.id }).to be false
788
+ end
789
+
540
790
  it 'exists?' do
541
- expect(@brazil_client.items.exists?(@item_brazil)).to be true
791
+ expect(@brazil_client.items.exists?(@item_brazil.id)).to be true
542
792
  @brazil_client.items.destroy_all
543
- expect(@brazil_client.items.exists?(@item_brazil)).to be false
793
+ expect(@brazil_client.items.exists?(@item_brazil.id)).to be false
544
794
  end
545
795
 
546
796
  it 'uniq' do
@@ -584,7 +834,7 @@ describe Octopus::AssociationShardTracking, :shards => [:brazil, :master, :canad
584
834
  expect(@comment_brazil.commentable).to eq(new_brazil_client)
585
835
  end
586
836
 
587
- describe 'it should works when using' do
837
+ describe 'it should work when using' do
588
838
  before(:each) do
589
839
  @comment_brazil_2 = Comment.using(:brazil).create!(:name => 'Brazil Comment 2')
590
840
  expect(@brazil_client.comments.to_set).to eq([@comment_brazil].to_set)
@@ -630,6 +880,12 @@ describe Octopus::AssociationShardTracking, :shards => [:brazil, :master, :canad
630
880
  expect(@brazil_client.comments.count).to eq(2)
631
881
  end
632
882
 
883
+ it 'group + count' do
884
+ expect(@brazil_client.comments.group(:id).count.length).to eq(1)
885
+ _cmt = @brazil_client.comments.create(:name => 'Builded Comment')
886
+ expect(@brazil_client.comments.group(:id).count.length).to eq(2)
887
+ end
888
+
633
889
  it 'size' do
634
890
  expect(@brazil_client.comments.size).to eq(1)
635
891
  _cmt = @brazil_client.comments.create(:name => 'Builded Comment')
@@ -681,10 +937,82 @@ describe Octopus::AssociationShardTracking, :shards => [:brazil, :master, :canad
681
937
  expect(@brazil_client.comments.first).to be_nil
682
938
  end
683
939
 
940
+ it 'where' do
941
+ expect(@brazil_client.comments.where('1=1')).to eq([@comment_brazil])
942
+ @brazil_client.comments.destroy_all
943
+ expect(@brazil_client.comments.where('1=1')).to be_empty
944
+ end
945
+
946
+ it 'map' do
947
+ expect(@brazil_client.comments.map(&:id)).to eq([@comment_brazil.id])
948
+ @brazil_client.comments.destroy_all
949
+ expect(@brazil_client.comments.map(&:id)).to be_empty
950
+ end
951
+
952
+ it 'where + map' do
953
+ expect(@brazil_client.comments.where('1=1').map(&:id)).to eq([@comment_brazil.id])
954
+ @brazil_client.comments.destroy_all
955
+ expect(@brazil_client.comments.where('1=1').map(&:id)).to be_empty
956
+ end
957
+
958
+ it 'where + each_with_index + map (enum method chain)' do
959
+ expect(@brazil_client.comments.where('1=1').each_with_index.map { |r, i| [r.id, i]}).to eq([[@comment_brazil.id, 0]])
960
+ @brazil_client.comments.destroy_all
961
+ expect(@brazil_client.comments.where('1=1').each_with_index.map { |r, i| [r.id, i]}).to be_empty
962
+ end
963
+
964
+ it 'where + sum' do
965
+ expect(@brazil_client.comments.where('1=1').sum(&:id)).to eq(@comment_brazil.id)
966
+ @brazil_client.comments.destroy_all
967
+ expect(@brazil_client.comments.where('1=1').sum(&:id)).to eq(0)
968
+ end
969
+
970
+ it 'where + index_by' do
971
+ expect(@brazil_client.comments.where('1=1').index_by(&:id)).to eq(@comment_brazil.id => @comment_brazil)
972
+ @brazil_client.comments.destroy_all
973
+ expect(@brazil_client.comments.where('1=1').index_by(&:id)).to be_empty
974
+ end
975
+
976
+ it 'where + find' do
977
+ expect(@brazil_client.comments.where('1=1').find(@comment_brazil.id)).to eq(@comment_brazil)
978
+ @brazil_client.comments.destroy_all
979
+ expect { @brazil_client.comments.where('1=1').find(@comment_brazil.id) }.to raise_error ActiveRecord::RecordNotFound
980
+ end
981
+
982
+ it 'where + find with block' do
983
+ expect(@brazil_client.comments.where('1=1').find { |c| c.id == @comment_brazil.id }).to eq(@comment_brazil)
984
+ @brazil_client.comments.destroy_all
985
+ expect(@brazil_client.comments.where('1=1').find { |c| c.id == @comment_brazil.id }).to be_nil
986
+ end
987
+
988
+ it 'where + select' do
989
+ expect(@brazil_client.comments.where('1=1').select(:name).first.name).to eq(@comment_brazil.name)
990
+ @brazil_client.comments.destroy_all
991
+ expect(@brazil_client.comments.where('1=1').select(:name)).to be_empty
992
+ end
993
+
994
+ it 'where + select with block' do
995
+ expect(@brazil_client.comments.where('1=1').select { |c| c.id == @comment_brazil.id }).to eq([@comment_brazil])
996
+ @brazil_client.comments.destroy_all
997
+ expect(@brazil_client.comments.where('1=1').select { |c| c.id == @comment_brazil.id }).to be_empty
998
+ end
999
+
1000
+ it 'where + any?' do
1001
+ expect(@brazil_client.comments.where('1=1').any?).to be true
1002
+ @brazil_client.comments.destroy_all
1003
+ expect(@brazil_client.comments.where('1=1').any?).to be false
1004
+ end
1005
+
1006
+ it 'where + any? with block' do
1007
+ expect(@brazil_client.comments.where('1=1').any? { |c| c.id == @comment_brazil.id }).to be true
1008
+ @brazil_client.comments.destroy_all
1009
+ expect(@brazil_client.comments.where('1=1').any? { |c| c.id == @comment_brazil.id }).to be false
1010
+ end
1011
+
684
1012
  it 'exists?' do
685
- expect(@brazil_client.comments.exists?(@comment_brazil)).to be true
1013
+ expect(@brazil_client.comments.exists?(@comment_brazil.id)).to be true
686
1014
  @brazil_client.comments.destroy_all
687
- expect(@brazil_client.comments.exists?(@comment_brazil)).to be false
1015
+ expect(@brazil_client.comments.exists?(@comment_brazil.id)).to be false
688
1016
  end
689
1017
 
690
1018
  it 'uniq' do
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ describe Octopus::LoadBalancing::RoundRobin do
4
+ it "raises an error when no shards are given" do
5
+ expect do
6
+ Octopus::LoadBalancing::RoundRobin.new([])
7
+ end.to raise_error Octopus::Exception
8
+ end
9
+
10
+ it "does not raise an error if slaves given" do
11
+ expect do
12
+ Octopus::LoadBalancing::RoundRobin.new([:stub])
13
+ end.to_not raise_error Octopus::Exception
14
+ end
15
+ end
@@ -9,7 +9,7 @@ describe Octopus::LogSubscriber, :shards => [:canada] do
9
9
  end
10
10
 
11
11
  after :each do
12
- ActiveRecord::Base.logger = nil
12
+ ActiveRecord::Base.logger = Logger.new(File.open('database.log', 'a'))
13
13
  end
14
14
 
15
15
  it 'should add to the default logger the shard name the query was sent to' do
@@ -1,5 +1,14 @@
1
1
  require 'spec_helper'
2
2
 
3
+ def get_all_versions
4
+ if Octopus.atleast_rails52?
5
+ migrations_root = File.expand_path(File.join(File.dirname(__FILE__), '..', 'migrations'))
6
+ ActiveRecord::MigrationContext.new(migrations_root).get_all_versions
7
+ else
8
+ ActiveRecord::Migrator.get_all_versions
9
+ end
10
+ end
11
+
3
12
  describe Octopus::Migration do
4
13
  it 'should run just in the master shard' do
5
14
  OctopusHelper.migrating_to_version 1 do
@@ -30,6 +39,32 @@ describe Octopus::Migration do
30
39
  end
31
40
  end
32
41
 
42
+ it "should rollback correctly migrations" do
43
+ migrations_root = File.expand_path(File.join(File.dirname(__FILE__), '..', 'migrations'))
44
+ if Octopus.atleast_rails52?
45
+ OctopusHelper.migrate_to_version(:up, migrations_root, 4)
46
+ else
47
+ ActiveRecord::Migrator.run(:up, migrations_root, 4)
48
+ end
49
+
50
+ expect(User.using(:canada).find_by_name('Group')).not_to be_nil
51
+ expect(User.using(:brazil).find_by_name('Group')).not_to be_nil
52
+ expect(User.using(:russia).find_by_name('Group')).not_to be_nil
53
+
54
+
55
+ Octopus.using(:canada) do
56
+ if Octopus.atleast_rails52?
57
+ OctopusHelper.migrate_to_version(:down, migrations_root, 4)
58
+ else
59
+ ActiveRecord::Migrator.rollback(migrations_root, 4)
60
+ end
61
+ end
62
+
63
+ expect(User.using(:canada).find_by_name('Group')).to be_nil
64
+ expect(User.using(:brazil).find_by_name('Group')).to be_nil
65
+ expect(User.using(:russia).find_by_name('Group')).to be_nil
66
+ end
67
+
33
68
  it 'should run once per shard' do
34
69
  OctopusHelper.migrating_to_version 5 do
35
70
  expect(User.using(:canada).where(:name => 'MultipleGroup').size).to eq(1)
@@ -80,9 +115,9 @@ describe Octopus::Migration do
80
115
  class SchemaMigration < ActiveRecord::Base; end
81
116
 
82
117
  OctopusHelper.migrating_to_version 14 do
83
- expect(Octopus.using(:canada) { ActiveRecord::Migrator.get_all_versions }).to include(14)
84
- expect(Octopus.using(:brazil) { ActiveRecord::Migrator.get_all_versions }).to include(14)
85
- expect(Octopus.using(:russia) { ActiveRecord::Migrator.get_all_versions }).to include(14)
118
+ expect(Octopus.using(:canada) { get_all_versions }).to include(14)
119
+ expect(Octopus.using(:brazil) { get_all_versions }).to include(14)
120
+ expect(Octopus.using(:russia) { get_all_versions }).to include(14)
86
121
  end
87
122
  end
88
123
 
@@ -93,9 +128,9 @@ describe Octopus::Migration do
93
128
  Octopus.using(:canada) { SchemaMigration.create(:version => 14) }
94
129
 
95
130
  OctopusHelper.migrating_to_version 14 do
96
- expect(Octopus.using(:canada) { ActiveRecord::Migrator.get_all_versions }).to include(14)
97
- expect(Octopus.using(:brazil) { ActiveRecord::Migrator.get_all_versions }).to include(14)
98
- expect(Octopus.using(:russia) { ActiveRecord::Migrator.get_all_versions }).to include(14)
131
+ expect(Octopus.using(:canada) { get_all_versions }).to include(14)
132
+ expect(Octopus.using(:brazil) { get_all_versions }).to include(14)
133
+ expect(Octopus.using(:russia) { get_all_versions }).to include(14)
99
134
  end
100
135
  end
101
136
 
@@ -103,13 +138,12 @@ describe Octopus::Migration do
103
138
  it 'should run migrations on all shards in the default_migration_group' do
104
139
  OctopusHelper.using_environment :octopus_with_default_migration_group do
105
140
  OctopusHelper.migrating_to_version 15 do
106
- expect(Octopus.using(:master) { ActiveRecord::Migrator.get_all_versions }).not_to include(15)
107
- expect(Octopus.using(:canada) { ActiveRecord::Migrator.get_all_versions }).to include(15)
108
- expect(Octopus.using(:brazil) { ActiveRecord::Migrator.get_all_versions }).to include(15)
109
- expect(Octopus.using(:russia) { ActiveRecord::Migrator.get_all_versions }).to include(15)
141
+ expect(Octopus.using(:master) { get_all_versions }).not_to include(15)
142
+ expect(Octopus.using(:canada) { get_all_versions }).to include(15)
143
+ expect(Octopus.using(:brazil) { get_all_versions }).to include(15)
144
+ expect(Octopus.using(:russia) { get_all_versions }).to include(15)
110
145
  end
111
146
  end
112
147
  end
113
148
  end
114
-
115
149
  end