ar-octopus 0.8.0 → 0.8.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- ZWQzNDQ0MzMzZWViNTFiYjY5MWRlODZjN2M2MGFlNDMwM2RjMTY2Mw==
4
+ MTRmYWZkMTg0YzU4MTM4YmNjYTM3MDE3MDVjZjQ1MjdiYmE2NDkwMg==
5
5
  data.tar.gz: !binary |-
6
- YmUzNzY2YzQ0ZWUwOWVjZDI4ZWQwOGEyMGZmOWY3NDg1MzA0MjNhZg==
6
+ ODhhZTJjNDQzZDVhMWZhYzc1NzRjYWNjOTdlYTQ5MTNlYzk5YWJkMA==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- ODcyN2VkMDQ3Zjk4MjVlYTEyMGMxYmU4NmFhMmI1ZmM0OGFkMDc5Mzk1MWRk
10
- OWIyYzMwMTY5MjVhYjE1MDljOTlkMjI4N2E3OTYyMGY4YzIyMGUwZGVjZTM4
11
- ZTI3ZGRiZWU2NjkyNGQzNDcwNTM3Y2FlNjM3MWIwNGI4MGIzMWY=
9
+ Y2JiNmI0MjEzYWRjYTFhYjMwN2IyYWQwMTQyMDI1M2UyYTdiNzU3NGY4ZDlm
10
+ MGYwNDQ2NGViMjhjOGRjMTZiNjdjN2VhODZiOGQ3ZWQ2Njg5OTFjZWE1ZDQ5
11
+ ZThjNjUxOTNhYzYyNTMwMjk3MjkwYmYzNmU3YjA0Y2MzMjMyZmE=
12
12
  data.tar.gz: !binary |-
13
- M2M5MDVjNGU4NWU3MTcxYzljOTJmNTVlMGI5NzY5ZTliYzBmODIxZjIzNTE3
14
- NGVlZWU3MmNkNDIwYzYxNDVhMzM1NmVlZmFkZGNkZmYwM2Y2NzY0OThhMTBm
15
- NjYzMWM0NDAyNDMxN2ZmNzY0ZWFhNmYwN2M5NWIwNmE3MDdjNWE=
13
+ MjU1YzZlNzczNGM2OGQ2YzMxYmZhMWE4M2QzYTQ5ZjM1NjEwYTQ4MDJiMDY5
14
+ YzM0Mjg4OTc4MmI4ZGYxMTlhNDJmYWMxMzA3MjU5ZDdmNjIwNmNmNmNlMmY3
15
+ OWZjY2RkNTViY2MzOTdjMjU5NTg2NjFkNDcyZmRiMWU5NDA2MWM=
@@ -27,7 +27,7 @@ When using replication, all writes queries will be sent to master, and read quer
27
27
 
28
28
  Add this line to Gemfile:
29
29
 
30
- gem 'ar-octopus', :require => 'octopus'
30
+ gem 'ar-octopus'
31
31
 
32
32
  Currently, Octopus doesn't support Rails 2. If you need support for rails 2, please use the version 0.5.0.
33
33
 
@@ -107,6 +107,13 @@ You also could send a migration to a group of shards. This migration will be se
107
107
  end
108
108
  end
109
109
 
110
+ You can specify a `default_migration_group` for migrations, so that modifications to each individual migration file are not needed:
111
+
112
+ octopus:
113
+ default_migration_group: europe_databases
114
+
115
+ There is no need for a corresponding `default_migration_shard` - simply define that database to be your master. You might want this setting if all of your databases have identical schemas, but are not replicated.
116
+
110
117
  ### Rails Controllers
111
118
 
112
119
  If you want to send a specified action, or all actions from a controller, to a specific shard, use this syntax:
@@ -157,7 +164,7 @@ If you are having issues running the octopus spec suite, verify your database us
157
164
 
158
165
  ## Thanks
159
166
 
160
- This project is sponsored by the <a href="http://www.rubysoc.org">Ruby Summer of Code</a>,
167
+ This project is sponsored by the <a href="http://www.rubysoc.org">Ruby Summer of Code</a>, Rapid River Software,
161
168
  and my mentors <a href="http://github.com/mperham">Mike Perham</a> and <a href="http://github.com/amitagarwal">Amit Agarwal</a>.
162
169
 
163
170
  ## Copyright
