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