cassandra-cql 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
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,21 @@
1
+ =begin
2
+ Copyright 2011 Inside Systems, Inc.
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ =end
16
+
17
+ require 'simple_uuid'
18
+
19
+ module CassandraCQL
20
+ class UUID < SimpleUUID::UUID; end
21
+ end
@@ -0,0 +1,19 @@
1
+ =begin
2
+ Copyright 2011 Inside Systems, Inc.
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ =end
16
+
17
+ module CassandraCQL
18
+ VERSION = "1.0.1"
19
+ end
@@ -0,0 +1,105 @@
1
+ require File.expand_path('spec_helper.rb', File.dirname(__FILE__))
2
+ include CassandraCQL
3
+
4
+ describe "ColumnFamily class" do
5
+ before(:each) do
6
+ @connection = setup_cassandra_connection
7
+ @connection.execute("USE system")
8
+ @super_column_family = @connection.schema.column_families["HintsColumnFamily"]
9
+ @standard_column_family = @connection.schema.column_families["NodeIdInfo"]
10
+ end
11
+
12
+ context "initialize" do
13
+ it "should set a cf_def" do
14
+ @super_column_family.cf_def.should_not be_nil
15
+ @standard_column_family.cf_def.should_not be_nil
16
+ end
17
+
18
+ it "should have some common attributes" do
19
+ [@standard_column_family, @super_column_family].each do |column|
20
+ column.name.should_not be_nil
21
+ column.id.should_not be_nil
22
+ column.column_type.should_not be_nil
23
+ end
24
+ end
25
+
26
+ it "should super method_missing" do
27
+ expect {
28
+ @standard_column_family.this_method_does_not_exist
29
+ }.to raise_error NoMethodError
30
+ expect {
31
+ @super_column_family.this_method_does_not_exist
32
+ }.to raise_error NoMethodError
33
+ end
34
+ end
35
+
36
+ context "with a standard column family" do
37
+ it "should be standard" do
38
+ @standard_column_family.super?.should be_false
39
+ @standard_column_family.standard?.should be_true
40
+ @standard_column_family.type.should eq("Standard")
41
+ end
42
+ end
43
+
44
+ context "with a super column family" do
45
+ it "should be super" do
46
+ @super_column_family.super?.should be_true
47
+ @super_column_family.standard?.should be_false
48
+ @super_column_family.type.should eq("Super")
49
+ end
50
+ end
51
+
52
+ context "when calling self.cast" do
53
+ it "should turn UUID bytes into a UUID object" do
54
+ uuid = UUID.new
55
+ ColumnFamily.cast(uuid.bytes, "TimeUUIDType").should eq(uuid)
56
+ end
57
+
58
+ it "should turn a UUID bytes into a UUID object" do
59
+ uuid = UUID.new
60
+ ColumnFamily.cast(uuid.bytes, "UUIDType").should eq(uuid)
61
+ end
62
+
63
+ it "should turn a packed long into a number" do
64
+ number = 2**33
65
+ packed = [number >> 32, number].pack("N*")
66
+
67
+ ColumnFamily.cast(packed, "LongType").should eq(number)
68
+ ColumnFamily.cast(packed, "CounterColumnType").should eq(number)
69
+ end
70
+
71
+ it "should turn a packed negative long into a negative number" do
72
+ number = -2**33
73
+ packed = [number >> 32, number].pack("N*")
74
+
75
+ ColumnFamily.cast(packed, "LongType").should eq(number)
76
+ ColumnFamily.cast(packed, "CounterColumnType").should eq(number)
77
+ end
78
+
79
+ it "should call to_s with AsciiType" do
80
+ obj = double("String")
81
+ obj.stub(:to_s) { "string" }
82
+ obj.should_receive(:to_s)
83
+ ColumnFamily.cast(obj, "AsciiType")
84
+ end
85
+
86
+ it "should call to_s with UTF8Type" do
87
+ obj = double("String")
88
+ obj.stub(:to_s) { "string" }
89
+ obj.should_receive(:to_s)
90
+ ColumnFamily.cast(obj, "UTF8Type")
91
+ end
92
+
93
+ it "should return self with BytesType" do
94
+ obj = Object.new
95
+ ColumnFamily.cast(obj, "BytesType").object_id.should eq(obj.object_id)
96
+ end
97
+
98
+ it "should return nil for all types of nil" do
99
+ %w(TimeUUIDType UUIDType LongType IntegerType
100
+ UTF8Type AsciiType CounterColumnType).each do |type|
101
+ ColumnFamily.cast(nil, type).should eq(nil)
102
+ end
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,225 @@
1
+ # encoding: utf-8
2
+ require File.expand_path('spec_helper.rb', File.dirname(__FILE__))
3
+ include CassandraCQL
4
+
5
+ describe "Comparator Roundtrip tests" do
6
+ before(:each) do
7
+ @connection = setup_cassandra_connection
8
+ end
9
+
10
+ def create_and_fetch_column(column_family, name)
11
+ @connection.execute("insert into #{column_family} (id, ?) values (?, ?)", name, 'test', 'test')
12
+ row = @connection.execute("select ? from #{column_family} where id = ?", name, 'test').fetch
13
+ row.column_names[0]
14
+ end
15
+
16
+ def create_column_family(name, comparator_type)
17
+ if !@connection.schema.column_family_names.include?(name)
18
+ @connection.execute("CREATE COLUMNFAMILY #{name} (id text PRIMARY KEY) WITH comparator=?", comparator_type)
19
+ end
20
+ end
21
+
22
+ context "with ascii comparator" do
23
+ let(:cf_name) { "comparator_cf_ascii" }
24
+ before(:each) { create_column_family(cf_name, 'AsciiType') }
25
+
26
+ it "should return an ascii string" do
27
+ create_and_fetch_column(cf_name, "test string").should eq("test string")
28
+ end
29
+ end
30
+
31
+ context "with bigint comparator" do
32
+ let(:cf_name) { "comparator_cf_bigint" }
33
+ before(:each) { create_column_family(cf_name, 'LongType') }
34
+
35
+ def test_for_value(value)
36
+ create_and_fetch_column(cf_name, value).should eq(value)
37
+ create_and_fetch_column(cf_name, value*-1).should eq(value*-1)
38
+ end
39
+
40
+ it "should properly convert integer values that fit into 1 byte" do
41
+ test_for_value(1)
42
+ end
43
+ it "should properly convert integer values that fit into 2 bytes" do
44
+ test_for_value(2**8 + 80)
45
+ end
46
+ it "should properly convert integer values that fit into 3 bytes" do
47
+ test_for_value(2**16 + 622)
48
+ end
49
+ it "should properly convert integer values that fit into 4 bytes" do
50
+ test_for_value(2**24 + 45820)
51
+ end
52
+ it "should properly convert integer values that fit into 5 bytes" do
53
+ test_for_value(2**32 + 618387)
54
+ end
55
+ end
56
+
57
+ context "with blob comparator" do
58
+ let(:cf_name) { "comparator_cf_blob" }
59
+ before(:each) { create_column_family(cf_name, 'BytesType') }
60
+
61
+ it "should return a blob" do
62
+ bytes = "binary\x00"
63
+ bytes = bytes.force_encoding('ASCII-8BIT') if RUBY_VERSION >= "1.9"
64
+ create_and_fetch_column(cf_name, bytes).should eq(bytes)
65
+ end
66
+ end
67
+
68
+ context "with boolean comparator" do
69
+ let(:cf_name) { "comparator_cf_boolean" }
70
+ before(:each) { create_column_family(cf_name, 'BooleanType') }
71
+
72
+ it "should return true" do
73
+ create_and_fetch_column(cf_name, true).should be_true
74
+ end
75
+
76
+ it "should return false" do
77
+ create_and_fetch_column(cf_name, false).should be_false
78
+ end
79
+ end
80
+
81
+
82
+ context "with decimal comparator" do
83
+ let(:cf_name) { "comparator_cf_decimal" }
84
+ before(:each) { create_column_family(cf_name, 'DecimalType') }
85
+
86
+ def test_for_value(value)
87
+ create_and_fetch_column(cf_name, value).should eq(value)
88
+ create_and_fetch_column(cf_name, value*-1).should eq(value*-1)
89
+ end
90
+
91
+ # These tests currently crash the node
92
+ it "should return a small decimal" #do
93
+ # test_for_value(15.333)
94
+ # end
95
+ it "should return a huge decimal" #do
96
+ # test_for_value(BigDecimal.new('129182739481237481341234123411.1029348102934810293481039'))
97
+ # end
98
+ end
99
+
100
+ context "with double comparator" do
101
+ let(:cf_name) { "comparator_cf_double" }
102
+ before(:each) { create_column_family(cf_name, 'DoubleType') }
103
+
104
+ def test_for_value(value)
105
+ create_and_fetch_column(cf_name, value).should be_within(0.1).of(value)
106
+ create_and_fetch_column(cf_name, value*-1).should be_within(0.1).of(value*-1)
107
+ end
108
+
109
+ it "should properly convert some float values" do
110
+ test_for_value(1.125)
111
+ test_for_value(384.125)
112
+ test_for_value(65540.125)
113
+ test_for_value(16777217.125)
114
+ test_for_value(109911627776.125)
115
+ end
116
+ end
117
+
118
+ context "with float comparator" do
119
+ let(:cf_name) { "comparator_cf_float" }
120
+ before(:each) { create_column_family(cf_name, 'FloatType') }
121
+
122
+ def test_for_value(value)
123
+ create_and_fetch_column(cf_name, value*-1).should eq(value*-1)
124
+ create_and_fetch_column(cf_name, value).should eq(value)
125
+ end
126
+
127
+ it "should properly convert some float values" do
128
+ test_for_value(1.125)
129
+ test_for_value(384.125)
130
+ test_for_value(65540.125)
131
+ end
132
+ end
133
+
134
+ context "with int comparator" do
135
+ let(:cf_name) { "comparator_cf_int" }
136
+ before(:each) { create_column_family(cf_name, 'Int32Type') }
137
+
138
+ def test_for_value(value)
139
+ create_and_fetch_column(cf_name, value).should eq(value)
140
+ create_and_fetch_column(cf_name, value*-1).should eq(value*-1)
141
+ end
142
+
143
+ it "should properly convert integer values that fit into 1 byte" do
144
+ test_for_value(1)
145
+ end
146
+ it "should properly convert integer values that fit into 2 bytes" do
147
+ test_for_value(2**8 + 80)
148
+ end
149
+ it "should properly convert integer values that fit into 3 bytes" do
150
+ test_for_value(2**16 + 622)
151
+ end
152
+ it "should properly convert integer values that fit into 4 bytes" do
153
+ test_for_value(2**24 + 45820)
154
+ end
155
+ end
156
+
157
+ context "with text comparator" do
158
+ let(:cf_name) { "comparator_cf_text" }
159
+ before(:each) { create_column_family(cf_name, 'UTF8Type') }
160
+
161
+ it "should return a non-multibyte string" do
162
+ create_and_fetch_column(cf_name, "snark").should eq("snark")
163
+ end
164
+
165
+ it "should return a multibyte string" do
166
+ create_and_fetch_column(cf_name, "snårk").should eq("snårk")
167
+ end
168
+ end
169
+
170
+ context "with timestamp comparator" do
171
+ let(:cf_name) { "comparator_cf_timestamp" }
172
+ before(:each) { create_column_family(cf_name, 'TimeUUIDType') }
173
+
174
+ it "should return a timestamp" do
175
+ uuid = UUID.new
176
+ create_and_fetch_column(cf_name, uuid).should eq(uuid)
177
+ end
178
+ end
179
+
180
+ context "with uuid comparator" do
181
+ let(:cf_name) { "comparator_cf_uuid" }
182
+ before(:each) { create_column_family(cf_name, 'UUIDType') }
183
+
184
+ it "should return a uuid" do
185
+ uuid = UUID.new
186
+ create_and_fetch_column(cf_name, uuid).should eq(uuid)
187
+ end
188
+ end
189
+
190
+ context "with varchar comparator" do
191
+ let(:cf_name) { "comparator_cf_varchar" }
192
+ before(:each) { create_column_family(cf_name, 'UTF8Type') }
193
+
194
+ it "should return a non-multibyte string" do
195
+ create_and_fetch_column(cf_name, "snark").should eq("snark")
196
+ end
197
+
198
+ it "should return a multibyte string" do
199
+ create_and_fetch_column(cf_name, "snårk").should eq("snårk")
200
+ end
201
+ end
202
+
203
+ context "with varint comparator" do
204
+ let(:cf_name) { "comparator_cf_varint" }
205
+ before(:each) { create_column_family(cf_name, 'IntegerType') }
206
+
207
+ def test_for_value(value)
208
+ create_and_fetch_column(cf_name, value).should eq(value)
209
+ create_and_fetch_column(cf_name, value*-1).should eq(value*-1)
210
+ end
211
+
212
+ it "should properly convert integer values that fit into 1 byte" do
213
+ test_for_value(1)
214
+ end
215
+ it "should properly convert integer values that fit into 2 bytes" do
216
+ test_for_value(2**8 + 80)
217
+ end
218
+ it "should properly convert integer values that fit into 3 bytes" do
219
+ test_for_value(2**16 + 622)
220
+ end
221
+ it "should properly convert integer values that fit into more than 8 bytes" do
222
+ test_for_value(2**256)
223
+ end
224
+ end
225
+ end
@@ -0,0 +1,41 @@
1
+ # Licensed to the Apache Software Foundation (ASF) under one
2
+ # or more contributor license agreements. See the NOTICE file
3
+ # distributed with this work for additional information
4
+ # regarding copyright ownership. The ASF licenses this file
5
+ # to you under the Apache License, Version 2.0 (the
6
+ # "License"); you may not use this file except in compliance
7
+ # with the License. You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ if [ "x$CASSANDRA_HOME" = "x" ]; then
18
+ CASSANDRA_HOME=`dirname $0`/..
19
+ fi
20
+
21
+ # The directory where Cassandra's configs live (required)
22
+ if [ "x$CASSANDRA_CONF" = "x" ]; then
23
+ CASSANDRA_CONF=$CASSANDRA_HOME/conf
24
+ fi
25
+
26
+ # This can be the path to a jar file, or a directory containing the
27
+ # compiled classes. NOTE: This isn't needed by the startup script,
28
+ # it's just used here in constructing the classpath.
29
+ cassandra_bin=$CASSANDRA_HOME/build/classes/main
30
+ cassandra_bin=$cassandra_bin:$CASSANDRA_HOME/build/classes/thrift
31
+ #cassandra_bin=$cassandra_home/build/cassandra.jar
32
+
33
+ # JAVA_HOME can optionally be set here
34
+ #JAVA_HOME=/usr/local/jdk6
35
+
36
+ # The java classpath (required)
37
+ CLASSPATH=$CASSANDRA_CONF:$cassandra_bin
38
+
39
+ for jar in $CASSANDRA_HOME/lib/*.jar; do
40
+ CLASSPATH=$CLASSPATH:$jar
41
+ done
@@ -0,0 +1,61 @@
1
+ # Cassandra storage config YAML
2
+ cluster_name: 'Test'
3
+ initial_token:
4
+ auto_bootstrap: false
5
+ hinted_handoff_enabled: true
6
+ max_hint_window_in_ms: 3600000 # one hour
7
+ hinted_handoff_throttle_delay_in_ms: 50
8
+ authenticator: org.apache.cassandra.auth.AllowAllAuthenticator
9
+ authority: org.apache.cassandra.auth.AllowAllAuthority
10
+ partitioner: org.apache.cassandra.dht.RandomPartitioner
11
+
12
+ # directories where Cassandra should store data on disk.
13
+ data_file_directories:
14
+ - data/data
15
+ commitlog_directory: data/commitlog
16
+
17
+ # saved caches
18
+ saved_caches_directory: data/saved_caches
19
+
20
+ commitlog_rotation_threshold_in_mb: 128
21
+ commitlog_sync: periodic
22
+ commitlog_sync_period_in_ms: 10000
23
+ seed_provider:
24
+ - class_name: org.apache.cassandra.locator.SimpleSeedProvider
25
+ parameters:
26
+ - seeds: "127.0.0.1"
27
+ flush_largest_memtables_at: 0.75
28
+ reduce_cache_sizes_at: 0.85
29
+ reduce_cache_capacity_to: 0.6
30
+ concurrent_reads: 32
31
+ concurrent_writes: 32
32
+ memtable_flush_queue_size: 4
33
+ sliced_buffer_size_in_kb: 64
34
+ storage_port: 7000
35
+ listen_address: localhost
36
+ rpc_address: localhost
37
+ rpc_port: 9160
38
+ rpc_keepalive: true
39
+ thrift_framed_transport_size_in_mb: 15
40
+ thrift_max_message_length_in_mb: 16
41
+ incremental_backups: false
42
+ snapshot_before_compaction: false
43
+ column_index_size_in_kb: 64
44
+ in_memory_compaction_limit_in_mb: 64
45
+ concurrent_compactors: 1
46
+ compaction_throughput_mb_per_sec: 16
47
+ compaction_preheat_key_cache: true
48
+ rpc_timeout_in_ms: 10000
49
+ endpoint_snitch: org.apache.cassandra.locator.SimpleSnitch
50
+ dynamic_snitch: true
51
+ dynamic_snitch_update_interval_in_ms: 100
52
+ dynamic_snitch_reset_interval_in_ms: 600000
53
+ dynamic_snitch_badness_threshold: 0.0
54
+ request_scheduler: org.apache.cassandra.scheduler.NoScheduler
55
+ index_interval: 128
56
+ encryption_options:
57
+ internode_encryption: none
58
+ keystore: conf/.keystore
59
+ keystore_password: cassandra
60
+ truststore: conf/.truststore
61
+ truststore_password: cassandra