@@ -29,7 +29,7 @@ Gem::Specification.new do |s|
29
29
  s.add_development_dependency 'mysql2', '> 0.3'
30
30
  s.add_development_dependency 'pg', '>= 0.11.0'
31
31
  s.add_development_dependency 'sqlite3', '>= 1.3.4'
32
- s.add_development_dependency 'pry'
32
+ s.add_development_dependency 'pry-debugger'
33
33
  s.add_development_dependency 'appraisal', '>= 0.3.8'
34
34
 
35
35
  s.license = 'MIT'
@@ -3,6 +3,39 @@ module Octopus::Association
3
3
  base.send(:include, InstanceMethods)
4
4
  end
5
5
 
6
+ module QueryOnCurrentShard
7
+
8
+ METHODS= %w[
9
+ all
10
+ average
11
+ count
12
+ empty?
13
+ exists?
14
+ find
15
+ find_by_sql
16
+ first
17
+ last
18
+ maximum
19
+ minimum
20
+ pluck
21
+ scoping
22
+ size
23
+ sum
24
+ to_a
25
+ ]
26
+
27
+ METHODS.each do |m|
28
+ define_method m.to_sym do |*args,&block|
29
+ if self.respond_to?(:proxy_association) and self.proxy_association
30
+ self.proxy_association.owner.run_on_shard { super(*args, &block) }
31
+ else
32
+ super(*args, &block)
33
+ end
34
+ end
35
+ end
36
+
37
+ end
38
+
6
39
  module InstanceMethods
7
40
  def set_connection_on_association(record)
8
41
  return unless ::Octopus.enabled?
@@ -64,6 +97,8 @@ module Octopus::Association
64
97
  else
65
98
  options[:before_remove] = :set_connection_on_association
66
99
  end
100
+
101
+ options[:extend] = [ Octopus::Association::QueryOnCurrentShard, options[:extend] ].flatten.compact
67
102
  end
68
103
  end
69
104
 
@@ -1,63 +1,49 @@
1
1
  module Octopus::AssociationCollection
2
2
 
3
+ METHODS = %w[
4
+ reader
5
+ writer
6
+ ids_reader
7
+ ids_writer
8
+ create
9
+ create!
10
+ build
11
+ any?
12
+ count
13
+ empty?
14
+ first
15
+ include?
16
+ last
17
+ length
18
+ load_target
19
+ many?
20
+ size
21
+ select
22
+ uniq
23
+ ]
24
+
3
25
  def self.included(base)
4
26
  base.instance_eval do
5
- alias_method_chain :reader, :octopus
6
- alias_method_chain :writer, :octopus
7
- alias_method_chain :ids_reader, :octopus
8
- alias_method_chain :ids_writer, :octopus
9
- alias_method_chain :create, :octopus
10
- alias_method_chain :create!, :octopus
11
- alias_method_chain :build, :octopus
27
+ METHODS.each do |m|
28
+ alias_method_chain m.to_sym, :octopus
29
+ end
12
30
  end
13
31
  end
14
32
 
15
- def build_with_octopus(*args, &block)
16
- owner.reload_connection
17
- build_without_octopus(*args, &block)
18
- end
19
-
20
- def reader_with_octopus(*args)
21
- owner.reload_connection
22
- reader_without_octopus(*args)
23
- end
24
-
25
- def writer_with_octopus(*args)
26
- owner.reload_connection
27
- writer_without_octopus(*args)
28
- end
29
-
30
- def ids_reader_with_octopus(*args)
31
- owner.reload_connection
32
- ids_reader_without_octopus(*args)
33
- end
34
-
35
- def ids_writer_with_octopus(*args)
36
- owner.reload_connection
37
- ids_writer_without_octopus(*args)
38
- end
39
-
40
- def create_with_octopus(*args, &block)
41
- owner.reload_connection
42
- create_without_octopus(*args, &block)
43
- end
44
-
45
- def create_with_octopus!(*args, &block)
46
- owner.reload_connection
47
- create_without_octopus!(*args, &block)
33
+ METHODS.each do |m|
34
+ m =~ /([^!?]+)([!?])?/
35
+ method, punctuation = [ $1, $2 ]
36
+ with = :"#{method}_with_octopus#{punctuation}"
37
+ without = :"#{method}_without_octopus#{punctuation}"
38
+ define_method with do |*args, &block|
39
+ @owner.run_on_shard { send(without, *args, &block) }
40
+ end
48
41
  end
