ar-octopus 0.8.0 → 0.8.1

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