mcmire-cassandra 0.12.2 → 0.12.3
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/CHANGELOG +7 -2
- data/Gemfile +8 -0
- data/Manifest +16 -0
- data/conf/0.8/schema.json +4 -1
- data/conf/0.8/schema.txt +1 -1
- data/conf/1.0/cassandra.in.sh +41 -0
- data/conf/1.0/cassandra.yaml +415 -0
- data/conf/1.0/log4j-server.properties +40 -0
- data/conf/1.0/schema.json +69 -0
- data/conf/1.0/schema.txt +51 -0
- data/lib/cassandra.rb +1 -0
- data/lib/cassandra/1.0.rb +7 -0
- data/lib/cassandra/1.0/cassandra.rb +10 -0
- data/lib/cassandra/1.0/columns.rb +4 -0
- data/lib/cassandra/1.0/protocol.rb +23 -0
- data/lib/cassandra/columns.rb +2 -1
- data/lib/cassandra/composite.rb +118 -0
- data/mcmire-cassandra.gemspec +5 -5
- data/test/cassandra_mock_test.rb +6 -0
- data/test/cassandra_test.rb +58 -13
- data/test/composite_type_test.rb +29 -0
- data/vendor/1.0/gen-rb/cassandra.rb +2215 -0
- data/vendor/1.0/gen-rb/cassandra_constants.rb +12 -0
- data/vendor/1.0/gen-rb/cassandra_types.rb +857 -0
- metadata +32 -11
@@ -0,0 +1,40 @@
|
|
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
|
+
# for production, you should probably set pattern to %c instead of %l.
|
18
|
+
# (%l is slower.)
|
19
|
+
|
20
|
+
# output messages into a rolling log file as well as stdout
|
21
|
+
log4j.rootLogger=INFO,stdout,R
|
22
|
+
|
23
|
+
# stdout
|
24
|
+
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
|
25
|
+
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
|
26
|
+
log4j.appender.stdout.layout.ConversionPattern=%5p %d{HH:mm:ss,SSS} %m%n
|
27
|
+
|
28
|
+
# rolling log file
|
29
|
+
log4j.appender.R=org.apache.log4j.RollingFileAppender
|
30
|
+
log4j.appender.R.maxFileSize=20MB
|
31
|
+
log4j.appender.R.maxBackupIndex=50
|
32
|
+
log4j.appender.R.layout=org.apache.log4j.PatternLayout
|
33
|
+
log4j.appender.R.layout.ConversionPattern=%5p [%t] %d{ISO8601} %F (line %L) %m%n
|
34
|
+
# Edit the next line to point to your logs directory
|
35
|
+
log4j.appender.R.File=data/logs/system.log
|
36
|
+
|
37
|
+
# Application logging options
|
38
|
+
#log4j.logger.org.apache.cassandra=DEBUG
|
39
|
+
#log4j.logger.org.apache.cassandra.db=DEBUG
|
40
|
+
#log4j.logger.org.apache.cassandra.service.StorageProxy=DEBUG
|
@@ -0,0 +1,69 @@
|
|
1
|
+
{"Twitter":{
|
2
|
+
"Users":{
|
3
|
+
"comparator_type":"org.apache.cassandra.db.marshal.UTF8Type",
|
4
|
+
"column_type":"Standard"},
|
5
|
+
"UserAudits":{
|
6
|
+
"comparator_type":"org.apache.cassandra.db.marshal.UTF8Type",
|
7
|
+
"column_type":"Standard"},
|
8
|
+
"UserCounters":{
|
9
|
+
"comparator_type":"org.apache.cassandra.db.marshal.UTF8Type",
|
10
|
+
"column_type":"Standard",
|
11
|
+
"default_validation_class":"CounterColumnType"},
|
12
|
+
"UserCounterAggregates":{
|
13
|
+
"subcomparator_type":"org.apache.cassandra.db.marshal.UTF8Type",
|
14
|
+
"comparator_type":"org.apache.cassandra.db.marshal.UTF8Type",
|
15
|
+
"column_type":"Super",
|
16
|
+
"default_validation_class":"CounterColumnType"},
|
17
|
+
"UserRelationships":{
|
18
|
+
"subcomparator_type":"org.apache.cassandra.db.marshal.TimeUUIDType",
|
19
|
+
"comparator_type":"org.apache.cassandra.db.marshal.UTF8Type",
|
20
|
+
"column_type":"Super"},
|
21
|
+
"Usernames":{
|
22
|
+
"comparator_type":"org.apache.cassandra.db.marshal.UTF8Type",
|
23
|
+
"column_type":"Standard"},
|
24
|
+
"Statuses":{
|
25
|
+
"comparator_type":"org.apache.cassandra.db.marshal.UTF8Type",
|
26
|
+
"column_type":"Standard"},
|
27
|
+
"StatusAudits":{
|
28
|
+
"comparator_type":"org.apache.cassandra.db.marshal.UTF8Type",
|
29
|
+
"column_type":"Standard"},
|
30
|
+
"StatusRelationships":{
|
31
|
+
"subcomparator_type":"org.apache.cassandra.db.marshal.TimeUUIDType",
|
32
|
+
"comparator_type":"org.apache.cassandra.db.marshal.UTF8Type",
|
33
|
+
"column_type":"Super"},
|
34
|
+
"Indexes":{
|
35
|
+
"comparator_type":"org.apache.cassandra.db.marshal.UTF8Type",
|
36
|
+
"column_type":"Super"},
|
37
|
+
"TimelinishThings":{
|
38
|
+
"comparator_type":"org.apache.cassandra.db.marshal.BytesType",
|
39
|
+
"column_type":"Standard"}
|
40
|
+
},
|
41
|
+
"Multiblog":{
|
42
|
+
"Blogs":{
|
43
|
+
"comparator_type":"org.apache.cassandra.db.marshal.TimeUUIDType",
|
44
|
+
"column_type":"Standard"},
|
45
|
+
"Comments":{
|
46
|
+
"comparator_type":"org.apache.cassandra.db.marshal.TimeUUIDType",
|
47
|
+
"column_type":"Standard"}
|
48
|
+
},
|
49
|
+
"MultiblogLong":{
|
50
|
+
"Blogs":{
|
51
|
+
"comparator_type":"org.apache.cassandra.db.marshal.LongType",
|
52
|
+
"column_type":"Standard"},
|
53
|
+
"Comments":{
|
54
|
+
"comparator_type":"org.apache.cassandra.db.marshal.LongType",
|
55
|
+
"column_type":"Standard"}
|
56
|
+
},
|
57
|
+
"TypeConversions":{
|
58
|
+
"UUIDColumnConversion":{
|
59
|
+
"comparator_type":"org.apache.cassandra.db.marshal.TimeUUIDType",
|
60
|
+
"column_type":"Standard"},
|
61
|
+
"SuperUUID":{
|
62
|
+
"subcomparator_type":"org.apache.cassandra.db.marshal.TimeUUIDType",
|
63
|
+
"comparator_type":"org.apache.cassandra.db.marshal.TimeUUIDType",
|
64
|
+
"column_type":"Super"},
|
65
|
+
"CompositeColumnConversion":{
|
66
|
+
"comparator_type":"org.apache.cassandra.db.marshal.CompositeType(org.apache.cassandra.db.marshal.IntegerType,org.apache.cassandra.db.marshal.UTF8Type)",
|
67
|
+
"column_type":"Standard"}
|
68
|
+
}
|
69
|
+
}
|
data/conf/1.0/schema.txt
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
create keyspace Twitter with
|
2
|
+
placement_strategy = 'org.apache.cassandra.locator.SimpleStrategy' AND
|
3
|
+
strategy_options = {replication_factor:1};
|
4
|
+
use Twitter;
|
5
|
+
create column family Users with comparator = 'UTF8Type';
|
6
|
+
create column family UserAudits with comparator = 'UTF8Type';
|
7
|
+
create column family UserCounters with comparator = 'UTF8Type' and
|
8
|
+
default_validation_class = CounterColumnType;
|
9
|
+
create column family UserCounterAggregates with column_type = 'Super'
|
10
|
+
and comparator = 'UTF8Type' and
|
11
|
+
subcomparator = 'UTF8Type' and
|
12
|
+
default_validation_class = CounterColumnType;
|
13
|
+
create column family UserRelationships with
|
14
|
+
comparator = 'UTF8Type' and
|
15
|
+
column_type = 'Super' and
|
16
|
+
subcomparator = 'TimeUUIDType';
|
17
|
+
create column family Usernames with comparator = 'UTF8Type';
|
18
|
+
create column family Statuses with comparator = 'UTF8Type';
|
19
|
+
create column family StatusAudits with comparator = 'UTF8Type';
|
20
|
+
create column family StatusRelationships with
|
21
|
+
comparator = 'UTF8Type' and
|
22
|
+
column_type = 'Super' and
|
23
|
+
subcomparator = 'TimeUUIDType';
|
24
|
+
create column family Indexes with
|
25
|
+
comparator = 'UTF8Type' and
|
26
|
+
column_type = 'Super';
|
27
|
+
create column family TimelinishThings with
|
28
|
+
comparator = 'BytesType';
|
29
|
+
|
30
|
+
create keyspace Multiblog with
|
31
|
+
placement_strategy = 'org.apache.cassandra.locator.SimpleStrategy' AND
|
32
|
+
strategy_options = {replication_factor:1};
|
33
|
+
use Multiblog;
|
34
|
+
create column family Blogs with comparator = 'TimeUUIDType';
|
35
|
+
create column family Comments with comparator = 'TimeUUIDType';
|
36
|
+
|
37
|
+
|
38
|
+
create keyspace MultiblogLong with
|
39
|
+
placement_strategy = 'org.apache.cassandra.locator.SimpleStrategy' AND
|
40
|
+
strategy_options = {replication_factor:1};
|
41
|
+
use MultiblogLong;
|
42
|
+
create column family Blogs with comparator = 'LongType';
|
43
|
+
create column family Comments with comparator = 'LongType';
|
44
|
+
|
45
|
+
create keyspace TypeConversions with
|
46
|
+
placement_strategy = 'org.apache.cassandra.locator.SimpleStrategy' AND
|
47
|
+
strategy_options = {replication_factor:1};
|
48
|
+
use TypeConversions;
|
49
|
+
create column family UUIDColumnConversion with comparator = TimeUUIDType;
|
50
|
+
create column family SuperUUID with comparator = TimeUUIDType and column_type = Super;
|
51
|
+
create column family CompositeColumnConversion with comparator = 'CompositeType(IntegerType, UTF8Type)';
|
data/lib/cassandra.rb
CHANGED
@@ -0,0 +1,10 @@
|
|
1
|
+
class Cassandra
|
2
|
+
|
3
|
+
## Counters
|
4
|
+
|
5
|
+
# Add a value to the counter in cf:key:super column:column
|
6
|
+
def add(column_family, key, value, *columns_and_options)
|
7
|
+
column_family, column, sub_column, options = extract_and_validate_params(column_family, key, columns_and_options, WRITE_DEFAULTS)
|
8
|
+
_add(column_family, key, column, sub_column, value, options[:consistency])
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require "#{File.expand_path(File.dirname(__FILE__))}/../0.7/protocol"
|
2
|
+
|
3
|
+
class Cassandra
|
4
|
+
# Inner methods for actually doing the Thrift calls
|
5
|
+
module Protocol #:nodoc:
|
6
|
+
private
|
7
|
+
|
8
|
+
def _remove_counter(key, column_path, consistency_level)
|
9
|
+
client.remove_counter(key, column_path, consistency_level)
|
10
|
+
end
|
11
|
+
|
12
|
+
def _add(column_family, key, column, sub_column, value, consistency)
|
13
|
+
if is_super(column_family)
|
14
|
+
column_parent = CassandraThrift::ColumnParent.new(:column_family => column_family, :super_column => column)
|
15
|
+
counter_column = CassandraThrift::CounterColumn.new(:name => sub_column, :value => value)
|
16
|
+
else
|
17
|
+
column_parent = CassandraThrift::ColumnParent.new(:column_family => column_family)
|
18
|
+
counter_column = CassandraThrift::CounterColumn.new(:name => column, :value => value)
|
19
|
+
end
|
20
|
+
client.add(key, column_parent, counter_column, consistency)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/cassandra/columns.rb
CHANGED
@@ -18,10 +18,11 @@ class Cassandra
|
|
18
18
|
|
19
19
|
def column_name_class_for_key(column_family, comparator_key)
|
20
20
|
property = column_family_property(column_family, comparator_key)
|
21
|
-
property =~
|
21
|
+
property =~ /[^(]*\.(.*?)$/
|
22
22
|
case $1
|
23
23
|
when "LongType" then Long
|
24
24
|
when "LexicalUUIDType", "TimeUUIDType" then SimpleUUID::UUID
|
25
|
+
when /^CompositeType\(/ then Composite
|
25
26
|
else
|
26
27
|
String # UTF8, Ascii, Bytes, anything else
|
27
28
|
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
|
2
|
+
class Cassandra
|
3
|
+
class Composite
|
4
|
+
include ::Comparable
|
5
|
+
attr_reader :parts
|
6
|
+
attr_reader :column_slice
|
7
|
+
|
8
|
+
def initialize(*parts)
|
9
|
+
options = {}
|
10
|
+
if parts.last.is_a?(Hash)
|
11
|
+
options = parts.pop
|
12
|
+
end
|
13
|
+
@column_slice = options[:slice]
|
14
|
+
raise ArgumentError if @column_slice != nil && ![:before, :after].include?(@column_slice)
|
15
|
+
|
16
|
+
if parts.length == 1 && parts[0].instance_of?(self.class)
|
17
|
+
@column_slice = parts[0].column_slice
|
18
|
+
@parts = parts[0].parts
|
19
|
+
elsif parts.length == 1 && parts[0].instance_of?(String) && @column_slice.nil? && valid_packed_composite?(parts[0])
|
20
|
+
unpack(parts[0])
|
21
|
+
else
|
22
|
+
@parts = parts
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def [](*args)
|
27
|
+
return @parts[*args]
|
28
|
+
end
|
29
|
+
|
30
|
+
def pack
|
31
|
+
packed = @parts.map do |part|
|
32
|
+
[part.length].pack('n') + part + "\x00"
|
33
|
+
end
|
34
|
+
if @column_slice
|
35
|
+
part = @parts[-1]
|
36
|
+
packed[-1] = [part.length].pack('n') + part + slice_end_of_component
|
37
|
+
end
|
38
|
+
return packed.join('')
|
39
|
+
end
|
40
|
+
|
41
|
+
def to_s
|
42
|
+
return pack
|
43
|
+
end
|
44
|
+
|
45
|
+
def <=>(other)
|
46
|
+
if !other.instance_of?(self.class)
|
47
|
+
return @parts.first <=> other
|
48
|
+
end
|
49
|
+
eoc = slice_end_of_component.unpack('c')[0]
|
50
|
+
other_eoc = other.slice_end_of_component.unpack('c')[0]
|
51
|
+
@parts.zip(other.parts).each do |a, b|
|
52
|
+
next if a == b
|
53
|
+
if a.nil? && b.nil?
|
54
|
+
return eoc <=> other_eoc
|
55
|
+
end
|
56
|
+
|
57
|
+
if a.nil?
|
58
|
+
return @column_slice == :after ? 1 : -1
|
59
|
+
end
|
60
|
+
if b.nil?
|
61
|
+
return other.column_slice == :after ? -1 : 1
|
62
|
+
end
|
63
|
+
return -1 if a < b
|
64
|
+
return 1 if a > b
|
65
|
+
end
|
66
|
+
return 0
|
67
|
+
end
|
68
|
+
|
69
|
+
def inspect
|
70
|
+
return "#<Composite:#{@column_slice} #{@parts.inspect}>"
|
71
|
+
end
|
72
|
+
|
73
|
+
def slice_end_of_component
|
74
|
+
return "\x01" if @column_slice == :after
|
75
|
+
return "\xFF" if @column_slice == :before
|
76
|
+
return "\x00"
|
77
|
+
end
|
78
|
+
|
79
|
+
private
|
80
|
+
def unpack(packed_string)
|
81
|
+
parts = []
|
82
|
+
end_of_component = nil
|
83
|
+
while packed_string.length > 0
|
84
|
+
length = packed_string.slice(0, 2).unpack('n')[0]
|
85
|
+
parts << packed_string.slice(2, length)
|
86
|
+
end_of_component = packed_string.slice(2 + length, 1)
|
87
|
+
|
88
|
+
packed_string = packed_string.slice(3 + length, packed_string.length)
|
89
|
+
end
|
90
|
+
@column_slice = :after if end_of_component == "\x01"
|
91
|
+
@column_slice = :before if end_of_component == "\xFF"
|
92
|
+
@parts = parts
|
93
|
+
end
|
94
|
+
|
95
|
+
def valid_packed_composite?(packed_string)
|
96
|
+
while packed_string.length > 0
|
97
|
+
length = packed_string.slice(0, 2).unpack('n')[0]
|
98
|
+
return false if length.nil? || length + 3 > packed_string.length
|
99
|
+
|
100
|
+
end_of_component = packed_string.slice(2 + length, 1)
|
101
|
+
if length + 3 != packed_string.length
|
102
|
+
return false if end_of_component != "\x00"
|
103
|
+
end
|
104
|
+
|
105
|
+
packed_string = packed_string.slice(3 + length, packed_string.length)
|
106
|
+
end
|
107
|
+
return true
|
108
|
+
end
|
109
|
+
|
110
|
+
def hash
|
111
|
+
return to_s.hash
|
112
|
+
end
|
113
|
+
|
114
|
+
def eql?(other)
|
115
|
+
return to_s == other.to_s
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
data/mcmire-cassandra.gemspec
CHANGED
@@ -2,23 +2,23 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = "mcmire-cassandra"
|
5
|
-
s.version = "0.12.
|
5
|
+
s.version = "0.12.3"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 0.8") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["Evan Weaver, Ryan King"]
|
9
|
-
s.date = "2012-
|
9
|
+
s.date = "2012-05-08"
|
10
10
|
s.description = "A Ruby client for the Cassandra distributed database."
|
11
11
|
s.email = ""
|
12
12
|
s.executables = ["cassandra_helper"]
|
13
|
-
s.extra_rdoc_files = ["CHANGELOG", "LICENSE", "README.md", "bin/cassandra_helper", "lib/cassandra.rb", "lib/cassandra/0.6.rb", "lib/cassandra/0.6/cassandra.rb", "lib/cassandra/0.6/columns.rb", "lib/cassandra/0.6/protocol.rb", "lib/cassandra/0.7.rb", "lib/cassandra/0.7/cassandra.rb", "lib/cassandra/0.7/columns.rb", "lib/cassandra/0.7/protocol.rb", "lib/cassandra/0.8.rb", "lib/cassandra/0.8/cassandra.rb", "lib/cassandra/0.8/columns.rb", "lib/cassandra/0.8/protocol.rb", "lib/cassandra/array.rb", "lib/cassandra/cassandra.rb", "lib/cassandra/column_family.rb", "lib/cassandra/columns.rb", "lib/cassandra/comparable.rb", "lib/cassandra/constants.rb", "lib/cassandra/debug.rb", "lib/cassandra/helpers.rb", "lib/cassandra/keyspace.rb", "lib/cassandra/long.rb", "lib/cassandra/mock.rb", "lib/cassandra/ordered_hash.rb", "lib/cassandra/protocol.rb", "lib/cassandra/time.rb"]
|
14
|
-
s.files = ["CHANGELOG", "LICENSE", "Manifest", "README.md", "Rakefile", "bin/cassandra_helper", "conf/0.6/cassandra.in.sh", "conf/0.6/log4j.properties", "conf/0.6/schema.json", "conf/0.6/storage-conf.xml", "conf/0.7/cassandra.in.sh", "conf/0.7/cassandra.yaml", "conf/0.7/log4j-server.properties", "conf/0.7/schema.json", "conf/0.7/schema.txt", "conf/0.8/cassandra.in.sh", "conf/0.8/cassandra.yaml", "conf/0.8/log4j-server.properties", "conf/0.8/schema.json", "conf/0.8/schema.txt", "lib/cassandra.rb", "lib/cassandra/0.6.rb", "lib/cassandra/0.6/cassandra.rb", "lib/cassandra/0.6/columns.rb", "lib/cassandra/0.6/protocol.rb", "lib/cassandra/0.7.rb", "lib/cassandra/0.7/cassandra.rb", "lib/cassandra/0.7/columns.rb", "lib/cassandra/0.7/protocol.rb", "lib/cassandra/0.8.rb", "lib/cassandra/0.8/cassandra.rb", "lib/cassandra/0.8/columns.rb", "lib/cassandra/0.8/protocol.rb", "lib/cassandra/array.rb", "lib/cassandra/cassandra.rb", "lib/cassandra/column_family.rb", "lib/cassandra/columns.rb", "lib/cassandra/comparable.rb", "lib/cassandra/constants.rb", "lib/cassandra/debug.rb", "lib/cassandra/helpers.rb", "lib/cassandra/keyspace.rb", "lib/cassandra/long.rb", "lib/cassandra/mock.rb", "lib/cassandra/ordered_hash.rb", "lib/cassandra/protocol.rb", "lib/cassandra/time.rb", "test/cassandra_client_test.rb", "test/cassandra_mock_test.rb", "test/cassandra_test.rb", "test/comparable_types_test.rb", "test/eventmachine_test.rb", "test/ordered_hash_test.rb", "test/test_helper.rb", "vendor/0.6/gen-rb/cassandra.rb", "vendor/0.6/gen-rb/cassandra_constants.rb", "vendor/0.6/gen-rb/cassandra_types.rb", "vendor/0.7/gen-rb/cassandra.rb", "vendor/0.7/gen-rb/cassandra_constants.rb", "vendor/0.7/gen-rb/cassandra_types.rb", "vendor/0.8/gen-rb/cassandra.rb", "vendor/0.8/gen-rb/cassandra_constants.rb", "vendor/0.8/gen-rb/cassandra_types.rb", "
|
13
|
+
s.extra_rdoc_files = ["CHANGELOG", "LICENSE", "README.md", "bin/cassandra_helper", "lib/cassandra.rb", "lib/cassandra/0.6.rb", "lib/cassandra/0.6/cassandra.rb", "lib/cassandra/0.6/columns.rb", "lib/cassandra/0.6/protocol.rb", "lib/cassandra/0.7.rb", "lib/cassandra/0.7/cassandra.rb", "lib/cassandra/0.7/columns.rb", "lib/cassandra/0.7/protocol.rb", "lib/cassandra/0.8.rb", "lib/cassandra/0.8/cassandra.rb", "lib/cassandra/0.8/columns.rb", "lib/cassandra/0.8/protocol.rb", "lib/cassandra/1.0.rb", "lib/cassandra/1.0/cassandra.rb", "lib/cassandra/1.0/columns.rb", "lib/cassandra/1.0/protocol.rb", "lib/cassandra/array.rb", "lib/cassandra/cassandra.rb", "lib/cassandra/column_family.rb", "lib/cassandra/columns.rb", "lib/cassandra/comparable.rb", "lib/cassandra/composite.rb", "lib/cassandra/constants.rb", "lib/cassandra/debug.rb", "lib/cassandra/helpers.rb", "lib/cassandra/keyspace.rb", "lib/cassandra/long.rb", "lib/cassandra/mock.rb", "lib/cassandra/ordered_hash.rb", "lib/cassandra/protocol.rb", "lib/cassandra/time.rb"]
|
14
|
+
s.files = ["CHANGELOG", "Gemfile", "LICENSE", "Manifest", "README.md", "Rakefile", "bin/cassandra_helper", "conf/0.6/cassandra.in.sh", "conf/0.6/log4j.properties", "conf/0.6/schema.json", "conf/0.6/storage-conf.xml", "conf/0.7/cassandra.in.sh", "conf/0.7/cassandra.yaml", "conf/0.7/log4j-server.properties", "conf/0.7/schema.json", "conf/0.7/schema.txt", "conf/0.8/cassandra.in.sh", "conf/0.8/cassandra.yaml", "conf/0.8/log4j-server.properties", "conf/0.8/schema.json", "conf/0.8/schema.txt", "conf/1.0/cassandra.in.sh", "conf/1.0/cassandra.yaml", "conf/1.0/log4j-server.properties", "conf/1.0/schema.json", "conf/1.0/schema.txt", "lib/cassandra.rb", "lib/cassandra/0.6.rb", "lib/cassandra/0.6/cassandra.rb", "lib/cassandra/0.6/columns.rb", "lib/cassandra/0.6/protocol.rb", "lib/cassandra/0.7.rb", "lib/cassandra/0.7/cassandra.rb", "lib/cassandra/0.7/columns.rb", "lib/cassandra/0.7/protocol.rb", "lib/cassandra/0.8.rb", "lib/cassandra/0.8/cassandra.rb", "lib/cassandra/0.8/columns.rb", "lib/cassandra/0.8/protocol.rb", "lib/cassandra/1.0.rb", "lib/cassandra/1.0/cassandra.rb", "lib/cassandra/1.0/columns.rb", "lib/cassandra/1.0/protocol.rb", "lib/cassandra/array.rb", "lib/cassandra/cassandra.rb", "lib/cassandra/column_family.rb", "lib/cassandra/columns.rb", "lib/cassandra/comparable.rb", "lib/cassandra/composite.rb", "lib/cassandra/constants.rb", "lib/cassandra/debug.rb", "lib/cassandra/helpers.rb", "lib/cassandra/keyspace.rb", "lib/cassandra/long.rb", "lib/cassandra/mock.rb", "lib/cassandra/ordered_hash.rb", "lib/cassandra/protocol.rb", "lib/cassandra/time.rb", "mcmire-cassandra.gemspec", "test/cassandra_client_test.rb", "test/cassandra_mock_test.rb", "test/cassandra_test.rb", "test/comparable_types_test.rb", "test/composite_type_test.rb", "test/eventmachine_test.rb", "test/ordered_hash_test.rb", "test/test_helper.rb", "vendor/0.6/gen-rb/cassandra.rb", "vendor/0.6/gen-rb/cassandra_constants.rb", "vendor/0.6/gen-rb/cassandra_types.rb", "vendor/0.7/gen-rb/cassandra.rb", "vendor/0.7/gen-rb/cassandra_constants.rb", "vendor/0.7/gen-rb/cassandra_types.rb", "vendor/0.8/gen-rb/cassandra.rb", "vendor/0.8/gen-rb/cassandra_constants.rb", "vendor/0.8/gen-rb/cassandra_types.rb", "vendor/1.0/gen-rb/cassandra.rb", "vendor/1.0/gen-rb/cassandra_constants.rb", "vendor/1.0/gen-rb/cassandra_types.rb"]
|
15
15
|
s.homepage = "http://fauna.github.com/fauna/mcmire-cassandra/"
|
16
16
|
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Mcmire-cassandra", "--main", "README.md"]
|
17
17
|
s.require_paths = ["lib"]
|
18
18
|
s.rubyforge_project = "fauna"
|
19
19
|
s.rubygems_version = "1.8.11"
|
20
20
|
s.summary = "A Ruby client for the Cassandra distributed database."
|
21
|
-
s.test_files = ["test/cassandra_client_test.rb", "test/cassandra_mock_test.rb", "test/cassandra_test.rb", "test/comparable_types_test.rb", "test/eventmachine_test.rb", "test/ordered_hash_test.rb", "test/test_helper.rb"]
|
21
|
+
s.test_files = ["test/cassandra_client_test.rb", "test/cassandra_mock_test.rb", "test/cassandra_test.rb", "test/comparable_types_test.rb", "test/composite_type_test.rb", "test/eventmachine_test.rb", "test/ordered_hash_test.rb", "test/test_helper.rb"]
|
22
22
|
|
23
23
|
if s.respond_to? :specification_version then
|
24
24
|
s.specification_version = 3
|
data/test/cassandra_mock_test.rb
CHANGED
@@ -22,6 +22,12 @@ class CassandraMockTest < CassandraTest
|
|
22
22
|
|
23
23
|
@uuids = (0..6).map {|i| SimpleUUID::UUID.new(Time.at(2**(24+i))) }
|
24
24
|
@longs = (0..6).map {|i| Long.new(Time.at(2**(24+i))) }
|
25
|
+
@composites = [
|
26
|
+
Cassandra::Composite.new([5].pack('N'), "zebra"),
|
27
|
+
Cassandra::Composite.new([5].pack('N'), "aardvark"),
|
28
|
+
Cassandra::Composite.new([1].pack('N'), "elephant"),
|
29
|
+
Cassandra::Composite.new([10].pack('N'), "kangaroo"),
|
30
|
+
]
|
25
31
|
end
|
26
32
|
|
27
33
|
def test_setup
|
data/test/cassandra_test.rb
CHANGED
@@ -21,6 +21,12 @@ class CassandraTest < Test::Unit::TestCase
|
|
21
21
|
|
22
22
|
@uuids = (0..6).map {|i| SimpleUUID::UUID.new(Time.at(2**(24+i))) }
|
23
23
|
@longs = (0..6).map {|i| Long.new(Time.at(2**(24+i))) }
|
24
|
+
@composites = [
|
25
|
+
Cassandra::Composite.new([5].pack('N'), "zebra"),
|
26
|
+
Cassandra::Composite.new([5].pack('N'), "aardvark"),
|
27
|
+
Cassandra::Composite.new([1].pack('N'), "elephant"),
|
28
|
+
Cassandra::Composite.new([10].pack('N'), "kangaroo"),
|
29
|
+
]
|
24
30
|
end
|
25
31
|
|
26
32
|
def test_inspect
|
@@ -43,7 +49,7 @@ class CassandraTest < Test::Unit::TestCase
|
|
43
49
|
end
|
44
50
|
|
45
51
|
def test_get_key
|
46
|
-
|
52
|
+
|
47
53
|
@twitter.insert(:Users, key, {'body' => 'v', 'user' => 'v'})
|
48
54
|
assert_equal({'body' => 'v', 'user' => 'v'}, @twitter.get(:Users, key))
|
49
55
|
assert_equal(['body', 'user'].sort, @twitter.get(:Users, key).timestamps.keys.sort)
|
@@ -501,12 +507,12 @@ class CassandraTest < Test::Unit::TestCase
|
|
501
507
|
|
502
508
|
def test_count_columns
|
503
509
|
columns = (1..200).inject(Hash.new){|h,v| h['column' + v.to_s] = v.to_s; h;}
|
504
|
-
|
510
|
+
|
505
511
|
@twitter.insert(:Statuses, key, columns)
|
506
512
|
assert_equal 200, @twitter.count_columns(:Statuses, key, :count => 200)
|
507
|
-
assert_equal 100, @twitter.count_columns(:Statuses, key)
|
513
|
+
assert_equal 100, @twitter.count_columns(:Statuses, key)
|
508
514
|
assert_equal 55, @twitter.count_columns(:Statuses, key, :count => 55)
|
509
|
-
|
515
|
+
|
510
516
|
end
|
511
517
|
|
512
518
|
def test_count_super_columns
|
@@ -556,24 +562,24 @@ class CassandraTest < Test::Unit::TestCase
|
|
556
562
|
assert_equal({}, @twitter.get(:Users, k + '2')) # Not yet written
|
557
563
|
assert_equal({}, @twitter.get(:Statuses, k + '3')) # Not yet written
|
558
564
|
|
559
|
-
@twitter.remove(:Users, k + '1') # Full row
|
565
|
+
@twitter.remove(:Users, k + '1') # Full row
|
560
566
|
assert_equal({'body' => 'v1', 'user' => 'v1'}, @twitter.get(:Users, k + '1')) # Not yet removed
|
561
567
|
|
562
568
|
@twitter.remove(:Users, k + '0', 'delete_me') # A single column of the row
|
563
569
|
assert_equal({'delete_me' => 'v0', 'keep_me' => 'v0'}, @twitter.get(:Users, k + '0')) # Not yet removed
|
564
|
-
|
570
|
+
|
565
571
|
@twitter.remove(:Users, k + '4')
|
566
572
|
@twitter.insert(:Users, k + '4', {'body' => 'v4', 'user' => 'v4'})
|
567
573
|
assert_equal({}, @twitter.get(:Users, k + '4')) # Not yet written
|
568
574
|
|
569
575
|
# SuperColumns
|
570
576
|
# Add and delete new sub columns to the user timeline supercolumn
|
571
|
-
@twitter.insert(:StatusRelationships, k, {'user_timelines' => new_subcolumns })
|
577
|
+
@twitter.insert(:StatusRelationships, k, {'user_timelines' => new_subcolumns })
|
572
578
|
@twitter.remove(:StatusRelationships, k, 'user_timelines' , subcolumn_to_delete ) # Delete the first of the initial_subcolumns from the user_timeline supercolumn
|
573
579
|
assert_equal(initial_subcolumns, @twitter.get(:StatusRelationships, k, 'user_timelines')) # No additions or deletes reflected yet
|
574
|
-
# Delete a complete supercolumn
|
580
|
+
# Delete a complete supercolumn
|
575
581
|
@twitter.remove(:StatusRelationships, k, 'dummy_supercolumn' ) # Delete the full dummy supercolumn
|
576
|
-
assert_equal({@uuids[5] => 'value'}, @twitter.get(:StatusRelationships, k, 'dummy_supercolumn')) # dummy supercolumn not yet deleted
|
582
|
+
assert_equal({@uuids[5] => 'value'}, @twitter.get(:StatusRelationships, k, 'dummy_supercolumn')) # dummy supercolumn not yet deleted
|
577
583
|
end
|
578
584
|
|
579
585
|
assert_equal({'body' => 'v2', 'user' => 'v2'}, @twitter.get(:Users, k + '2')) # Written
|
@@ -581,9 +587,9 @@ class CassandraTest < Test::Unit::TestCase
|
|
581
587
|
assert_equal({'body' => 'v4', 'user' => 'v4'}, @twitter.get(:Users, k + '4')) # Written
|
582
588
|
assert_equal({'body' => 'v'}, @twitter.get(:Statuses, k + '3')) # Written
|
583
589
|
assert_equal({}, @twitter.get(:Users, k + '1')) # Removed
|
584
|
-
|
590
|
+
|
585
591
|
assert_equal({ 'keep_me' => 'v0'}, @twitter.get(:Users, k + '0')) # 'delete_me' column removed
|
586
|
-
|
592
|
+
|
587
593
|
|
588
594
|
assert_equal({'body' => 'v2', 'user' => 'v2'}.keys.sort, @twitter.get(:Users, k + '2').timestamps.keys.sort) # Written
|
589
595
|
assert_equal({'body' => 'v3', 'user' => 'v3', 'location' => 'v3'}.keys.sort, @twitter.get(:Users, k + '3').timestamps.keys.sort) # Written and compacted
|
@@ -593,7 +599,7 @@ class CassandraTest < Test::Unit::TestCase
|
|
593
599
|
# Final result: initial_subcolumns - initial_subcolumns.first + new_subcolumns
|
594
600
|
resulting_subcolumns = initial_subcolumns.merge(new_subcolumns).reject{|k2,v| k2 == subcolumn_to_delete }
|
595
601
|
assert_equal(resulting_subcolumns, @twitter.get(:StatusRelationships, key, 'user_timelines'))
|
596
|
-
assert_equal({}, @twitter.get(:StatusRelationships, key, 'dummy_supercolumn')) # dummy supercolumn deleted
|
602
|
+
assert_equal({}, @twitter.get(:StatusRelationships, key, 'dummy_supercolumn')) # dummy supercolumn deleted
|
597
603
|
|
598
604
|
end
|
599
605
|
|
@@ -834,8 +840,47 @@ class CassandraTest < Test::Unit::TestCase
|
|
834
840
|
assert_equal(1, @twitter.get(:UserCounterAggregates, 'bob', 'DAU', 'today'))
|
835
841
|
assert_equal(2, @twitter.get(:UserCounterAggregates, 'bob', 'DAU', 'tomorrow'))
|
836
842
|
end
|
843
|
+
|
844
|
+
def test_composite_column_type_conversion
|
845
|
+
columns = {}
|
846
|
+
@composites.each_with_index do |c, index|
|
847
|
+
columns[c] = "value-#{index}"
|
848
|
+
end
|
849
|
+
@type_conversions.insert(:CompositeColumnConversion, key, columns)
|
850
|
+
columns_in_order = [
|
851
|
+
Cassandra::Composite.new([1].pack('N'), "elephant"),
|
852
|
+
Cassandra::Composite.new([5].pack('N'), "aardvark"),
|
853
|
+
Cassandra::Composite.new([5].pack('N'), "zebra"),
|
854
|
+
Cassandra::Composite.new([10].pack('N'), "kangaroo"),
|
855
|
+
]
|
856
|
+
assert_equal(columns_in_order, @type_conversions.get(:CompositeColumnConversion, key).keys)
|
857
|
+
|
858
|
+
column_slice = @type_conversions.get(:CompositeColumnConversion, key,
|
859
|
+
:start => Cassandra::Composite.new([1].pack('N')),
|
860
|
+
:finish => Cassandra::Composite.new([10].pack('N')),
|
861
|
+
).keys
|
862
|
+
assert_equal(columns_in_order[0..-2], column_slice)
|
863
|
+
|
864
|
+
column_slice = @type_conversions.get(:CompositeColumnConversion, key,
|
865
|
+
:start => Cassandra::Composite.new([5].pack('N')),
|
866
|
+
:finish => Cassandra::Composite.new([5].pack('N'), :slice => :after),
|
867
|
+
).keys
|
868
|
+
assert_equal(columns_in_order[1..2], column_slice)
|
869
|
+
|
870
|
+
column_slice = @type_conversions.get(:CompositeColumnConversion, key,
|
871
|
+
:start => Cassandra::Composite.new([5].pack('N'), :slice => :after).to_s,
|
872
|
+
).keys
|
873
|
+
assert_equal([columns_in_order[-1]], column_slice)
|
874
|
+
|
875
|
+
column_slice = @type_conversions.get(:CompositeColumnConversion, key,
|
876
|
+
:finish => Cassandra::Composite.new([10].pack('N'), :slice => :before).to_s,
|
877
|
+
).keys
|
878
|
+
assert_equal(columns_in_order[0..-2], column_slice)
|
879
|
+
|
880
|
+
assert_equal('value-2', @type_conversions.get(:CompositeColumnConversion, key, columns_in_order.first))
|
881
|
+
end
|
837
882
|
end
|
838
|
-
|
883
|
+
|
839
884
|
def test_column_timestamps
|
840
885
|
base_time = Time.now
|
841
886
|
@twitter.insert(:Statuses, "time-key", { "body" => "value" })
|