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.
Files changed (49) hide show
  1. data/.gitignore +9 -0
  2. data/Gemfile +4 -0
  3. data/LICENSE.txt +203 -0
  4. data/README.rdoc +78 -0
  5. data/Rakefile +150 -0
  6. data/cassandra-cql.gemspec +29 -0
  7. data/lib/cassandra-cql.rb +39 -0
  8. data/lib/cassandra-cql/database.rb +107 -0
  9. data/lib/cassandra-cql/result.rb +133 -0
  10. data/lib/cassandra-cql/row.rb +59 -0
  11. data/lib/cassandra-cql/schema.rb +108 -0
  12. data/lib/cassandra-cql/statement.rb +111 -0
  13. data/lib/cassandra-cql/types/abstract_type.rb +47 -0
  14. data/lib/cassandra-cql/types/ascii_type.rb +25 -0
  15. data/lib/cassandra-cql/types/boolean_type.rb +25 -0
  16. data/lib/cassandra-cql/types/bytes_type.rb +21 -0
  17. data/lib/cassandra-cql/types/decimal_type.rb +25 -0
  18. data/lib/cassandra-cql/types/double_type.rb +25 -0
  19. data/lib/cassandra-cql/types/float_type.rb +25 -0
  20. data/lib/cassandra-cql/types/integer_type.rb +27 -0
  21. data/lib/cassandra-cql/types/long_type.rb +27 -0
  22. data/lib/cassandra-cql/types/utf8_type.rb +25 -0
  23. data/lib/cassandra-cql/types/uuid_type.rb +27 -0
  24. data/lib/cassandra-cql/utility.rb +37 -0
  25. data/lib/cassandra-cql/uuid.rb +21 -0
  26. data/lib/cassandra-cql/version.rb +19 -0
  27. data/spec/column_family_spec.rb +105 -0
  28. data/spec/comparator_spec.rb +225 -0
  29. data/spec/conf/0.8/cassandra.in.sh +41 -0
  30. data/spec/conf/0.8/cassandra.yaml +61 -0
  31. data/spec/conf/0.8/log4j-server.properties +40 -0
  32. data/spec/conf/0.8/schema.txt +10 -0
  33. data/spec/conf/1.0/cassandra.in.sh +41 -0
  34. data/spec/conf/1.0/cassandra.yaml +416 -0
  35. data/spec/conf/1.0/log4j-server.properties +40 -0
  36. data/spec/conf/1.0/schema.txt +10 -0
  37. data/spec/result_spec.rb +173 -0
  38. data/spec/row_spec.rb +55 -0
  39. data/spec/rowkey_spec.rb +223 -0
  40. data/spec/schema_spec.rb +51 -0
  41. data/spec/spec_helper.rb +23 -0
  42. data/spec/statement_spec.rb +224 -0
  43. data/spec/utility_spec.rb +26 -0
  44. data/spec/uuid_spec.rb +26 -0
  45. data/spec/validation_spec.rb +250 -0
  46. data/vendor/gen-rb/cassandra.rb +2212 -0
  47. data/vendor/gen-rb/cassandra_constants.rb +10 -0
  48. data/vendor/gen-rb/cassandra_types.rb +854 -0
  49. metadata +171 -0
@@ -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
@@ -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
+
@@ -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