cequel 0.5.6 → 1.0.0.pre.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (108) hide show
  1. checksums.yaml +7 -0
  2. data/lib/cequel.rb +5 -8
  3. data/lib/cequel/errors.rb +1 -0
  4. data/lib/cequel/metal.rb +17 -0
  5. data/lib/cequel/metal/batch.rb +62 -0
  6. data/lib/cequel/metal/cql_row_specification.rb +26 -0
  7. data/lib/cequel/metal/data_set.rb +461 -0
  8. data/lib/cequel/metal/deleter.rb +47 -0
  9. data/lib/cequel/metal/incrementer.rb +35 -0
  10. data/lib/cequel/metal/inserter.rb +53 -0
  11. data/lib/cequel/metal/keyspace.rb +213 -0
  12. data/lib/cequel/metal/row.rb +48 -0
  13. data/lib/cequel/metal/row_specification.rb +37 -0
  14. data/lib/cequel/metal/statement.rb +30 -0
  15. data/lib/cequel/metal/updater.rb +65 -0
  16. data/lib/cequel/metal/writer.rb +73 -0
  17. data/lib/cequel/model.rb +12 -84
  18. data/lib/cequel/model/association_collection.rb +23 -0
  19. data/lib/cequel/model/associations.rb +84 -80
  20. data/lib/cequel/model/base.rb +74 -0
  21. data/lib/cequel/model/belongs_to_association.rb +31 -0
  22. data/lib/cequel/model/callbacks.rb +14 -10
  23. data/lib/cequel/model/collection.rb +255 -0
  24. data/lib/cequel/model/errors.rb +6 -6
  25. data/lib/cequel/model/has_many_association.rb +26 -0
  26. data/lib/cequel/model/mass_assignment.rb +31 -0
  27. data/lib/cequel/model/persistence.rb +119 -115
  28. data/lib/cequel/model/properties.rb +89 -87
  29. data/lib/cequel/model/railtie.rb +21 -14
  30. data/lib/cequel/model/record_set.rb +285 -0
  31. data/lib/cequel/model/schema.rb +33 -0
  32. data/lib/cequel/model/scoped.rb +5 -48
  33. data/lib/cequel/model/validations.rb +18 -18
  34. data/lib/cequel/schema.rb +15 -0
  35. data/lib/cequel/schema/column.rb +135 -0
  36. data/lib/cequel/schema/create_table_dsl.rb +56 -0
  37. data/lib/cequel/schema/keyspace.rb +50 -0
  38. data/lib/cequel/schema/table.rb +120 -0
  39. data/lib/cequel/schema/table_property.rb +67 -0
  40. data/lib/cequel/schema/table_reader.rb +139 -0
  41. data/lib/cequel/schema/table_synchronizer.rb +114 -0
  42. data/lib/cequel/schema/table_updater.rb +83 -0
  43. data/lib/cequel/schema/table_writer.rb +80 -0
  44. data/lib/cequel/schema/update_table_dsl.rb +60 -0
  45. data/lib/cequel/type.rb +232 -0
  46. data/lib/cequel/version.rb +1 -1
  47. data/spec/environment.rb +5 -1
  48. data/spec/examples/metal/data_set_spec.rb +608 -0
  49. data/spec/examples/model/associations_spec.rb +84 -74
  50. data/spec/examples/model/callbacks_spec.rb +66 -59
  51. data/spec/examples/model/list_spec.rb +393 -0
  52. data/spec/examples/model/map_spec.rb +229 -0
  53. data/spec/examples/model/mass_assignment_spec.rb +55 -0
  54. data/spec/examples/model/naming_spec.rb +11 -4
  55. data/spec/examples/model/persistence_spec.rb +140 -150
  56. data/spec/examples/model/properties_spec.rb +122 -75
  57. data/spec/examples/model/record_set_spec.rb +285 -0
  58. data/spec/examples/model/schema_spec.rb +44 -0
  59. data/spec/examples/model/serialization_spec.rb +20 -14
  60. data/spec/examples/model/set_spec.rb +133 -0
  61. data/spec/examples/model/spec_helper.rb +0 -10
  62. data/spec/examples/model/validations_spec.rb +51 -38
  63. data/spec/examples/schema/table_reader_spec.rb +328 -0
  64. data/spec/examples/schema/table_synchronizer_spec.rb +172 -0
  65. data/spec/examples/schema/table_updater_spec.rb +157 -0
  66. data/spec/examples/schema/table_writer_spec.rb +225 -0
  67. data/spec/examples/spec_helper.rb +29 -0
  68. data/spec/examples/type_spec.rb +204 -0
  69. data/spec/support/helpers.rb +67 -8
  70. metadata +121 -152
  71. data/lib/cequel/batch.rb +0 -58
  72. data/lib/cequel/cql_row_specification.rb +0 -22
  73. data/lib/cequel/data_set.rb +0 -371
  74. data/lib/cequel/keyspace.rb +0 -205
  75. data/lib/cequel/model/class_internals.rb +0 -49
  76. data/lib/cequel/model/column.rb +0 -20
  77. data/lib/cequel/model/counter.rb +0 -35
  78. data/lib/cequel/model/dictionary.rb +0 -126
  79. data/lib/cequel/model/dirty.rb +0 -53
  80. data/lib/cequel/model/dynamic.rb +0 -31
  81. data/lib/cequel/model/inheritable.rb +0 -48
  82. data/lib/cequel/model/instance_internals.rb +0 -23
  83. data/lib/cequel/model/local_association.rb +0 -42
  84. data/lib/cequel/model/magic.rb +0 -79
  85. data/lib/cequel/model/mass_assignment_security.rb +0 -21
  86. data/lib/cequel/model/naming.rb +0 -17
  87. data/lib/cequel/model/observer.rb +0 -42
  88. data/lib/cequel/model/readable_dictionary.rb +0 -182
  89. data/lib/cequel/model/remote_association.rb +0 -40
  90. data/lib/cequel/model/scope.rb +0 -362
  91. data/lib/cequel/model/subclass_internals.rb +0 -45
  92. data/lib/cequel/model/timestamps.rb +0 -52
  93. data/lib/cequel/model/translation.rb +0 -17
  94. data/lib/cequel/row_specification.rb +0 -63
  95. data/lib/cequel/statement.rb +0 -23
  96. data/spec/examples/data_set_spec.rb +0 -444
  97. data/spec/examples/keyspace_spec.rb +0 -84
  98. data/spec/examples/model/counter_spec.rb +0 -94
  99. data/spec/examples/model/dictionary_spec.rb +0 -301
  100. data/spec/examples/model/dirty_spec.rb +0 -39
  101. data/spec/examples/model/dynamic_spec.rb +0 -41
  102. data/spec/examples/model/inheritable_spec.rb +0 -45
  103. data/spec/examples/model/magic_spec.rb +0 -199
  104. data/spec/examples/model/mass_assignment_security_spec.rb +0 -13
  105. data/spec/examples/model/observer_spec.rb +0 -86
  106. data/spec/examples/model/scope_spec.rb +0 -677
  107. data/spec/examples/model/timestamps_spec.rb +0 -52
  108. data/spec/examples/model/translation_spec.rb +0 -23
