cassandra 0.5.5 → 0.5.6

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.
@@ -1,87 +0,0 @@
1
-
2
- class Cassandra
3
- # A bunch of crap, mostly related to introspecting on column types
4
- module Columns #:nodoc:
5
- private
6
-
7
- def is_super(column_family)
8
- @is_super[column_family] ||= column_family_property(column_family, 'Type') == "Super"
9
- end
10
-
11
- def column_name_class(column_family)
12
- @column_name_class[column_family] ||= column_name_class_for_key(column_family, "CompareWith")
13
- end
14
-
15
- def sub_column_name_class(column_family)
16
- @sub_column_name_class[column_family] ||= column_name_class_for_key(column_family, "CompareSubcolumnsWith")
17
- end
18
-
19
- def column_name_class_for_key(column_family, comparator_key)
20
- property = column_family_property(column_family, comparator_key)
21
- property =~ /.*\.(.*?)$/
22
- case $1
23
- when "LongType" then Long
24
- when "LexicalUUIDType", "TimeUUIDType" then UUID
25
- else
26
- String # UTF8, Ascii, Bytes, anything else
27
- end
28
- end
29
-
30
- def column_family_property(column_family, key)
31
- @schema[column_family][key]
32
- rescue NoMethodError
33
- raise AccessError, "Invalid column family \"#{column_family}\""
34
- end
35
-
36
- def assert_column_name_classes(column_family, columns, sub_columns = nil)
37
- {Array(columns) => column_name_class(column_family),
38
- Array(sub_columns) => sub_column_name_class(column_family)}.each do |columns, klass|
39
- columns.each do |column|
40
- raise Comparable::TypeError, "Expected #{column.inspect} to be a #{klass}" if !column.is_a?(klass)
41
- end
42
- end
43
- end
44
-
45
- def columns_to_hash(column_family, columns)
46
- columns_to_hash_for_classes(columns, column_name_class(column_family), sub_column_name_class(column_family))
47
- end
48
-
49
- def sub_columns_to_hash(column_family, columns)
50
- columns_to_hash_for_classes(columns, sub_column_name_class(column_family))
51
- end
52
-
53
- def columns_to_hash_for_classes(columns, column_name_class, sub_column_name_class = nil)
54
- hash = OrderedHash.new
55
- Array(columns).each do |c|
56
- c = c.super_column || c.column if c.is_a?(CassandraThrift::ColumnOrSuperColumn)
57
- hash[column_name_class.new(c.name)] = case c
58
- when CassandraThrift::SuperColumn
59
- columns_to_hash_for_classes(c.columns, sub_column_name_class) # Pop the class stack, and recurse
60
- when CassandraThrift::Column
61
- c.value
62
- end
63
- end
64
- hash
65
- end
66
-
67
- def hash_to_columns(column_family, hash, timestamp)
68
- assert_column_name_classes(column_family, hash.keys)
69
- hash.map do |column, value|
70
- CassandraThrift::ColumnOrSuperColumn.new(:column =>
71
- CassandraThrift::Column.new(:name => column.to_s, :value => value, :timestamp => timestamp))
72
- end
73
- end
74
-
75
- def hash_to_super_columns(column_family, hash, timestamp)
76
- assert_column_name_classes(column_family, hash.keys)
77
- hash.map do |column, sub_hash|
78
- assert_column_name_classes(column_family, nil, sub_hash.keys)
79
- sub_columns = sub_hash.map do |sub_column, value|
80
- CassandraThrift::Column.new(:name => sub_column.to_s, :value => value, :timestamp => timestamp)
81
- end
82
- CassandraThrift::ColumnOrSuperColumn.new(:super_column =>
83
- CassandraThrift::SuperColumn.new(:name => column.to_s, :columns => sub_columns))
84
- end
85
- end
86
- end
87
- end
@@ -1,28 +0,0 @@
1
-
2
- class Cassandra
3
- # Abstract base class for comparable numeric column name types
4
- class Comparable
5
- class TypeError < ::TypeError #:nodoc:
6
- end
7
-
8
- def <=>(other)
9
- self.to_i <=> other.to_i
10
- end
11
-
12
- def hash
13
- @bytes.hash
14
- end
15
-
16
- def eql?(other)
17
- other.is_a?(Comparable) and @bytes == other.to_s
18
- end
19
-
20
- def ==(other)
21
- self.to_i == other.to_i
22
- end
23
-
24
- def to_s
25
- @bytes
26
- end
27
- end
28
- end
@@ -1,12 +0,0 @@
1
-
2
- class Cassandra
3
- # A helper module you can include in your own class. Makes it easier
4
- # to work with Cassandra subclasses.
5
- module Constants
6
- include Cassandra::Consistency
7
-
8
- UUID = Cassandra::UUID
9
- Long = Cassandra::Long
10
- OrderedHash = Cassandra::OrderedHash
11
- end
12
- end
@@ -1,7 +0,0 @@
1
-
2
- class CassandraThrift::Cassandra::Client
3
- def send_message(*args)
4
- pp args
5
- super
6
- end
7
- end
@@ -1,55 +0,0 @@
1
-
2
- class Cassandra
3
- # A temporally-ordered Long class for use in Cassandra column names
4
- class Long < Comparable
5
-
6
- def initialize(bytes = nil)
7
- case bytes
8
- when String
9
- case bytes.size
10
- when 8 # Raw byte array
11
- @bytes = bytes
12
- when 18 # Human-readable UUID-like representation; inverse of #to_guid
13
- elements = bytes.split("-")
14
- raise TypeError, "Malformed UUID-like representation" if elements.size != 3
15
- @bytes = elements.join.to_a.pack('H32')
16
- else
17
- raise TypeError, "8 bytes required for byte array, or 18 characters required for UUID-like representation"
18
- end
19
- when Integer
20
- raise TypeError, "Integer must be between 0 and 2**64" if bytes < 0 or bytes > 2**64
21
- @bytes = [bytes >> 32, bytes % 2**32].pack("NN")
22
- when NilClass, Time
23
- # Time.stamp is 52 bytes, so we have 12 bytes of entropy left over
24
- int = ((bytes || Time).stamp << 12) + rand(2**12)
25
- @bytes = [int >> 32, int % 2**32].pack("NN")
26
- else
27
- raise TypeError, "Can't convert from #{bytes.class}"
28
- end
29
- end
30
-
31
- def to_i
32
- @to_i ||= begin
33
- ints = @bytes.unpack("NN")
34
- (ints[0] << 32) +
35
- ints[1]
36
- end
37
- end
38
-
39
- def to_guid
40
- "%08x-%04x-%04x" % @bytes.unpack("Nnn")
41
- end
42
-
43
- def inspect
44
- "<Cassandra::Long##{object_id} time: #{
45
- Time.at((to_i >> 12) / 1_000_000).inspect
46
- }, usecs: #{
47
- (to_i >> 12) % 1_000_000
48
- }, jitter: #{
49
- to_i % 2**12
50
- }, guid: #{
51
- to_guid
52
- }>"
53
- end
54
- end
55
- end
@@ -1,135 +0,0 @@
1
-
2
- class Cassandra
3
- # Hash is ordered in Ruby 1.9!
4
- if RUBY_VERSION >= '1.9'
5
- OrderedHash = ::Hash
6
- else
7
- # Copyright (c) 2004-2009 David Heinemeier Hansson
8
- #
9
- # Permission is hereby granted, free of charge, to any person obtaining
10
- # a copy of this software and associated documentation files (the
11
- # "Software"), to deal in the Software without restriction, including
12
- # without limitation the rights to use, copy, modify, merge, publish,
13
- # distribute, sublicense, and/or sell copies of the Software, and to
14
- # permit persons to whom the Software is furnished to do so, subject to
15
- # the following conditions:
16
- #
17
- # The above copyright notice and this permission notice shall be
18
- # included in all copies or substantial portions of the Software.
19
- #
20
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21
- # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22
- # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23
- # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24
- # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25
- # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26
- # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27
-
28
- class OrderedHash < Hash #:nodoc: all
29
- require 'enumerator'
30
-
31
- def self.[](*array)
32
- hash = new
33
- array.each_slice(2) { |key, value| hash[key] = value }
34
- hash
35
- end
36
-
37
- def initialize(*args, &block)
38
- super
39
- @keys = []
40
- end
41
-
42
- def initialize_copy(other)
43
- super
44
- # make a deep copy of keys
45
- @keys = other.keys
46
- end
47
-
48
- def []=(key, value)
49
- @keys << key if !has_key?(key)
50
- super
51
- end
52
-
53
- def delete(key)
54
- if has_key? key
55
- index = @keys.index(key)
56
- @keys.delete_at index
57
- end
58
- super
59
- end
60
-
61
- def delete_if
62
- super
63
- sync_keys!
64
- self
65
- end
66
-
67
- def reject!
68
- super
69
- sync_keys!
70
- self
71
- end
72
-
73
- def reject(&block)
74
- dup.reject!(&block)
75
- end
76
-
77
- def keys
78
- @keys.dup
79
- end
80
-
81
- def values
82
- @keys.collect { |key| self[key] }
83
- end
84
-
85
- def to_hash
86
- self
87
- end
88
-
89
- def each_key
90
- @keys.each { |key| yield key }
91
- end
92
-
93
- def each_value
94
- @keys.each { |key| yield self[key]}
95
- end
96
-
97
- def each
98
- @keys.each {|key| yield [key, self[key]]}
99
- end
100
-
101
- alias_method :each_pair, :each
102
-
103
- def clear
104
- super
105
- @keys.clear
106
- self
107
- end
108
-
109
- def shift
110
- k = @keys.first
111
- v = delete(k)
112
- [k, v]
113
- end
114
-
115
- def merge!(other_hash)
116
- other_hash.each {|k,v| self[k] = v }
117
- self
118
- end
119
-
120
- def merge(other_hash)
121
- dup.merge!(other_hash)
122
- end
123
-
124
- def inspect
125
- "#<OrderedHash #{super}>"
126
- end
127
-
128
- private
129
-
130
- def sync_keys!
131
- @keys.delete_if {|k| !has_key?(k)}
132
- end
133
- end
134
- end
135
- end
@@ -1,74 +0,0 @@
1
-
2
- class Cassandra
3
- # Inner methods for actually doing the Thrift calls
4
- module Protocol #:nodoc:
5
- private
6
-
7
- def _mutate(mutation, consistency)
8
- @client.batch_mutate(@keyspace, mutation, consistency)
9
- end
10
-
11
- def _count_columns(column_family, key, super_column, consistency)
12
- @client.get_count(@keyspace, key,
13
- CassandraThrift::ColumnParent.new(:column_family => column_family, :super_column => super_column),
14
- consistency
15
- )
16
- end
17
-
18
- def _get_columns(column_family, key, columns, sub_columns, consistency)
19
- result = if is_super(column_family)
20
- if sub_columns
21
- columns_to_hash(column_family, @client.get_slice(@keyspace, key,
22
- CassandraThrift::ColumnParent.new(:column_family => column_family, :super_column => columns),
23
- CassandraThrift::SlicePredicate.new(:column_names => sub_columns),
24
- consistency))
25
- else
26
- columns_to_hash(column_family, @client.get_slice(@keyspace, key,
27
- CassandraThrift::ColumnParent.new(:column_family => column_family),
28
- CassandraThrift::SlicePredicate.new(:column_names => columns),
29
- consistency))
30
- end
31
- else
32
- columns_to_hash(column_family, @client.get_slice(@keyspace, key,
33
- CassandraThrift::ColumnParent.new(:column_family => column_family),
34
- CassandraThrift::SlicePredicate.new(:column_names => columns),
35
- consistency))
36
- end
37
- sub_columns || columns.map { |name| result[name] }
38
- end
39
-
40
- def _get(column_family, key, column, sub_column, count, start, finish, reversed, consistency)
41
- # Single values; count and range parameters have no effect
42
- if is_super(column_family) and sub_column
43
- column_path = CassandraThrift::ColumnPath.new(:column_family => column_family, :super_column => column, :column => sub_column)
44
- @client.get(@keyspace, key, column_path, consistency).column.value
45
- elsif !is_super(column_family) and column
46
- column_path = CassandraThrift::ColumnPath.new(:column_family => column_family, :column => column)
47
- @client.get(@keyspace, key, column_path, consistency).column.value
48
-
49
- # Slices
50
- else
51
- # FIXME Comparable types in range are not enforced
52
- predicate = CassandraThrift::SlicePredicate.new(:slice_range =>
53
- CassandraThrift::SliceRange.new(
54
- :reversed => reversed,
55
- :count => count,
56
- :start => start.to_s,
57
- :finish => finish.to_s))
58
-
59
- if is_super(column_family) and column
60
- column_parent = CassandraThrift::ColumnParent.new(:column_family => column_family, :super_column => column)
61
- sub_columns_to_hash(column_family, @client.get_slice(@keyspace, key, column_parent, predicate, consistency))
62
- else
63
- column_parent = CassandraThrift::ColumnParent.new(:column_family => column_family)
64
- columns_to_hash(column_family, @client.get_slice(@keyspace, key, column_parent, predicate, consistency))
65
- end
66
- end
67
- end
68
-
69
- def _get_range(column_family, start, finish, count, consistency)
70
- # FIXME Consistency is ignored
71
- @client.get_key_range(@keyspace, column_family, start.to_s, finish.to_s, count)
72
- end
73
- end
74
- end
@@ -1,21 +0,0 @@
1
-
2
- module CassandraThrift #:nodoc: all
3
- module Cassandra
4
- class SafeClient
5
- def initialize(client, transport)
6
- @client = client
7
- @transport = transport
8
- end
9
-
10
- def method_missing(*args)
11
- @client.send(*args)
12
- rescue IOError, UnavailableException
13
- @transport.close rescue nil
14
- @transport.open
15
- raise if defined?(once)
16
- once = true
17
- retry
18
- end
19
- end
20
- end
21
- end
@@ -1,11 +0,0 @@
1
-
2
- class Time
3
- def self.stamp
4
- Time.now.stamp
5
- end
6
-
7
- def stamp
8
- to_i * 1_000_000 + usec
9
- end
10
- end
11
-
@@ -1,109 +0,0 @@
1
-
2
- class Cassandra
3
-
4
- # UUID format version 1, as specified in RFC 4122, with jitter in place of the mac address and sequence counter.
5
- class UUID < Comparable
6
-
7
- class InvalidVersion < StandardError #:nodoc:
8
- end
9
-
10
- GREGORIAN_EPOCH_OFFSET = 0x01B2_1DD2_1381_4000 # Oct 15, 1582
11
-
12
- VARIANT = 0b1000_0000_0000_0000
13
-
14
- def initialize(bytes = nil)
15
- case bytes
16
- when String
17
- case bytes.size
18
- when 16 # Raw byte array
19
- @bytes = bytes
20
- when 36 # Human-readable UUID representation; inverse of #to_guid
21
- elements = bytes.split("-")
22
- raise TypeError, "Malformed UUID representation" if elements.size != 5
23
- @bytes = elements.join.to_a.pack('H32')
24
- else
25
- raise TypeError, "16 bytes required for byte array, or 36 characters required for UUID representation"
26
- end
27
-
28
- when Integer
29
- raise TypeError, "Integer must be between 0 and 2**128" if bytes < 0 or bytes > 2**128
30
- @bytes = [
31
- (bytes >> 96) & 0xFFFF_FFFF,
32
- (bytes >> 64) & 0xFFFF_FFFF,
33
- (bytes >> 32) & 0xFFFF_FFFF,
34
- bytes & 0xFFFF_FFFF
35
- ].pack("NNNN")
36
-
37
- when NilClass, Time
38
- time = (bytes || Time).stamp * 10 + GREGORIAN_EPOCH_OFFSET
39
- # See http://github.com/spectra/ruby-uuid/
40
- @bytes = [
41
- time & 0xFFFF_FFFF,
42
- time >> 32,
43
- ((time >> 48) & 0x0FFF) | 0x1000,
44
- # Top 3 bytes reserved
45
- rand(2**13) | VARIANT,
46
- rand(2**16),
47
- rand(2**32)
48
- ].pack("NnnnnN")
49
-
50
- else
51
- raise TypeError, "Can't convert from #{bytes.class}"
52
- end
53
- end
54
-
55
- def to_i
56
- ints = @bytes.unpack("NNNN")
57
- (ints[0] << 96) +
58
- (ints[1] << 64) +
59
- (ints[2] << 32) +
60
- ints[3]
61
- end
62
-
63
- def version
64
- time_high = @bytes.unpack("NnnQ")[2]
65
- version = (time_high & 0xF000).to_s(16)[0].chr.to_i
66
- version > 0 and version < 6 ? version : -1
67
- end
68
-
69
- def variant
70
- @bytes.unpack('QnnN')[1] >> 13
71
- end
72
-
73
- def to_guid
74
- elements = @bytes.unpack("NnnCCa6")
75
- node = elements[-1].unpack('C*')
76
- elements[-1] = '%02x%02x%02x%02x%02x%02x' % node
77
- "%08x-%04x-%04x-%02x%02x-%s" % elements
78
- end
79
-
80
- def seconds
81
- total_usecs / 1_000_000
82
- end
83
-
84
- def usecs
85
- total_usecs % 1_000_000
86
- end
87
-
88
- def <=>(other)
89
- total_usecs <=> other.send(:total_usecs)
90
- end
91
-
92
- def inspect(long = false)
93
- "<Cassandra::UUID##{object_id} time: #{
94
- Time.at(seconds).inspect
95
- }, usecs: #{
96
- usecs
97
- } jitter: #{
98
- @bytes.unpack('QQ')[1]
99
- }" + (long ? ", version: #{version}, variant: #{variant}, guid: #{to_guid}>" : ">")
100
- end
101
-
102
- private
103
-
104
- def total_usecs
105
- elements = @bytes.unpack("NnnQ")
106
- (elements[0] + (elements[1] << 32) + ((elements[2] & 0x0FFF) << 48) - GREGORIAN_EPOCH_OFFSET) / 10
107
- end
108
- end
109
- end