sessionm-cassandra_object 4.0.28 → 4.0.29

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 23762bc97b24f059702d33a82198651dc12a5849
4
- data.tar.gz: e5bdeca74f220ad8ade8f35a20b3751efd256eec
3
+ metadata.gz: 3b6090a71669ad2ce1765f4df908af55554ad3c2
4
+ data.tar.gz: bc7618330745f2d61d1e50c06514ef509fd68591
5
5
  SHA512:
6
- metadata.gz: ffff8841ff8da649d139ddc24d54c0a28bbba823fbe25ec7a00cde71a3685bc33e2ac92b1973a09208f419ef0660a03a2ae840dc008bd4af57ed3f8120399a39
7
- data.tar.gz: 88af7c90d6177d05afaf0d37f0eee2ecc563dd4ea9a48e3195d587dad18e88768f5f40389be12eedac86554de24c507cca1f14af4f9a33711feb4d79cf301312
6
+ metadata.gz: 693a6518ae0b0a296e45c6f1e1f52561b2fb8523b0ba0862b19c5efa4dd8bc2e697311e79046a044a5a893578a873f62c8420bd8457616e9031165ca811669a2
7
+ data.tar.gz: 2562aaf301fe5b205952ec04205657d39c76f1d8f0be22860f7c90b08e850f6d4d9894533f8424b8eaca1aa446a09445855e0f39dade50fff4a545f06402214f
@@ -54,4 +54,7 @@ module CassandraObject
54
54
  end
55
55
  end
56
56
 
57
+ require 'cassandra_object/custom_comparable'
58
+ require 'cassandra_object/composite'
59
+ require 'cassandra_object/long'
57
60
  require 'cassandra_object/railtie'
