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 +8 -8
- data/README.mkdn +9 -2
- data/ar-octopus.gemspec +1 -1
- data/lib/octopus/association.rb +35 -0
- data/lib/octopus/association_collection.rb +33 -47
- data/lib/octopus/migration.rb +5 -4
- data/lib/octopus/model.rb +34 -13
- data/lib/octopus/proxy.rb +20 -10
- data/lib/octopus/rails3/abstract_adapter.rb +0 -11
- data/lib/octopus/rails3/persistence.rb +8 -16
- data/lib/octopus/rails3/singular_association.rb +5 -5
- data/lib/octopus/version.rb +1 -1
- data/spec/config/shards.yml +5 -1
- data/spec/migrations/15_create_user_on_shards_of_default_group_with_versions.rb +9 -0
- data/spec/octopus/association_spec.rb +52 -5
- data/spec/octopus/migration_spec.rb +14 -0
- data/spec/octopus/proxy_spec.rb +33 -0
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
MTRmYWZkMTg0YzU4MTM4YmNjYTM3MDE3MDVjZjQ1MjdiYmE2NDkwMg==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
ODhhZTJjNDQzZDVhMWZhYzc1NzRjYWNjOTdlYTQ5MTNlYzk5YWJkMA==
|
7
7
|
!binary "U0hBNTEy":
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
Y2JiNmI0MjEzYWRjYTFhYjMwN2IyYWQwMTQyMDI1M2UyYTdiNzU3NGY4ZDlm
|
10
|
+
MGYwNDQ2NGViMjhjOGRjMTZiNjdjN2VhODZiOGQ3ZWQ2Njg5OTFjZWE1ZDQ5
|
11
|
+
ZThjNjUxOTNhYzYyNTMwMjk3MjkwYmYzNmU3YjA0Y2MzMjMyZmE=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
MjU1YzZlNzczNGM2OGQ2YzMxYmZhMWE4M2QzYTQ5ZjM1NjEwYTQ4MDJiMDY5
|
14
|
+
YzM0Mjg4OTc4MmI4ZGYxMTlhNDJmYWMxMzA3MjU5ZDdmNjIwNmNmNmNlMmY3
|
15
|
+
OWZjY2RkNTViY2MzOTdjMjU5NTg2NjFkNDcyZmRiMWU5NDA2MWM=
|
data/README.mkdn
CHANGED
@@ -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'
|
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
|
data/ar-octopus.gemspec
CHANGED
@@ -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'
|
data/lib/octopus/association.rb
CHANGED
@@ -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
|
-
|
6
|
-
|
7
|
-
|
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
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
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)
|
data/lib/octopus/migration.rb
CHANGED
@@ -16,10 +16,10 @@ module Octopus::Migration
|
|
16
16
|
include InstanceOrClassMethods
|
17
17
|
|
18
18
|
def self.included(base)
|
19
|
-
base.
|
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.
|
60
|
+
base.extend(ClassMethods)
|
60
61
|
|
61
62
|
base.class_eval do
|
62
63
|
class << self
|
data/lib/octopus/model.rb
CHANGED
@@ -31,7 +31,7 @@ module Octopus::Model
|
|
31
31
|
|
32
32
|
def hijack_initializer()
|
33
33
|
attr_accessor :current_shard
|
34
|
-
|
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
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
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)
|
data/lib/octopus/proxy.rb
CHANGED
@@ -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
|
-
|
223
|
-
|
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
|
234
|
-
@shards.each { |k, v| safe_connection(v).
|
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
|
-
|
6
|
-
super
|
5
|
+
run_on_shard { super }
|
7
6
|
end
|
8
7
|
|
9
8
|
def update_attributes(*args)
|
10
|
-
|
11
|
-
super
|
9
|
+
run_on_shard { super }
|
12
10
|
end
|
13
11
|
|
14
12
|
def update_attributes!(*args)
|
15
|
-
|
16
|
-
super
|
13
|
+
run_on_shard { super }
|
17
14
|
end
|
18
15
|
|
19
16
|
def reload(*args)
|
20
|
-
|
21
|
-
super
|
17
|
+
run_on_shard { super }
|
22
18
|
end
|
23
19
|
|
24
20
|
def delete
|
25
|
-
|
26
|
-
super
|
21
|
+
run_on_shard { super }
|
27
22
|
end
|
28
23
|
|
29
24
|
def destroy
|
30
|
-
|
31
|
-
super
|
25
|
+
run_on_shard { super }
|
32
26
|
end
|
33
27
|
|
34
28
|
def touch(name=nil)
|
35
|
-
|
36
|
-
super
|
29
|
+
run_on_shard { super }
|
37
30
|
end
|
38
31
|
|
39
32
|
def update_column(*args)
|
40
|
-
|
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.
|
13
|
+
owner.run_on_shard { reader_without_octopus(*args) }
|
14
14
|
end
|
15
15
|
|
16
16
|
def writer_with_octopus(*args)
|
17
|
-
owner.
|
17
|
+
owner.run_on_shard { writer_without_octopus(*args) }
|
18
18
|
end
|
19
19
|
|
20
20
|
def create_with_octopus(*args)
|
21
|
-
owner.
|
21
|
+
owner.run_on_shard { create_without_octopus(*args) }
|
22
22
|
end
|
23
23
|
|
24
24
|
def create_with_octopus!(*args)
|
25
|
-
owner.
|
25
|
+
owner.run_on_shard { create_without_octopus!(*args) }
|
26
26
|
end
|
27
27
|
|
28
28
|
def build_with_octopus(*args)
|
29
|
-
owner.
|
29
|
+
owner.run_on_shard { build_without_octopus(*args) }
|
30
30
|
end
|
31
31
|
|
32
32
|
end
|
data/lib/octopus/version.rb
CHANGED
data/spec/config/shards.yml
CHANGED
@@ -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:
|
@@ -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
|
230
|
-
@programmer.projects().should
|
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
|
383
|
-
@brazil_client.items().should
|
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
|
data/spec/octopus/proxy_spec.rb
CHANGED
@@ -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.
|
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:
|
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
|