49
42
 
50
43
  def should_wrap_the_connection?
51
44
  @owner.respond_to?(:current_shard) && @owner.current_shard != nil
52
45
  end
53
46
 
54
- def count(*args)
55
- if should_wrap_the_connection?
56
- Octopus.using(@owner.current_shard) { super }
57
- else
58
- super
59
- end
60
- end
61
47
  end
62
48
 
63
49
  ActiveRecord::Associations::CollectionAssociation.send(:include, Octopus::AssociationCollection)
@@ -16,10 +16,10 @@ module Octopus::Migration
16
16
  include InstanceOrClassMethods
17
17
 
18
18
  def self.included(base)
19
- base.send(:extend, ClassMethods)
19
+ base.extend(ClassMethods)
20
20
 
21
21
  base.alias_method_chain :announce, :octopus
22
- base.class_attribute :current_shard, :current_group, :instance_reader => false, :instance_writer => false
22
+ base.class_attribute :current_shard, :current_group, :current_group_specified, :instance_reader => false, :instance_writer => false
23
23
  end
24
24
 
25
25
  module ClassMethods
@@ -34,13 +34,14 @@ module Octopus::Migration
34
34
  return self unless connection.is_a?(Octopus::Proxy)
35
35
 
36
36
  self.current_group = groups
37
+ self.current_group_specified = true
37
38
  self
38
39
  end
39
40
 
40
41
  def shards
41
42
  shards = Set.new
42
43
 
43
- if groups = current_group
44
+ if groups = (current_group_specified ? current_group : Octopus.config[:default_migration_group])
44
45
  Array.wrap(groups).each do |group|
45
46
  group_shards = connection.shards_for_group(group)
46
47
  shards.merge(group_shards) if group_shards
@@ -56,7 +57,7 @@ end
56
57
 
57
58
  module Octopus::Migrator
58
59
  def self.included(base)
59
- base.send(:extend, ClassMethods)
60
+ base.extend(ClassMethods)
60
61
 
61
62
  base.class_eval do
62
63
  class << self
@@ -31,7 +31,7 @@ module Octopus::Model
31
31
 
32
32
  def hijack_initializer()
33
33
  attr_accessor :current_shard
34
- before_save :reload_connection
34
+ around_save :run_on_shard
35
35
 
36
36
  def set_current_shard
37
37
  return unless Octopus.enabled?
@@ -72,9 +72,36 @@ module Octopus::Model
72
72
  end
73
73
  end
74
74
 
75
+ def self.clear_active_connections_with_octopus!
76
+ if should_use_normal_connection?
77
+ clear_active_connections_without_octopus!
78
+ else
79
+ connection_proxy.clear_active_connections!
80
+ end
81
+ end
82
+
83
+ def self.clear_all_connections_with_octopus!
84
+ if should_use_normal_connection?
85
+ clear_all_connections_without_octopus!
86
+ else
87
+ connection_proxy.clear_all_connections!
88
+ end
89
+ end
90
+
91
+ def self.connected_with_octopus?
92
+ if should_use_normal_connection?
93
+ connected_without_octopus?
94
+ else
95
+ connection_proxy.connected?
96
+ end
97
+ end
98
+
75
99
  class << self
76
100
  alias_method_chain :connection, :octopus
77
101
  alias_method_chain :connection_pool, :octopus
102
+ alias_method_chain :clear_all_connections!, :octopus
103
+ alias_method_chain :clear_active_connections!, :octopus
104
+ alias_method_chain :connected?, :octopus
78
105
  end
79
106
  end
80
107
  end
@@ -93,18 +120,12 @@ module Octopus::Model
93
120
  self.respond_to?(:current_shard) && !self.current_shard.nil?
94
121
  end
95
122
 
96
- def reload_connection_safe(&block)
97
- return yield unless should_set_current_shard?
98
- original = self.class.connection_proxy.current_shard
99
- self.class.connection_proxy.current_shard = self.current_shard
100
- result = yield
101
- self.class.connection_proxy.current_shard = original
102
- result
103
- end
104
-
105
- def reload_connection()
106
- return unless should_set_current_shard?
107
- self.class.connection_proxy.current_shard = self.current_shard
123
+ def run_on_shard(&block)
124
+ if self.current_shard
125
+ self.class.connection_proxy.run_queries_on_shard(self.current_shard, &block)
126
+ else
127
+ yield
128
+ end
108
129
  end
