cequel 1.0.0.pre.4 → 1.0.0.pre.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/cequel/errors.rb +1 -0
- data/lib/cequel/record.rb +1 -0
- data/lib/cequel/record/bound.rb +101 -0
- data/lib/cequel/record/collection.rb +34 -8
- data/lib/cequel/record/persistence.rb +23 -3
- data/lib/cequel/record/properties.rb +8 -10
- data/lib/cequel/record/record_set.rb +55 -37
- data/lib/cequel/schema/column.rb +4 -0
- data/lib/cequel/schema/table_reader.rb +3 -3
- data/lib/cequel/type.rb +23 -17
- data/lib/cequel/version.rb +1 -1
- data/spec/examples/record/list_spec.rb +51 -0
- data/spec/examples/record/map_spec.rb +57 -0
- data/spec/examples/record/persistence_spec.rb +64 -0
- data/spec/examples/record/properties_spec.rb +19 -5
- data/spec/examples/record/record_set_spec.rb +126 -9
- data/spec/examples/record/schema_spec.rb +4 -0
- data/spec/examples/record/set_spec.rb +29 -0
- data/spec/examples/schema/table_reader_spec.rb +2 -2
- data/spec/support/helpers.rb +18 -0
- metadata +3 -2
data/lib/cequel/schema/column.rb
CHANGED
@@ -57,7 +57,7 @@ module Cequel
|
|
57
57
|
unless comparators
|
58
58
|
table.compact_storage = true
|
59
59
|
return unless column_data.empty?
|
60
|
-
column_aliases <<
|
60
|
+
column_aliases << :column1 if column_aliases.empty?
|
61
61
|
comparators = [table_data['comparator']]
|
62
62
|
end
|
63
63
|
column_aliases.zip(comparators) do |column_alias, type|
|
@@ -66,7 +66,7 @@ module Cequel
|
|
66
66
|
clustering_order = :desc
|
67
67
|
end
|
68
68
|
table.add_clustering_column(
|
69
|
-
column_alias.
|
69
|
+
column_alias.to_sym,
|
70
70
|
Type.lookup_internal(type),
|
71
71
|
clustering_order
|
72
72
|
)
|
@@ -76,7 +76,7 @@ module Cequel
|
|
76
76
|
def read_data_columns
|
77
77
|
if column_data.empty?
|
78
78
|
table.add_data_column(
|
79
|
-
table_data['value_alias'],
|
79
|
+
(table_data['value_alias'] || :value).to_sym,
|
80
80
|
Type.lookup_internal(table_data['default_validator']),
|
81
81
|
false
|
82
82
|
)
|
data/lib/cequel/type.rb
CHANGED
@@ -58,18 +58,18 @@ module Cequel
|
|
58
58
|
|
59
59
|
class String < Base
|
60
60
|
|
61
|
-
|
62
|
-
|
63
|
-
def ensure_encoding(value, encoding)
|
64
|
-
str = value.to_s
|
61
|
+
def cast(value)
|
62
|
+
str = String(value)
|
65
63
|
str.encoding.name == encoding ? str : str.dup.force_encoding(encoding)
|
66
64
|
end
|
67
65
|
|
68
66
|
end
|
69
67
|
|
70
68
|
class Ascii < String
|
71
|
-
|
72
|
-
|
69
|
+
private
|
70
|
+
|
71
|
+
def encoding
|
72
|
+
'US-ASCII'
|
73
73
|
end
|
74
74
|
end
|
75
75
|
register Ascii.instance
|
@@ -81,10 +81,14 @@ module Cequel
|
|
81
81
|
end
|
82
82
|
|
83
83
|
def cast(value)
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
84
|
+
value = value.to_s(16) if Integer === value
|
85
|
+
super
|
86
|
+
end
|
87
|
+
|
88
|
+
private
|
89
|
+
|
90
|
+
def encoding
|
91
|
+
'ASCII-8BIT'
|
88
92
|
end
|
89
93
|
|
90
94
|
end
|
@@ -104,7 +108,7 @@ module Cequel
|
|
104
108
|
end
|
105
109
|
|
106
110
|
def cast(value)
|
107
|
-
value
|
111
|
+
Integer(value)
|
108
112
|
end
|
109
113
|
|
110
114
|
end
|
@@ -112,14 +116,14 @@ module Cequel
|
|
112
116
|
|
113
117
|
class Decimal < Base
|
114
118
|
def cast(value)
|
115
|
-
BigDecimal.new(value, 0)
|
119
|
+
BigDecimal === value ? value : BigDecimal.new(value, 0)
|
116
120
|
end
|
117
121
|
end
|
118
122
|
register Decimal.instance
|
119
123
|
|
120
124
|
class Double < Base
|
121
125
|
def cast(value)
|
122
|
-
value
|
126
|
+
Float(value)
|
123
127
|
end
|
124
128
|
end
|
125
129
|
register Double.instance
|
@@ -140,7 +144,7 @@ module Cequel
|
|
140
144
|
end
|
141
145
|
|
142
146
|
def cast(value)
|
143
|
-
value
|
147
|
+
Integer(value)
|
144
148
|
end
|
145
149
|
|
146
150
|
end
|
@@ -168,8 +172,10 @@ module Cequel
|
|
168
172
|
[:varchar]
|
169
173
|
end
|
170
174
|
|
171
|
-
|
172
|
-
|
175
|
+
private
|
176
|
+
|
177
|
+
def encoding
|
178
|
+
'UTF-8'
|
173
179
|
end
|
174
180
|
|
175
181
|
end
|
@@ -186,7 +192,7 @@ module Cequel
|
|
186
192
|
elsif value.respond_to?(:to_time) then value.to_time
|
187
193
|
elsif Numeric === value then Time.at(value)
|
188
194
|
else Time.parse(value.to_s)
|
189
|
-
end
|
195
|
+
end.utc
|
190
196
|
end
|
191
197
|
|
192
198
|
end
|
data/lib/cequel/version.rb
CHANGED
@@ -5,6 +5,7 @@ describe Cequel::Record::List do
|
|
5
5
|
key :permalink, :text
|
6
6
|
column :title, :text
|
7
7
|
list :tags, :text
|
8
|
+
list :contributor_ids, :int
|
8
9
|
end
|
9
10
|
|
10
11
|
let(:scope) { cequel[:posts].where(:permalink => 'cequel') }
|
@@ -14,6 +15,7 @@ describe Cequel::Record::List do
|
|
14
15
|
Post.new do |post|
|
15
16
|
post.permalink = 'cequel'
|
16
17
|
post.tags = %w(one two)
|
18
|
+
post.contributor_ids = [1, 2]
|
17
19
|
end.tap(&:save)
|
18
20
|
end
|
19
21
|
|
@@ -27,6 +29,20 @@ describe Cequel::Record::List do
|
|
27
29
|
end
|
28
30
|
end
|
29
31
|
|
32
|
+
context 'updating' do
|
33
|
+
it 'should overwrite value' do
|
34
|
+
post.tags = %w(three four)
|
35
|
+
post.save!
|
36
|
+
subject[:tags].should == %w(three four)
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'should cast collection before overwriting' do
|
40
|
+
post.tags = Set['three', 'four']
|
41
|
+
post.save!
|
42
|
+
subject[:tags].should == %w(three four)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
30
46
|
describe '#<<' do
|
31
47
|
it 'should add new items' do
|
32
48
|
post.tags << 'three' << 'four'
|
@@ -52,6 +68,11 @@ describe Cequel::Record::List do
|
|
52
68
|
unloaded_post.tags << 'four' << 'five'
|
53
69
|
unloaded_post.tags.should == %w(one two four five)
|
54
70
|
end
|
71
|
+
|
72
|
+
it 'should cast to defined value' do
|
73
|
+
post.contributor_ids << '3' << 4.0
|
74
|
+
post.contributor_ids.should == [1, 2, 3, 4]
|
75
|
+
end
|
55
76
|
end
|
56
77
|
|
57
78
|
describe '#[]=' do
|
@@ -64,6 +85,11 @@ describe Cequel::Record::List do
|
|
64
85
|
post.tags.should == %w(one TWO)
|
65
86
|
end
|
66
87
|
|
88
|
+
it 'should cast element before replacing' do
|
89
|
+
post.contributor_ids[1] = '5'
|
90
|
+
post.contributor_ids.should == [1, 5]
|
91
|
+
end
|
92
|
+
|
67
93
|
it 'should replace an element without reading' do
|
68
94
|
cequel.should_not_receive :execute
|
69
95
|
unloaded_post.tags[1] = 'TWO'
|
@@ -87,6 +113,11 @@ describe Cequel::Record::List do
|
|
87
113
|
post.tags.should == %w(One Two)
|
88
114
|
end
|
89
115
|
|
116
|
+
it 'should cast multiple elements before replacing them' do
|
117
|
+
post.contributor_ids[0, 2] = %w(4 5)
|
118
|
+
post.contributor_ids.should == [4, 5]
|
119
|
+
end
|
120
|
+
|
90
121
|
it 'should remove elements beyond positional arguments' do
|
91
122
|
scope.list_append(:tags, 'four')
|
92
123
|
post.tags[0, 3] = 'ONE'
|
@@ -151,6 +182,11 @@ describe Cequel::Record::List do
|
|
151
182
|
post.tags.should == %w(one two four five)
|
152
183
|
end
|
153
184
|
|
185
|
+
it 'should cast elements before concatentating' do
|
186
|
+
post.contributor_ids.concat(%w(3 4))
|
187
|
+
post.contributor_ids.should == [1, 2, 3, 4]
|
188
|
+
end
|
189
|
+
|
154
190
|
it 'should concat elements without loading' do
|
155
191
|
cequel.should_not_receive :execute
|
156
192
|
unloaded_post.tags.concat(['four', 'five'])
|
@@ -178,6 +214,11 @@ describe Cequel::Record::List do
|
|
178
214
|
post.tags.should == %w(one)
|
179
215
|
end
|
180
216
|
|
217
|
+
it 'should cast argument' do
|
218
|
+
post.contributor_ids.delete('2')
|
219
|
+
post.contributor_ids.should == [1]
|
220
|
+
end
|
221
|
+
|
181
222
|
it 'should delete without loading' do
|
182
223
|
cequel.should_not_receive :execute
|
183
224
|
unloaded_post.tags.delete('two')
|
@@ -292,6 +333,11 @@ describe Cequel::Record::List do
|
|
292
333
|
post.tags.should == %w(four five)
|
293
334
|
end
|
294
335
|
|
336
|
+
it 'should cast before overwriting' do
|
337
|
+
post.contributor_ids.replace(%w(3 4 5))
|
338
|
+
post.contributor_ids.should == [3, 4, 5]
|
339
|
+
end
|
340
|
+
|
295
341
|
it 'should overwrite without reading' do
|
296
342
|
cequel.should_not_receive :execute
|
297
343
|
unloaded_post.tags.replace(%w(four five))
|
@@ -374,6 +420,11 @@ describe Cequel::Record::List do
|
|
374
420
|
post.tags.should == %w(minustwo minusone one two)
|
375
421
|
end
|
376
422
|
|
423
|
+
it 'should cast element before unshifting' do
|
424
|
+
post.contributor_ids.unshift('0')
|
425
|
+
post.contributor_ids.should == [0, 1, 2]
|
426
|
+
end
|
427
|
+
|
377
428
|
it 'should unshift without reading' do
|
378
429
|
cequel.should_not_receive :execute
|
379
430
|
unloaded_post.tags.unshift('minustwo', 'minusone')
|
@@ -27,6 +27,20 @@ describe Cequel::Record::Map do
|
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
|
+
context 'updating' do
|
31
|
+
it 'should overwrite value' do
|
32
|
+
post.likes = {'charlotte' => 3, 'dave' => 4}
|
33
|
+
post.save!
|
34
|
+
subject[:likes].should == {'charlotte' => 3, 'dave' => 4}
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'should cast collection before overwriting' do
|
38
|
+
post.likes = [['charlotte', 3], ['dave', 4]]
|
39
|
+
post.save!
|
40
|
+
subject[:likes].should == {'charlotte' => 3, 'dave' => 4}
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
30
44
|
describe 'atomic modification' do
|
31
45
|
before { scope.map_update(:likes, 'charles' => 3) }
|
32
46
|
|
@@ -39,6 +53,16 @@ describe Cequel::Record::Map do
|
|
39
53
|
post.likes.should == {'alice' => 1, 'bob' => 2, 'david' => 4}
|
40
54
|
end
|
41
55
|
|
56
|
+
it 'should cast keys when updating' do
|
57
|
+
post.likes[:david] = 4
|
58
|
+
post.likes.should == {'alice' => 1, 'bob' => 2, 'david' => 4}
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'should cast values when updating' do
|
62
|
+
post.likes['david'] = 4.0
|
63
|
+
post.likes.should == {'alice' => 1, 'bob' => 2, 'david' => 4}
|
64
|
+
end
|
65
|
+
|
42
66
|
it 'should write without reading' do
|
43
67
|
max_statements! 2
|
44
68
|
unloaded_post.likes['david'] = 4
|
@@ -83,6 +107,11 @@ describe Cequel::Record::Map do
|
|
83
107
|
post.likes.should == {'alice' => 1}
|
84
108
|
end
|
85
109
|
|
110
|
+
it 'should cast key before deleting' do
|
111
|
+
post.likes.delete(:bob)
|
112
|
+
post.likes.should == {'alice' => 1}
|
113
|
+
end
|
114
|
+
|
86
115
|
it 'should delete without reading' do
|
87
116
|
max_statements! 2
|
88
117
|
unloaded_post.likes.delete('bob')
|
@@ -106,6 +135,22 @@ describe Cequel::Record::Map do
|
|
106
135
|
{'alice' => 1, 'bob' => 2, 'david' => 4, 'emily' => 5}
|
107
136
|
end
|
108
137
|
|
138
|
+
it 'should cast keys before updating' do
|
139
|
+
post.likes.merge!(david: 4, emily: 5)
|
140
|
+
post.save
|
141
|
+
post.likes.should ==
|
142
|
+
{'alice' => 1, 'bob' => 2, 'david' => 4, 'emily' => 5}
|
143
|
+
end
|
144
|
+
|
145
|
+
it 'should cast values before updating' do
|
146
|
+
post.likes.merge!('david' => '4', 'emily' => 5.0)
|
147
|
+
post.save
|
148
|
+
subject[:likes].should ==
|
149
|
+
{'alice' => 1, 'bob' => 2, 'charles' => 3, 'david' => 4, 'emily' => 5}
|
150
|
+
post.likes.should ==
|
151
|
+
{'alice' => 1, 'bob' => 2, 'david' => 4, 'emily' => 5}
|
152
|
+
end
|
153
|
+
|
109
154
|
it 'should write without reading' do
|
110
155
|
max_statements! 2
|
111
156
|
unloaded_post.likes.merge!('david' => 4, 'emily' => 5)
|
@@ -129,6 +174,18 @@ describe Cequel::Record::Map do
|
|
129
174
|
post.likes.should == {'david' => 4, 'emily' => 5}
|
130
175
|
end
|
131
176
|
|
177
|
+
it 'should cast keys before overwriting' do
|
178
|
+
post.likes.replace(david: 4, emily: 5)
|
179
|
+
post.likes.should == {'david' => 4, 'emily' => 5}
|
180
|
+
end
|
181
|
+
|
182
|
+
it 'should cast values before overwriting' do
|
183
|
+
post.likes.replace('david' => '4', 'emily' => 5.0)
|
184
|
+
post.save
|
185
|
+
subject[:likes].should == {'david' => 4, 'emily' => 5}
|
186
|
+
post.likes.should == {'david' => 4, 'emily' => 5}
|
187
|
+
end
|
188
|
+
|
132
189
|
it 'should overwrite without reading' do
|
133
190
|
max_statements! 2
|
134
191
|
unloaded_post.likes.replace('david' => 4, 'emily' => 5)
|
@@ -36,6 +36,12 @@ describe Cequel::Record::Persistence do
|
|
36
36
|
it 'should mark row persisted' do
|
37
37
|
blog.should be_persisted
|
38
38
|
end
|
39
|
+
|
40
|
+
it 'should fail fast if keys are missing' do
|
41
|
+
expect {
|
42
|
+
Blog.new.save
|
43
|
+
}.to raise_error(Cequel::MissingKeyError)
|
44
|
+
end
|
39
45
|
end
|
40
46
|
|
41
47
|
context 'on update' do
|
@@ -59,6 +65,13 @@ describe Cequel::Record::Persistence do
|
|
59
65
|
it 'should remove old column values' do
|
60
66
|
subject[:description].should be_nil
|
61
67
|
end
|
68
|
+
|
69
|
+
it 'should not allow changing key values' do
|
70
|
+
expect {
|
71
|
+
blog.subdomain = 'soup'
|
72
|
+
blog.save
|
73
|
+
}.to raise_error(ArgumentError)
|
74
|
+
end
|
62
75
|
end
|
63
76
|
end
|
64
77
|
|
@@ -80,6 +93,14 @@ describe Cequel::Record::Persistence do
|
|
80
93
|
it 'should save instance' do
|
81
94
|
Blog.find(blog.subdomain).name.should == 'Big Data'
|
82
95
|
end
|
96
|
+
|
97
|
+
it 'should fail fast if keys are missing' do
|
98
|
+
expect {
|
99
|
+
Blog.create do |blog|
|
100
|
+
blog.name = 'Big Data'
|
101
|
+
end
|
102
|
+
}.to raise_error(Cequel::MissingKeyError)
|
103
|
+
end
|
83
104
|
end
|
84
105
|
|
85
106
|
describe 'with attributes' do
|
@@ -94,6 +115,12 @@ describe Cequel::Record::Persistence do
|
|
94
115
|
it 'should save instance' do
|
95
116
|
Blog.find(blog.subdomain).name.should == 'Big Data'
|
96
117
|
end
|
118
|
+
|
119
|
+
it 'should fail fast if keys are missing' do
|
120
|
+
expect {
|
121
|
+
Blog.create(:name => 'Big Data')
|
122
|
+
}.to raise_error(Cequel::MissingKeyError)
|
123
|
+
end
|
97
124
|
end
|
98
125
|
end
|
99
126
|
|
@@ -111,6 +138,11 @@ describe Cequel::Record::Persistence do
|
|
111
138
|
it 'should save instance' do
|
112
139
|
Blog.find(blog.subdomain).name.should == 'The Big Data Blog'
|
113
140
|
end
|
141
|
+
|
142
|
+
it 'should not allow updating key values' do
|
143
|
+
expect { blog.update_attributes(:subdomain => 'soup') }
|
144
|
+
.to raise_error(ArgumentError)
|
145
|
+
end
|
114
146
|
end
|
115
147
|
|
116
148
|
describe '#destroy' do
|
@@ -150,6 +182,24 @@ describe Cequel::Record::Persistence do
|
|
150
182
|
it 'should mark row persisted' do
|
151
183
|
post.should be_persisted
|
152
184
|
end
|
185
|
+
|
186
|
+
it 'should fail fast if parent keys are missing' do
|
187
|
+
expect {
|
188
|
+
Post.new do |post|
|
189
|
+
post.permalink = 'cequel'
|
190
|
+
post.title = 'Cequel'
|
191
|
+
end.tap(&:save)
|
192
|
+
}.to raise_error(Cequel::MissingKeyError)
|
193
|
+
end
|
194
|
+
|
195
|
+
it 'should fail fast if row keys are missing' do
|
196
|
+
expect {
|
197
|
+
Post.new do |post|
|
198
|
+
post.blog_subdomain = 'cassandra'
|
199
|
+
post.title = 'Cequel'
|
200
|
+
end.tap(&:save)
|
201
|
+
}.to raise_error(Cequel::MissingKeyError)
|
202
|
+
end
|
153
203
|
end
|
154
204
|
|
155
205
|
context 'on update' do
|
@@ -173,6 +223,20 @@ describe Cequel::Record::Persistence do
|
|
173
223
|
it 'should remove old column values' do
|
174
224
|
subject[:body].should be_nil
|
175
225
|
end
|
226
|
+
|
227
|
+
it 'should not allow changing parent key values' do
|
228
|
+
expect {
|
229
|
+
post.blog_subdomain = 'soup'
|
230
|
+
post.save
|
231
|
+
}.to raise_error(ArgumentError)
|
232
|
+
end
|
233
|
+
|
234
|
+
it 'should not allow changing row key values' do
|
235
|
+
expect {
|
236
|
+
post.permalink = 'soup-recipes'
|
237
|
+
post.save
|
238
|
+
}.to raise_error(ArgumentError)
|
239
|
+
end
|
176
240
|
end
|
177
241
|
end
|
178
242
|
|