cassandra-cql 1.0.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.
- data/.gitignore +9 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +203 -0
- data/README.rdoc +78 -0
- data/Rakefile +150 -0
- data/cassandra-cql.gemspec +29 -0
- data/lib/cassandra-cql.rb +39 -0
- data/lib/cassandra-cql/database.rb +107 -0
- data/lib/cassandra-cql/result.rb +133 -0
- data/lib/cassandra-cql/row.rb +59 -0
- data/lib/cassandra-cql/schema.rb +108 -0
- data/lib/cassandra-cql/statement.rb +111 -0
- data/lib/cassandra-cql/types/abstract_type.rb +47 -0
- data/lib/cassandra-cql/types/ascii_type.rb +25 -0
- data/lib/cassandra-cql/types/boolean_type.rb +25 -0
- data/lib/cassandra-cql/types/bytes_type.rb +21 -0
- data/lib/cassandra-cql/types/decimal_type.rb +25 -0
- data/lib/cassandra-cql/types/double_type.rb +25 -0
- data/lib/cassandra-cql/types/float_type.rb +25 -0
- data/lib/cassandra-cql/types/integer_type.rb +27 -0
- data/lib/cassandra-cql/types/long_type.rb +27 -0
- data/lib/cassandra-cql/types/utf8_type.rb +25 -0
- data/lib/cassandra-cql/types/uuid_type.rb +27 -0
- data/lib/cassandra-cql/utility.rb +37 -0
- data/lib/cassandra-cql/uuid.rb +21 -0
- data/lib/cassandra-cql/version.rb +19 -0
- data/spec/column_family_spec.rb +105 -0
- data/spec/comparator_spec.rb +225 -0
- data/spec/conf/0.8/cassandra.in.sh +41 -0
- data/spec/conf/0.8/cassandra.yaml +61 -0
- data/spec/conf/0.8/log4j-server.properties +40 -0
- data/spec/conf/0.8/schema.txt +10 -0
- data/spec/conf/1.0/cassandra.in.sh +41 -0
- data/spec/conf/1.0/cassandra.yaml +416 -0
- data/spec/conf/1.0/log4j-server.properties +40 -0
- data/spec/conf/1.0/schema.txt +10 -0
- data/spec/result_spec.rb +173 -0
- data/spec/row_spec.rb +55 -0
- data/spec/rowkey_spec.rb +223 -0
- data/spec/schema_spec.rb +51 -0
- data/spec/spec_helper.rb +23 -0
- data/spec/statement_spec.rb +224 -0
- data/spec/utility_spec.rb +26 -0
- data/spec/uuid_spec.rb +26 -0
- data/spec/validation_spec.rb +250 -0
- data/vendor/gen-rb/cassandra.rb +2212 -0
- data/vendor/gen-rb/cassandra_constants.rb +10 -0
- data/vendor/gen-rb/cassandra_types.rb +854 -0
- metadata +171 -0
data/spec/schema_spec.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
require File.expand_path('spec_helper.rb', File.dirname(__FILE__))
|
2
|
+
include CassandraCQL
|
3
|
+
|
4
|
+
describe "Schema class" do
|
5
|
+
before(:each) do
|
6
|
+
@connection = setup_cassandra_connection
|
7
|
+
@connection.execute("USE system")
|
8
|
+
end
|
9
|
+
|
10
|
+
context "initialize" do
|
11
|
+
it "should set a thrift schema object" do
|
12
|
+
@connection.schema.schema.should be_kind_of(CassandraCQL::Thrift::KsDef)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should set column family hash" do
|
16
|
+
@connection.schema.column_families.should be_kind_of(Hash)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should set column family hash" do
|
20
|
+
@connection.schema.column_families.should be_kind_of(Hash)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should method_missing" do
|
25
|
+
expect {
|
26
|
+
@connection.schema.this_method_does_not_exist
|
27
|
+
}.to raise_error NoMethodError
|
28
|
+
end
|
29
|
+
|
30
|
+
context "name" do
|
31
|
+
it "should return keyspace name" do
|
32
|
+
@connection.schema.name.should eq('system')
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context "to_s" do
|
37
|
+
it "should return keyspace name" do
|
38
|
+
@connection.schema.to_s.should eq(@connection.schema.name)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context "column_family_names" do
|
43
|
+
it "should return cf_def names" do
|
44
|
+
@connection.schema.column_family_names.sort.should eq(@connection.schema.schema.cf_defs.map(&:name).sort)
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should be the same as tables" do
|
48
|
+
@connection.schema.column_family_names.should eq(@connection.schema.tables)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'rspec'
|
3
|
+
$LOAD_PATH << "#{File.expand_path(File.dirname(__FILE__))}/../lib"
|
4
|
+
require 'cassandra-cql'
|
5
|
+
|
6
|
+
def yaml_fixture(file)
|
7
|
+
if file.kind_of?(Symbol)
|
8
|
+
file = "#{file}.yaml"
|
9
|
+
elsif file !~ /\.yaml$/
|
10
|
+
file = "#{file}.yaml"
|
11
|
+
end
|
12
|
+
YAML::load_file(File.dirname(__FILE__) + "/fixtures/#{file}")
|
13
|
+
end
|
14
|
+
|
15
|
+
def setup_cassandra_connection
|
16
|
+
connection = CassandraCQL::Database.new(["127.0.0.1:9160"], {}, :retries => 2, :timeout => 1) rescue false
|
17
|
+
if !connection.keyspaces.map(&:name).include?("CassandraCQLTestKeyspace")
|
18
|
+
connection.execute("CREATE KEYSPACE CassandraCQLTestKeyspace WITH strategy_class='org.apache.cassandra.locator.SimpleStrategy' AND strategy_options:replication_factor=1")
|
19
|
+
end
|
20
|
+
connection.execute("USE CassandraCQLTestKeyspace")
|
21
|
+
|
22
|
+
connection
|
23
|
+
end
|
@@ -0,0 +1,224 @@
|
|
1
|
+
require File.expand_path('spec_helper.rb', File.dirname(__FILE__))
|
2
|
+
include CassandraCQL
|
3
|
+
|
4
|
+
describe "initialize" do
|
5
|
+
it "should set a handle and prepare statement" do
|
6
|
+
statement = "use keyspace1"
|
7
|
+
handle = double("Database")
|
8
|
+
sth = Statement.new(handle, statement)
|
9
|
+
sth.statement.should eq(statement)
|
10
|
+
sth.instance_variable_get("@handle").should eq(handle)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe "execute" do
|
15
|
+
context "when performing keyspace operations" do
|
16
|
+
before(:each) do
|
17
|
+
@connection = setup_cassandra_connection
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should set keyspace without compression" do
|
21
|
+
@connection.keyspace.should_not eq('system')
|
22
|
+
stmt = @connection.prepare("use system")
|
23
|
+
stmt.execute([], :compression => false).should be_nil
|
24
|
+
@connection.keyspace.should eq('system')
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should set keyspace with compression" do
|
28
|
+
@connection.keyspace.should_not eq('system')
|
29
|
+
stmt = @connection.prepare("use system")
|
30
|
+
stmt.execute([], :compression => true).should be_nil
|
31
|
+
@connection.keyspace.should eq('system')
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should set keyspace to nil when deleting keyspace" do
|
35
|
+
@connection.execute("DROP KEYSPACE #{@connection.keyspace}").should be_nil
|
36
|
+
@connection.keyspace.should be_nil
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context "when performing void-returning column_family operations" do
|
41
|
+
before(:each) do
|
42
|
+
@connection = setup_cassandra_connection
|
43
|
+
if !@connection.schema.column_family_names.include?('colfam_ops')
|
44
|
+
@connection.execute("CREATE COLUMNFAMILY colfam_ops (id varchar PRIMARY KEY)")
|
45
|
+
else
|
46
|
+
@connection.execute("TRUNCATE colfam_ops")
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should return nil when inserting" do
|
51
|
+
@connection.execute("INSERT INTO colfam_ops (id, column) VALUES (?, ?)", "key", "value").should be_nil
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should return nil when updating" do
|
55
|
+
@connection.execute("UPDATE colfam_ops SET column=? WHERE id=?", "value", "key").should be_nil
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should return nil when deleting" do
|
59
|
+
@connection.execute("DELETE FROM colfam_ops WHERE id=?", "key").should be_nil
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe "escape" do
|
65
|
+
it "should escape quotes" do
|
66
|
+
Statement.escape(%q{'}).should eq(%q{''})
|
67
|
+
Statement.escape(%q{\'}).should eq(%q{\''})
|
68
|
+
Statement.escape(%q{''}).should eq(%q{''''})
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe "quote" do
|
73
|
+
context "with a string" do
|
74
|
+
it "should add quotes" do
|
75
|
+
Statement.quote("test").should eq("'test'")
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
context "with an integer" do
|
80
|
+
it "should not add quotes" do
|
81
|
+
Statement.quote(15).should eq(15)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
context "with an array" do
|
86
|
+
it "should return a comma-separated list" do
|
87
|
+
Statement.quote([1, 2, 3]).should eq("1,2,3")
|
88
|
+
Statement.quote(["a", "b''", "c"]).should eq("'a','b''','c'")
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
context "with an unsupported object" do
|
93
|
+
it "should raise an exception" do
|
94
|
+
expect {
|
95
|
+
Statement.quote(Time.new)
|
96
|
+
}.to raise_error(CassandraCQL::Error::UnescapableObject)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
describe "cast_to_cql" do
|
102
|
+
context "with a Time object" do
|
103
|
+
it "should return a guid of a UUID" do
|
104
|
+
ts = Time.new - 86400 # set it to yesterday just to be sure no defaulting to today misses an error
|
105
|
+
guid = Statement.cast_to_cql(ts)
|
106
|
+
guid.should be_kind_of(String)
|
107
|
+
expect {
|
108
|
+
ret = UUID.new(guid)
|
109
|
+
uuid_ts = Time.at(ret.seconds)
|
110
|
+
[:year, :month, :day, :hour, :min, :sec].each do |sym|
|
111
|
+
uuid_ts.send(sym).should eq(ts.send(sym))
|
112
|
+
end
|
113
|
+
}.to_not raise_error
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
context "with a Fixnum object" do
|
118
|
+
it "should return the same object" do
|
119
|
+
Statement.cast_to_cql(15).should eq(15)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
context "with a UUID object" do
|
124
|
+
it "should return the a guid" do
|
125
|
+
uuid = UUID.new
|
126
|
+
guid = Statement.cast_to_cql(uuid)
|
127
|
+
guid.should eq(uuid.to_guid)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
context "with a String without quotes" do
|
132
|
+
it "should return a copy of itself" do
|
133
|
+
str = "This is a string"
|
134
|
+
new_str = Statement.cast_to_cql(str)
|
135
|
+
str.should eq(str)
|
136
|
+
new_str.object_id.should_not eq(str.object_id)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
context "with a String with quotes" do
|
141
|
+
it "should return a quoted version" do
|
142
|
+
str = "This is a ' string"
|
143
|
+
new_str = Statement.cast_to_cql(str)
|
144
|
+
new_str.should_not eq(str)
|
145
|
+
new_str.should eq(Statement.escape(str))
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
context "with binary data" do
|
150
|
+
it "should return an unpacked version" do
|
151
|
+
bytes = "binary\x00"
|
152
|
+
bytes = bytes.force_encoding('ASCII-8BIT') if RUBY_VERSION >= "1.9"
|
153
|
+
new_data = Statement.cast_to_cql(bytes)
|
154
|
+
new_data.should_not eq(bytes)
|
155
|
+
[new_data].pack('H*').should eq(bytes)
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
context "with an array of Fixnums" do
|
160
|
+
it "should equal itself" do
|
161
|
+
arr = [1, 2, 3]
|
162
|
+
Statement.cast_to_cql(arr).should eq(arr)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
context "with an array of Strings" do
|
167
|
+
it "should return quoted versions of itself" do
|
168
|
+
arr = ["test", "'"]
|
169
|
+
res = Statement.cast_to_cql(arr)
|
170
|
+
arr.map { |o| Statement.cast_to_cql(o) }.should eq(res)
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
describe "sanitize" do
|
176
|
+
context "with no bind vars" do
|
177
|
+
it "should return itself" do
|
178
|
+
Statement.sanitize("use keyspace").should eq("use keyspace")
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
context "when expecting bind vars" do
|
183
|
+
it "should raise an exception with bind variable mismatch" do
|
184
|
+
expect {
|
185
|
+
Statement.sanitize("use keyspace ?")
|
186
|
+
}.to raise_error(Error::InvalidBindVariable)
|
187
|
+
|
188
|
+
expect {
|
189
|
+
Statement.sanitize("use keyspace ?", ['too', 'many'])
|
190
|
+
}.to raise_error(Error::InvalidBindVariable)
|
191
|
+
end
|
192
|
+
|
193
|
+
it "should not raise an exception with matching bind vars" do
|
194
|
+
expect {
|
195
|
+
Statement.sanitize("use keyspace ?", ["test"]).should eq("use keyspace 'test'")
|
196
|
+
}.to_not raise_error(Error::InvalidBindVariable)
|
197
|
+
end
|
198
|
+
|
199
|
+
it "should have bind vars in the right order" do
|
200
|
+
expect {
|
201
|
+
Statement.sanitize("use keyspace ? with randomness (?)", ["test", "stuff"]).should eq("use keyspace 'test' with randomness ('stuff')")
|
202
|
+
}.to_not raise_error(Error::InvalidBindVariable)
|
203
|
+
end
|
204
|
+
|
205
|
+
it "should not double-escape the single quotes in your string" do
|
206
|
+
Statement.sanitize(
|
207
|
+
"insert into keyspace (key, ?) values (?)", ["vanilla", %Q{I\'m a string with \'cool\' quotes}]
|
208
|
+
).should eq("insert into keyspace (key, 'vanilla') values ('I''m a string with ''cool'' quotes')")
|
209
|
+
end
|
210
|
+
|
211
|
+
it "should handle numbers and stuff appropriately" do
|
212
|
+
Statement.sanitize(
|
213
|
+
"insert into keyspace (key, ?) values (?)", [488, 60.368]
|
214
|
+
).should eq("insert into keyspace (key, 488) values (60.368)")
|
215
|
+
end
|
216
|
+
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
describe "finish" do
|
221
|
+
it "should just return true .. nothing to clean up yet" do
|
222
|
+
Statement.new(nil, 'whatever').finish.should be_true
|
223
|
+
end
|
224
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require File.expand_path('spec_helper.rb', File.dirname(__FILE__))
|
3
|
+
include CassandraCQL
|
4
|
+
|
5
|
+
describe "compress" do
|
6
|
+
it "should return some valid gzipped stuff" do
|
7
|
+
stuff = "This is some stuff"
|
8
|
+
bytes = Utility.compress(stuff)
|
9
|
+
Utility.binary_data?(bytes).should be_true
|
10
|
+
Utility.decompress(bytes).should eq(stuff)
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should be binary data" do
|
14
|
+
if RUBY_VERSION >= "1.9"
|
15
|
+
Utility.binary_data?("binary\x00".force_encoding('ASCII-8BIT')).should be_true
|
16
|
+
else
|
17
|
+
Utility.binary_data?("binary\x00").should be_true
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should not be binary data" do
|
22
|
+
Utility.binary_data?("test").should_not be_true
|
23
|
+
Utility.binary_data?("snårk").should_not be_true
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
data/spec/uuid_spec.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require File.expand_path('spec_helper.rb', File.dirname(__FILE__))
|
2
|
+
include CassandraCQL
|
3
|
+
|
4
|
+
describe "UUID" do
|
5
|
+
it "should respond_to to_guid" do
|
6
|
+
UUID.new.respond_to?(:to_guid)
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should respond_to to_time" do
|
10
|
+
UUID.new.respond_to?(:to_time)
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should instantiate from raw bytes" do
|
14
|
+
UUID.new("\252}\303\374\3137\021\340\237\214\251}\315\351 ]")
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should instantiate from a Time object" do
|
18
|
+
ts = Time.new
|
19
|
+
UUID.new(ts).to_time.should eq(ts)
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should turn have a to_time class method that takes bytes" do
|
23
|
+
UUID.to_time("\252}\303\374\3137\021\340\237\214\251}\315\351 ]").should be_kind_of(Time)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
@@ -0,0 +1,250 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require File.expand_path('spec_helper.rb', File.dirname(__FILE__))
|
3
|
+
include CassandraCQL
|
4
|
+
|
5
|
+
describe "Validation Roundtrip tests" do
|
6
|
+
before(:each) do
|
7
|
+
@connection = setup_cassandra_connection
|
8
|
+
end
|
9
|
+
|
10
|
+
def create_and_fetch_column(column_family, value)
|
11
|
+
@connection.execute("insert into #{column_family} (id, test_column) values (?, ?)", 'test', value)
|
12
|
+
return @connection.execute("select test_column from #{column_family} where id = ?", 'test').fetch[0]
|
13
|
+
end
|
14
|
+
|
15
|
+
def create_column_family(name, test_column_type, opts="")
|
16
|
+
if !@connection.schema.column_family_names.include?(name)
|
17
|
+
@connection.execute("CREATE COLUMNFAMILY #{name} (id text PRIMARY KEY, test_column #{test_column_type}) #{opts}")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
context "with ascii validation" do
|
22
|
+
let(:cf_name) { "validation_cf_ascii" }
|
23
|
+
before(:each) { create_column_family(cf_name, 'ascii') }
|
24
|
+
|
25
|
+
it "should return an ascii string" do
|
26
|
+
create_and_fetch_column(cf_name, "test string").should eq("test string")
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context "with bigint validation" do
|
31
|
+
let(:cf_name) { "validation_cf_bigint" }
|
32
|
+
before(:each) { create_column_family(cf_name, 'bigint') }
|
33
|
+
|
34
|
+
def test_for_value(value)
|
35
|
+
create_and_fetch_column(cf_name, value).should eq(value)
|
36
|
+
create_and_fetch_column(cf_name, value*-1).should eq(value*-1)
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should properly convert integer values that fit into 1 byte" do
|
40
|
+
test_for_value(1)
|
41
|
+
end
|
42
|
+
it "should properly convert integer values that fit into 2 bytes" do
|
43
|
+
test_for_value(2**8 + 80)
|
44
|
+
end
|
45
|
+
it "should properly convert integer values that fit into 3 bytes" do
|
46
|
+
test_for_value(2**16 + 622)
|
47
|
+
end
|
48
|
+
it "should properly convert integer values that fit into 4 bytes" do
|
49
|
+
test_for_value(2**24 + 45820)
|
50
|
+
end
|
51
|
+
it "should properly convert integer values that fit into 5 bytes" do
|
52
|
+
test_for_value(2**32 + 618387)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context "with blob validation" do
|
57
|
+
let(:cf_name) { "validation_cf_blob" }
|
58
|
+
before(:each) { create_column_family(cf_name, 'blob') }
|
59
|
+
|
60
|
+
it "should return a blob" do
|
61
|
+
bytes = "binary\x00"
|
62
|
+
bytes = bytes.force_encoding('ASCII-8BIT') if RUBY_VERSION >= "1.9"
|
63
|
+
create_and_fetch_column(cf_name, bytes).should eq(bytes)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
context "with boolean validation" do
|
68
|
+
let(:cf_name) { "validation_cf_boolean" }
|
69
|
+
before(:each) { create_column_family(cf_name, 'boolean') }
|
70
|
+
|
71
|
+
it "should return true" do
|
72
|
+
create_and_fetch_column(cf_name, true).should be_true
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should return false" do
|
76
|
+
create_and_fetch_column(cf_name, false).should be_false
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
context "with counter validation" do
|
81
|
+
let(:cf_name) { "validation_cf_counter" }
|
82
|
+
before(:each) {
|
83
|
+
if !@connection.schema.column_family_names.include?(cf_name)
|
84
|
+
@connection.execute("CREATE COLUMNFAMILY #{cf_name} (id text PRIMARY KEY) WITH default_validation=CounterColumnType")
|
85
|
+
end
|
86
|
+
@connection.execute("TRUNCATE #{cf_name}")
|
87
|
+
}
|
88
|
+
|
89
|
+
it "should increment a few times" do
|
90
|
+
10.times do |i|
|
91
|
+
@connection.execute("UPDATE #{cf_name} SET test=test + 1 WHERE id=?", 'test_key')
|
92
|
+
@connection.execute("SELECT test FROM #{cf_name} WHERE id=?", 'test_key').fetch[0].should eq(i+1)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
it "should decrement a few times" do
|
97
|
+
10.times do |i|
|
98
|
+
@connection.execute("UPDATE #{cf_name} SET test=test - 1 WHERE id=?", 'test_key')
|
99
|
+
@connection.execute("SELECT test FROM #{cf_name} WHERE id=?", 'test_key').fetch[0].should eq((i+1)*-1)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
context "with decimal validation" do
|
105
|
+
let(:cf_name) { "validation_cf_decimal" }
|
106
|
+
before(:each) { create_column_family(cf_name, 'decimal') }
|
107
|
+
|
108
|
+
def test_for_value(value)
|
109
|
+
create_and_fetch_column(cf_name, value).should eq(value)
|
110
|
+
create_and_fetch_column(cf_name, value*-1).should eq(value*-1)
|
111
|
+
end
|
112
|
+
|
113
|
+
it "should return a small decimal" do
|
114
|
+
test_for_value(15.333)
|
115
|
+
end
|
116
|
+
it "should return a huge decimal" do
|
117
|
+
test_for_value(BigDecimal.new('129182739481237481341234123411.1029348102934810293481039'))
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
context "with double validation" do
|
122
|
+
let(:cf_name) { "validation_cf_double" }
|
123
|
+
before(:each) { create_column_family(cf_name, 'double') }
|
124
|
+
|
125
|
+
def test_for_value(value)
|
126
|
+
create_and_fetch_column(cf_name, value).should be_within(0.1).of(value)
|
127
|
+
create_and_fetch_column(cf_name, value*-1).should be_within(0.1).of(-1*value)
|
128
|
+
end
|
129
|
+
|
130
|
+
it "should properly convert some float values" do
|
131
|
+
test_for_value(1.125)
|
132
|
+
test_for_value(384.125)
|
133
|
+
test_for_value(65540.125)
|
134
|
+
test_for_value(16777217.125)
|
135
|
+
test_for_value(1099511627776.125)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
context "with float validation" do
|
140
|
+
let(:cf_name) { "validation_cf_float" }
|
141
|
+
before(:each) { create_column_family(cf_name, 'float') }
|
142
|
+
|
143
|
+
def test_for_value(value)
|
144
|
+
create_and_fetch_column(cf_name, value*-1).should eq(value*-1)
|
145
|
+
create_and_fetch_column(cf_name, value).should eq(value)
|
146
|
+
end
|
147
|
+
|
148
|
+
it "should properly convert some float values" do
|
149
|
+
test_for_value(1.125)
|
150
|
+
test_for_value(384.125)
|
151
|
+
test_for_value(65540.125)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
context "with int validation" do
|
156
|
+
let(:cf_name) { "validation_cf_int" }
|
157
|
+
before(:each) { create_column_family(cf_name, 'int') }
|
158
|
+
|
159
|
+
def test_for_value(value)
|
160
|
+
create_and_fetch_column(cf_name, value).should eq(value)
|
161
|
+
create_and_fetch_column(cf_name, value*-1).should eq(value*-1)
|
162
|
+
end
|
163
|
+
|
164
|
+
it "should properly convert integer values that fit into 1 byte" do
|
165
|
+
test_for_value(1)
|
166
|
+
end
|
167
|
+
it "should properly convert integer values that fit into 2 bytes" do
|
168
|
+
test_for_value(2**8 + 80)
|
169
|
+
end
|
170
|
+
it "should properly convert integer values that fit into 3 bytes" do
|
171
|
+
test_for_value(2**16 + 622)
|
172
|
+
end
|
173
|
+
it "should properly convert integer values that fit into 4 bytes" do
|
174
|
+
test_for_value(2**24 + 45820)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
context "with text validation" do
|
179
|
+
let(:cf_name) { "validation_cf_text" }
|
180
|
+
before(:each) { create_column_family(cf_name, 'varchar') }
|
181
|
+
|
182
|
+
it "should return a non-multibyte string" do
|
183
|
+
create_and_fetch_column(cf_name, "snark").should eq("snark")
|
184
|
+
end
|
185
|
+
|
186
|
+
it "should return a multibyte string" do
|
187
|
+
if RUBY_VERSION >= "1.9"
|
188
|
+
create_and_fetch_column(cf_name, "sn\xC3\xA5rk".force_encoding('UTF-8')).should eq("sn\xC3\xA5rk".force_encoding('UTF-8'))
|
189
|
+
else
|
190
|
+
create_and_fetch_column(cf_name, "snårk").should eq("snårk")
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
context "with timestamp validation" do
|
196
|
+
let(:cf_name) { "validation_cf_timestamp" }
|
197
|
+
before(:each) { create_column_family(cf_name, 'timestamp') }
|
198
|
+
|
199
|
+
it "should return a timestamp" do
|
200
|
+
uuid = UUID.new
|
201
|
+
#create_and_fetch_column(cf_name, uuid).should eq(uuid)
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
context "with uuid validation" do
|
206
|
+
let(:cf_name) { "validation_cf_uuid" }
|
207
|
+
before(:each) { create_column_family(cf_name, 'uuid') }
|
208
|
+
|
209
|
+
it "should return a uuid" do
|
210
|
+
uuid = UUID.new
|
211
|
+
create_and_fetch_column(cf_name, uuid).should eq(uuid)
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
context "with varchar validation" do
|
216
|
+
let(:cf_name) { "validation_cf_varchar" }
|
217
|
+
before(:each) { create_column_family(cf_name, 'varchar') }
|
218
|
+
|
219
|
+
it "should return a non-multibyte string" do
|
220
|
+
create_and_fetch_column(cf_name, "snark").should eq("snark")
|
221
|
+
end
|
222
|
+
|
223
|
+
it "should return a multibyte string" do
|
224
|
+
create_and_fetch_column(cf_name, "snårk").should eq("snårk")
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
context "with varint validation" do
|
229
|
+
let(:cf_name) { "validation_cf_varint" }
|
230
|
+
before(:each) { create_column_family(cf_name, 'varint') }
|
231
|
+
|
232
|
+
def test_for_value(value)
|
233
|
+
create_and_fetch_column(cf_name, value).should eq(value)
|
234
|
+
create_and_fetch_column(cf_name, value*-1).should eq(value*-1)
|
235
|
+
end
|
236
|
+
|
237
|
+
it "should properly convert integer values that fit into 1 byte" do
|
238
|
+
test_for_value(1)
|
239
|
+
end
|
240
|
+
it "should properly convert integer values that fit into 2 bytes" do
|
241
|
+
test_for_value(2**8 + 80)
|
242
|
+
end
|
243
|
+
it "should properly convert integer values that fit into 3 bytes" do
|
244
|
+
test_for_value(2**16 + 622)
|
245
|
+
end
|
246
|
+
it "should properly convert integer values that fit into more than 8 bytes" do
|
247
|
+
test_for_value(2**256)
|
248
|
+
end
|
249
|
+
end
|
250
|
+
end
|