109
130
 
110
131
  def equality_with_octopus(comparison_object)
@@ -12,7 +12,6 @@ class Octopus::Proxy
12
12
  @shards = HashWithIndifferentAccess.new
13
13
  @groups = {}
14
14
  @adapters = Set.new
15
- @shards[:master] = ActiveRecord::Base.connection_pool_without_octopus()
16
15
  @config = ActiveRecord::Base.connection_pool_without_octopus.connection.instance_variable_get(:@config)
17
16
 
18
17
  if !config.nil?
@@ -23,7 +22,7 @@ class Octopus::Proxy
23
22
  shards_config ||= []
24
23
 
25
24
  shards_config.each do |key, value|
26
- if value.is_a?(String)
25
+ if value.is_a?(String)
27
26
  value = resolve_string_connection(value).merge(:octopus_shard => key)
28
27
  initialize_adapter(value['adapter'])
29
28
  @shards[key.to_sym] = connection_pool_for(value, "#{value['adapter']}_connection")
@@ -45,6 +44,8 @@ class Octopus::Proxy
45
44
  end
46
45
  end
47
46
  end
47
+
48
+ @shards[:master] ||= ActiveRecord::Base.connection_pool_without_octopus()
48
49
  end
49
50
 
50
51
  def initialize_replication(config)
@@ -137,7 +138,7 @@ class Octopus::Proxy
137
138
  # Rails 3.1 sets automatic_reconnect to false when it removes
138
139
  # connection pool. Octopus can potentially retain a reference to a closed
139
140
  # connection pool. Previously, that would work since the pool would just
140
- # reconnect, but in Rails 3.1 the flag prevents this.
141
+ # reconnect, but in Rails 3.1 the flag prevents this.
141
142
  def safe_connection(connection_pool)
142
143
  connection_pool.automatic_reconnect ||= true
143
144
  connection_pool.connection()
@@ -219,19 +220,28 @@ class Octopus::Proxy
219
220
  end
220
221
 
221
222
  def enable_query_cache!
222
- @shards.each do |k, v|
223
- c = safe_connection(v)
224
- c.clear_query_cache_without_octopus
225
- c.enable_query_cache!
226
- end
223
+ clear_query_cache
224
+ @shards.each { |k, v| safe_connection(v).enable_query_cache! }
227
225
  end
228
226
 
229
227
  def disable_query_cache!
230
228
  @shards.each { |k, v| safe_connection(v).disable_query_cache! }
231
229
  end
232
230
 
233
- def clear_all_query_caches!
234
- @shards.each { |k, v| safe_connection(v).clear_query_cache_without_octopus }
231
+ def clear_query_cache
232
+ @shards.each { |k, v| safe_connection(v).clear_query_cache }
233
+ end
234
+
235
+ def clear_active_connections!
236
+ @shards.each { |k, v| v.release_connection }
237
+ end
238
+
239
+ def clear_all_connections!
240
+ @shards.each { |k, v| v.disconnect! }
241
+ end
242
+
243
+ def connected?
244
+ @shards.any? { |k, v| v.connected? }
235
245
  end
236
246
 
237
247
  protected
@@ -26,7 +26,6 @@ module Octopus
26
26
 
27
27
  def self.included(base)
28
28
  base.alias_method_chain :initialize, :octopus_shard
29
- base.alias_method_chain :clear_query_cache, :octopus
30
29
  end
31
30
 
32
31
  def octopus_shard
@@ -38,16 +37,6 @@ module Octopus
38
37
  @instrumenter = InstrumenterDecorator.new(self, @instrumenter)
39
38
  end
40
39
 
41
- # Intercept calls to clear_query_cache and make sure that all
42
- # query caches on all shards are invalidated, just to be safe.
43
- def clear_query_cache_with_octopus
44
- if Octopus.enabled?
45
- ActiveRecord::Base.connection_proxy.clear_all_query_caches!
46
- else
47
- clear_query_cache_without_octopus
48
- end
49
- end
50
-
51
40
  end
52
41
  end
53
42
  end
@@ -2,43 +2,35 @@ module Octopus
2
2
  module Rails3
3
3
  module Persistence
4
4
  def update_attribute(*args)
