gotime-cassandra_object 0.8.2 → 0.8.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/gotime-cassandra_object.gemspec +1 -1
- data/lib/cassandra_object/associations.rb +6 -5
- data/lib/cassandra_object/associations/one_to_many.rb +135 -133
- data/lib/cassandra_object/associations/one_to_one.rb +65 -63
- data/lib/cassandra_object/identity.rb +8 -5
- data/lib/cassandra_object/identity/hashed_natural_key_factory.rb +10 -0
- metadata +16 -15
@@ -1,9 +1,10 @@
|
|
1
|
-
require 'cassandra_object/associations/one_to_many'
|
2
|
-
require 'cassandra_object/associations/one_to_one'
|
3
|
-
|
4
1
|
module CassandraObject
|
5
2
|
module Associations
|
6
3
|
extend ActiveSupport::Concern
|
4
|
+
extend ActiveSupport::Autoload
|
5
|
+
|
6
|
+
autoload :OneToMany
|
7
|
+
autoload :OneToOne
|
7
8
|
|
8
9
|
included do
|
9
10
|
class_inheritable_hash :associations
|
@@ -16,9 +17,9 @@ module CassandraObject
|
|
16
17
|
|
17
18
|
def association(association_name, options= {})
|
18
19
|
if options[:unique]
|
19
|
-
write_inheritable_hash(:associations, {association_name =>
|
20
|
+
write_inheritable_hash(:associations, {association_name => OneToOne.new(association_name, self, options)})
|
20
21
|
else
|
21
|
-
write_inheritable_hash(:associations, {association_name =>
|
22
|
+
write_inheritable_hash(:associations, {association_name => OneToMany.new(association_name, self, options)})
|
22
23
|
end
|
23
24
|
end
|
24
25
|
|
@@ -1,152 +1,154 @@
|
|
1
1
|
module CassandraObject
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
def find(owner, options = {})
|
21
|
-
reversed = options.has_key?(:reversed) ? options[: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)
|
23
|
-
cursor.find(options[:limit] || 100)
|
24
|
-
end
|
25
|
-
|
26
|
-
def add(owner, record, set_inverse = true)
|
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)
|
2
|
+
module Associations
|
3
|
+
class OneToMany
|
4
|
+
include Consistency
|
5
|
+
|
6
|
+
attr_accessor :write_consistency
|
7
|
+
attr_accessor :read_consistency
|
8
|
+
|
9
|
+
def initialize(association_name, owner_class, options)
|
10
|
+
@association_name = association_name.to_s
|
11
|
+
@owner_class = owner_class
|
12
|
+
@target_class_name = options[:class_name] || association_name.to_s.singularize.camelize
|
13
|
+
@options = options
|
14
|
+
|
15
|
+
@write_consistency = owner_class.write_consistency
|
16
|
+
@read_consistency = owner_class.write_consistency
|
17
|
+
|
18
|
+
define_methods!
|
31
19
|
end
|
32
|
-
|
33
|
-
|
20
|
+
|
21
|
+
def find(owner, options = {})
|
22
|
+
reversed = options.has_key?(:reversed) ? options[:reversed] : reversed?
|
23
|
+
cursor = CassandraObject::Cursor.new(target_class, column_family, owner.key.to_s, @association_name, :start_after => options[:start_after], :reversed => reversed, :consistency => read_consistency)
|
24
|
+
cursor.find(options[:limit] || 100)
|
25
|
+
end
|
26
|
+
|
27
|
+
def add(owner, record, set_inverse = true)
|
28
|
+
key = owner.key
|
29
|
+
attributes = {@association_name=>{new_key=>record.key.to_s}}
|
30
|
+
ActiveSupport::Notifications.instrument("insert.cassandra_object", :key => key, :attributes => attributes) do
|
31
|
+
connection.insert(column_family, key.to_s, attributes, :consistency => write_consistency_for_thrift)
|
32
|
+
end
|
33
|
+
if has_inverse? && set_inverse
|
34
|
+
inverse.set_inverse(record, owner)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def new_key
|
39
|
+
SimpleUUID::UUID.new
|
40
|
+
end
|
41
|
+
|
42
|
+
def column_family
|
43
|
+
@owner_class.to_s + "Relationships"
|
44
|
+
end
|
45
|
+
|
46
|
+
def connection
|
47
|
+
@owner_class.connection
|
48
|
+
end
|
49
|
+
|
50
|
+
def target_class
|
51
|
+
@target_class ||= @target_class_name.constantize
|
52
|
+
end
|
53
|
+
|
54
|
+
def new_proxy(owner)
|
55
|
+
OneToManyAssociationProxy.new(self, owner)
|
56
|
+
end
|
57
|
+
|
58
|
+
def has_inverse?
|
59
|
+
@options[:inverse_of]
|
34
60
|
end
|
35
|
-
end
|
36
|
-
|
37
|
-
def new_key
|
38
|
-
SimpleUUID::UUID.new
|
39
|
-
end
|
40
|
-
|
41
|
-
def column_family
|
42
|
-
@owner_class.to_s + "Relationships"
|
43
|
-
end
|
44
|
-
|
45
|
-
def connection
|
46
|
-
@owner_class.connection
|
47
|
-
end
|
48
|
-
|
49
|
-
def target_class
|
50
|
-
@target_class ||= @target_class_name.constantize
|
51
|
-
end
|
52
|
-
|
53
|
-
def new_proxy(owner)
|
54
|
-
OneToManyAssociationProxy.new(self, owner)
|
55
|
-
end
|
56
|
-
|
57
|
-
def has_inverse?
|
58
|
-
@options[:inverse_of]
|
59
|
-
end
|
60
|
-
|
61
|
-
def inverse
|
62
|
-
has_inverse? && target_class.associations[@options[:inverse_of]]
|
63
|
-
end
|
64
|
-
|
65
|
-
def set_inverse(owner, record)
|
66
|
-
add(owner, record, false)
|
67
|
-
end
|
68
|
-
|
69
|
-
def reversed?
|
70
|
-
@options[:reversed] == true
|
71
|
-
end
|
72
61
|
|
73
|
-
|
74
|
-
|
62
|
+
def inverse
|
63
|
+
has_inverse? && target_class.associations[@options[:inverse_of]]
|
64
|
+
end
|
65
|
+
|
66
|
+
def set_inverse(owner, record)
|
67
|
+
add(owner, record, false)
|
68
|
+
end
|
69
|
+
|
70
|
+
def reversed?
|
71
|
+
@options[:reversed] == true
|
72
|
+
end
|
73
|
+
|
74
|
+
def define_methods!
|
75
|
+
@owner_class.class_eval <<-eos
|
75
76
|
def #{@association_name}
|
76
77
|
@_#{@association_name} ||= self.class.associations[:#{@association_name}].new_proxy(self)
|
77
78
|
end
|
78
|
-
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
class OneToManyAssociationProxy
|
83
|
-
def initialize(association, owner)
|
84
|
-
@association = association
|
85
|
-
@owner = owner
|
86
|
-
end
|
87
|
-
|
88
|
-
include Enumerable
|
89
|
-
def each
|
90
|
-
target.each do |i|
|
91
|
-
yield i
|
79
|
+
eos
|
92
80
|
end
|
93
81
|
end
|
94
82
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
def <<(record)
|
100
|
-
@association.add(@owner, record)
|
101
|
-
if loaded?
|
102
|
-
@target << record
|
83
|
+
class OneToManyAssociationProxy
|
84
|
+
def initialize(association, owner)
|
85
|
+
@association = association
|
86
|
+
@owner = owner
|
103
87
|
end
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
@
|
127
|
-
|
88
|
+
|
89
|
+
include Enumerable
|
90
|
+
def each
|
91
|
+
target.each do |i|
|
92
|
+
yield i
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def [](index)
|
97
|
+
to_a[index]
|
98
|
+
end
|
99
|
+
|
100
|
+
def <<(record)
|
101
|
+
@association.add(@owner, record)
|
102
|
+
if loaded?
|
103
|
+
@target << record
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
# Get the targets of this association proxy
|
108
|
+
#
|
109
|
+
# @param [Hash] options the options with which to modify this query
|
110
|
+
# @option options [String] :start_after the key after which to start returning results
|
111
|
+
# @option options [Boolean] :reversed (false or association default) return the results in reverse order
|
112
|
+
# @option options [Integer] :limit the max number of results to return
|
113
|
+
# @return [Array<CassandraObject::Base>] an array of objects of type self#target_class
|
114
|
+
#
|
115
|
+
def all(options = {})
|
116
|
+
@association.find(@owner, options)
|
117
|
+
end
|
118
|
+
|
119
|
+
# Create a record of the associated type with
|
120
|
+
# the supplied attributes and add it to this
|
121
|
+
# association
|
122
|
+
#
|
123
|
+
# @param [Hash] attributes the attributes with which to create the object
|
124
|
+
# @return [CassandraObject::Base] the newly created object
|
125
|
+
#
|
126
|
+
def create(attributes)
|
127
|
+
@association.target_class.create(attributes).tap do |record|
|
128
|
+
if record.valid?
|
129
|
+
self << record
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
def create!(attributes)
|
135
|
+
@association.target_class.create!(attributes).tap do |record|
|
128
136
|
self << record
|
129
137
|
end
|
130
138
|
end
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
139
|
+
|
140
|
+
def target
|
141
|
+
@target ||= begin
|
142
|
+
@loaded = true
|
143
|
+
@association.find(@owner)
|
144
|
+
end
|
136
145
|
end
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
@loaded
|
142
|
-
@association.find(@owner)
|
146
|
+
|
147
|
+
alias to_a target
|
148
|
+
|
149
|
+
def loaded?
|
150
|
+
defined?(@loaded) && @loaded
|
143
151
|
end
|
144
152
|
end
|
145
|
-
|
146
|
-
alias to_a target
|
147
|
-
|
148
|
-
def loaded?
|
149
|
-
defined?(@loaded) && @loaded
|
150
|
-
end
|
151
153
|
end
|
152
154
|
end
|
@@ -1,77 +1,79 @@
|
|
1
1
|
module CassandraObject
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
2
|
+
module Associations
|
3
|
+
class OneToOne
|
4
|
+
def initialize(association_name, owner_class, options)
|
5
|
+
@association_name = association_name.to_s
|
6
|
+
@owner_class = owner_class
|
7
|
+
@target_class_name = options[:class_name] || association_name.to_s.camelize
|
8
|
+
@options = options
|
8
9
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
10
|
+
define_methods!
|
11
|
+
end
|
12
|
+
|
13
|
+
def define_methods!
|
14
|
+
@owner_class.class_eval <<-eos
|
14
15
|
def #{@association_name}
|
15
16
|
@_#{@association_name} ||= self.class.associations[:#{@association_name}].find(self)
|
16
17
|
end
|
17
|
-
|
18
|
+
|
18
19
|
def #{@association_name}=(record)
|
19
20
|
@_#{@association_name} = record
|
20
21
|
self.class.associations[:#{@association_name}].set(self, record)
|
21
22
|
end
|
22
|
-
|
23
|
-
end
|
24
|
-
|
25
|
-
def clear(owner)
|
26
|
-
connection.remove(column_family, owner.key.to_s, @association_name)
|
27
|
-
end
|
28
|
-
|
29
|
-
def find(owner)
|
30
|
-
if key = connection.get(column_family, owner.key.to_s, @association_name.to_s, :count=>1).values.first
|
31
|
-
target_class.get(key)
|
32
|
-
else
|
33
|
-
nil
|
23
|
+
eos
|
34
24
|
end
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
clear(owner)
|
39
|
-
connection.insert(column_family, owner.key.to_s, {@association_name=>{new_key => record.key.to_s}})
|
40
|
-
if has_inverse? && set_inverse
|
41
|
-
inverse.set_inverse(record, owner)
|
25
|
+
|
26
|
+
def clear(owner)
|
27
|
+
connection.remove(column_family, owner.key.to_s, @association_name)
|
42
28
|
end
|
43
|
-
end
|
44
|
-
|
45
|
-
def new_key
|
46
|
-
SimpleUUID::UUID.new
|
47
|
-
end
|
48
|
-
|
49
|
-
def set_inverse(owner, record)
|
50
|
-
set(owner, record, false)
|
51
|
-
end
|
52
|
-
|
53
|
-
def has_inverse?
|
54
|
-
@options[:inverse_of]
|
55
|
-
end
|
56
|
-
|
57
|
-
def inverse
|
58
|
-
has_inverse? && target_class.associations[@options[:inverse_of]]
|
59
|
-
end
|
60
29
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
30
|
+
def find(owner)
|
31
|
+
if key = connection.get(column_family, owner.key.to_s, @association_name.to_s, :count=>1).values.first
|
32
|
+
target_class.get(key)
|
33
|
+
else
|
34
|
+
nil
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def set(owner, record, set_inverse = true)
|
39
|
+
clear(owner)
|
40
|
+
connection.insert(column_family, owner.key.to_s, {@association_name=>{new_key => record.key.to_s}})
|
41
|
+
if has_inverse? && set_inverse
|
42
|
+
inverse.set_inverse(record, owner)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def new_key
|
47
|
+
SimpleUUID::UUID.new
|
48
|
+
end
|
49
|
+
|
50
|
+
def set_inverse(owner, record)
|
51
|
+
set(owner, record, false)
|
52
|
+
end
|
53
|
+
|
54
|
+
def has_inverse?
|
55
|
+
@options[:inverse_of]
|
56
|
+
end
|
57
|
+
|
58
|
+
def inverse
|
59
|
+
has_inverse? && target_class.associations[@options[:inverse_of]]
|
60
|
+
end
|
61
|
+
|
62
|
+
def column_family
|
63
|
+
@owner_class.to_s + "Relationships"
|
64
|
+
end
|
65
|
+
|
66
|
+
def connection
|
67
|
+
@owner_class.connection
|
68
|
+
end
|
69
|
+
|
70
|
+
def target_class
|
71
|
+
@target_class ||= @target_class_name.constantize
|
72
|
+
end
|
73
|
+
|
74
|
+
def new_proxy(owner)
|
75
|
+
# OneToManyAssociationProxy.new(self, owner)
|
76
|
+
end
|
75
77
|
end
|
76
78
|
end
|
77
|
-
end
|
79
|
+
end
|
@@ -1,13 +1,16 @@
|
|
1
|
-
require 'cassandra_object/identity/abstract_key_factory'
|
2
|
-
require 'cassandra_object/identity/key'
|
3
|
-
require 'cassandra_object/identity/uuid_key_factory'
|
4
|
-
require 'cassandra_object/identity/natural_key_factory'
|
5
|
-
|
6
1
|
module CassandraObject
|
7
2
|
# Some docs will be needed here but the gist of this is simple. Instead of returning a string, Base#key now returns a key object.
|
8
3
|
# There are corresponding key factories which generate them
|
9
4
|
module Identity
|
10
5
|
extend ActiveSupport::Concern
|
6
|
+
extend ActiveSupport::Autoload
|
7
|
+
|
8
|
+
autoload :Key
|
9
|
+
autoload :AbstractKeyFactory
|
10
|
+
autoload :UUIDKeyFactory
|
11
|
+
autoload :NaturalKeyFactory
|
12
|
+
autoload :HashedNaturalKeyFactory
|
13
|
+
|
11
14
|
module ClassMethods
|
12
15
|
# Indicate what kind of key the model will have: uuid or natural
|
13
16
|
#
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'digest/sha1'
|
2
|
+
module CassandraObject
|
3
|
+
module Identity
|
4
|
+
class HashedNaturalKeyFactory < NaturalKeyFactory
|
5
|
+
def next_key(object)
|
6
|
+
NaturalKey.new(Digest::SHA1.hexdigest(attributes.map { |a| object.attributes[a.to_s] }.join(separator)))
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gotime-cassandra_object
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.8.
|
4
|
+
version: 0.8.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -15,7 +15,7 @@ default_executable:
|
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: activesupport
|
18
|
-
requirement: &
|
18
|
+
requirement: &11677480 !ruby/object:Gem::Requirement
|
19
19
|
none: false
|
20
20
|
requirements:
|
21
21
|
- - ~>
|
@@ -23,10 +23,10 @@ dependencies:
|
|
23
23
|
version: '3'
|
24
24
|
type: :runtime
|
25
25
|
prerelease: false
|
26
|
-
version_requirements: *
|
26
|
+
version_requirements: *11677480
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: activemodel
|
29
|
-
requirement: &
|
29
|
+
requirement: &11676780 !ruby/object:Gem::Requirement
|
30
30
|
none: false
|
31
31
|
requirements:
|
32
32
|
- - ~>
|
@@ -34,10 +34,10 @@ dependencies:
|
|
34
34
|
version: '3'
|
35
35
|
type: :runtime
|
36
36
|
prerelease: false
|
37
|
-
version_requirements: *
|
37
|
+
version_requirements: *11676780
|
38
38
|
- !ruby/object:Gem::Dependency
|
39
39
|
name: cassandra
|
40
|
-
requirement: &
|
40
|
+
requirement: &11676220 !ruby/object:Gem::Requirement
|
41
41
|
none: false
|
42
42
|
requirements:
|
43
43
|
- - ! '>='
|
@@ -45,10 +45,10 @@ dependencies:
|
|
45
45
|
version: '0'
|
46
46
|
type: :runtime
|
47
47
|
prerelease: false
|
48
|
-
version_requirements: *
|
48
|
+
version_requirements: *11676220
|
49
49
|
- !ruby/object:Gem::Dependency
|
50
50
|
name: shoulda
|
51
|
-
requirement: &
|
51
|
+
requirement: &11675520 !ruby/object:Gem::Requirement
|
52
52
|
none: false
|
53
53
|
requirements:
|
54
54
|
- - ! '>='
|
@@ -56,10 +56,10 @@ dependencies:
|
|
56
56
|
version: '0'
|
57
57
|
type: :development
|
58
58
|
prerelease: false
|
59
|
-
version_requirements: *
|
59
|
+
version_requirements: *11675520
|
60
60
|
- !ruby/object:Gem::Dependency
|
61
61
|
name: bundler
|
62
|
-
requirement: &
|
62
|
+
requirement: &11674780 !ruby/object:Gem::Requirement
|
63
63
|
none: false
|
64
64
|
requirements:
|
65
65
|
- - ~>
|
@@ -67,10 +67,10 @@ dependencies:
|
|
67
67
|
version: 1.0.0
|
68
68
|
type: :development
|
69
69
|
prerelease: false
|
70
|
-
version_requirements: *
|
70
|
+
version_requirements: *11674780
|
71
71
|
- !ruby/object:Gem::Dependency
|
72
72
|
name: jeweler
|
73
|
-
requirement: &
|
73
|
+
requirement: &11674020 !ruby/object:Gem::Requirement
|
74
74
|
none: false
|
75
75
|
requirements:
|
76
76
|
- - ~>
|
@@ -78,10 +78,10 @@ dependencies:
|
|
78
78
|
version: 1.5.1
|
79
79
|
type: :development
|
80
80
|
prerelease: false
|
81
|
-
version_requirements: *
|
81
|
+
version_requirements: *11674020
|
82
82
|
- !ruby/object:Gem::Dependency
|
83
83
|
name: rcov
|
84
|
-
requirement: &
|
84
|
+
requirement: &11673460 !ruby/object:Gem::Requirement
|
85
85
|
none: false
|
86
86
|
requirements:
|
87
87
|
- - ! '>='
|
@@ -89,7 +89,7 @@ dependencies:
|
|
89
89
|
version: '0'
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
|
-
version_requirements: *
|
92
|
+
version_requirements: *11673460
|
93
93
|
description: Cassandra ActiveModel
|
94
94
|
email: grantr@gmail.com
|
95
95
|
executables: []
|
@@ -124,6 +124,7 @@ files:
|
|
124
124
|
- lib/cassandra_object/generators/templates/migration.rb.erb
|
125
125
|
- lib/cassandra_object/identity.rb
|
126
126
|
- lib/cassandra_object/identity/abstract_key_factory.rb
|
127
|
+
- lib/cassandra_object/identity/hashed_natural_key_factory.rb
|
127
128
|
- lib/cassandra_object/identity/key.rb
|
128
129
|
- lib/cassandra_object/identity/natural_key_factory.rb
|
129
130
|
- lib/cassandra_object/identity/uuid_key_factory.rb
|