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.
- checksums.yaml +7 -0
- data/lib/cequel.rb +5 -8
- data/lib/cequel/errors.rb +1 -0
- data/lib/cequel/metal.rb +17 -0
- data/lib/cequel/metal/batch.rb +62 -0
- data/lib/cequel/metal/cql_row_specification.rb +26 -0
- data/lib/cequel/metal/data_set.rb +461 -0
- data/lib/cequel/metal/deleter.rb +47 -0
- data/lib/cequel/metal/incrementer.rb +35 -0
- data/lib/cequel/metal/inserter.rb +53 -0
- data/lib/cequel/metal/keyspace.rb +213 -0
- data/lib/cequel/metal/row.rb +48 -0
- data/lib/cequel/metal/row_specification.rb +37 -0
- data/lib/cequel/metal/statement.rb +30 -0
- data/lib/cequel/metal/updater.rb +65 -0
- data/lib/cequel/metal/writer.rb +73 -0
- data/lib/cequel/model.rb +12 -84
- data/lib/cequel/model/association_collection.rb +23 -0
- data/lib/cequel/model/associations.rb +84 -80
- data/lib/cequel/model/base.rb +74 -0
- data/lib/cequel/model/belongs_to_association.rb +31 -0
- data/lib/cequel/model/callbacks.rb +14 -10
- data/lib/cequel/model/collection.rb +255 -0
- data/lib/cequel/model/errors.rb +6 -6
- data/lib/cequel/model/has_many_association.rb +26 -0
- data/lib/cequel/model/mass_assignment.rb +31 -0
- data/lib/cequel/model/persistence.rb +119 -115
- data/lib/cequel/model/properties.rb +89 -87
- data/lib/cequel/model/railtie.rb +21 -14
- data/lib/cequel/model/record_set.rb +285 -0
- data/lib/cequel/model/schema.rb +33 -0
- data/lib/cequel/model/scoped.rb +5 -48
- data/lib/cequel/model/validations.rb +18 -18
- data/lib/cequel/schema.rb +15 -0
- data/lib/cequel/schema/column.rb +135 -0
- data/lib/cequel/schema/create_table_dsl.rb +56 -0
- data/lib/cequel/schema/keyspace.rb +50 -0
- data/lib/cequel/schema/table.rb +120 -0
- data/lib/cequel/schema/table_property.rb +67 -0
- data/lib/cequel/schema/table_reader.rb +139 -0
- data/lib/cequel/schema/table_synchronizer.rb +114 -0
- data/lib/cequel/schema/table_updater.rb +83 -0
- data/lib/cequel/schema/table_writer.rb +80 -0
- data/lib/cequel/schema/update_table_dsl.rb +60 -0
- data/lib/cequel/type.rb +232 -0
- data/lib/cequel/version.rb +1 -1
- data/spec/environment.rb +5 -1
- data/spec/examples/metal/data_set_spec.rb +608 -0
- data/spec/examples/model/associations_spec.rb +84 -74
- data/spec/examples/model/callbacks_spec.rb +66 -59
- data/spec/examples/model/list_spec.rb +393 -0
- data/spec/examples/model/map_spec.rb +229 -0
- data/spec/examples/model/mass_assignment_spec.rb +55 -0
- data/spec/examples/model/naming_spec.rb +11 -4
- data/spec/examples/model/persistence_spec.rb +140 -150
- data/spec/examples/model/properties_spec.rb +122 -75
- data/spec/examples/model/record_set_spec.rb +285 -0
- data/spec/examples/model/schema_spec.rb +44 -0
- data/spec/examples/model/serialization_spec.rb +20 -14
- data/spec/examples/model/set_spec.rb +133 -0
- data/spec/examples/model/spec_helper.rb +0 -10
- data/spec/examples/model/validations_spec.rb +51 -38
- data/spec/examples/schema/table_reader_spec.rb +328 -0
- data/spec/examples/schema/table_synchronizer_spec.rb +172 -0
- data/spec/examples/schema/table_updater_spec.rb +157 -0
- data/spec/examples/schema/table_writer_spec.rb +225 -0
- data/spec/examples/spec_helper.rb +29 -0
- data/spec/examples/type_spec.rb +204 -0
- data/spec/support/helpers.rb +67 -8
- metadata +121 -152
- data/lib/cequel/batch.rb +0 -58
- data/lib/cequel/cql_row_specification.rb +0 -22
- data/lib/cequel/data_set.rb +0 -371
- data/lib/cequel/keyspace.rb +0 -205
- data/lib/cequel/model/class_internals.rb +0 -49
- data/lib/cequel/model/column.rb +0 -20
- data/lib/cequel/model/counter.rb +0 -35
- data/lib/cequel/model/dictionary.rb +0 -126
- data/lib/cequel/model/dirty.rb +0 -53
- data/lib/cequel/model/dynamic.rb +0 -31
- data/lib/cequel/model/inheritable.rb +0 -48
- data/lib/cequel/model/instance_internals.rb +0 -23
- data/lib/cequel/model/local_association.rb +0 -42
- data/lib/cequel/model/magic.rb +0 -79
- data/lib/cequel/model/mass_assignment_security.rb +0 -21
- data/lib/cequel/model/naming.rb +0 -17
- data/lib/cequel/model/observer.rb +0 -42
- data/lib/cequel/model/readable_dictionary.rb +0 -182
- data/lib/cequel/model/remote_association.rb +0 -40
- data/lib/cequel/model/scope.rb +0 -362
- data/lib/cequel/model/subclass_internals.rb +0 -45
- data/lib/cequel/model/timestamps.rb +0 -52
- data/lib/cequel/model/translation.rb +0 -17
- data/lib/cequel/row_specification.rb +0 -63
- data/lib/cequel/statement.rb +0 -23
- data/spec/examples/data_set_spec.rb +0 -444
- data/spec/examples/keyspace_spec.rb +0 -84
- data/spec/examples/model/counter_spec.rb +0 -94
- data/spec/examples/model/dictionary_spec.rb +0 -301
- data/spec/examples/model/dirty_spec.rb +0 -39
- data/spec/examples/model/dynamic_spec.rb +0 -41
- data/spec/examples/model/inheritable_spec.rb +0 -45
- data/spec/examples/model/magic_spec.rb +0 -199
- data/spec/examples/model/mass_assignment_security_spec.rb +0 -13
- data/spec/examples/model/observer_spec.rb +0 -86
- data/spec/examples/model/scope_spec.rb +0 -677
- data/spec/examples/model/timestamps_spec.rb +0 -52
- data/spec/examples/model/translation_spec.rb +0 -23
@@ -0,0 +1,44 @@
|
|
1
|
+
require File.expand_path('../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
describe Cequel::Model::Schema do
|
4
|
+
after { cequel.schema.drop_table(:posts) }
|
5
|
+
subject { cequel.schema.read_table(:posts) }
|
6
|
+
|
7
|
+
let(:model) do
|
8
|
+
Class.new(Cequel::Model::Base) do
|
9
|
+
self.table_name = 'posts'
|
10
|
+
|
11
|
+
key :permalink, :text
|
12
|
+
column :title, :text
|
13
|
+
list :categories, :text
|
14
|
+
set :tags, :text
|
15
|
+
map :trackbacks, :timestamp, :text
|
16
|
+
table_property :comment, 'Blog Posts'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
context 'new model with simple primary key' do
|
21
|
+
before { model.synchronize_schema }
|
22
|
+
|
23
|
+
its(:partition_keys) { should == [Cequel::Schema::Column.new(:permalink, :text)] }
|
24
|
+
its(:data_columns) { should include(Cequel::Schema::Column.new(:title, :text)) }
|
25
|
+
its(:data_columns) { should include(Cequel::Schema::List.new(:categories, :text)) }
|
26
|
+
its(:data_columns) { should include(Cequel::Schema::Set.new(:tags, :text)) }
|
27
|
+
its(:data_columns) { should include(Cequel::Schema::Map.new(:trackbacks, :timestamp, :text)) }
|
28
|
+
specify { subject.property(:comment).should == 'Blog Posts' }
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'existing model with additional attribute' do
|
32
|
+
before do
|
33
|
+
cequel.schema.create_table :posts do
|
34
|
+
key :permalink, :text
|
35
|
+
column :title, :text
|
36
|
+
list :categories, :text
|
37
|
+
set :tags, :text
|
38
|
+
end
|
39
|
+
model.synchronize_schema
|
40
|
+
end
|
41
|
+
|
42
|
+
its(:data_columns) { should include(Cequel::Schema::Map.new(:trackbacks, :timestamp, :text)) }
|
43
|
+
end
|
44
|
+
end
|
@@ -1,20 +1,26 @@
|
|
1
|
-
|
1
|
+
require_relative 'spec_helper'
|
2
2
|
|
3
|
-
describe '
|
4
|
-
|
3
|
+
describe 'serialization' do
|
4
|
+
model :Post do
|
5
|
+
key :blog_subdomain, :text
|
6
|
+
key :id, :uuid
|
7
|
+
column :title, :text
|
8
|
+
column :body, :text
|
9
|
+
end
|
10
|
+
|
11
|
+
uuid :id
|
5
12
|
|
6
|
-
|
7
|
-
|
8
|
-
|
13
|
+
let(:attributes) do
|
14
|
+
{
|
15
|
+
blog_subdomain: 'big-data',
|
16
|
+
id: id,
|
17
|
+
title: 'Cequel',
|
18
|
+
}
|
9
19
|
end
|
10
20
|
|
11
|
-
it 'should
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
<id type="integer">1</id>
|
16
|
-
<title>Cequel</title>
|
17
|
-
</post>
|
18
|
-
XML
|
21
|
+
it 'should provide JSON serialization' do
|
22
|
+
Post.include_root_in_json = false
|
23
|
+
Post.new(attributes).as_json.symbolize_keys.
|
24
|
+
should == attributes.merge(body: nil)
|
19
25
|
end
|
20
26
|
end
|
@@ -0,0 +1,133 @@
|
|
1
|
+
require File.expand_path('../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
describe Cequel::Model::Set do
|
4
|
+
model :Post do
|
5
|
+
key :permalink, :text
|
6
|
+
column :title, :text
|
7
|
+
set :tags, :text
|
8
|
+
end
|
9
|
+
|
10
|
+
let(:scope) { cequel[:posts].where(:permalink => 'cequel') }
|
11
|
+
subject { scope.first }
|
12
|
+
|
13
|
+
let! :post do
|
14
|
+
Post.new do |post|
|
15
|
+
post.permalink = 'cequel'
|
16
|
+
post.tags = Set['one', 'two']
|
17
|
+
end.tap(&:save)
|
18
|
+
end
|
19
|
+
|
20
|
+
let! :unloaded_post do
|
21
|
+
Post['cequel']
|
22
|
+
end
|
23
|
+
|
24
|
+
context 'new record' do
|
25
|
+
it 'should save set as-is' do
|
26
|
+
subject[:tags].should == Set['one', 'two']
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe 'atomic modification' do
|
31
|
+
before { scope.set_add(:tags, 'three') }
|
32
|
+
|
33
|
+
describe '#add' do
|
34
|
+
it 'should add atomically' do
|
35
|
+
post.tags.add('four')
|
36
|
+
post.save
|
37
|
+
subject[:tags].should == Set['one', 'two', 'three', 'four']
|
38
|
+
post.tags.should == Set['one', 'two', 'four']
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'should add without reading' do
|
42
|
+
max_statements! 2
|
43
|
+
unloaded_post.tags.add('four')
|
44
|
+
unloaded_post.save
|
45
|
+
subject[:tags].should == Set['one', 'two', 'three', 'four']
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'should apply add post-hoc' do
|
49
|
+
unloaded_post.tags.add('four')
|
50
|
+
unloaded_post.tags.should == Set['one', 'two', 'three', 'four']
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe '#clear' do
|
55
|
+
it 'should clear atomically' do
|
56
|
+
post.tags.clear
|
57
|
+
post.save
|
58
|
+
subject[:tags].should be_blank
|
59
|
+
post.tags.should == Set[]
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'should clear without reading' do
|
63
|
+
max_statements! 2
|
64
|
+
unloaded_post.tags.clear
|
65
|
+
unloaded_post.save
|
66
|
+
subject[:tags].should be_blank
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'should apply clear post-hoc' do
|
70
|
+
unloaded_post.tags.clear
|
71
|
+
unloaded_post.tags.should == Set[]
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe '#delete' do
|
76
|
+
it 'should delete atomically' do
|
77
|
+
post.tags.delete('two')
|
78
|
+
post.save
|
79
|
+
subject[:tags].should == Set['one', 'three']
|
80
|
+
post.tags.should == Set['one']
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'should delete without reading' do
|
84
|
+
max_statements! 2
|
85
|
+
unloaded_post.tags.delete('two')
|
86
|
+
unloaded_post.save
|
87
|
+
subject[:tags].should == Set['one', 'three']
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'should apply delete post-hoc' do
|
91
|
+
unloaded_post.tags.delete('two')
|
92
|
+
unloaded_post.tags.should == Set['one', 'three']
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
describe '#replace' do
|
97
|
+
it 'should replace atomically' do
|
98
|
+
post.tags.replace(Set['a', 'b'])
|
99
|
+
post.save
|
100
|
+
subject[:tags].should == Set['a', 'b']
|
101
|
+
post.tags.should == Set['a', 'b']
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'should replace without reading' do
|
105
|
+
max_statements! 2
|
106
|
+
unloaded_post.tags.replace(Set['a', 'b'])
|
107
|
+
unloaded_post.save
|
108
|
+
subject[:tags].should == Set['a', 'b']
|
109
|
+
end
|
110
|
+
|
111
|
+
it 'should apply delete post-hoc' do
|
112
|
+
unloaded_post.tags.replace(Set['a', 'b'])
|
113
|
+
unloaded_post.tags.should == Set['a', 'b']
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
specify { expect { post.tags.add?('three') }.to raise_error(NoMethodError) }
|
118
|
+
specify { expect { post.tags.collect!(&:upcase) }.
|
119
|
+
to raise_error(NoMethodError) }
|
120
|
+
specify { expect { post.tags.delete?('two') }.to raise_error(NoMethodError) }
|
121
|
+
specify { expect { post.tags.delete_if { |s| s.starts_with?('t') }}.
|
122
|
+
to raise_error(NoMethodError) }
|
123
|
+
specify { expect { post.tags.flatten! }.to raise_error(NoMethodError) }
|
124
|
+
specify { expect { post.tags.keep_if { |s| s.starts_with?('t') }}.
|
125
|
+
to raise_error(NoMethodError) }
|
126
|
+
specify { expect { post.tags.map!(&:upcase) }.
|
127
|
+
to raise_error(NoMethodError) }
|
128
|
+
specify { expect { post.tags.reject! { |s| s.starts_with?('t') }}.
|
129
|
+
to raise_error(NoMethodError) }
|
130
|
+
specify { expect { post.tags.select! { |s| s.starts_with?('t') }}.
|
131
|
+
to raise_error(NoMethodError) }
|
132
|
+
end
|
133
|
+
end
|
@@ -1,12 +1,2 @@
|
|
1
1
|
require File.expand_path('../../spec_helper', __FILE__)
|
2
2
|
require 'cequel/model'
|
3
|
-
|
4
|
-
Dir.glob(File.join(File.dirname(__FILE__), '../../models/**/*.rb')).each do |file|
|
5
|
-
require file
|
6
|
-
end
|
7
|
-
|
8
|
-
RSpec.configure do |config|
|
9
|
-
config.before :each do
|
10
|
-
Cequel::Model.keyspace.connection = connection
|
11
|
-
end
|
12
|
-
end
|
@@ -1,86 +1,99 @@
|
|
1
|
-
|
1
|
+
require_relative 'spec_helper'
|
2
2
|
|
3
3
|
describe Cequel::Model::Validations do
|
4
|
+
model :Post do
|
5
|
+
key :permalink, :text
|
6
|
+
column :title, :text
|
7
|
+
column :body, :text
|
8
|
+
|
9
|
+
validates :title, :presence => true
|
10
|
+
before_validation { |post| post.called_validate_callback = true }
|
11
|
+
|
12
|
+
attr_accessor :called_validate_callback
|
13
|
+
end
|
14
|
+
|
15
|
+
let(:invalid_post) do
|
16
|
+
Post.new do |post|
|
17
|
+
post.permalink = 'invalid'
|
18
|
+
post.body = 'This is an invalid post.'
|
19
|
+
end
|
20
|
+
end
|
21
|
+
let(:valid_post) do
|
22
|
+
Post.new do |post|
|
23
|
+
post.permalink = 'valid'
|
24
|
+
post.title = 'Valid Post'
|
25
|
+
end
|
26
|
+
end
|
27
|
+
let(:unloaded_post) { Post['unloaded'] }
|
28
|
+
|
4
29
|
describe '#valid?' do
|
5
30
|
it 'should be false if model is not valid' do
|
6
|
-
|
31
|
+
invalid_post.should_not be_valid
|
7
32
|
end
|
8
33
|
|
9
34
|
it 'should be true if model is valid' do
|
10
|
-
|
35
|
+
valid_post.should be_valid
|
11
36
|
end
|
12
37
|
end
|
13
38
|
|
14
39
|
describe '#save' do
|
15
40
|
it 'should return false and not persist model if invalid' do
|
16
|
-
|
41
|
+
invalid_post.save.should be_false
|
17
42
|
end
|
18
43
|
|
19
44
|
it 'should return true and persist model if valid' do
|
20
|
-
|
21
|
-
|
45
|
+
valid_post.save.should be_true
|
46
|
+
Post.find('valid').title.should == 'Valid Post'
|
47
|
+
end
|
22
48
|
|
23
|
-
|
49
|
+
it 'should bypass validations if :validate => false is passed' do
|
50
|
+
invalid_post.save(:validate => false).should be_true
|
51
|
+
Post.find('invalid').body.should == 'This is an invalid post.'
|
24
52
|
end
|
25
53
|
end
|
26
54
|
|
27
55
|
describe '#save!' do
|
28
56
|
it 'should raise error and not persist model if invalid' do
|
29
|
-
expect
|
30
|
-
|
31
|
-
end.to raise_error(Cequel::Model::RecordInvalid)
|
57
|
+
expect { invalid_post.save! }.
|
58
|
+
to raise_error(Cequel::Model::RecordInvalid)
|
32
59
|
end
|
33
60
|
|
34
61
|
it 'should persist model and return self if valid' do
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
post = Post.new(:id => 1, :title => 'Cequel', :require_title => true)
|
39
|
-
post.save!.should == post
|
62
|
+
expect { valid_post.save! }.to_not raise_error
|
63
|
+
Post.find(valid_post.permalink).title.should == 'Valid Post'
|
40
64
|
end
|
41
65
|
end
|
42
66
|
|
43
67
|
describe '#update_attributes!' do
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
Post.find(1)
|
48
|
-
end
|
49
|
-
|
50
|
-
it 'should change attributes and save them if valid' do
|
51
|
-
connection.should_receive(:execute).
|
52
|
-
with "UPDATE posts SET ? = ? WHERE ? = ?", 'body', 'Cequel cequel', :id, 1
|
53
|
-
post.update_attributes!(:body => 'Cequel cequel')
|
68
|
+
it 'should raise error and not update data in the database' do
|
69
|
+
expect { invalid_post.update_attributes!(:body => 'My Post') }.
|
70
|
+
to raise_error(Cequel::Model::RecordInvalid)
|
54
71
|
end
|
55
72
|
|
56
|
-
it 'should
|
57
|
-
|
58
|
-
|
59
|
-
to raise_error(Cequel::Model::RecordInvalid)
|
73
|
+
it 'should return successfully and update data in the database if valid' do
|
74
|
+
invalid_post.update_attributes!(:title => 'My Post')
|
75
|
+
Post.find(invalid_post.permalink).title.should == 'My Post'
|
60
76
|
end
|
61
77
|
end
|
62
78
|
|
63
79
|
describe '::create!' do
|
64
80
|
it 'should raise RecordInvalid and not persist model if invalid' do
|
65
81
|
expect do
|
66
|
-
Post.create!(:
|
82
|
+
Post.create!(:permalink => 'cequel', :body => 'Cequel')
|
67
83
|
end.to raise_error(Cequel::Model::RecordInvalid)
|
68
84
|
end
|
69
85
|
|
70
|
-
it 'should
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
Post.create!(:id => 1, :title => 'Cequel', :require_title => true).
|
75
|
-
title.should == 'Cequel'
|
86
|
+
it 'should persist record to database if valid' do
|
87
|
+
Post.create!(:permalink => 'cequel', :title => 'Cequel')
|
88
|
+
Post.find('cequel').title.should == 'Cequel'
|
76
89
|
end
|
77
90
|
end
|
78
91
|
|
79
92
|
describe 'callbacks' do
|
80
93
|
it 'should call validation callbacks' do
|
81
|
-
post = Post.new(:
|
94
|
+
post = Post.new(:title => 'cequel')
|
82
95
|
post.valid?
|
83
|
-
post.should
|
96
|
+
post.called_validate_callback.should be_true
|
84
97
|
end
|
85
98
|
end
|
86
99
|
end
|
@@ -0,0 +1,328 @@
|
|
1
|
+
require File.expand_path('../../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
describe Cequel::Schema::TableReader do
|
4
|
+
|
5
|
+
after do
|
6
|
+
cequel.schema.drop_table(:posts)
|
7
|
+
end
|
8
|
+
|
9
|
+
let(:table) { cequel.schema.read_table(:posts) }
|
10
|
+
|
11
|
+
describe 'reading simple key' do
|
12
|
+
before do
|
13
|
+
cequel.execute("CREATE TABLE posts (permalink text PRIMARY KEY)")
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'should read name correctly' do
|
17
|
+
table.partition_keys.first.name.should == :permalink
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'should read type correctly' do
|
21
|
+
table.partition_keys.first.type.should be_a(Cequel::Type::Text)
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'should have no nonpartition keys' do
|
25
|
+
table.clustering_columns.should be_empty
|
26
|
+
end
|
27
|
+
end # describe 'reading simple key'
|
28
|
+
|
29
|
+
describe 'reading single non-partition key' do
|
30
|
+
before do
|
31
|
+
cequel.execute <<-CQL
|
32
|
+
CREATE TABLE posts (
|
33
|
+
blog_subdomain text,
|
34
|
+
permalink ascii,
|
35
|
+
PRIMARY KEY (blog_subdomain, permalink)
|
36
|
+
)
|
37
|
+
CQL
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'should read partition key name' do
|
41
|
+
table.partition_keys.map(&:name).should == [:blog_subdomain]
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'should read partition key type' do
|
45
|
+
table.partition_keys.map(&:type).should == [Cequel::Type::Text.instance]
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'should read non-partition key name' do
|
49
|
+
table.clustering_columns.map(&:name).should == [:permalink]
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'should read non-partition key type' do
|
53
|
+
table.clustering_columns.map(&:type).
|
54
|
+
should == [Cequel::Type::Ascii.instance]
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'should default clustering order to asc' do
|
58
|
+
table.clustering_columns.map(&:clustering_order).should == [:asc]
|
59
|
+
end
|
60
|
+
end # describe 'reading single non-partition key'
|
61
|
+
|
62
|
+
describe 'reading reverse-ordered non-partition key' do
|
63
|
+
before do
|
64
|
+
cequel.execute <<-CQL
|
65
|
+
CREATE TABLE posts (
|
66
|
+
blog_subdomain text,
|
67
|
+
permalink ascii,
|
68
|
+
PRIMARY KEY (blog_subdomain, permalink)
|
69
|
+
)
|
70
|
+
WITH CLUSTERING ORDER BY (permalink DESC)
|
71
|
+
CQL
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'should read non-partition key name' do
|
75
|
+
table.clustering_columns.map(&:name).should == [:permalink]
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'should read non-partition key type' do
|
79
|
+
table.clustering_columns.map(&:type).
|
80
|
+
should == [Cequel::Type::Ascii.instance]
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'should recognize reversed clustering order' do
|
84
|
+
table.clustering_columns.map(&:clustering_order).should == [:desc]
|
85
|
+
end
|
86
|
+
end # describe 'reading reverse-ordered non-partition key'
|
87
|
+
|
88
|
+
describe 'reading compound non-partition key' do
|
89
|
+
before do
|
90
|
+
cequel.execute <<-CQL
|
91
|
+
CREATE TABLE posts (
|
92
|
+
blog_subdomain text,
|
93
|
+
permalink ascii,
|
94
|
+
author_id uuid,
|
95
|
+
PRIMARY KEY (blog_subdomain, permalink, author_id)
|
96
|
+
)
|
97
|
+
WITH CLUSTERING ORDER BY (permalink DESC, author_id ASC)
|
98
|
+
CQL
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'should read non-partition key names' do
|
102
|
+
table.clustering_columns.map(&:name).should == [:permalink, :author_id]
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'should read non-partition key types' do
|
106
|
+
table.clustering_columns.map(&:type).
|
107
|
+
should == [Cequel::Type::Ascii.instance, Cequel::Type::Uuid.instance]
|
108
|
+
end
|
109
|
+
|
110
|
+
it 'should read heterogeneous clustering orders' do
|
111
|
+
table.clustering_columns.map(&:clustering_order).should == [:desc, :asc]
|
112
|
+
end
|
113
|
+
end # describe 'reading compound non-partition key'
|
114
|
+
|
115
|
+
describe 'reading compound partition key' do
|
116
|
+
before do
|
117
|
+
cequel.execute <<-CQL
|
118
|
+
CREATE TABLE posts (
|
119
|
+
blog_subdomain text,
|
120
|
+
permalink ascii,
|
121
|
+
PRIMARY KEY ((blog_subdomain, permalink))
|
122
|
+
)
|
123
|
+
CQL
|
124
|
+
end
|
125
|
+
|
126
|
+
it 'should read partition key names' do
|
127
|
+
table.partition_keys.map(&:name).should == [:blog_subdomain, :permalink]
|
128
|
+
end
|
129
|
+
|
130
|
+
it 'should read partition key types' do
|
131
|
+
table.partition_keys.map(&:type).
|
132
|
+
should == [Cequel::Type::Text.instance, Cequel::Type::Ascii.instance]
|
133
|
+
end
|
134
|
+
|
135
|
+
it 'should have empty nonpartition keys' do
|
136
|
+
table.clustering_columns.should be_empty
|
137
|
+
end
|
138
|
+
|
139
|
+
end # describe 'reading compound partition key'
|
140
|
+
|
141
|
+
describe 'reading compound partition and non-partition keys' do
|
142
|
+
before do
|
143
|
+
cequel.execute <<-CQL
|
144
|
+
CREATE TABLE posts (
|
145
|
+
blog_subdomain text,
|
146
|
+
permalink ascii,
|
147
|
+
author_id uuid,
|
148
|
+
published_at timestamp,
|
149
|
+
PRIMARY KEY ((blog_subdomain, permalink), author_id, published_at)
|
150
|
+
)
|
151
|
+
WITH CLUSTERING ORDER BY (author_id ASC, published_at DESC)
|
152
|
+
CQL
|
153
|
+
end
|
154
|
+
|
155
|
+
it 'should read partition key names' do
|
156
|
+
table.partition_keys.map(&:name).should == [:blog_subdomain, :permalink]
|
157
|
+
end
|
158
|
+
|
159
|
+
it 'should read partition key types' do
|
160
|
+
table.partition_keys.map(&:type).
|
161
|
+
should == [Cequel::Type::Text.instance, Cequel::Type::Ascii.instance]
|
162
|
+
end
|
163
|
+
|
164
|
+
it 'should read non-partition key names' do
|
165
|
+
table.clustering_columns.map(&:name).
|
166
|
+
should == [:author_id, :published_at]
|
167
|
+
end
|
168
|
+
|
169
|
+
it 'should read non-partition key types' do
|
170
|
+
table.clustering_columns.map(&:type).should ==
|
171
|
+
[Cequel::Type::Uuid.instance, Cequel::Type::Timestamp.instance]
|
172
|
+
end
|
173
|
+
|
174
|
+
it 'should read clustering order' do
|
175
|
+
table.clustering_columns.map(&:clustering_order).should == [:asc, :desc]
|
176
|
+
end
|
177
|
+
|
178
|
+
end # describe 'reading compound partition and non-partition keys'
|
179
|
+
|
180
|
+
describe 'reading data columns' do
|
181
|
+
|
182
|
+
before do
|
183
|
+
cequel.execute <<-CQL
|
184
|
+
CREATE TABLE posts (
|
185
|
+
blog_subdomain text,
|
186
|
+
permalink ascii,
|
187
|
+
title text,
|
188
|
+
author_id uuid,
|
189
|
+
categories LIST <text>,
|
190
|
+
tags SET <text>,
|
191
|
+
trackbacks MAP <timestamp,ascii>,
|
192
|
+
PRIMARY KEY (blog_subdomain, permalink)
|
193
|
+
)
|
194
|
+
CQL
|
195
|
+
cequel.execute('CREATE INDEX ON posts (author_id)')
|
196
|
+
end
|
197
|
+
|
198
|
+
it 'should read types of scalar data columns' do
|
199
|
+
table.data_columns.find { |column| column.name == :title }.type.
|
200
|
+
should == Cequel::Type[:text]
|
201
|
+
table.data_columns.find { |column| column.name == :author_id }.type.
|
202
|
+
should == Cequel::Type[:uuid]
|
203
|
+
end
|
204
|
+
|
205
|
+
it 'should read index attributes' do
|
206
|
+
table.data_columns.find { |column| column.name == :author_id }.index_name.
|
207
|
+
should == :posts_author_id_idx
|
208
|
+
end
|
209
|
+
|
210
|
+
it 'should leave nil index for non-indexed columns' do
|
211
|
+
table.data_columns.find { |column| column.name == :title }.index_name.
|
212
|
+
should be_nil
|
213
|
+
end
|
214
|
+
|
215
|
+
it 'should read list columns' do
|
216
|
+
table.data_columns.find { |column| column.name == :categories }.
|
217
|
+
should be_a(Cequel::Schema::List)
|
218
|
+
end
|
219
|
+
|
220
|
+
it 'should read list column type' do
|
221
|
+
table.data_columns.find { |column| column.name == :categories }.type.
|
222
|
+
should == Cequel::Type[:text]
|
223
|
+
end
|
224
|
+
|
225
|
+
it 'should read set columns' do
|
226
|
+
table.data_columns.find { |column| column.name == :tags }.
|
227
|
+
should be_a(Cequel::Schema::Set)
|
228
|
+
end
|
229
|
+
|
230
|
+
it 'should read set column type' do
|
231
|
+
table.data_columns.find { |column| column.name == :tags }.type.
|
232
|
+
should == Cequel::Type[:text]
|
233
|
+
end
|
234
|
+
|
235
|
+
it 'should read map columns' do
|
236
|
+
table.data_columns.find { |column| column.name == :trackbacks }.
|
237
|
+
should be_a(Cequel::Schema::Map)
|
238
|
+
end
|
239
|
+
|
240
|
+
it 'should read map column key type' do
|
241
|
+
table.data_columns.find { |column| column.name == :trackbacks }.key_type.
|
242
|
+
should == Cequel::Type[:timestamp]
|
243
|
+
end
|
244
|
+
|
245
|
+
it 'should read map column value type' do
|
246
|
+
table.data_columns.find { |column| column.name == :trackbacks }.
|
247
|
+
value_type.should == Cequel::Type[:ascii]
|
248
|
+
end
|
249
|
+
|
250
|
+
end # describe 'reading data columns'
|
251
|
+
|
252
|
+
describe 'reading storage properties' do
|
253
|
+
|
254
|
+
before do
|
255
|
+
cequel.execute <<-CQL
|
256
|
+
CREATE TABLE posts (permalink text PRIMARY KEY)
|
257
|
+
WITH bloom_filter_fp_chance = 0.02
|
258
|
+
AND comment = 'Posts table'
|
259
|
+
AND compaction = {
|
260
|
+
'class' : 'SizeTieredCompactionStrategy',
|
261
|
+
'bucket_high' : 1.8,
|
262
|
+
'max_threshold' : 64,
|
263
|
+
'min_sstable_size' : 50,
|
264
|
+
'tombstone_compaction_interval' : 2
|
265
|
+
} AND compression = {
|
266
|
+
'sstable_compression' : 'DeflateCompressor',
|
267
|
+
'chunk_length_kb' : 128,
|
268
|
+
'crc_check_chance' : 0.5
|
269
|
+
}
|
270
|
+
CQL
|
271
|
+
end
|
272
|
+
|
273
|
+
it 'should read float properties' do
|
274
|
+
table.property(:bloom_filter_fp_chance).should == 0.02
|
275
|
+
end
|
276
|
+
|
277
|
+
it 'should read string properties' do
|
278
|
+
table.property(:comment).should == 'Posts table'
|
279
|
+
end
|
280
|
+
|
281
|
+
it 'should read and simplify compaction class' do
|
282
|
+
table.property(:compaction)[:class].
|
283
|
+
should == 'SizeTieredCompactionStrategy'
|
284
|
+
end
|
285
|
+
|
286
|
+
it 'should read float properties from compaction hash' do
|
287
|
+
table.property(:compaction)[:bucket_high].should == 1.8
|
288
|
+
end
|
289
|
+
|
290
|
+
it 'should read integer properties from compaction hash' do
|
291
|
+
table.property(:compaction)[:max_threshold].should == 64
|
292
|
+
end
|
293
|
+
|
294
|
+
it 'should read and simplify compression class' do
|
295
|
+
table.property(:compression)[:sstable_compression].
|
296
|
+
should == 'DeflateCompressor'
|
297
|
+
end
|
298
|
+
|
299
|
+
it 'should read integer properties from compression class' do
|
300
|
+
table.property(:compression)[:chunk_length_kb].should == 128
|
301
|
+
end
|
302
|
+
|
303
|
+
it 'should read float properties from compression class' do
|
304
|
+
table.property(:compression)[:crc_check_chance].should == 0.5
|
305
|
+
end
|
306
|
+
|
307
|
+
end # describe 'reading storage properties'
|
308
|
+
|
309
|
+
describe 'compact storage' do
|
310
|
+
|
311
|
+
it 'should read non-compact storage status' do
|
312
|
+
cequel.execute <<-CQL
|
313
|
+
CREATE TABLE posts (permalink text PRIMARY KEY, body text)
|
314
|
+
CQL
|
315
|
+
table.should_not be_compact_storage
|
316
|
+
end
|
317
|
+
|
318
|
+
it 'should read compact storage status' do
|
319
|
+
cequel.execute <<-CQL
|
320
|
+
CREATE TABLE posts (permalink text PRIMARY KEY, body text)
|
321
|
+
WITH COMPACT STORAGE
|
322
|
+
CQL
|
323
|
+
table.should be_compact_storage
|
324
|
+
end
|
325
|
+
|
326
|
+
end
|
327
|
+
|
328
|
+
end
|