@@ -0,0 +1,140 @@
1
+ class Cassandra
2
+ class Composite
3
+ include ::Comparable
4
+ attr_reader :parts
5
+ attr_reader :column_slice
6
+
7
+ def initialize(*parts)
8
+ return if parts.empty?
9
+
10
+ options = {}
11
+ if parts.last.is_a?(Hash)
12
+ options = parts.pop
13
+ end
14
+ @column_slice = options[:slice]
15
+ raise ArgumentError if @column_slice != nil && ![:before, :after].include?(@column_slice)
16
+
17
+ if parts.length == 1 && parts[0].instance_of?(self.class)
18
+ @column_slice = parts[0].column_slice
19
+ @parts = parts[0].parts
20
+ elsif parts.length == 1 && parts[0].instance_of?(String) && @column_slice.nil? && try_packed_composite(parts[0])
21
+ @hash = parts[0].hash
22
+ else
23
+ @parts = parts
24
+ end
25
+ end
26
+
27
+ def self.new_from_packed(packed)
28
+ obj = new
29
+ obj.fast_unpack(packed)
30
+ return obj
31
+ end
32
+
33
+ def [](*args)
34
+ return @parts[*args]
35
+ end
36
+
37
+ def pack
38
+ packed = @parts.map do |part|
39
+ [part.length].pack('n') + part + "\x00"
40
+ end
41
+ if @column_slice
42
+ part = @parts[-1]
43
+ packed[-1] = [part.length].pack('n') + part + slice_end_of_component
44
+ end
45
+ return packed.join('')
46
+ end
47
+
48
+ def to_s
49
+ return pack
50
+ end
51
+
52
+ def <=>(other)
53
+ if !other.instance_of?(self.class)
54
+ return @parts.first <=> other
55
+ end
56
+ eoc = slice_end_of_component.unpack('c')[0]
57
+ other_eoc = other.slice_end_of_component.unpack('c')[0]
58
+ @parts.zip(other.parts).each do |a, b|
59
+ next if a == b
60
+ if a.nil? && b.nil?
61
+ return eoc <=> other_eoc
62
+ end
63
+
64
+ if a.nil?
65
+ return @column_slice == :after ? 1 : -1
66
+ end
67
+ if b.nil?
68
+ return other.column_slice == :after ? -1 : 1
69
+ end
70
+ return -1 if a < b
71
+ return 1 if a > b
72
+ end
73
+ return 0
74
+ end
75
+
76
+ def inspect
77
+ return "#<#{self.class}:#{@column_slice} #{@parts.inspect}>"
78
+ end
79
+
80
+ def slice_end_of_component
81
+ return "\x01" if @column_slice == :after
82
+ return "\xFF" if @column_slice == :before
83
+ return "\x00"
84
+ end
85
+
86
+ def fast_unpack(packed_string)
87
+ @hash = packed_string.hash
88
+
89
+ @parts = []
90
+ end_of_component = packed_string.slice(packed_string.length-1, 1)
91
+ while packed_string.length > 0
92
+ length = packed_string.unpack('n')[0]
93
+ @parts << packed_string.slice(2, length)
94
+
95
+ packed_string.slice!(0, length+3)
96
+ end
97
+
98
+ @column_slice = :after if end_of_component == "\x01"
99
+ @column_slice = :before if end_of_component == "\xFF"
100
+ end
101
+
102
+ private
103
+ def try_packed_composite(packed_string)
104
+ parts = []
105
+ end_of_component = nil
106
+ while packed_string.length > 0
107
+ length = packed_string.slice(0, 2).unpack('n')[0]
108
+ return false if length.nil? || length + 3 > packed_string.length
109
+
110
+ parts << packed_string.slice(2, length)
111
+ end_of_component = packed_string.slice(2 + length, 1)
112
+ if length + 3 != packed_string.length
113
+ return false if end_of_component != "\x00"
114
+ end
115
+
116
+ packed_string = packed_string.slice(3 + length, packed_string.length)
117
+ end
118
+
119
+ @column_slice = :after if end_of_component == "\x01"
120
+ @column_slice = :before if end_of_component == "\xFF"
121
+ @parts = parts
122
+
123
+ return true
124
+ end
125
+
126
+ def hash
127
+ return @hash ||= pack.hash
128
+ end
129
+
130
+ def eql?(other)
131
+ return to_s == other.to_s
132
+ end
133
+ end
134
+ end
135
+
136
+ begin
137
+ require "cassandra_native"
138
+ rescue LoadError
139
+ puts "Unable to load cassandra_native extension. Defaulting to pure Ruby libraries."
140
+ end
@@ -0,0 +1,28 @@
1
+
2
+ class Cassandra
3
+ # Abstract base class for comparable numeric column name types
4
+ class CustomComparable
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
+ other.respond_to?(:to_i) && self.to_i == other.to_i
22
+ end
23
+
24
+ def to_s
25
+ @bytes
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,58 @@
1
+
2
+ class Cassandra
3
+ # A temporally-ordered Long class for use in Cassandra column names
4
+ class Long < CustomComparable
5
+
6
+ # FIXME Should unify with or subclass Cassandra::UUID
7
+ def initialize(bytes = nil)
8
+ case bytes
9
+ when self.class # Long
10
+ @bytes = bytes.to_s
11
+ when String
12
+ case bytes.size
13
+ when 8 # Raw byte array
14
+ @bytes = bytes
15
+ when 18 # Human-readable UUID-like representation; inverse of #to_guid
16
+ elements = bytes.split("-")
17
+ raise TypeError, "Expected #{bytes.inspect} to cast to a #{self.class} (malformed UUID-like representation)" if elements.size != 3
18
+ @bytes = [elements.join].pack('H32')
19
+ else
20
+ raise TypeError, "Expected #{bytes.inspect} to cast to a #{self.class} (invalid bytecount)"
21
+ end
22
+ when Integer
23
+ raise TypeError, "Expected #{bytes.inspect} to cast to a #{self.class} (integer out of range)" if bytes < 0 or bytes > 2**64
24
+ @bytes = [bytes >> 32, bytes % 2**32].pack("NN")
25
+ when NilClass, Time
26
+ # Time.stamp is 52 bytes, so we have 12 bytes of entropy left over
27
+ int = ((bytes || Time).stamp << 12) + rand(2**12)
28
+ @bytes = [int >> 32, int % 2**32].pack("NN")
29
+ else
30
+ raise TypeError, "Expected #{bytes.inspect} to cast to a #{self.class} (unknown source class)"
31
+ end
32
+ end
33
+
34
+ def to_i
35
+ @to_i ||= begin
36
+ ints = @bytes.unpack("NN")
37
+ (ints[0] << 32) +
38
+ ints[1]
39
+ end
40
+ end
41
+
42
+ def to_guid
43
+ "%08x-%04x-%04x" % @bytes.unpack("Nnn")
44
+ end
45
+
46
+ def inspect
47
+ "<Cassandra::Long##{object_id} time: #{
48
+ Time.at((to_i >> 12) / 1_000_000).utc.inspect
49
+ }, usecs: #{
50
+ (to_i >> 12) % 1_000_000
51
+ }, jitter: #{
52
+ to_i % 2**12
53
+ }, guid: #{
54
+ to_guid
55
+ }>"
56
+ end
57
+ end
58
+ end
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = 'sessionm-cassandra_object'
5
- s.version = '4.0.28'
5
+ s.version = '4.0.29'
6
6
  s.description = 'Cassandra ActiveModel'
7
7
  s.summary = 'Cassandra ActiveModel'
8
8
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sessionm-cassandra_object
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.28
4
+ version: 4.0.29
5
5
  platform: ruby
6
6
  authors:
7
7
  - Doug Youch
@@ -44,10 +44,12 @@ files:
44
44
  - lib/cassandra_object/batches.rb
45
45
  - lib/cassandra_object/callbacks.rb
46
46
  - lib/cassandra_object/collection.rb
47
+ - lib/cassandra_object/composite.rb
47
48
  - lib/cassandra_object/configuration.rb
48
49
  - lib/cassandra_object/connection.rb
49
50
  - lib/cassandra_object/consistency.rb
50
51
  - lib/cassandra_object/cursor.rb
52
+ - lib/cassandra_object/custom_comparable.rb
51
53
  - lib/cassandra_object/dirty.rb
52
54
  - lib/cassandra_object/errors.rb
53
55
  - lib/cassandra_object/finder_methods.rb
@@ -61,6 +63,7 @@ files:
61
63
  - lib/cassandra_object/identity/natural_key_factory.rb
62
64
  - lib/cassandra_object/identity/uuid_key_factory.rb
63
65
  - lib/cassandra_object/log_subscriber.rb
66
+ - lib/cassandra_object/long.rb
64
67
  - lib/cassandra_object/migrations.rb
65
68
  - lib/cassandra_object/migrations/migration.rb
66
69
  - lib/cassandra_object/mocking.rb