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.
- 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
|