ar-octopus 0.8.5 → 0.10.2

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