5
- reload_connection()
6
- super
5
+ run_on_shard { super }
7
6
  end
8
7
 
9
8
  def update_attributes(*args)
10
- reload_connection()
11
- super
9
+ run_on_shard { super }
12
10
  end
13
11
 
14
12
  def update_attributes!(*args)
15
- reload_connection()
16
- super
13
+ run_on_shard { super }
17
14
  end
18
15
 
19
16
  def reload(*args)
20
- reload_connection()
21
- super
17
+ run_on_shard { super }
22
18
  end
23
19
 
24
20
  def delete
25
- reload_connection()
26
- super
21
+ run_on_shard { super }
27
22
  end
28
23
 
29
24
  def destroy
30
- reload_connection()
31
- super
25
+ run_on_shard { super }
32
26
  end
33
27
 
34
28
  def touch(name=nil)
35
- reload_connection()
36
- super
29
+ run_on_shard { super }
37
30
  end
38
31
 
39
32
  def update_column(*args)
40
- reload_connection()
41
- super
33
+ run_on_shard { super }
42
34
  end
43
35
  end
44
36
  end
@@ -10,23 +10,23 @@ module Octopus::SingularAssociation
10
10
  end
11
11
 
12
12
  def reader_with_octopus(*args)
13
- owner.reload_connection_safe { reader_without_octopus(*args) }
13
+ owner.run_on_shard { reader_without_octopus(*args) }
14
14
  end
15
15
 
16
16
  def writer_with_octopus(*args)
17
- owner.reload_connection_safe { writer_without_octopus(*args) }
17
+ owner.run_on_shard { writer_without_octopus(*args) }
18
18
  end
19
19
 
20
20
  def create_with_octopus(*args)
21
- owner.reload_connection_safe { create_without_octopus(*args) }
21
+ owner.run_on_shard { create_without_octopus(*args) }
22
22
  end
23
23
 
24
24
  def create_with_octopus!(*args)
25
- owner.reload_connection_safe { create_without_octopus!(*args) }
25
+ owner.run_on_shard { create_without_octopus!(*args) }
26
26
  end
27
27
 
28
28
  def build_with_octopus(*args)
29
- owner.reload_connection_safe { build_without_octopus(*args) }
29
+ owner.run_on_shard { build_without_octopus(*args) }
30
30
  end
31
31
 
32
32
  end
@@ -1,3 +1,3 @@
1
1
  module Octopus
2
- VERSION = '0.8.0'
2
+ VERSION = '0.8.1'
3
3
  end
@@ -3,7 +3,7 @@ mysql: &mysql
3
3
  username: <%= ENV['MYSQL_USER'] || 'root' %>
4
4
  host: localhost
5
5
 
6
- octopus:
6
+ octopus: &octopus
7
7
  shards:
8
8
  alone_shard:
9
9
  database: octopus_shard_5
@@ -45,6 +45,10 @@ octopus:
45
45
 
46
46
  protocol_shard: postgres://<%= ENV['POSTGRES_USER'] || 'postgres' %>@localhost:5432/octopus_shard_2
47
47
 
48
+ octopus_with_default_migration_group:
49
+ <<: *octopus
50
+ default_migration_group: country_shards
51
+
48
52
  production_raise_error:
49
53
  shards:
50
54
  history_shards:
@@ -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
@@ -53,7 +53,7 @@ describe Octopus::Association, :shards => [:brazil, :master, :canada] do
53
53
  c.save()
54
54
  k.save()
55
55
 
56
- Computer.includes(:keyboard).find(c.id).should == c
56
+ Computer.using(:brazil).includes(:keyboard).find(c.id).should == c
57
57
  end
58
58
  end
59
59
 
@@ -71,11 +71,17 @@ describe Octopus::Association, :shards => [:brazil, :master, :canada] do
71
71
  it "should find all models in the specified shard" do
72
72
  @brazil_role.permission_ids().should == [@permission_brazil.id]
73
73
  @brazil_role.permissions().should == [@permission_brazil]
74
+
75
+ @brazil_role.permissions.first.should eq(@permission_brazil)
76
+ @brazil_role.permissions.last.should eq(@permission_brazil)
74
77
  end
75
78
 
76
79
  it "should finds the client that the item belongs" do
77
80
  @permission_brazil.role_ids.should == [@brazil_role.id]
