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.
@@ -18,6 +18,10 @@ module Cequel
18
18
  false
19
19
  end
20
20
 
21
+ def type?(type_in)
22
+ type.is_a?(type_in)
23
+ end
24
+
21
25
  def clustering_column?
22
26
  false
23
27
  end
@@ -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 << nil if column_aliases.empty?
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.try(:to_sym),
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
- private
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
- def cast(value)
72
- ensure_encoding(value, 'US-ASCII')
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
- case value
85
- when Integer then ensure_encoding(value.to_s(16), 'ASCII-8BIT')
86
- else ensure_encoding(value.to_s, 'ASCII-8BIT')
87
- end
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.to_i
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.to_f
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.to_i
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
- def cast(value)
172
- ensure_encoding(value, 'UTF-8')
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
@@ -1,3 +1,3 @@
1
1
  module Cequel
2
- VERSION = '1.0.0.pre.4'
2
+ VERSION = '1.0.0.pre.5'
3
3
  end
@@ -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