gotime-cassandra_object 0.7.2 → 0.7.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/VERSION +1 -1
- data/gotime-cassandra_object.gemspec +3 -2
- data/lib/cassandra_object.rb +1 -1
- data/lib/cassandra_object/associations.rb +1 -1
- data/lib/cassandra_object/associations/one_to_many.rb +14 -2
- data/lib/cassandra_object/base.rb +1 -1
- data/lib/cassandra_object/consistency.rb +30 -0
- data/lib/cassandra_object/cursor.rb +8 -3
- data/lib/cassandra_object/log_subscriber.rb +7 -1
- data/lib/cassandra_object/persistence.rb +13 -41
- data/lib/cassandra_object/types.rb +9 -1
- metadata +5 -4
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.7.
|
1
|
+
0.7.3
|
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{gotime-cassandra_object}
|
8
|
-
s.version = "0.7.
|
8
|
+
s.version = "0.7.3"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Michael Koziarski", "grantr"]
|
12
|
-
s.date = %q{2011-02-
|
12
|
+
s.date = %q{2011-02-04}
|
13
13
|
s.description = %q{Cassandra ActiveModel}
|
14
14
|
s.email = %q{grantr@gmail.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -35,6 +35,7 @@ Gem::Specification.new do |s|
|
|
35
35
|
"lib/cassandra_object/base.rb",
|
36
36
|
"lib/cassandra_object/callbacks.rb",
|
37
37
|
"lib/cassandra_object/collection.rb",
|
38
|
+
"lib/cassandra_object/consistency.rb",
|
38
39
|
"lib/cassandra_object/cursor.rb",
|
39
40
|
"lib/cassandra_object/dirty.rb",
|
40
41
|
"lib/cassandra_object/generators/migration_generator.rb",
|
data/lib/cassandra_object.rb
CHANGED
@@ -25,7 +25,7 @@ module CassandraObject
|
|
25
25
|
def remove(key)
|
26
26
|
begin
|
27
27
|
ActiveSupport::Notifications.instrument("remove.cassandra_object", :key => key) do
|
28
|
-
connection.remove("#{name}Relationships", key.to_s)
|
28
|
+
connection.remove("#{name}Relationships", key.to_s, :consistency => write_consistency_for_thrift)
|
29
29
|
end
|
30
30
|
rescue Cassandra::AccessError => e
|
31
31
|
raise e unless e.message =~ /Invalid column family/
|
@@ -1,22 +1,34 @@
|
|
1
1
|
module CassandraObject
|
2
2
|
class OneToManyAssociation
|
3
|
+
include Consistency
|
4
|
+
|
5
|
+
attr_accessor :write_consistency
|
6
|
+
attr_accessor :read_consistency
|
7
|
+
|
3
8
|
def initialize(association_name, owner_class, options)
|
4
9
|
@association_name = association_name.to_s
|
5
10
|
@owner_class = owner_class
|
6
11
|
@target_class_name = options[:class_name] || association_name.to_s.singularize.camelize
|
7
12
|
@options = options
|
13
|
+
|
14
|
+
@write_consistency = owner_class.write_consistency
|
15
|
+
@read_consistency = owner_class.write_consistency
|
8
16
|
|
9
17
|
define_methods!
|
10
18
|
end
|
11
19
|
|
12
20
|
def find(owner, options = {})
|
13
21
|
reversed = options.has_key?(:reversed) ? options[:reversed] : reversed?
|
14
|
-
cursor = CassandraObject::Cursor.new(target_class, column_family, owner.key.to_s, @association_name, :start_after => options[:start_after], :reversed => reversed)
|
22
|
+
cursor = CassandraObject::Cursor.new(target_class, column_family, owner.key.to_s, @association_name, :start_after => options[:start_after], :reversed => reversed, :consistency => read_consistency)
|
15
23
|
cursor.find(options[:limit] || 100)
|
16
24
|
end
|
17
25
|
|
18
26
|
def add(owner, record, set_inverse = true)
|
19
|
-
|
27
|
+
key = owner.key
|
28
|
+
attributes = {@association_name=>{new_key=>record.key.to_s}}
|
29
|
+
ActiveSupport::Notifications.instrument("insert.cassandra_object", :key => key, :attributes => attributes) do
|
30
|
+
connection.insert(column_family, key.to_s, attributes, :consistency => write_consistency_for_thrift)
|
31
|
+
end
|
20
32
|
if has_inverse? && set_inverse
|
21
33
|
inverse.set_inverse(record, owner)
|
22
34
|
end
|
@@ -2,6 +2,7 @@ require 'cassandra/0.7'
|
|
2
2
|
require 'set'
|
3
3
|
require 'cassandra_object/attributes'
|
4
4
|
require 'cassandra_object/dirty'
|
5
|
+
require 'cassandra_object/consistency'
|
5
6
|
require 'cassandra_object/persistence'
|
6
7
|
|
7
8
|
require 'cassandra_object/callbacks'
|
@@ -11,7 +12,6 @@ require 'cassandra_object/identity'
|
|
11
12
|
require 'cassandra_object/indexes'
|
12
13
|
require 'cassandra_object/serialization'
|
13
14
|
require 'cassandra_object/associations'
|
14
|
-
#require 'cassandra_object/sets'
|
15
15
|
require 'cassandra_object/migrations'
|
16
16
|
require 'cassandra_object/cursor'
|
17
17
|
require 'cassandra_object/collection'
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module CassandraObject
|
2
|
+
module Consistency
|
3
|
+
VALID_READ_CONSISTENCY_LEVELS = [:one, :quorum, :all]
|
4
|
+
VALID_WRITE_CONSISTENCY_LEVELS = VALID_READ_CONSISTENCY_LEVELS
|
5
|
+
|
6
|
+
def valid_read_consistency_level?(level)
|
7
|
+
!!VALID_READ_CONSISTENCY_LEVELS.include?(level)
|
8
|
+
end
|
9
|
+
|
10
|
+
def valid_write_consistency_level?(level)
|
11
|
+
!!VALID_WRITE_CONSISTENCY_LEVELS.include?(level)
|
12
|
+
end
|
13
|
+
|
14
|
+
def write_consistency_for_thrift
|
15
|
+
consistency_for_thrift(write_consistency)
|
16
|
+
end
|
17
|
+
|
18
|
+
def read_consistency_for_thrift
|
19
|
+
consistency_for_thrift(read_consistency)
|
20
|
+
end
|
21
|
+
|
22
|
+
def consistency_for_thrift(consistency)
|
23
|
+
{
|
24
|
+
:one => Cassandra::Consistency::ONE,
|
25
|
+
:quorum => Cassandra::Consistency::QUORUM,
|
26
|
+
:all => Cassandra::Consistency::ALL
|
27
|
+
}[consistency]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -1,11 +1,15 @@
|
|
1
1
|
module CassandraObject
|
2
2
|
class Cursor
|
3
|
+
include Consistency
|
4
|
+
|
3
5
|
def initialize(target_class, column_family, key, super_column, options={})
|
4
6
|
@target_class = target_class
|
5
7
|
@column_family = column_family
|
6
8
|
@key = key.to_s
|
7
9
|
@super_column = super_column
|
8
10
|
@options = options
|
11
|
+
@read_consistency = options[:read_consistency] || options[:consistency] || :quorum
|
12
|
+
@write_consitency = options[:write_consistency] || options[:consistency] || :quorum
|
9
13
|
@validators = []
|
10
14
|
end
|
11
15
|
|
@@ -23,7 +27,8 @@ module CassandraObject
|
|
23
27
|
while objects.size < number_to_find && !out_of_keys
|
24
28
|
index_results = connection.get(@column_family, @key, @super_column, :count=>limit,
|
25
29
|
:start=>start_with,
|
26
|
-
:reversed=>@options[:reversed]
|
30
|
+
:reversed=>@options[:reversed],
|
31
|
+
:consistency=>consistency_for_thrift(@read_consistency))
|
27
32
|
|
28
33
|
out_of_keys = index_results.size < limit
|
29
34
|
|
@@ -76,11 +81,11 @@ module CassandraObject
|
|
76
81
|
end
|
77
82
|
|
78
83
|
def remove(index_key)
|
79
|
-
connection.remove(@column_family, @key, @super_column, index_key)
|
84
|
+
connection.remove(@column_family, @key, @super_column, index_key, :consistency => consistency_for_thrift(@write_consistency))
|
80
85
|
end
|
81
86
|
|
82
87
|
def validator(&validator)
|
83
88
|
@validators << validator
|
84
89
|
end
|
85
90
|
end
|
86
|
-
end
|
91
|
+
end
|
@@ -12,6 +12,12 @@ module CassandraObject
|
|
12
12
|
debug " #{name} #{event.payload[:key]}"
|
13
13
|
end
|
14
14
|
|
15
|
+
def truncate(event)
|
16
|
+
name = 'CassandraObject truncate (%.1fms)' % event.duration
|
17
|
+
|
18
|
+
debug " #{name} #{event.payload[:column_family]}"
|
19
|
+
end
|
20
|
+
|
15
21
|
def insert(event)
|
16
22
|
name = 'CassandraObject insert (%.1fms)' % event.duration
|
17
23
|
|
@@ -21,7 +27,7 @@ module CassandraObject
|
|
21
27
|
def get_range(event)
|
22
28
|
name = 'CassandraObject get_range (%.1fms)' % event.duration
|
23
29
|
|
24
|
-
debug " #{name} (#{event.payload[:count]}) #{event.payload[:start]} => #{event.payload[:finish]}"
|
30
|
+
debug " #{name} (#{event.payload[:count]}) '#{event.payload[:start]}' => '#{event.payload[:finish]}'"
|
25
31
|
end
|
26
32
|
end
|
27
33
|
end
|
@@ -2,38 +2,31 @@ module CassandraObject
|
|
2
2
|
module Persistence
|
3
3
|
extend ActiveSupport::Concern
|
4
4
|
included do
|
5
|
-
|
6
|
-
|
5
|
+
extend Consistency
|
6
|
+
|
7
|
+
class_attribute :write_consistency
|
8
|
+
class_attribute :read_consistency
|
9
|
+
self.write_consistency = self.read_consistency = :quorum
|
7
10
|
end
|
8
11
|
|
9
|
-
VALID_READ_CONSISTENCY_LEVELS = [:one, :quorum, :all]
|
10
|
-
VALID_WRITE_CONSISTENCY_LEVELS = VALID_READ_CONSISTENCY_LEVELS
|
11
12
|
|
12
13
|
module ClassMethods
|
13
14
|
def consistency_levels(levels)
|
14
15
|
if levels.has_key?(:write)
|
15
16
|
unless valid_write_consistency_level?(levels[:write])
|
16
|
-
raise ArgumentError, "Invalid write consistency level. Valid levels are: #{VALID_WRITE_CONSISTENCY_LEVELS.inspect}. You gave me #{levels[:write].inspect}"
|
17
|
+
raise ArgumentError, "Invalid write consistency level. Valid levels are: #{Consistency::VALID_WRITE_CONSISTENCY_LEVELS.inspect}. You gave me #{levels[:write].inspect}"
|
17
18
|
end
|
18
19
|
self.write_consistency = levels[:write]
|
19
20
|
end
|
20
21
|
|
21
22
|
if levels.has_key?(:read)
|
22
23
|
unless valid_read_consistency_level?(levels[:read])
|
23
|
-
raise ArgumentError, "Invalid read consistency level. Valid levels are #{VALID_READ_CONSISTENCY_LEVELS.inspect}. You gave me #{levels[:write].inspect}"
|
24
|
+
raise ArgumentError, "Invalid read consistency level. Valid levels are #{Consistency::VALID_READ_CONSISTENCY_LEVELS.inspect}. You gave me #{levels[:write].inspect}"
|
24
25
|
end
|
25
26
|
self.read_consistency = levels[:read]
|
26
27
|
end
|
27
28
|
end
|
28
29
|
|
29
|
-
def write_consistency
|
30
|
-
read_inheritable_attribute(:write_consistency) || :quorum
|
31
|
-
end
|
32
|
-
|
33
|
-
def read_consistency
|
34
|
-
read_inheritable_attribute(:read_consistency) || :quorum
|
35
|
-
end
|
36
|
-
|
37
30
|
def get(key, options = {})
|
38
31
|
multi_get([key], options).values.first
|
39
32
|
end
|
@@ -65,13 +58,16 @@ module CassandraObject
|
|
65
58
|
end
|
66
59
|
|
67
60
|
def delete_all
|
68
|
-
|
61
|
+
ActiveSupport::Notifications.instrument("truncate.cassandra_object", :column_family => column_family) do
|
62
|
+
connection.truncate!(column_family)
|
63
|
+
end
|
69
64
|
end
|
70
65
|
|
71
66
|
def all(keyrange = ''..'', options = {})
|
72
|
-
|
67
|
+
options = {:consistency => self.read_consistency, :limit => 100}.merge(options)
|
68
|
+
count = options[:limit]
|
73
69
|
results = ActiveSupport::Notifications.instrument("get_range.cassandra_object", :start => keyrange.first, :finish => keyrange.last, :count => count) do
|
74
|
-
connection.get_range(column_family, :start => keyrange.first, :finish => keyrange.last, :count => count)
|
70
|
+
connection.get_range(column_family, :start => keyrange.first, :finish => keyrange.last, :count => count, :consistency=>consistency_for_thrift(options[:consistency]))
|
75
71
|
end
|
76
72
|
|
77
73
|
results.map do |result|
|
@@ -137,30 +133,6 @@ module CassandraObject
|
|
137
133
|
[{:Name=>column_family, :CompareWith=>"UTF8Type"}]
|
138
134
|
end
|
139
135
|
|
140
|
-
protected
|
141
|
-
def valid_read_consistency_level?(level)
|
142
|
-
!!VALID_READ_CONSISTENCY_LEVELS.include?(level)
|
143
|
-
end
|
144
|
-
|
145
|
-
def valid_write_consistency_level?(level)
|
146
|
-
!!VALID_WRITE_CONSISTENCY_LEVELS.include?(level)
|
147
|
-
end
|
148
|
-
|
149
|
-
def write_consistency_for_thrift
|
150
|
-
consistency_for_thrift(write_consistency)
|
151
|
-
end
|
152
|
-
|
153
|
-
def read_consistency_for_thrift
|
154
|
-
consistency_for_thrift(read_consistency)
|
155
|
-
end
|
156
|
-
|
157
|
-
def consistency_for_thrift(consistency)
|
158
|
-
{
|
159
|
-
:one => Cassandra::Consistency::ONE,
|
160
|
-
:quorum => Cassandra::Consistency::QUORUM,
|
161
|
-
:all => Cassandra::Consistency::ALL
|
162
|
-
}[consistency]
|
163
|
-
end
|
164
136
|
end
|
165
137
|
|
166
138
|
module InstanceMethods
|
@@ -26,7 +26,7 @@ module CassandraObject
|
|
26
26
|
module_function :encode
|
27
27
|
|
28
28
|
def decode(str)
|
29
|
-
return nil if str
|
29
|
+
return nil if str.empty?
|
30
30
|
raise ArgumentError.new("#{str} isn't a String that looks like a Float") unless str.kind_of?(String) && str.match(REGEX)
|
31
31
|
str.to_f
|
32
32
|
end
|
@@ -37,12 +37,14 @@ module CassandraObject
|
|
37
37
|
FORMAT = '%Y-%m-%d'
|
38
38
|
REGEX = /\A\d{4}-\d{2}-\d{2}\Z/
|
39
39
|
def encode(date)
|
40
|
+
return '' if date.nil?
|
40
41
|
raise ArgumentError.new("#{self} requires a Date") unless date.kind_of?(Date)
|
41
42
|
date.strftime(FORMAT)
|
42
43
|
end
|
43
44
|
module_function :encode
|
44
45
|
|
45
46
|
def decode(str)
|
47
|
+
return nil if str.empty?
|
46
48
|
raise ArgumentError.new("#{str} isn't a String that looks like a Date") unless str.kind_of?(String) && str.match(REGEX)
|
47
49
|
Date.strptime(str, FORMAT)
|
48
50
|
end
|
@@ -60,12 +62,14 @@ module CassandraObject
|
|
60
62
|
\s*\z/ix
|
61
63
|
|
62
64
|
def encode(time)
|
65
|
+
return '' if time.nil?
|
63
66
|
raise ArgumentError.new("#{self} requires a Time") unless time.kind_of?(Time)
|
64
67
|
time.xmlschema(6)
|
65
68
|
end
|
66
69
|
module_function :encode
|
67
70
|
|
68
71
|
def decode(str)
|
72
|
+
return nil if str.empty?
|
69
73
|
raise ArgumentError.new("#{str} isn't a String that looks like a Time") unless str.kind_of?(String) && str.match(REGEX)
|
70
74
|
Time.xmlschema(str)
|
71
75
|
end
|
@@ -86,6 +90,7 @@ module CassandraObject
|
|
86
90
|
|
87
91
|
module StringType
|
88
92
|
def encode(str)
|
93
|
+
return '' if str.nil?
|
89
94
|
raise ArgumentError.new("#{self} requires a String") unless str.kind_of?(String)
|
90
95
|
str.dup
|
91
96
|
end
|
@@ -99,6 +104,7 @@ module CassandraObject
|
|
99
104
|
|
100
105
|
module UTF8StringType
|
101
106
|
def encode(str)
|
107
|
+
return '' if str.nil?
|
102
108
|
# This is technically the most correct, but it is a pain to require utf-8 encoding for all strings. Should revisit.
|
103
109
|
#raise ArgumentError.new("#{self} requires a UTF-8 encoded String") unless str.kind_of?(String) && str.encoding == Encoding::UTF_8
|
104
110
|
raise ArgumentError.new("#{self} requires a String") unless str.kind_of?(String)
|
@@ -114,12 +120,14 @@ module CassandraObject
|
|
114
120
|
|
115
121
|
module HashType
|
116
122
|
def encode(hash)
|
123
|
+
return '' if hash.nil?
|
117
124
|
raise ArgumentError.new("#{self} requires a Hash") unless hash.kind_of?(Hash)
|
118
125
|
ActiveSupport::JSON.encode(hash)
|
119
126
|
end
|
120
127
|
module_function :encode
|
121
128
|
|
122
129
|
def decode(str)
|
130
|
+
return nil if str.empty?
|
123
131
|
ActiveSupport::JSON.decode(str)
|
124
132
|
end
|
125
133
|
module_function :decode
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 7
|
8
|
-
-
|
9
|
-
version: 0.7.
|
8
|
+
- 3
|
9
|
+
version: 0.7.3
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Michael Koziarski
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-02-
|
18
|
+
date: 2011-02-04 00:00:00 -08:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -154,6 +154,7 @@ files:
|
|
154
154
|
- lib/cassandra_object/base.rb
|
155
155
|
- lib/cassandra_object/callbacks.rb
|
156
156
|
- lib/cassandra_object/collection.rb
|
157
|
+
- lib/cassandra_object/consistency.rb
|
157
158
|
- lib/cassandra_object/cursor.rb
|
158
159
|
- lib/cassandra_object/dirty.rb
|
159
160
|
- lib/cassandra_object/generators/migration_generator.rb
|
@@ -212,7 +213,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
212
213
|
requirements:
|
213
214
|
- - ">="
|
214
215
|
- !ruby/object:Gem::Version
|
215
|
-
hash:
|
216
|
+
hash: -32715678761257107
|
216
217
|
segments:
|
217
218
|
- 0
|
218
219
|
version: "0"
|