78
81
  @permission_brazil.roles.should == [@brazil_role]
82
+
83
+ @permission_brazil.roles.first.should eq(@brazil_role)
84
+ @permission_brazil.roles.last.should eq(@brazil_role)
79
85
  end
80
86
 
81
87
  it "should update the attribute for the item" do
@@ -226,8 +232,11 @@ describe Octopus::Association, :shards => [:brazil, :master, :canada] do
226
232
  end
227
233
 
228
234
  it "should find all models in the specified shard" do
229
- @programmer.project_ids().should == [ @project.id]
230
- @programmer.projects().should == [@project]
235
+ @programmer.project_ids().should eq([@project.id])
236
+ @programmer.projects().should eq([@project])
237
+
238
+ @programmer.projects.first.should eq(@project)
239
+ @programmer.projects.last.should eq(@project)
231
240
  end
232
241
 
233
242
 
@@ -379,8 +388,11 @@ describe Octopus::Association, :shards => [:brazil, :master, :canada] do
379
388
  end
380
389
 
381
390
  it "should find all models in the specified shard" do
382
- @brazil_client.item_ids.should == [@item_brazil.id]
383
- @brazil_client.items().should == [@item_brazil]
391
+ @brazil_client.item_ids.should eq([@item_brazil.id])
392
+ @brazil_client.items().should eq([@item_brazil])
393
+
394
+ @brazil_client.items.last.should eq(@item_brazil)
395
+ @brazil_client.items.first.should eq(@item_brazil)
384
396
  end
385
397
 
386
398
  it "should finds the client that the item belongs" do
@@ -412,6 +424,25 @@ describe Octopus::Association, :shards => [:brazil, :master, :canada] do
412
424
  c.items().should == [item2]
413
425
  end
414
426
 
427
+ context "when calling methods on a collection generated by an association" do
428
+ let(:collection) { @brazil_client.items }
429
+ before :each do
430
+ @brazil_client.items.create(:name => 'Brazil Item #2')
431
+ end
432
+
433
+ it "can call collection indexes directly without resetting the collection's current_shard" do
434
+ last_item = collection[1]
435
+ collection.length.should == 2
436
+ collection.should eq([ collection[0], last_item ])
437
+ end
438
+
439
+ it "can call methods on the collection without resetting the collection's current_shard" do
440
+ last_item = collection[collection.size-1]
441
+ collection.length.should == 2
442
+ collection.should eq([ collection[0], last_item ])
443
+ end
444
+ end
445
+
415
446
  describe "it should works when using" do
416
447
  before(:each) do
417
448
  @item_brazil_2 = Item.using(:brazil).create!(:name => "Brazil Item 2")
@@ -434,6 +465,14 @@ describe Octopus::Association, :shards => [:brazil, :master, :canada] do
434
465
  @brazil_client.items.to_set.should == [@item_brazil, @item_brazil_2].to_set
435
466
  end
436
467
 
468
+ it "all" do
469
+ item = @brazil_client.items.build(:name => "Builded Item")
470
+ item.save()
471
+ i = @brazil_client.items
472
+ i.to_set.should == [@item_brazil, item].to_set
473
+ i.reload.all.to_set.should == [@item_brazil, item].to_set
474
+ end
475
+
437
476
  it "build" do
438
477
  item = @brazil_client.items.build(:name => "Builded Item")
439
478
  item.save()
@@ -570,6 +609,14 @@ describe Octopus::Association, :shards => [:brazil, :master, :canada] do
570
609
  @brazil_client.comments.to_set.should == [@comment_brazil, @comment_brazil_2].to_set
571
610
  end
572
611
 
612
+ it "all" do
613
+ comment = @brazil_client.comments.build(:name => "Builded Comment")
614
+ comment.save()
615
+ c = @brazil_client.comments
616
+ c.to_set.should == [@comment_brazil, comment].to_set
617
+ c.reload.all.to_set.should == [@comment_brazil, comment].to_set
618
+ end
619
+
573
620
  it "build" do
574
621
  comment = @brazil_client.comments.build(:name => "Builded Comment")
575
622
  comment.save()
@@ -98,4 +98,18 @@ describe Octopus::Migration do
98
98
  Octopus.using(:russia) { ActiveRecord::Migrator.get_all_versions }.should include(14)
99
99
  end
100
100
  end
