cassandra 0.5.5 → 0.5.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -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