@@ -1,39 +0,0 @@
1
- require File.expand_path('../spec_helper', __FILE__)
2
-
3
- describe Cequel::Model::Dirty do
4
- let(:post) { Post.new(:id => 1) }
5
-
6
- it 'should not have changed attributes by default' do
7
- post.changed_attributes.should be_empty
8
- end
9
-
10
- it 'should have changed attributes if attributes change' do
11
- post.title = 'Cequel'
12
- post.changed_attributes.should == {:title => nil}.with_indifferent_access
13
- end
14
-
15
- it 'should not have changed attributes if attribute set to the same thing' do
16
- post.title = nil
17
- post.changed_attributes.should be_empty
18
- end
19
-
20
- it 'should support *_changed? method' do
21
- post.title = 'Cequel'
22
- post.title_changed?.should be_true
23
- end
24
-
25
- it 'should not have changed attributes after save' do
26
- connection.stub(:execute)
27
- post.title = 'Cequel'
28
- post.save
29
- post.changed_attributes.should be_empty
30
- end
31
-
32
- it 'should have previous changes after save' do
33
- connection.stub(:execute)
34
- post.title = 'Cequel'
35
- post.save
36
- post.previous_changes.
37
- should == { :title => [nil, 'Cequel'] }.with_indifferent_access
38
- end
39
- end
@@ -1,41 +0,0 @@
1
- require File.expand_path('../spec_helper', __FILE__)
2
-
3
- describe Cequel::Model::Dynamic do
4
-
5
- let(:category) { Category.new(:id => 1, :name => 'Big Data') }
6
-
7
- it 'should allow getting and setting of dynamic attributes' do
8
- category[:tag] = 'bigdata'
9
- category[:tag].should == 'bigdata'
10
- end
11
-
12
- it 'should insert dynamic values' do
13
- category[:tag] = 'bigdata'
14
- connection.should_receive(:execute).
15
- with "INSERT INTO categories (?) VALUES (?)", ['id', 'name', 'tag'], [1, 'Big Data', 'bigdata']
16
- category.save
17
- end
18
-
19
- it 'should update dynamic values' do
20
- category[:tag] = 'bigdata'
21
- connection.stub(:execute).
22
- with "INSERT INTO categories (?) VALUES (?)", ['id', 'name', 'tag'], [1, 'Big Data', 'bigdata']
23
- category.save
24
- category[:tag] = 'big-data'
25
- category[:color] = 'blue'
26
- connection.should_receive(:execute).
27
- with "UPDATE categories SET ? = ?, ? = ? WHERE ? = ?", 'tag', 'big-data', 'color', 'blue', :id, 1
28
- category.save
29
- end
30
-
31
- it 'should delete dynamic values' do
32
- category[:tag] = 'bigdata'
33
- connection.stub(:execute).
34
- with "INSERT INTO categories (?) VALUES (?)", ['id', 'name', 'tag'], [1, 'Big Data', 'bigdata']
35
- category.save
36
- category[:tag] = nil
37
- connection.should_receive(:execute).
38
- with "DELETE ? FROM categories WHERE ? = ?", ['tag'], :id, 1
39
- category.save
40
- end
41
- end
@@ -1,45 +0,0 @@
1
- require File.expand_path('../spec_helper', __FILE__)
2
-
3
- describe Cequel::Model::Inheritable do
4
- it 'should inherit key from superclass' do
5
- Photo.key_alias.should == :id
6
- end
7
-
8
- it 'should inherit columns from superclass' do
9
- Photo.column_names.should == [:id, :class_name, :label, :checksum, :url]
10
- end
11
-
12
- it 'should return ::base_class for base class' do
13
- Asset.base_class.should == Asset
14
- end
15
-
16
- it 'should return ::base_class for subclass' do
17
- Photo.base_class.should == Asset
18
- end
19
-
20
- it 'should not allow overriding a class without a type column' do
21
- base = Class.new do
22
- include Cequel::Model
23
- key :id, :integer
24
- end
25
- expect { sub = Class.new(base) }.to raise_error(ArgumentError)
26
- end
27
-
28
- it 'should set type on initialization' do
29
- Photo.new.class_name.should == 'Photo'
30
- end
31
-
32
- it 'should query correct column family when querying subclass' do
33
- connection.stub(:execute).
34
- with("SELECT * FROM assets WHERE ? = ? LIMIT 1", :id, 1).
35
- and_return result_stub(:id => 1, :label => 'Cequel')
36
- Photo.find(1)
37
- end
38
-
39
- it 'should hydrate correct model class when querying base class' do
40
- connection.stub(:execute).
41
- with('SELECT * FROM assets WHERE ? = ? LIMIT 1', :id, 1).
42
- and_return result_stub(:id => 1, :class_name => 'Photo', :label => 'Cequel')
43
- Asset.find(1).should be_a(Photo)
44
- end
45
- end
@@ -1,199 +0,0 @@
1
- require File.expand_path('../spec_helper', __FILE__)
2
-
3
- describe Cequel::Model::Magic do
4
- describe '::find_by_*' do
5
- it 'should magically look up one record by given value' do
6
- connection.stub(:execute).
7
- with("SELECT * FROM posts WHERE ? = ? LIMIT 1", :title, 'Cequel').
8
- and_return result_stub(:id => 1, :title => 'Cequel')
9
-
10
- Post.find_by_title('Cequel').id.should == 1
11
- end
12
-
13
- it 'should magically look up one record by multiple values' do
14
- connection.stub(:execute).
15
- with("SELECT * FROM posts WHERE ? = ? AND ? = ? LIMIT 1", :title, 'Cequel', :published, true).
16
- and_return result_stub(:id => 1, :title => 'Cequel', :published => true)
17
-
18
- Post.find_by_title_and_published('Cequel', true).id.should == 1
19
- end
20
-
21
- it 'should magically work on scopes' do
22
- connection.stub(:execute).
23
- with("SELECT ? FROM posts WHERE ? = ? AND ? = ? LIMIT 1", [:id], :title, 'Cequel', :published, true).
24
- and_return result_stub(:id => 1)
25
-
26
- Post.select(:id).find_by_title_and_published('Cequel', true).id.should == 1
27
- end
28
-
29
- it 'should raise error if specified columns different from arg count' do
30
- expect { Post.find_by_title_and_published('Cequel') }.
31
- to raise_error(ArgumentError)
32
- end
33
- end
34
-
35
- describe '::find_all_by_*' do
36
- context 'with existing record specified as args' do
37
- it 'should magically look up one record by multiple values' do
38
- connection.stub(:execute).
39
- with("SELECT * FROM posts WHERE ? = ? AND ? = ?", :title, 'Cequel', :published, true).
40
- and_return result_stub(
41
- {:id => 1, :title => 'Cequel', :published => true},
42
- {:id => 2, :title => 'Cequel2', :published => true }
43
- )
44
-
45
- Post.find_all_by_title_and_published('Cequel', true).map(&:id).
46
- should == [1, 2]
47
- end
48
-
49
- it 'should magically work on scopes' do
50
- connection.stub(:execute).
51
- with("SELECT ? FROM posts WHERE ? = ? AND ? = ?", [:id], :title, 'Cequel', :published, true).
52
- and_return result_stub(
53
- {:id => 1},
54
- {:id => 2}
55
- )
56
-
57
- Post.select(:id).find_all_by_title_and_published('Cequel', true).map(&:id).
58
- should == [1, 2]
59
- end
60
- end
61
- end
62
-
63
- describe '::find_or_create_by_*' do
64
- it 'should return existing record from args' do
65
- connection.stub(:execute).
66
- with("SELECT * FROM posts WHERE ? = ? AND ? = ? LIMIT 1", :title, 'Cequel', :published, true).
67
- and_return result_stub(:id => 1, :title => 'Cequel', :published => true)
68
-
69
- Post.find_or_create_by_title_and_published('Cequel', true).id.should == 1
70
- end
71
-
72
- it 'should create new record from args' do
73
- now = Time.now
74
- Time.stub!(:now).and_return now
75
- connection.stub(:execute).
76
- with("SELECT * FROM blogs WHERE ? = ? LIMIT 1", :id, 1).
77
- and_return result_stub
78
- connection.should_receive(:execute).
79
- with(
80
- "INSERT INTO blogs (?) VALUES (?)",
81
- ['id', 'published', 'updated_at', 'created_at'],
82
- [1, true, now, now]
83
- )
84
-
85
- Blog.find_or_create_by_id(1).id.should == 1
86
- end
87
-
88
- it 'should look up record from attributes' do
89
- connection.stub(:execute).
90
- with("SELECT * FROM posts WHERE ? = ? AND ? = ? LIMIT 1", :title, 'Cequel', :published, true).
91
- and_return result_stub(:id => 1, :title => 'Cequel', :published => true)
92
-
93
- Post.find_or_create_by_title_and_published(
94
- :id => 2, :title => 'Cequel', :published => true
95
- ).id.should == 1
96
- end
97
-
98
- it 'should create record from all attributes specified, including non-lookup ones' do
99
- connection.stub(:execute).
100
- with("SELECT * FROM posts WHERE ? = ? AND ? = ? LIMIT 1", :title, 'Cequel', :published, true).
101
- and_return result_stub
102
- connection.should_receive(:execute).
103
- with(
104
- "INSERT INTO posts (?) VALUES (?)",
105
- ['id', 'title', 'published'],
106
- [2, 'Cequel', true])
107
-
108
- Post.find_or_create_by_title_and_published(
109
- :id => 2, :title => 'Cequel', :published => true
110
- ).id.should == 2
111
- end
112
-
113
- it 'should yield instance on create if block given' do
114
- connection.stub(:execute).
115
- with("SELECT * FROM posts WHERE ? = ? AND ? = ? LIMIT 1", :title, 'Cequel', :published, true).
116
- and_return result_stub
117
- connection.should_receive(:execute).
118
- with(
119
- "INSERT INTO posts (?) VALUES (?)",
120
- ['id', 'title', 'published'],
121
- [2, 'Cequel', true]
122
- )
123
-
124
- Post.find_or_create_by_title_and_published('Cequel', true) do |post|
125
- post.id = 2
126
- end.id.should == 2
127
- end
128
-
129
- it 'should work on scopes' do
130
- connection.stub(:execute).
131
- with("SELECT ? FROM posts WHERE ? = ? AND ? = ? LIMIT 1", [:id], :title, 'Cequel', :published, true).
132
- and_return result_stub(:id => 1)
133
-
134
- Post.select(:id).find_or_create_by_title_and_published('Cequel', true).id.
135
- should == 1
136
- end
137
- end
138
-
139
- describe '::find_or_initialize_by_*' do
140
- it 'should return existing record from args' do
141
- connection.stub(:execute).
142
- with("SELECT * FROM posts WHERE ? = ? AND ? = ? LIMIT 1", :title, 'Cequel', :published, true).
143
- and_return result_stub(:id => 1, :title => 'Cequel', :published => true)
144
-
145
- Post.find_or_initialize_by_title_and_published('Cequel', true).id.should == 1
146
- end
147
-
148
- it 'should initialize new record from args' do
149
- now = Time.now
150
- Time.stub!(:now).and_return now
151
- timestamp = (now.to_f * 1000).to_i
152
- connection.stub(:execute).
153
- with("SELECT * FROM blogs WHERE ? = ? LIMIT 1", :id, 1).
154
- and_return result_stub
155
-
156
- Blog.find_or_initialize_by_id(1).id.should == 1
157
- end
158
-
159
- it 'should look up record from attributes' do
160
- connection.stub(:execute).
161
- with("SELECT * FROM posts WHERE ? = ? AND ? = ? LIMIT 1", :title, 'Cequel', :published, true).
162
- and_return result_stub(:id => 1, :title => 'Cequel', :published => true)
163
-
164
- Post.find_or_initialize_by_title_and_published(
165
- :id => 2, :title => 'Cequel', :published => true
166
- ).id.should == 1
167
- end
168
-
169
- it 'should create record from all attributes specified, including non-lookup ones' do
170
- connection.stub(:execute).
171
- with("SELECT * FROM posts WHERE ? = ? AND ? = ? LIMIT 1", :title, 'Cequel', :published, true).
172
- and_return result_stub
173
-
174
- Post.find_or_initialize_by_title_and_published(
175
- :id => 2, :title => 'Cequel', :published => true
176
- ).id.should == 2
177
- end
178
-
179
- it 'should yield instance on initialize if block given' do
180
- connection.stub(:execute).
181
- with("SELECT * FROM posts WHERE ? = ? AND ? = ? LIMIT 1", :title, 'Cequel', :published, true).
182
- and_return result_stub
183
-
184
- Post.find_or_initialize_by_title_and_published('Cequel', true) do |post|
185
- post.id = 2
186
- end.id.should == 2
187
- end
188
-
189
- it 'should work on scopes' do
190
- connection.stub(:execute).
191
- with("SELECT ? FROM posts WHERE ? = ? AND ? = ? LIMIT 1", [:id], :title, 'Cequel', :published, true).
192
- and_return result_stub(:id => 1)
193
-
194
- Post.select(:id).find_or_initialize_by_title_and_published('Cequel', true).id.
195
- should == 1
196
- end
197
-
198
- end
199
- end
@@ -1,13 +0,0 @@
1
- require File.expand_path('../spec_helper', __FILE__)
2
-
3
- describe Cequel::Model::MassAssignmentSecurity do
4
- let(:post) { Post.new(:id => 1, :title => 'Cequel', :blog_id => 3) }
5
-
6
- it 'should allow setting of unprotected attributes' do
7
- post.title.should == 'Cequel'
8
- end
9
-
10
- it 'should not allow setting of protected attributes' do
11
- post.blog_id.should be_nil
12
- end
13
- end
@@ -1,86 +0,0 @@
1
- require File.expand_path('../spec_helper', __FILE__)
2
-
3
- describe Cequel::Model::Observer do
4
- before do
5
- Cequel::Model.observers = [:post_observer, :asset_observer]
6
- Cequel::Model.instantiate_observers
7
- end
8
-
9
- let(:post) do
10
- connection.stub(:execute).
11
- with("SELECT * FROM posts WHERE ? = ? LIMIT 1", :id, 1).
12
- and_return result_stub('id' => 1, 'title' => 'Hey')
13
- Post.find(1)
14
- end
15
-
16
- shared_examples_for 'observing callbacks' do |*callbacks|
17
-
18
- all_callbacks = [
19
- :before_create, :after_create, :before_update, :after_update,
20
- :before_save, :after_save, :before_destroy, :after_destroy,
21
- :before_validation, :after_validation
22
- ]
23
-
24
- callbacks.each do |callback|
25
- it "should observe #{callback}" do
26
- post.should have_been_observed(callback)
27
- end
28
- end
29
-
30
- (all_callbacks - callbacks).each do |callback|
31
- it "should not observe #{callback}" do
32
- post.should_not have_been_observed(callback)
33
- end
34
- end
35
- end
36
-
37
- context 'on create' do
38
- let(:post) do
39
- connection.stub(:execute).
40
- with "INSERT INTO posts (?) VALUES (?)", ['id', 'title'], [1, 'Hey']
41
- Post.new(:id => 1, :title => 'Hey')
42
- end
43
-
44
- before { post.save }
45
-
46
- it_should_behave_like 'observing callbacks',
47
- :before_create, :after_create, :before_save, :after_save, :before_validation, :after_validation
48
- end
49
-
50
- context 'on update' do
51
-
52
- before { post.save }
53
-
54
- it_should_behave_like 'observing callbacks',
55
- :before_update, :after_update, :before_save, :after_save, :before_validation, :after_validation
56
- end
57
-
58
- context 'on destroy 'do
59
-
60
- before do
61
- connection.stub(:execute).
62
- with "DELETE FROM posts WHERE ? = ?", :id, 1
63
-
64
- post.destroy
65
- end
66
-
67
- it_should_behave_like 'observing callbacks', :before_destroy, :after_destroy
68
- end
69
-
70
- context 'on validation' do
71
- before do
72
- post.valid?
73
- end
74
-
75
- it_should_behave_like 'observing callbacks', :before_validation, :after_validation
76
- end
77
-
78
- context 'with inheritence' do
79
- it 'should observe subclass' do
80
- connection.stub(:execute).
81
- with("INSERT INTO assets (?) VALUES (?)", ['id', 'label', 'class_name'], [1, 'Cequel', 'Photo'])
82
- photo = Photo.create!(:id => 1, :label => 'Cequel')
83
- photo.should have_observed(:before_save)
84
- end
85
- end
86
- end
@@ -1,677 +0,0 @@
1
- require File.expand_path('../spec_helper', __FILE__)
2
-
3
- describe Cequel::Model::Scope do
4
- describe '#each' do
5
- it 'should provide enumerator for query results' do
6
- connection.stub(:execute).with("SELECT * FROM posts").
7
- and_return result_stub(:id => 1, :title => 'Cequel')
8
-
9
- Post.all.map { |post| [post.id, post.title] }.
10
- should == [[1, 'Cequel']]
11
- end
12
-
13
- it 'should enumerate results for just id if no key restriction' do
14
- connection.stub(:execute).with("SELECT ? FROM posts", [:id]).
15
- and_return result_stub(:id => 1)
16
-
17
- Post.select(:id).to_a.map { |post| post.id }.should == [1]
18
- end
19
-
20
- it 'should not enumerate results for just id if key restriction' do
21
- connection.stub(:execute).with("SELECT * FROM posts").
22
- and_return result_stub(:id => 1)
23
-
24
- Post.all.to_a.map { |post| post.id }.should == []
25
- end
26
-
27
- it 'should provide enumerator if no block given' do
28
- enum = Post.all.each
29
-
30
- connection.stub(:execute).with("SELECT * FROM posts").
31
- and_return result_stub(:id => 1, :title => 'Cequel')
32
-
33
- enum.map { |post| post.title }.should == ['Cequel']
34
- end
35
-
36
- it 'should enumerate zero times if empty-collection key restriction given' do
37
- Post.where(:id => []).to_a.should == []
38
- end
39
-
40
- it 'should enumerate zero times if empty-collection restriction given' do
41
- Post.where(:title => []).to_a.should == []
42
- end
43
- end
44
-
45
- describe '#first' do
46
- it 'should query for a single post' do
47
- connection.stub(:execute).with("SELECT * FROM posts LIMIT 1").
48
- and_return result_stub(:id => 1, :title => 'Cequel')
49
-
50
- Post.first.title.should == 'Cequel'
51
- end
52
-
53
- it 'should query for a single post within scope' do
54
- connection.stub(:execute).with("SELECT ? FROM posts LIMIT 1", [:id, :title]).
55
- and_return result_stub(:id => 1, :title => 'Cequel')
56
-
57
- Post.select(:id, :title).first.title.should == 'Cequel'
58
- end
59
-
60
- it 'should query scopes successively when multi-valued non-key column selected' do
61
- connection.stub(:execute).with("SELECT * FROM posts WHERE ? = ? LIMIT 1", :title, 'Cequel').
62
- and_return result_stub
63
- connection.stub(:execute).with("SELECT * FROM posts WHERE ? = ? LIMIT 1", :title, 'Cassandra').
64
- and_return result_stub(:id => 1, :title => 'Cassandra')
65
- connection.stub(:execute).with("SELECT * FROM posts WHERE ? = ? LIMIT 1", :title, 'CQL').
66
- and_return result_stub(:id => 2, :title => 'CQL')
67
-
68
- Post.where(:title => %w(Cequel Cassandra CQL)).first.title.
69
- should == 'Cassandra'
70
- end
71
-
72
- it 'should apply index preference when specified' do
73
- connection.should_receive(:execute).
74
- with("SELECT * FROM assets WHERE ? = ? AND ? = ? LIMIT 1", :checksum, 'abcdef', :class_name, 'Photo').
75
- and_return result_stub
76
- Photo.where(:checksum => 'abcdef').first
77
- end
78
-
79
- it 'should return nil when empty key collection given' do
80
- Post.where(:id => []).first.should be_nil
81
- end
82
-
83
- it 'should return nil when empty non-key collection given' do
84
- Post.where(:title => []).first.should be_nil
85
- end
86
- end
87
-
88
- describe '#count' do
89
- it 'should count records' do
90
- connection.stub(:execute).with("SELECT COUNT(*) FROM posts").
91
- and_return result_stub('count' => 5)
92
-
93
- Post.count.should == 5
94
- end
95
-
96
- it 'should count records in scope' do
97
- connection.stub(:execute).
98
- with("SELECT COUNT(*) FROM posts WHERE ? = ?", :blog_id, 1).
99
- and_return result_stub('count' => 5)
100
-
101
- Post.where(:blog_id => 1).count.should == 5
102
- end
103
-
104
- it 'should raise error if attempting count with key restriction' do
105
- expect { Post.where(:id => [1, 2, 3]).count }.
106
- to raise_error(Cequel::Model::InvalidQuery)
107
- end
108
-
109
- it 'should perform multiple COUNT queries if non-key column selected for multiple values' do
110
- connection.stub(:execute).
111
- with("SELECT COUNT(*) FROM posts WHERE ? = ?", :blog_id, 1).
112
- and_return result_stub('count' => 3)
113
- connection.stub(:execute).
114
- with("SELECT COUNT(*) FROM posts WHERE ? = ?", :blog_id, 2).
115
- and_return result_stub('count' => 2)
116
-
117
- Post.where(:blog_id => [1, 2]).count.should == 5
118
- end
119
-
120
- it 'should return nil if empty non-key restriction given' do
121
- Post.where(:title => []).count.should == 0
122
- end
123
-
124
- it 'should apply index preference when specified' do
125
- connection.should_receive(:execute).
126
- with("SELECT COUNT(*) FROM assets WHERE ? = ? AND ? = ?", :checksum, 'abcdef', :class_name, 'Photo').
127
- and_return result_stub('count' => 0)
128
- Photo.where(:checksum => 'abcdef').count
129
- end
130
- end
131
-
132
- describe '#find' do
133
- it 'should send scoped query when no block is passed' do
134
- connection.stub(:execute).
135
- with("SELECT ? FROM posts WHERE ? = ? LIMIT 1", [:id, :title], :id, 1).
136
- and_return result_stub(:id => 1, :title => 'Cequel')
137
-
138
- Post.select(:id, :title).find(1).title.should == 'Cequel'
139
- end
140
-
141
- it 'should send scoped query with multiple keys when no block is passed' do
142
- connection.stub(:execute).
143
- with("SELECT ? FROM posts WHERE ? IN (?)", [:id, :title], :id, [1, 2]).
144
- and_return result_stub(
145
- {:id => 1, :title => 'Cequel'},
146
- {:id => 2, :title => 'Cequel 2'}
147
- )
148
-
149
- Post.select(:id, :title).find(1, 2).
150
- map { |post| post.title }.should == ['Cequel', 'Cequel 2']
151
- end
152
-
153
- it 'should delegate to enumerator when block is passed' do
154
- connection.stub(:execute).
155
- with("SELECT ? FROM posts", [:id, :title]).
156
- and_return result_stub(
157
- {:id => 1, :title => 'Cequel'},
158
- {:id => 2, :title => 'Cequel 2'}
159
- )
160
-
161
- Post.select(:id, :title).find { |post| post.id == 2 }.title.
162
- should == 'Cequel 2'
163
- end
164
- end
165
-
166
- describe '#any?' do
167
- it 'if called without block, should return true if COUNT > 0' do
168
- connection.stub(:execute).
169
- with("SELECT COUNT(*) FROM posts WHERE ? = ?", :blog_id, 1).
170
- and_return result_stub('count' => 5)
171
-
172
- Post.where(:blog_id => 1).any?.should be_true
173
- end
174
-
175
- it 'if called without block, should return false if COUNT == 0' do
176
- connection.stub(:execute).
177
- with("SELECT COUNT(*) FROM posts WHERE ? = ?", :blog_id, 1).
178
- and_return result_stub('count' => 0)
179
-
180
- Post.where(:blog_id => 1).any?.should be_false
181
- end
182
-
183
- it 'if called with block should delegate to enumerator' do
184
- connection.stub(:execute).
185
- with("SELECT * FROM posts WHERE ? = ?", :blog_id, 1).
186
- and_return result_stub(
187
- {:id => 1, :title => 'Cequel'},
188
- {:id => 2, :title => 'Cequel 2'}
189
- )
190
-
191
- Post.where(:blog_id => 1).any? { |post| post.id == 1 }.should be_true
192
- Post.where(:blog_id => 1).any? { |post| post.id == 8 }.should be_false
193
- end
194
- end
195
-
196
- describe '#none?' do
197
- it 'if called without block, should return false if COUNT > 0' do
198
- connection.stub(:execute).
199
- with("SELECT COUNT(*) FROM posts WHERE ? = ?", :blog_id, 1).
200
- and_return result_stub('count' => 5)
201
-
202
- Post.where(:blog_id => 1).none?.should be_false
203
- end
204
-
205
- it 'if called without block, should return true if COUNT == 0' do
206
- connection.stub(:execute).
207
- with("SELECT COUNT(*) FROM posts WHERE ? = ?", :blog_id, 1).
208
- and_return result_stub('count' => 0)
209
-
210
- Post.where(:blog_id => 1).none?.should be_true
211
- end
212
-
213
- it 'if called with block should delegate to enumerator' do
214
- connection.stub(:execute).
215
- with("SELECT * FROM posts WHERE ? = ?", :blog_id, 1).
216
- and_return result_stub(
217
- {:id => 1, :title => 'Cequel'},
218
- {:id => 2, :title => 'Cequel 2'}
219
- )
220
-
221
- Post.where(:blog_id => 1).none? { |post| post.id == 1 }.should be_false
222
- Post.where(:blog_id => 1).none? { |post| post.id == 8 }.should be_true
223
- end
224
- end
225
-
226
- describe '#one?' do
227
- it 'if called without block, should return false if COUNT == 0' do
228
- connection.stub(:execute).
229
- with("SELECT COUNT(*) FROM posts WHERE ? = ?", :blog_id, 1).
230
- and_return result_stub('count' => 0)
231
-
232
- Post.where(:blog_id => 1).one?.should be_false
233
- end
234
-
235
- it 'if called without block, should return true if COUNT == 1' do
236
- connection.stub(:execute).
237
- with("SELECT COUNT(*) FROM posts WHERE ? = ?", :blog_id, 1).
238
- and_return result_stub('count' => 1)
239
-
240
- Post.where(:blog_id => 1).one?.should be_true
241
- end
242
-
243
- it 'if called without block, should return false if COUNT > 1' do
244
- connection.stub(:execute).
245
- with("SELECT COUNT(*) FROM posts WHERE ? = ?", :blog_id, 1).
246
- and_return result_stub('count' => 12)
247
-
248
- Post.where(:blog_id => 1).one?.should be_false
249
- end
250
-
251
- it 'if called with block should delegate to enumerator' do
252
- connection.stub(:execute).
253
- with("SELECT * FROM posts WHERE ? = ?", :blog_id, 1).
254
- and_return result_stub(
255
- {:id => 1, :title => 'Cequel'},
256
- {:id => 2, :title => 'Cequel 2'}
257
- )
258
-
259
- Post.where(:blog_id => 1).none? { |post| post.id == 1 }.should be_false
260
- Post.where(:blog_id => 1).none? { |post| post.id == 8 }.should be_true
261
- end
262
- end
263
-
264
- describe '#find_in_batches' do
265
- it 'should select in batches of given size' do
266
- connection.stub(:execute).with("SELECT * FROM posts LIMIT 2").
267
- and_return result_stub(
268
- {:id => 1, :title => 'Post 1'},
269
- {:id => 2, :title => 'Post 2'}
270
- )
271
- connection.stub(:execute).
272
- with("SELECT * FROM posts WHERE ? > ? LIMIT 2", :id, 2).
273
- and_return result_stub(:id => 3, :title => 'Post 3')
274
- batches = []
275
- Post.find_in_batches(:batch_size => 2) do |batch|
276
- batches << batch
277
- end
278
- batches.map { |batch| batch.map(&:title) }.should ==
279
- [['Post 1', 'Post 2'], ['Post 3']]
280
- end
281
-
282
- it 'should not duplicate last key if given back first in next batch' do
283
- connection.stub(:execute).with("SELECT * FROM posts LIMIT 2").
284
- and_return result_stub(
285
- {:id => 1, :title => 'Post 1'},
286
- {:id => 2, :title => 'Post 2'}
287
- )
288
- connection.stub(:execute).
289
- with("SELECT * FROM posts WHERE ? > ? LIMIT 2", :id, 2).
290
- and_return result_stub(
291
- {:id => 2, :title => 'Post 2'},
292
- {:id => 3, :title => 'Post 3'}
293
- )
294
- connection.stub(:execute).
295
- with("SELECT * FROM posts WHERE ? > ? LIMIT 2", :id, 3).
296
- and_return result_stub()
297
- batches = []
298
- Post.find_in_batches(:batch_size => 2) do |batch|
299
- batches << batch
300
- end
301
- batches.map { |batch| batch.map(&:title) }.should ==
302
- [['Post 1', 'Post 2'], ['Post 3']]
303
- end
304
-
305
- it 'should iterate over batches of keys' do
306
- connection.stub(:execute).with("SELECT * FROM posts WHERE ? IN (?)", :id, [1, 2]).
307
- and_return result_stub(
308
- {:id => 1, :title => 'Post 1'},
309
- {:id => 2, :title => 'Post 2'}
310
- )
311
- connection.stub(:execute).
312
- with("SELECT * FROM posts WHERE ? = ?", :id, 3).
313
- and_return result_stub(:id => 3, :title => 'Post 3')
314
- batches = []
315
- Post.where(:id => [1, 2, 3]).find_in_batches(:batch_size => 2) do |batch|
316
- batches << batch
317
- end
318
- batches.map { |batch| batch.map(&:title) }.should ==
319
- [['Post 1', 'Post 2'], ['Post 3']]
320
- end
321
-
322
- it 'should respect scope' do
323
- connection.stub(:execute).with("SELECT ? FROM posts LIMIT 2", [:id, :title]).
324
- and_return result_stub(
325
- {:id => 1, :title => 'Post 1'},
326
- {:id => 2, :title => 'Post 2'}
327
- )
328
- connection.stub(:execute).
329
- with("SELECT ? FROM posts WHERE ? > ? LIMIT 2", [:id, :title], :id, 2).
330
- and_return result_stub(:id => 3, :title => 'Post 3')
331
- batches = []
332
- Post.select(:id, :title).find_in_batches(:batch_size => 2) do |batch|
333
- batches << batch
334
- end
335
- batches.map { |batch| batch.map(&:title) }.should ==
336
- [['Post 1', 'Post 2'], ['Post 3']]
337
- end
338
-
339
- it 'should add key column to SELECT if omitted' do
340
- connection.stub(:execute).with("SELECT ? FROM posts LIMIT 2", [:title, :id]).
341
- and_return result_stub(
342
- {:id => 1, :title => 'Post 1'},
343
- {:id => 2, :title => 'Post 2'}
344
- )
345
- connection.stub(:execute).
346
- with("SELECT ? FROM posts WHERE ? > ? LIMIT 2", [:title, :id], :id, 2).
347
- and_return result_stub(:id => 3, :title => 'Post 3')
348
- batches = []
349
- Post.select(:title).find_in_batches(:batch_size => 2) do |batch|
350
- batches << batch
351
- end
352
- batches.map { |batch| batch.map(&:title) }.should ==
353
- [['Post 1', 'Post 2'], ['Post 3']]
354
- end
355
- end
356
-
357
- describe '#find_each' do
358
- it 'should iterate over batches and yield results one by one' do
359
- connection.stub(:execute).with("SELECT * FROM posts LIMIT 2").
360
- and_return result_stub(
361
- {:id => 1, :title => 'Post 1'},
362
- {:id => 2, :title => 'Post 2'}
363
- )
364
- connection.stub(:execute).
365
- with("SELECT * FROM posts WHERE ? > ? LIMIT 2", :id, 2).
366
- and_return result_stub(:id => 3, :title => 'Post 3')
367
- Post.find_each(:batch_size => 2).map { |post| post.title }.
368
- should == ['Post 1', 'Post 2', 'Post 3']
369
- end
370
- end
371
-
372
- describe '#select' do
373
- it 'should scope columns in data set' do
374
- connection.stub(:execute).with("SELECT ? FROM posts", [:id, :title]).
375
- and_return result_stub(:id => 1, :title => 'Cequel')
376
-
377
- Post.select(:id, :title).map { |post| post.title }.should == ['Cequel']
378
- end
379
-
380
- it 'should fail fast if attempting to select only key column with restrictions on key column' do
381
- expect { Post.where(:id => 1).select(:id) }.
382
- to raise_error(Cequel::Model::InvalidQuery)
383
- end
384
-
385
- it 'should delegate to enumerator if block given' do
386
- connection.stub(:execute).
387
- with("SELECT * FROM posts WHERE ? = ?", :blog_id, 1).
388
- and_return result_stub(
389
- {:id => 1, :title => 'Cequel'},
390
- {:id => 2, :title => 'Cequel 2'},
391
- {:id => 3, :title => 'Cequel 3'}
392
- )
393
-
394
- Post.where(:blog_id => 1).select { |post| post.id < 3 }.
395
- map { |post| post.title }.should == ['Cequel', 'Cequel 2']
396
- end
397
- end
398
-
399
- describe '#select!' do
400
- it 'should override previous columns in data set' do
401
- connection.stub(:execute).with("SELECT ? FROM posts", [:id, :published]).
402
- and_return result_stub(:id => 1, :published => true)
403
-
404
- Post.select(:id, :title).select!(:id, :published).
405
- map { |post| post.published }.should == [true]
406
- end
407
- end
408
-
409
- describe '#consistency' do
410
- it 'should scope consistency in data set' do
411
- connection.stub(:execute).with("SELECT * FROM posts USING CONSISTENCY QUORUM").
412
- and_return result_stub(:id => 1, :title => 'Cequel')
413
-
414
- Post.consistency(:quorum).map { |post| post.title }.should == ['Cequel']
415
- end
416
- end
417
-
418
- describe '#where' do
419
- it 'should scope to row specifications in data set' do
420
- connection.stub(:execute).with("SELECT * FROM posts WHERE ? = ?", :id, 1).
421
- and_return result_stub(:id => 1, :title => 'Cequel')
422
-
423
- Post.where(:id => 1).map { |post| post.title }.should == ['Cequel']
424
- end
425
-
426
- it 'should perform multiple queries if IN query performed on non-key column' do
427
- connection.stub(:execute).with("SELECT * FROM posts WHERE ? = ?", :title, 'Cequel').
428
- and_return result_stub(:id => 1, :title => 'Cequel')
429
- connection.stub(:execute).with("SELECT * FROM posts WHERE ? = ?", :title, 'Fun').
430
- and_return result_stub(
431
- {:id => 2, :title => 'Fun'},
432
- {:id => 3, :title => 'Fun'}
433
- )
434
- Post.where(:title => %w(Cequel Fun)).map(&:id).
435
- should == [1, 2, 3]
436
- end
437
-
438
- it 'should fail fast if attempting to select only key column with restrictions on key column' do
439
- expect { Post.select(:id).where(:id => 1) }.
440
- to raise_error(Cequel::Model::InvalidQuery)
441
- end
442
-
443
- it 'should fail fast if attempting to mix key and non-key columns' do
444
- expect { Post.where(:id => 1).where(:title => 'Cequel') }.
445
- to raise_error(Cequel::Model::InvalidQuery)
446
- end
447
-
448
- it 'should use index preference if given' do
449
- connection.should_receive(:execute).
450
- with("SELECT * FROM assets WHERE ? = ? AND ? = ?", :checksum, 'abcdef', :class_name, 'Photo').
451
- and_return result_stub
452
- Photo.where(:checksum => 'abcdef').to_a
453
- end
454
- end
455
-
456
- describe '#where!' do
457
- it 'should override previously chained row specifications' do
458
- connection.stub(:execute).with("SELECT * FROM posts WHERE ? = ?", :title, 'Cequel').
459
- and_return result_stub(:id => 1, :title => 'Cequel')
460
-
461
- Post.where(:id => 1).where!(:title => 'Cequel').
462
- map { |post| post.title }.should == ['Cequel']
463
- end
464
- end
465
-
466
- describe '#limit' do
467
- it 'should limit results in data set' do
468
- connection.stub(:execute).with("SELECT * FROM posts LIMIT 5").
469
- and_return result_stub(:id => 1, :title => 'Cequel')
470
-
471
- Post.limit(5).map { |post| post.title }.should == ['Cequel']
472
- end
473
- end
474
-
475
- describe 'chaining' do
476
- it 'should aggregate scopes' do
477
- connection.stub(:execute).
478
- with("SELECT ? FROM posts USING CONSISTENCY QUORUM WHERE ? = ? LIMIT 5", [:id, :title], :blog_id, 1).
479
- and_return result_stub(:id => 1, :title => 'Cequel')
480
-
481
- Post.select(:id, :title).
482
- consistency(:quorum).
483
- where(:blog_id => 1).
484
- limit(5).
485
- map { |post| post.title }.should == ['Cequel']
486
- end
487
-
488
- it 'should delegate unknown methods to the underlying class with self as current scope' do
489
- connection.stub(:execute).
490
- with("SELECT ? FROM posts USING CONSISTENCY QUORUM WHERE ? = ? LIMIT 5", [:id, :title], :blog_id, 1).
491
- and_return result_stub(:id => 1, :title => 'Cequel')
492
-
493
- Post.select(:id, :title).
494
- consistency(:quorum).
495
- for_blog(1).
496
- limit(5).
497
- map { |post| post.title }.should == ['Cequel']
498
- end
499
-
500
- end
501
-
502
- describe '#update_all' do
503
- context 'with no scope restrictions' do
504
- let(:scope) { Post }
505
-
506
- it 'should get all keys and then update htem' do
507
- connection.should_receive(:execute).
508
- with("SELECT ? FROM posts", [:id]).
509
- and_return result_stub(
510
- {:id => 1},
511
- {:id => 2}
512
- )
513
- connection.should_receive(:execute).
514
- with "UPDATE posts SET ? = ? WHERE ? IN (?)", :title, 'Cequel', :id, [1, 2]
515
- scope.update_all(:title => 'Cequel')
516
- end
517
- end
518
-
519
- context 'with scope selecting on ids' do
520
- let(:scope) { Post.where(:id => [1, 2]) }
521
-
522
- it 'should issue scoped update request' do
523
- connection.should_receive(:execute).
524
- with "UPDATE posts SET ? = ? WHERE ? IN (?)", :title, 'Cequel', :id, [1, 2]
525
- scope.update_all(:title => 'Cequel')
526
- end
527
-
528
- end
529
-
530
- context 'with scope selecting on non-IDs' do
531
- let(:scope) { Post.where(:published => false) }
532
-
533
- it 'should perform "subquery" and issue update' do
534
- connection.stub(:execute).
535
- with("SELECT ? FROM posts WHERE ? = ?", [:id], :published, false).
536
- and_return result_stub({:id => 1}, {:id => 2})
537
-
538
- connection.should_receive(:execute).
539
- with "UPDATE posts SET ? = ? WHERE ? IN (?)", :title, 'Cequel', :id, [1, 2]
540
-
541
- scope.update_all(:title => 'Cequel')
542
- end
543
- end
544
-
545
- context 'with scope selecting multiple values on non-key column' do
546
- let(:scope) { Post.where(:title => %w(Cequel Cassandra)) }
547
-
548
- it 'should perform multiple subqueries and execute single update on returned keys' do
549
- connection.stub(:execute).
550
- with("SELECT ? FROM posts WHERE ? = ?", [:id], :title, 'Cequel').
551
- and_return result_stub({:id => 1}, {:id => 2})
552
-
553
- connection.stub(:execute).
554
- with("SELECT ? FROM posts WHERE ? = ?", [:id], :title, 'Cassandra').
555
- and_return result_stub({:id => 3}, {:id => 4})
556
-
557
- connection.should_receive(:execute).
558
- with "UPDATE posts SET ? = ? WHERE ? IN (?)", :published, true, :id, [1, 2, 3, 4]
559
-
560
- scope.update_all(:published => true)
561
- end
562
- end
563
- end
564
-
565
- describe '#destroy_all' do
566
- context 'with no scope restrictions' do
567
- let(:scope) { Post }
568
-
569
- it 'should destroy all instances' do
570
- connection.should_receive(:execute).
571
- with('SELECT * FROM posts').
572
- and_return result_stub(
573
- {'id' => 1, 'title' => 'Cequel'},
574
- {'id' => 2, 'title' => 'Cassandra'}
575
- )
576
- connection.should_receive(:execute).
577
- with "DELETE FROM posts WHERE ? = ?", :id, 1
578
- connection.should_receive(:execute).
579
- with "DELETE FROM posts WHERE ? = ?", :id, 2
580
- scope.destroy_all
581
- end
582
- end
583
-
584
- context 'with column restrictions' do
585
- let(:scope) { Post.where(:id => [1, 2]) }
586
-
587
- it 'should issue scoped update request' do
588
- connection.should_receive(:execute).
589
- with("SELECT * FROM posts WHERE ? IN (?)", :id, [1, 2]).
590
- and_return result_stub(
591
- {'id' => 1, 'title' => 'Cequel'},
592
- {'id' => 2, 'title' => 'Cassandra'}
593
- )
594
- connection.should_receive(:execute).
595
- with "DELETE FROM posts WHERE ? = ?", :id, 1
596
- connection.should_receive(:execute).
597
- with "DELETE FROM posts WHERE ? = ?", :id, 2
598
- scope.destroy_all
599
- end
600
-
601
- end
602
- end
603
-
604
- describe '#delete_all' do
605
- context 'with no scope restrictions' do
606
- let(:scope) { Post }
607
-
608
- it 'should truncate keyspace' do
609
- connection.should_receive(:execute).
610
- with "TRUNCATE posts"
611
- Post.delete_all
612
- end
613
- end
614
-
615
- context 'with scope selecting on ids' do
616
- let(:scope) { Post.where(:id => [1, 2]) }
617
-
618
- it 'should issue scoped delete request' do
619
- connection.should_receive(:execute).
620
- with "DELETE FROM posts WHERE ? IN (?)", :id, [1, 2]
621
- scope.delete_all
622
- end
623
-
624
- end
625
-
626
- context 'with scope selecting on non-IDs' do
627
- let(:scope) { Post.where(:published => false) }
628
-
629
- it 'should perform "subquery" and issue update' do
630
- connection.stub(:execute).
631
- with("SELECT ? FROM posts WHERE ? = ?", [:id], :published, false).
632
- and_return result_stub({:id => 1}, {:id => 2})
633
-
634
- connection.should_receive(:execute).
635
- with "DELETE FROM posts WHERE ? IN (?)", :id, [1, 2]
636
-
637
- scope.delete_all
638
- end
639
- end
640
-
641
- context 'with scope selecting multiple values on non-key column' do
642
- let(:scope) { Post.where(:title => %w(Cequel Cassandra)) }
643
-
644
- it 'should perform multiple subqueries and execute single update on returned keys' do
645
- connection.stub(:execute).
646
- with("SELECT ? FROM posts WHERE ? = ?", [:id], :title, 'Cequel').
647
- and_return result_stub({:id => 1}, {:id => 2})
648
-
649
- connection.stub(:execute).
650
- with("SELECT ? FROM posts WHERE ? = ?", [:id], :title, 'Cassandra').
651
- and_return result_stub({:id => 3}, {:id => 4})
652
-
653
- connection.should_receive(:execute).
654
- with "DELETE FROM posts WHERE ? IN (?)", :id, [1, 2, 3, 4]
655
-
656
- scope.delete_all
657
- end
658
- end
659
- end
660
-
661
- describe '::default_scope' do
662
- it 'should include in scope by default' do
663
- connection.should_receive(:execute).
664
- with("SELECT * FROM blogs LIMIT 100").and_return result_stub
665
-
666
- Blog.all.to_a
667
- end
668
-
669
- it 'should override as with normal scope' do
670
- connection.should_receive(:execute).
671
- with("SELECT * FROM blogs LIMIT 1000").and_return result_stub
672
-
673
- Blog.limit(1000).to_a
674
- end
675
- end
676
-
677
- end