ar-octopus 0.0.2 → 0.0.3
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.
- data/.gitignore +1 -0
- data/Rakefile +54 -1
- data/ar-octopus.gemspec +9 -4
- data/lib/octopus.rb +6 -3
- data/lib/octopus/association.rb +109 -0
- data/lib/octopus/association_collection.rb +40 -0
- data/lib/octopus/controller.rb +1 -9
- data/lib/octopus/has_and_belongs_to_many_association.rb +43 -0
- data/lib/octopus/migration.rb +19 -26
- data/lib/octopus/model.rb +97 -29
- data/lib/octopus/proxy.rb +42 -21
- data/spec/database_models.rb +31 -0
- data/spec/octopus/association_spec.rb +518 -0
- data/spec/octopus/model_spec.rb +66 -15
- data/spec/octopus/proxy_spec.rb +1 -1
- data/spec/spec_helper.rb +10 -6
- metadata +16 -4
data/lib/octopus/proxy.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require "set"
|
2
2
|
|
3
3
|
class Octopus::Proxy
|
4
|
-
attr_accessor :shards, :
|
4
|
+
attr_accessor :shards, :block, :groups, :current_group, :replicated, :slaves_list, :replicated_models, :using_enabled, :last_current_shard
|
5
5
|
|
6
6
|
delegate :increment_open_transactions, :decrement_open_transactions, :to => :select_connection
|
7
7
|
|
@@ -9,12 +9,18 @@ class Octopus::Proxy
|
|
9
9
|
@shards = {}
|
10
10
|
@groups = {}
|
11
11
|
@replicated_models = Set.new
|
12
|
-
@
|
13
|
-
@replicated = config[Octopus.env()]["replicated"] || false
|
12
|
+
@replicated = config[Octopus.env()]["replicated"]
|
14
13
|
@shards[:master] = ActiveRecord::Base.connection_pool()
|
15
|
-
|
16
|
-
|
17
|
-
|
14
|
+
Thread.current[:current_shard] = :master
|
15
|
+
|
16
|
+
initialize_shards(config)
|
17
|
+
|
18
|
+
if @replicated
|
19
|
+
initialize_replication()
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def initialize_shards(config)
|
18
24
|
config[Octopus.env()]["shards"].each do |key, value|
|
19
25
|
if value.has_key?("adapter")
|
20
26
|
initialize_adapter(value['adapter'])
|
@@ -30,14 +36,18 @@ class Octopus::Proxy
|
|
30
36
|
end
|
31
37
|
end
|
32
38
|
end
|
33
|
-
|
34
|
-
if @replicated
|
35
|
-
@slaves_list = @shards.keys
|
36
|
-
@slaves_list.delete(:master)
|
37
|
-
@slaves_list = @slaves_list.map {|sym| sym.to_s}.sort
|
38
|
-
end
|
39
39
|
end
|
40
|
-
|
40
|
+
|
41
|
+
def initialize_replication()
|
42
|
+
@slaves_list = @shards.keys
|
43
|
+
@slaves_list.delete(:master)
|
44
|
+
@slaves_list = @slaves_list.map {|sym| sym.to_s}.sort
|
45
|
+
end
|
46
|
+
|
47
|
+
def current_shard
|
48
|
+
Thread.current[:current_shard]
|
49
|
+
end
|
50
|
+
|
41
51
|
def current_shard=(shard_symbol)
|
42
52
|
if shard_symbol.is_a?(Array)
|
43
53
|
shard_symbol.each {|symbol| raise "Nonexistent Shard Name: #{symbol}" if @shards[symbol].nil? }
|
@@ -45,7 +55,7 @@ class Octopus::Proxy
|
|
45
55
|
raise "Nonexistent Shard Name: #{shard_symbol}" if @shards[shard_symbol].nil?
|
46
56
|
end
|
47
57
|
|
48
|
-
|
58
|
+
Thread.current[:current_shard] = shard_symbol
|
49
59
|
end
|
50
60
|
|
51
61
|
def current_group=(group_symbol)
|
@@ -57,7 +67,7 @@ class Octopus::Proxy
|
|
57
67
|
|
58
68
|
@current_group = group_symbol
|
59
69
|
end
|
60
|
-
|
70
|
+
|
61
71
|
def select_connection()
|
62
72
|
@shards[shard_name].connection()
|
63
73
|
end
|
@@ -83,13 +93,11 @@ class Octopus::Proxy
|
|
83
93
|
def transaction(options = {}, &block)
|
84
94
|
if should_send_queries_to_multiple_shards?
|
85
95
|
self.send_transaction_to_multiple_shards(current_shard, options, &block)
|
86
|
-
self.current_shard = :master
|
87
96
|
elsif should_send_queries_to_multiple_groups?
|
88
97
|
self.send_transaction_to_multiple_groups(options, &block)
|
89
|
-
self.current_group = nil
|
90
98
|
elsif should_send_queries_to_a_group_of_shards?
|
91
99
|
self.send_transaction_to_multiple_shards(@groups[current_group], options, &block)
|
92
|
-
self.current_group = nil
|
100
|
+
self.current_group = nil
|
93
101
|
else
|
94
102
|
select_connection.transaction(options, &block)
|
95
103
|
end
|
@@ -98,6 +106,7 @@ class Octopus::Proxy
|
|
98
106
|
def method_missing(method, *args, &block)
|
99
107
|
if should_clean_connection?(method)
|
100
108
|
conn = select_connection()
|
109
|
+
self.last_current_shard = self.current_shard
|
101
110
|
self.current_shard = :master
|
102
111
|
@using_enabled = nil
|
103
112
|
conn.send(method, *args, &block)
|
@@ -113,7 +122,19 @@ class Octopus::Proxy
|
|
113
122
|
select_connection().send(method, *args, &block)
|
114
123
|
end
|
115
124
|
end
|
116
|
-
|
125
|
+
|
126
|
+
def run_query_on_shard(shard, &block)
|
127
|
+
older_shard = self.current_shard
|
128
|
+
self.block = true
|
129
|
+
self.current_shard = shard
|
130
|
+
begin
|
131
|
+
yield
|
132
|
+
ensure
|
133
|
+
self.block = false
|
134
|
+
self.current_shard = older_shard
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
117
138
|
protected
|
118
139
|
def connection_pool_for(adapter, config)
|
119
140
|
ActiveRecord::ConnectionAdapters::ConnectionPool.new(ActiveRecord::Base::ConnectionSpecification.new(adapter, config))
|
@@ -134,7 +155,7 @@ class Octopus::Proxy
|
|
134
155
|
end
|
135
156
|
|
136
157
|
def should_clean_connection?(method)
|
137
|
-
method.to_s =~ /
|
158
|
+
method.to_s =~ /insert|select/ && !should_send_queries_to_multiple_shards? && !self.current_group && !replicated
|
138
159
|
end
|
139
160
|
|
140
161
|
def should_send_queries_to_multiple_shards?
|
@@ -150,7 +171,7 @@ class Octopus::Proxy
|
|
150
171
|
end
|
151
172
|
|
152
173
|
def should_send_queries_to_replicated_databases?(method)
|
153
|
-
@replicated && method.to_s
|
174
|
+
@replicated && method.to_s =~ /select/
|
154
175
|
end
|
155
176
|
|
156
177
|
def send_queries_to_multiple_groups(method, *args, &block)
|
data/spec/database_models.rb
CHANGED
@@ -20,4 +20,35 @@ end
|
|
20
20
|
#This items belongs to a client
|
21
21
|
class Item < ActiveRecord::Base
|
22
22
|
belongs_to :client
|
23
|
+
end
|
24
|
+
|
25
|
+
class Keyboard < ActiveRecord::Base
|
26
|
+
belongs_to :computer
|
27
|
+
end
|
28
|
+
|
29
|
+
class Computer < ActiveRecord::Base
|
30
|
+
has_one :keyboard
|
31
|
+
end
|
32
|
+
|
33
|
+
class Role < ActiveRecord::Base
|
34
|
+
has_and_belongs_to_many :permissions
|
35
|
+
end
|
36
|
+
|
37
|
+
class Permission < ActiveRecord::Base
|
38
|
+
has_and_belongs_to_many :roles
|
39
|
+
end
|
40
|
+
|
41
|
+
class Assignment < ActiveRecord::Base
|
42
|
+
belongs_to :programmer
|
43
|
+
belongs_to :project
|
44
|
+
end
|
45
|
+
|
46
|
+
class Programmer < ActiveRecord::Base
|
47
|
+
has_many :assignments
|
48
|
+
has_many :projects, :through => :assignments
|
49
|
+
end
|
50
|
+
|
51
|
+
class Project < ActiveRecord::Base
|
52
|
+
has_many :assignments
|
53
|
+
has_many :programmers, :through => :assignments
|
23
54
|
end
|
@@ -0,0 +1,518 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
describe Octopus::Association do
|
4
|
+
describe "when you have a 1 x 1 relationship" do
|
5
|
+
before(:each) do
|
6
|
+
@computer_brazil = Computer.using(:brazil).create!(:name => "Computer Brazil")
|
7
|
+
@computer_master = Computer.create!(:name => "Computer Brazil")
|
8
|
+
@keyboard_brazil = Keyboard.using(:brazil).create!(:name => "Keyboard Brazil", :computer => @computer_brazil)
|
9
|
+
@keyboard_master = Keyboard.create!(:name => "Keyboard Master", :computer => @computer_master)
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should find the models" do
|
13
|
+
@keyboard_master.computer.should == @computer_master
|
14
|
+
@keyboard_brazil.computer.should == @computer_brazil
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should read correctly the relationed model" do
|
18
|
+
new_computer_brazil = Computer.using(:brazil).create!(:name => "New Computer Brazil")
|
19
|
+
new_computer_master = Computer.create!(:name => "New Computer Brazil")
|
20
|
+
@keyboard_brazil.computer = new_computer_brazil
|
21
|
+
@keyboard_brazil.save()
|
22
|
+
@keyboard_brazil.reload
|
23
|
+
@keyboard_brazil.computer_id.should == new_computer_brazil.id
|
24
|
+
@keyboard_brazil.computer.should == new_computer_brazil
|
25
|
+
new_computer_brazil.save()
|
26
|
+
new_computer_brazil.reload
|
27
|
+
new_computer_brazil.keyboard.should == @keyboard_brazil
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should work when using #build_computer or #build_keyboard" do
|
31
|
+
c = Computer.using(:brazil).create!(:name => "Computer Brazil")
|
32
|
+
k = c.build_keyboard(:name => "Building keyboard")
|
33
|
+
c.save()
|
34
|
+
k.save()
|
35
|
+
c.keyboard.should == k
|
36
|
+
k.computer_id.should == c.id
|
37
|
+
k.computer.should == c
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should work when using #create_computer or #create_keyboard" do
|
41
|
+
c = Computer.using(:brazil).create!(:name => "Computer Brazil")
|
42
|
+
k = c.create_keyboard(:name => "Building keyboard")
|
43
|
+
c.save()
|
44
|
+
k.save()
|
45
|
+
c.keyboard.should == k
|
46
|
+
k.computer_id.should == c.id
|
47
|
+
k.computer.should == c
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should works when using create!" do
|
51
|
+
c = Computer.using(:brazil).create!(:name => "Computer Brazil")
|
52
|
+
k = c.keyboard.create!(:name => "New Keyboard")
|
53
|
+
c.save()
|
54
|
+
k.save()
|
55
|
+
c.reload()
|
56
|
+
k.reload()
|
57
|
+
c.keyboard.should == k
|
58
|
+
k.computer_id.should == c.id
|
59
|
+
k.computer.should == c
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe "when you have a N x N reliationship" do
|
64
|
+
before(:each) do
|
65
|
+
@brazil_role = Role.using(:brazil).create!(:name => "Brazil Role")
|
66
|
+
@master_role = Role.create!(:name => "Master Role")
|
67
|
+
@permission_brazil = Permission.using(:brazil).create!(:name => "Brazil Permission")
|
68
|
+
@permission_master = Permission.using(:master).create!(:name => "Master Permission")
|
69
|
+
@brazil_role.permissions << @permission_brazil
|
70
|
+
@brazil_role.save()
|
71
|
+
Client.using(:master).create!(:name => "teste")
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should find all models in the specified shard" do
|
75
|
+
@brazil_role.permission_ids().should == [@permission_brazil.id]
|
76
|
+
@brazil_role.permissions().should == [@permission_brazil]
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should finds the client that the item belongs" do
|
80
|
+
@permission_brazil.role_ids.should == [@brazil_role.id]
|
81
|
+
@permission_brazil.roles.should == [@brazil_role]
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should update the attribute for the item" do
|
85
|
+
new_brazil_role = Role.using(:brazil).create!(:name => "new Role")
|
86
|
+
@permission_brazil.roles = [new_brazil_role]
|
87
|
+
@permission_brazil.roles.should == [new_brazil_role]
|
88
|
+
@permission_brazil.save()
|
89
|
+
@permission_brazil.reload
|
90
|
+
@permission_brazil.role_ids.should == [new_brazil_role.id]
|
91
|
+
@permission_brazil.roles().should == [new_brazil_role]
|
92
|
+
end
|
93
|
+
|
94
|
+
it "should works for build method" do
|
95
|
+
new_brazil_role = Role.using(:brazil).create!(:name => "Brazil Role")
|
96
|
+
c = new_brazil_role.permissions.create(:name => "new Permission")
|
97
|
+
c.save()
|
98
|
+
new_brazil_role.save()
|
99
|
+
c.roles().should == [new_brazil_role]
|
100
|
+
new_brazil_role.permissions.should == [c]
|
101
|
+
end
|
102
|
+
|
103
|
+
describe "it should works when using" do
|
104
|
+
before(:each) do
|
105
|
+
@permission_brazil_2 = Permission.using(:brazil).create!(:name => "Brazil Item 2")
|
106
|
+
@role = Role.using(:brazil).create!(:name => "testes")
|
107
|
+
end
|
108
|
+
|
109
|
+
it "update_attributes" do
|
110
|
+
@permission_brazil_2.update_attributes(:role_ids => [@role.id])
|
111
|
+
@permission_brazil_2.roles.to_set.should == [@role].to_set
|
112
|
+
end
|
113
|
+
|
114
|
+
it "update_attribute" do
|
115
|
+
@permission_brazil_2.update_attribute(:role_ids, [@role.id])
|
116
|
+
@permission_brazil_2.roles.to_set.should == [@role].to_set
|
117
|
+
end
|
118
|
+
|
119
|
+
it "<<" do
|
120
|
+
@permission_brazil_2.roles << @role
|
121
|
+
@role.save()
|
122
|
+
@permission_brazil_2.save()
|
123
|
+
@permission_brazil_2.reload
|
124
|
+
@permission_brazil_2.roles.to_set.should == [@role].to_set
|
125
|
+
end
|
126
|
+
|
127
|
+
it "build" do
|
128
|
+
role = @permission_brazil_2.roles.build(:name => "Builded Role")
|
129
|
+
@permission_brazil_2.save()
|
130
|
+
@permission_brazil_2.roles.to_set.should == [role].to_set
|
131
|
+
end
|
132
|
+
|
133
|
+
it "create" do
|
134
|
+
role = @permission_brazil_2.roles.create(:name => "Builded Role")
|
135
|
+
@permission_brazil_2.roles.to_set.should == [role].to_set
|
136
|
+
end
|
137
|
+
|
138
|
+
it "create" do
|
139
|
+
role = @permission_brazil_2.roles.create!(:name => "Builded Role")
|
140
|
+
@permission_brazil_2.roles.to_set.should == [role].to_set
|
141
|
+
end
|
142
|
+
|
143
|
+
it "count" do
|
144
|
+
@permission_brazil_2.roles.count.should == 0
|
145
|
+
role = @permission_brazil_2.roles.create(:name => "Builded Role")
|
146
|
+
@permission_brazil_2.roles.count.should == 1
|
147
|
+
role = @permission_brazil_2.roles.create(:name => "Builded Role")
|
148
|
+
@permission_brazil_2.roles.count.should == 2
|
149
|
+
end
|
150
|
+
|
151
|
+
it "size" do
|
152
|
+
@permission_brazil_2.roles.size.should == 0
|
153
|
+
role = @permission_brazil_2.roles.create(:name => "Builded Role")
|
154
|
+
@permission_brazil_2.roles.size.should == 1
|
155
|
+
role = @permission_brazil_2.roles.create(:name => "Builded Role")
|
156
|
+
@permission_brazil_2.roles.size.should == 2
|
157
|
+
end
|
158
|
+
|
159
|
+
it "length" do
|
160
|
+
@permission_brazil_2.roles.length.should == 0
|
161
|
+
role = @permission_brazil_2.roles.create(:name => "Builded Role")
|
162
|
+
@permission_brazil_2.roles.length.should == 1
|
163
|
+
role = @permission_brazil_2.roles.create(:name => "Builded Role")
|
164
|
+
@permission_brazil_2.roles.length.should == 2
|
165
|
+
end
|
166
|
+
|
167
|
+
|
168
|
+
it "empty?" do
|
169
|
+
@permission_brazil_2.roles.empty?.should be_true
|
170
|
+
role = @permission_brazil_2.roles.create(:name => "Builded Role")
|
171
|
+
@permission_brazil_2.roles.empty?.should be_false
|
172
|
+
end
|
173
|
+
|
174
|
+
it "delete_all" do
|
175
|
+
role = @permission_brazil_2.roles.create(:name => "Builded Role")
|
176
|
+
@permission_brazil_2.roles.empty?.should be_false
|
177
|
+
@permission_brazil_2.roles.delete_all
|
178
|
+
@permission_brazil_2.roles.empty?.should be_true
|
179
|
+
end
|
180
|
+
|
181
|
+
it "destroy_all" do
|
182
|
+
role = @permission_brazil_2.roles.create(:name => "Builded Role")
|
183
|
+
@permission_brazil_2.roles.empty?.should be_false
|
184
|
+
@permission_brazil_2.roles.destroy_all
|
185
|
+
@permission_brazil_2.roles.empty?.should be_true
|
186
|
+
end
|
187
|
+
|
188
|
+
it "find" do
|
189
|
+
role = @permission_brazil_2.roles.create(:name => "Builded Role")
|
190
|
+
@permission_brazil_2.roles.find(:first).should == role
|
191
|
+
@permission_brazil_2.roles.destroy_all
|
192
|
+
@permission_brazil_2.roles.find(:first).should be_nil
|
193
|
+
end
|
194
|
+
|
195
|
+
it "exists?" do
|
196
|
+
role = @permission_brazil_2.roles.create(:name => "Builded Role")
|
197
|
+
@permission_brazil_2.roles.exists?(role).should be_true
|
198
|
+
@permission_brazil_2.roles.destroy_all
|
199
|
+
@permission_brazil_2.roles.exists?(role).should be_false
|
200
|
+
end
|
201
|
+
|
202
|
+
it "clear" do
|
203
|
+
role = @permission_brazil_2.roles.create(:name => "Builded Role")
|
204
|
+
@permission_brazil_2.roles.empty?.should be_false
|
205
|
+
@permission_brazil_2.roles.clear
|
206
|
+
@permission_brazil_2.roles.empty?.should be_true
|
207
|
+
end
|
208
|
+
|
209
|
+
it "delete" do
|
210
|
+
role = @permission_brazil_2.roles.create(:name => "Builded Role")
|
211
|
+
@permission_brazil_2.roles.empty?.should be_false
|
212
|
+
@permission_brazil_2.roles.delete(role)
|
213
|
+
@permission_brazil_2.reload
|
214
|
+
@role.reload
|
215
|
+
@role.permissions.should == []
|
216
|
+
@permission_brazil_2.roles.should == []
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
describe "when you have has_many :through" do
|
222
|
+
before(:each) do
|
223
|
+
@programmer = Programmer.using(:brazil).create!(:name => "Thiago")
|
224
|
+
@project = Project.using(:brazil).create!(:name => "RubySoc")
|
225
|
+
@project2 = Project.using(:brazil).create!(:name => "Cobol Application")
|
226
|
+
@programmer.projects << @project
|
227
|
+
@programmer.save()
|
228
|
+
Project.using(:master).create!(:name => "Project Master")
|
229
|
+
end
|
230
|
+
|
231
|
+
it "should find all models in the specified shard" do
|
232
|
+
@programmer.project_ids().should == [ @project.id]
|
233
|
+
@programmer.projects().should == [@project]
|
234
|
+
end
|
235
|
+
|
236
|
+
|
237
|
+
it "should update the attribute for the item" do
|
238
|
+
new_brazil_programmer = Programmer.using(:brazil).create!(:name => "Joao")
|
239
|
+
@project.programmers = [new_brazil_programmer]
|
240
|
+
@project.programmers.should == [new_brazil_programmer]
|
241
|
+
@project.save()
|
242
|
+
@project.reload
|
243
|
+
@project.programmer_ids.should == [new_brazil_programmer.id]
|
244
|
+
@project.programmers().should == [new_brazil_programmer]
|
245
|
+
end
|
246
|
+
|
247
|
+
it "should works for create method" do
|
248
|
+
new_brazil_programmer = Programmer.using(:brazil).create!(:name => "Joao")
|
249
|
+
c = new_brazil_programmer.projects.create(:name => "new Project")
|
250
|
+
c.save()
|
251
|
+
new_brazil_programmer.save()
|
252
|
+
c.programmers().should == [new_brazil_programmer]
|
253
|
+
new_brazil_programmer.projects.should == [c]
|
254
|
+
end
|
255
|
+
|
256
|
+
describe "it should works when using" do
|
257
|
+
before(:each) do
|
258
|
+
@new_brazil_programmer = Programmer.using(:brazil).create!(:name => "Jose")
|
259
|
+
@project = Project.using(:brazil).create!(:name => "VB Application :-(")
|
260
|
+
end
|
261
|
+
|
262
|
+
it "update_attributes" do
|
263
|
+
@new_brazil_programmer.update_attributes(:project_ids => [@project.id])
|
264
|
+
@new_brazil_programmer.projects.to_set.should == [@project].to_set
|
265
|
+
end
|
266
|
+
|
267
|
+
it "update_attribute" do
|
268
|
+
@new_brazil_programmer.update_attribute(:project_ids, [@project.id])
|
269
|
+
@new_brazil_programmer.projects.to_set.should == [@project].to_set
|
270
|
+
end
|
271
|
+
|
272
|
+
it "<<" do
|
273
|
+
@new_brazil_programmer.projects << @project
|
274
|
+
@project.save()
|
275
|
+
@new_brazil_programmer.save()
|
276
|
+
@new_brazil_programmer.reload
|
277
|
+
@new_brazil_programmer.projects.to_set.should == [@project].to_set
|
278
|
+
end
|
279
|
+
|
280
|
+
it "build" do
|
281
|
+
role = @new_brazil_programmer.projects.build(:name => "New VB App :-/")
|
282
|
+
@new_brazil_programmer.save()
|
283
|
+
@new_brazil_programmer.projects.to_set.should == [role].to_set
|
284
|
+
end
|
285
|
+
|
286
|
+
it "create" do
|
287
|
+
role = @new_brazil_programmer.projects.create(:name => "New VB App :-/")
|
288
|
+
@new_brazil_programmer.projects.to_set.should == [role].to_set
|
289
|
+
end
|
290
|
+
|
291
|
+
it "create" do
|
292
|
+
role = @new_brazil_programmer.projects.create!(:name => "New VB App :-/")
|
293
|
+
@new_brazil_programmer.projects.to_set.should == [role].to_set
|
294
|
+
end
|
295
|
+
|
296
|
+
it "count" do
|
297
|
+
@new_brazil_programmer.projects.count.should == 0
|
298
|
+
role = @new_brazil_programmer.projects.create(:name => "New VB App :-/")
|
299
|
+
@new_brazil_programmer.projects.count.should == 1
|
300
|
+
role = @new_brazil_programmer.projects.create(:name => "New VB App :-/")
|
301
|
+
@new_brazil_programmer.projects.count.should == 2
|
302
|
+
end
|
303
|
+
|
304
|
+
it "size" do
|
305
|
+
@new_brazil_programmer.projects.size.should == 0
|
306
|
+
role = @new_brazil_programmer.projects.create(:name => "New VB App :-/")
|
307
|
+
@new_brazil_programmer.projects.size.should == 1
|
308
|
+
role = @new_brazil_programmer.projects.create(:name => "New VB App :-/")
|
309
|
+
@new_brazil_programmer.projects.size.should == 2
|
310
|
+
end
|
311
|
+
|
312
|
+
it "length" do
|
313
|
+
@new_brazil_programmer.projects.length.should == 0
|
314
|
+
role = @new_brazil_programmer.projects.create(:name => "New VB App :-/")
|
315
|
+
@new_brazil_programmer.projects.length.should == 1
|
316
|
+
role = @new_brazil_programmer.projects.create(:name => "New VB App :-/")
|
317
|
+
@new_brazil_programmer.projects.length.should == 2
|
318
|
+
end
|
319
|
+
|
320
|
+
|
321
|
+
it "empty?" do
|
322
|
+
@new_brazil_programmer.projects.empty?.should be_true
|
323
|
+
role = @new_brazil_programmer.projects.create(:name => "New VB App :-/")
|
324
|
+
@new_brazil_programmer.projects.empty?.should be_false
|
325
|
+
end
|
326
|
+
|
327
|
+
it "delete_all" do
|
328
|
+
role = @new_brazil_programmer.projects.create(:name => "New VB App :-/")
|
329
|
+
@new_brazil_programmer.projects.empty?.should be_false
|
330
|
+
@new_brazil_programmer.projects.delete_all
|
331
|
+
@new_brazil_programmer.projects.empty?.should be_true
|
332
|
+
end
|
333
|
+
|
334
|
+
it "destroy_all" do
|
335
|
+
role = @new_brazil_programmer.projects.create(:name => "New VB App :-/")
|
336
|
+
@new_brazil_programmer.projects.empty?.should be_false
|
337
|
+
@new_brazil_programmer.projects.destroy_all
|
338
|
+
@new_brazil_programmer.projects.empty?.should be_true
|
339
|
+
end
|
340
|
+
|
341
|
+
it "find" do
|
342
|
+
role = @new_brazil_programmer.projects.create(:name => "New VB App :-/")
|
343
|
+
@new_brazil_programmer.projects.find(:first).should == role
|
344
|
+
@new_brazil_programmer.projects.destroy_all
|
345
|
+
@new_brazil_programmer.projects.find(:first).should be_nil
|
346
|
+
end
|
347
|
+
|
348
|
+
it "exists?" do
|
349
|
+
role = @new_brazil_programmer.projects.create(:name => "New VB App :-/")
|
350
|
+
@new_brazil_programmer.projects.exists?(role).should be_true
|
351
|
+
@new_brazil_programmer.projects.destroy_all
|
352
|
+
@new_brazil_programmer.projects.exists?(role).should be_false
|
353
|
+
end
|
354
|
+
|
355
|
+
it "clear" do
|
356
|
+
role = @new_brazil_programmer.projects.create(:name => "New VB App :-/")
|
357
|
+
@new_brazil_programmer.projects.empty?.should be_false
|
358
|
+
@new_brazil_programmer.projects.clear
|
359
|
+
@new_brazil_programmer.projects.empty?.should be_true
|
360
|
+
end
|
361
|
+
|
362
|
+
it "delete" do
|
363
|
+
role = @new_brazil_programmer.projects.create(:name => "New VB App :-/")
|
364
|
+
@new_brazil_programmer.projects.empty?.should be_false
|
365
|
+
@new_brazil_programmer.projects.delete(role)
|
366
|
+
@new_brazil_programmer.reload
|
367
|
+
@project.reload
|
368
|
+
@project.programmers.should == []
|
369
|
+
@new_brazil_programmer.projects.should == []
|
370
|
+
end
|
371
|
+
end
|
372
|
+
end
|
373
|
+
|
374
|
+
describe "when you have a 1 x N relationship" do
|
375
|
+
before(:each) do
|
376
|
+
@brazil_client = Client.using(:brazil).create!(:name => "Brazil Client")
|
377
|
+
@master_client = Client.create!(:name => "Master Client")
|
378
|
+
@item_brazil = Item.using(:brazil).create!(:name => "Brazil Item", :client => @brazil_client)
|
379
|
+
@item_master = Item.create!(:name => "Master Item", :client => @master_client)
|
380
|
+
@brazil_client = Client.using(:brazil).find_by_name("Brazil Client")
|
381
|
+
Client.using(:master).create!(:name => "teste")
|
382
|
+
end
|
383
|
+
|
384
|
+
it "should find all models in the specified shard" do
|
385
|
+
@brazil_client.item_ids.should == [@item_brazil.id]
|
386
|
+
@brazil_client.items().should == [@item_brazil]
|
387
|
+
end
|
388
|
+
|
389
|
+
it "should finds the client that the item belongs" do
|
390
|
+
@item_brazil.client.should == @brazil_client
|
391
|
+
end
|
392
|
+
|
393
|
+
it "should update the attribute for the item" do
|
394
|
+
new_brazil_client = Client.using(:brazil).create!(:name => "new Client")
|
395
|
+
@item_brazil.client = new_brazil_client
|
396
|
+
@item_brazil.client.should == new_brazil_client
|
397
|
+
@item_brazil.save()
|
398
|
+
@item_brazil.reload
|
399
|
+
@item_brazil.client_id.should == new_brazil_client.id
|
400
|
+
@item_brazil.client().should == new_brazil_client
|
401
|
+
end
|
402
|
+
|
403
|
+
it "should works for build method" do
|
404
|
+
item2 = Item.using(:brazil).create!(:name => "Brazil Item")
|
405
|
+
c = item2.create_client(:name => "new Client")
|
406
|
+
c.save()
|
407
|
+
item2.save()
|
408
|
+
item2.client.should == c
|
409
|
+
c.items().should == [item2]
|
410
|
+
end
|
411
|
+
|
412
|
+
describe "it should works when using" do
|
413
|
+
before(:each) do
|
414
|
+
@item_brazil_2 = Item.using(:brazil).create!(:name => "Brazil Item 2")
|
415
|
+
@brazil_client.items.to_set.should == [@item_brazil].to_set
|
416
|
+
end
|
417
|
+
|
418
|
+
it "update_attributes" do
|
419
|
+
@brazil_client.update_attributes(:item_ids => [@item_brazil_2.id, @item_brazil.id])
|
420
|
+
@brazil_client.items.to_set.should == [@item_brazil, @item_brazil_2].to_set
|
421
|
+
end
|
422
|
+
|
423
|
+
it "update_attribute" do
|
424
|
+
@brazil_client.update_attribute(:item_ids, [@item_brazil_2.id, @item_brazil.id])
|
425
|
+
@brazil_client.items.to_set.should == [@item_brazil, @item_brazil_2].to_set
|
426
|
+
end
|
427
|
+
|
428
|
+
it "<<" do
|
429
|
+
@brazil_client.items << @item_brazil_2
|
430
|
+
@brazil_client.items.to_set.should == [@item_brazil, @item_brazil_2].to_set
|
431
|
+
end
|
432
|
+
|
433
|
+
it "build" do
|
434
|
+
item = @brazil_client.items.build(:name => "Builded Item")
|
435
|
+
item.save()
|
436
|
+
@brazil_client.items.to_set.should == [@item_brazil, item].to_set
|
437
|
+
end
|
438
|
+
|
439
|
+
it "create" do
|
440
|
+
item = @brazil_client.items.create(:name => "Builded Item")
|
441
|
+
@brazil_client.items.to_set.should == [@item_brazil, item].to_set
|
442
|
+
end
|
443
|
+
|
444
|
+
it "count" do
|
445
|
+
@brazil_client.items.count.should == 1
|
446
|
+
item = @brazil_client.items.create(:name => "Builded Item")
|
447
|
+
@brazil_client.items.count.should == 2
|
448
|
+
end
|
449
|
+
|
450
|
+
it "size" do
|
451
|
+
@brazil_client.items.size.should == 1
|
452
|
+
item = @brazil_client.items.create(:name => "Builded Item")
|
453
|
+
@brazil_client.items.size.should == 2
|
454
|
+
end
|
455
|
+
|
456
|
+
it "create!" do
|
457
|
+
item = @brazil_client.items.create!(:name => "Builded Item")
|
458
|
+
@brazil_client.items.to_set.should == [@item_brazil, item].to_set
|
459
|
+
end
|
460
|
+
|
461
|
+
it "length" do
|
462
|
+
@brazil_client.items.length.should == 1
|
463
|
+
item = @brazil_client.items.create(:name => "Builded Item")
|
464
|
+
@brazil_client.items.length.should == 2
|
465
|
+
end
|
466
|
+
|
467
|
+
it "empty?" do
|
468
|
+
@brazil_client.items.empty?.should be_false
|
469
|
+
c = Client.create!(:name => "Client1")
|
470
|
+
c.items.empty?.should be_true
|
471
|
+
end
|
472
|
+
|
473
|
+
it "delete" do
|
474
|
+
@brazil_client.items.empty?.should be_false
|
475
|
+
@brazil_client.items.delete(@item_brazil)
|
476
|
+
@brazil_client.reload
|
477
|
+
@item_brazil.reload
|
478
|
+
@item_brazil.client.should be_nil
|
479
|
+
@brazil_client.items.should == []
|
480
|
+
@brazil_client.items.empty?.should be_true
|
481
|
+
end
|
482
|
+
|
483
|
+
it "delete_all" do
|
484
|
+
@brazil_client.items.empty?.should be_false
|
485
|
+
@brazil_client.items.delete_all
|
486
|
+
@brazil_client.items.empty?.should be_true
|
487
|
+
end
|
488
|
+
|
489
|
+
it "destroy_all" do
|
490
|
+
@brazil_client.items.empty?.should be_false
|
491
|
+
@brazil_client.items.destroy_all
|
492
|
+
@brazil_client.items.empty?.should be_true
|
493
|
+
end
|
494
|
+
|
495
|
+
it "find" do
|
496
|
+
@brazil_client.items.find(:first).should == @item_brazil
|
497
|
+
@brazil_client.items.destroy_all
|
498
|
+
@brazil_client.items.find(:first).should be_nil
|
499
|
+
end
|
500
|
+
|
501
|
+
it "exists?" do
|
502
|
+
@brazil_client.items.exists?(@item_brazil).should be_true
|
503
|
+
@brazil_client.items.destroy_all
|
504
|
+
@brazil_client.items.exists?(@item_brazil).should be_false
|
505
|
+
end
|
506
|
+
|
507
|
+
it "uniq" do
|
508
|
+
@brazil_client.items.uniq.should == [@item_brazil]
|
509
|
+
end
|
510
|
+
|
511
|
+
it "clear" do
|
512
|
+
@brazil_client.items.empty?.should be_false
|
513
|
+
@brazil_client.items.clear
|
514
|
+
@brazil_client.items.empty?.should be_true
|
515
|
+
end
|
516
|
+
end
|
517
|
+
end
|
518
|
+
end
|