101
+
102
+ describe "when using a default_migration_group" do
103
+ it "should run migrations on all shards in the default_migration_group" do
104
+ OctopusHelper.using_environment :octopus_with_default_migration_group do
105
+ OctopusHelper.migrating_to_version 15 do
106
+ Octopus.using(:master) { ActiveRecord::Migrator.get_all_versions }.should_not include(15)
107
+ Octopus.using(:canada) { ActiveRecord::Migrator.get_all_versions }.should include(15)
108
+ Octopus.using(:brazil) { ActiveRecord::Migrator.get_all_versions }.should include(15)
109
+ Octopus.using(:russia) { ActiveRecord::Migrator.get_all_versions }.should include(15)
110
+ end
111
+ end
112
+ end
113
+ end
114
+
101
115
  end
@@ -263,4 +263,37 @@ describe Octopus::Proxy do
263
263
  end
264
264
  end
265
265
  end
266
+
267
+ describe "connection reuse" do
268
+ before :each do
269
+ @item_brazil_conn = Item.using(:brazil).new(:name => 'Brazil Item').connection.select_connection
270
+ @item_canada_conn = Item.using(:canada).new(:name => 'Canada Item').connection.select_connection
271
+ end
272
+
273
+ it "reuses connections" do
274
+ Item.using(:brazil).new(:name => 'Another Brazil Item').connection.select_connection.should eq(@item_brazil_conn)
275
+ Item.using(:canada).new(:name => 'Another Canada Item').connection.select_connection.should eq(@item_canada_conn)
276
+ end
277
+
278
+ it "reuses connections after clear_active_connections! is called" do
279
+ Item.using(:brazil).new(:name => 'Another Brazil Item').connection.select_connection.should eq(@item_brazil_conn)
280
+ Item.using(:canada).new(:name => 'Another Canada Item').connection.select_connection.should eq(@item_canada_conn)
281
+ end
282
+
283
+ it "creates new connections after clear_all_connections! is called" do
284
+ Item.clear_all_connections!
285
+ Item.using(:brazil).new(:name => 'Another Brazil Item').connection.select_connection.should_not eq(@item_brazil_conn)
286
+ Item.using(:canada).new(:name => 'Another Canada Item').connection.select_connection.should_not eq(@item_canada_conn)
287
+ end
288
+
289
+ it "is consistent with connected?" do
290
+ Item.connected?.should be_true
291
+ ActiveRecord::Base.connected?.should be_true
292
+
293
+ Item.clear_all_connections!
294
+
295
+ Item.connected?.should be_false
296
+ ActiveRecord::Base.connected?.should be_false
297
+ end
298
+ end
266
299
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ar-octopus
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
4
+ version: 0.8.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Thiago Pradi
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2013-11-01 00:00:00.000000000 Z
13
+ date: 2014-01-28 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: activerecord
@@ -111,7 +111,7 @@ dependencies:
111
111
  - !ruby/object:Gem::Version
112
112
  version: 1.3.4
113
113
  - !ruby/object:Gem::Dependency
114
- name: pry
114
+ name: pry-debugger
115
115
  requirement: !ruby/object:Gem::Requirement
116
116
  requirements:
117
117
  - - ! '>='
@@ -260,6 +260,7 @@ files:
260
260
  - spec/migrations/12_create_users_using_block.rb
261
261
  - spec/migrations/13_create_users_using_block_and_using.rb
262
262
  - spec/migrations/14_create_users_on_shards_of_a_group_with_versions.rb
263
+ - spec/migrations/15_create_user_on_shards_of_default_group_with_versions.rb
263
264
  - spec/migrations/1_create_users_on_master.rb
264
265
  - spec/migrations/2_create_users_on_canada.rb
265
266
  - spec/migrations/3_create_users_on_both_shards.rb
@@ -324,6 +325,7 @@ test_files:
324
325
  - spec/migrations/12_create_users_using_block.rb
325
326
  - spec/migrations/13_create_users_using_block_and_using.rb
326
327
  - spec/migrations/14_create_users_on_shards_of_a_group_with_versions.rb
328
+ - spec/migrations/15_create_user_on_shards_of_default_group_with_versions.rb
327
329
  - spec/migrations/1_create_users_on_master.rb
328
330
  - spec/migrations/2_create_users_on_canada.rb
329
331
  - spec/migrations/3_create_users_on_both_shards.rb