cequel 0.5.6 → 1.0.0.pre.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.
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