cassilds-model 0.0.4 → 0.0.5
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/lib/cassandra-model.rb +2 -2
- data/lib/cassandra-model/base.rb +2 -2
- data/lib/cassandra-model/callbacks.rb +261 -31
- data/lib/cassandra-model/railtie.rb +0 -1
- data/lib/cassandra-model/version.rb +1 -1
- metadata +8 -8
data/lib/cassandra-model.rb
CHANGED
@@ -21,10 +21,10 @@ unless Object.respond_to? :tap
|
|
21
21
|
end
|
22
22
|
|
23
23
|
require 'cassandra-model/types'
|
24
|
-
require 'active_support/callbacks'
|
25
24
|
require 'cassandra-model/config'
|
26
25
|
require 'cassandra-model/connection'
|
26
|
+
require 'cassandra-model/callbacks'
|
27
27
|
require 'cassandra-model/persistence'
|
28
28
|
require 'cassandra-model/batches'
|
29
29
|
require 'cassandra-model/base'
|
30
|
-
#require 'cassandra-model/railtie'
|
30
|
+
#require 'cassandra-model/railtie'
|
data/lib/cassandra-model/base.rb
CHANGED
@@ -3,7 +3,7 @@ require 'simple_uuid'
|
|
3
3
|
module CassandraModel
|
4
4
|
class Base
|
5
5
|
extend Forwardable
|
6
|
-
include
|
6
|
+
include CassandraModel::Callbacks
|
7
7
|
include CassandraModel::Persistence
|
8
8
|
include CassandraModel::Batches
|
9
9
|
|
@@ -180,4 +180,4 @@ module CassandraModel
|
|
180
180
|
alias :eql? ==
|
181
181
|
end
|
182
182
|
|
183
|
-
end
|
183
|
+
end
|
@@ -1,49 +1,279 @@
|
|
1
1
|
module CassandraModel
|
2
|
+
# Callbacks are hooks into the lifecycle of an object that allow you to trigger logic
|
3
|
+
# before or after an alteration of the object state.
|
4
|
+
#
|
5
|
+
# Mixing in this module allows you to define callbacks in your class.
|
6
|
+
#
|
7
|
+
# Example:
|
8
|
+
# class Storage
|
9
|
+
# include CustomCallbacks::Callbacks
|
10
|
+
#
|
11
|
+
# define_callbacks :before_save, :after_save
|
12
|
+
# end
|
13
|
+
#
|
14
|
+
# class ConfigStorage < Storage
|
15
|
+
# before_save :saving_message
|
16
|
+
# def saving_message
|
17
|
+
# puts "saving..."
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# after_save do |object|
|
21
|
+
# puts "saved"
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
# def save
|
25
|
+
# run_callbacks(:before_save)
|
26
|
+
# puts "- save"
|
27
|
+
# run_callbacks(:after_save)
|
28
|
+
# end
|
29
|
+
# end
|
30
|
+
#
|
31
|
+
# config = ConfigStorage.new
|
32
|
+
# config.save
|
33
|
+
#
|
34
|
+
# Output:
|
35
|
+
# saving...
|
36
|
+
# - save
|
37
|
+
# saved
|
38
|
+
#
|
39
|
+
# Callbacks from parent classes are inherited.
|
40
|
+
#
|
41
|
+
# Example:
|
42
|
+
# class Storage
|
43
|
+
# include CustomCallbacks::Callbacks
|
44
|
+
#
|
45
|
+
# define_callbacks :before_save, :after_save
|
46
|
+
#
|
47
|
+
# before_save :prepare
|
48
|
+
# def prepare
|
49
|
+
# puts "preparing save"
|
50
|
+
# end
|
51
|
+
# end
|
52
|
+
#
|
53
|
+
# class ConfigStorage < Storage
|
54
|
+
# before_save :saving_message
|
55
|
+
# def saving_message
|
56
|
+
# puts "saving..."
|
57
|
+
# end
|
58
|
+
#
|
59
|
+
# after_save do |object|
|
60
|
+
# puts "saved"
|
61
|
+
# end
|
62
|
+
#
|
63
|
+
# def save
|
64
|
+
# run_callbacks(:before_save)
|
65
|
+
# puts "- save"
|
66
|
+
# run_callbacks(:after_save)
|
67
|
+
# end
|
68
|
+
# end
|
69
|
+
#
|
70
|
+
# config = ConfigStorage.new
|
71
|
+
# config.save
|
72
|
+
#
|
73
|
+
# Output:
|
74
|
+
# preparing save
|
75
|
+
# saving...
|
76
|
+
# - save
|
77
|
+
# saved
|
2
78
|
module Callbacks
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
79
|
+
class CallbackChain < Array
|
80
|
+
def self.build(kind, *methods, &block)
|
81
|
+
methods, options = extract_options(*methods, &block)
|
82
|
+
methods.map! { |method| Callback.new(kind, method, options) }
|
83
|
+
new(methods)
|
84
|
+
end
|
7
85
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
EVAL
|
86
|
+
def run(object, options = {}, &terminator)
|
87
|
+
enumerator = options[:enumerator] || :each
|
88
|
+
|
89
|
+
unless block_given?
|
90
|
+
send(enumerator) { |callback| callback.call(object) }
|
91
|
+
else
|
92
|
+
send(enumerator) do |callback|
|
93
|
+
result = callback.call(object)
|
94
|
+
break result if terminator.call(result, object)
|
18
95
|
end
|
19
96
|
end
|
20
97
|
end
|
21
98
|
|
22
|
-
|
23
|
-
|
99
|
+
# TODO: Decompose into more Array like behavior
|
100
|
+
def replace_or_append!(chain)
|
101
|
+
if index = index(chain)
|
102
|
+
self[index] = chain
|
103
|
+
else
|
104
|
+
self << chain
|
105
|
+
end
|
106
|
+
self
|
107
|
+
end
|
108
|
+
|
109
|
+
def find(callback, &block)
|
110
|
+
select { |c| c == callback && (!block_given? || yield(c)) }.first
|
24
111
|
end
|
112
|
+
|
113
|
+
def delete(callback)
|
114
|
+
super(callback.is_a?(Callback) ? callback : find(callback))
|
115
|
+
end
|
116
|
+
|
117
|
+
private
|
118
|
+
def self.extract_options(*methods, &block)
|
119
|
+
methods.flatten!
|
120
|
+
options = methods.extract_options!
|
121
|
+
methods << block if block_given?
|
122
|
+
return methods, options
|
123
|
+
end
|
124
|
+
|
125
|
+
def extract_options(*methods, &block)
|
126
|
+
self.class.extract_options(*methods, &block)
|
127
|
+
end
|
25
128
|
end
|
26
129
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
130
|
+
class Callback
|
131
|
+
attr_reader :kind, :method, :identifier, :options
|
132
|
+
|
133
|
+
def initialize(kind, method, options = {})
|
134
|
+
@kind = kind
|
135
|
+
@method = method
|
136
|
+
@identifier = options[:identifier]
|
137
|
+
@options = options
|
138
|
+
end
|
139
|
+
|
140
|
+
def ==(other)
|
141
|
+
case other
|
142
|
+
when Callback
|
143
|
+
(self.identifier && self.identifier == other.identifier) || self.method == other.method
|
144
|
+
else
|
145
|
+
(self.identifier && self.identifier == other) || self.method == other
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
def eql?(other)
|
150
|
+
self == other
|
151
|
+
end
|
152
|
+
|
153
|
+
def dup
|
154
|
+
self.class.new(@kind, @method, @options.dup)
|
155
|
+
end
|
156
|
+
|
157
|
+
def hash
|
158
|
+
if @identifier
|
159
|
+
@identifier.hash
|
160
|
+
else
|
161
|
+
@method.hash
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
def call(*args, &block)
|
166
|
+
evaluate_method(method, *args, &block) if should_run_callback?(*args)
|
167
|
+
rescue LocalJumpError
|
168
|
+
raise ArgumentError,
|
169
|
+
"Cannot yield from a Proc type filter. The Proc must take two " +
|
170
|
+
"arguments and execute #call on the second argument."
|
33
171
|
end
|
34
172
|
|
35
173
|
private
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
174
|
+
def evaluate_method(method, *args, &block)
|
175
|
+
case method
|
176
|
+
when Symbol
|
177
|
+
object = args.shift
|
178
|
+
object.send(method, *args, &block)
|
179
|
+
when String
|
180
|
+
eval(method, args.first.instance_eval { binding })
|
181
|
+
when Proc, Method
|
182
|
+
method.call(*args, &block)
|
183
|
+
else
|
184
|
+
if method.respond_to?(kind)
|
185
|
+
method.send(kind, *args, &block)
|
186
|
+
else
|
187
|
+
raise ArgumentError,
|
188
|
+
"Callbacks must be a symbol denoting the method to call, a string to be evaluated, " +
|
189
|
+
"a block to be invoked, or an object responding to the callback method."
|
190
|
+
end
|
44
191
|
end
|
45
192
|
end
|
193
|
+
|
194
|
+
def should_run_callback?(*args)
|
195
|
+
[options[:if]].flatten.compact.all? { |a| evaluate_method(a, *args) } &&
|
196
|
+
![options[:unless]].flatten.compact.any? { |a| evaluate_method(a, *args) }
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
def self.included(base)
|
201
|
+
base.extend ClassMethods
|
202
|
+
end
|
203
|
+
|
204
|
+
module ClassMethods
|
205
|
+
def define_callbacks(*callbacks)
|
206
|
+
callbacks.each do |callback|
|
207
|
+
class_eval <<-"end_eval"
|
208
|
+
def self.#{callback}(*methods, &block) # def self.before_save(*methods, &block)
|
209
|
+
callbacks = CallbackChain.build(:#{callback}, *methods, &block) # callbacks = CallbackChain.build(:before_save, *methods, &block)
|
210
|
+
@#{callback}_callbacks ||= CallbackChain.new # @before_save_callbacks ||= CallbackChain.new
|
211
|
+
@#{callback}_callbacks.concat callbacks # @before_save_callbacks.concat callbacks
|
212
|
+
end # end
|
213
|
+
#
|
214
|
+
def self.#{callback}_callback_chain # def self.before_save_callback_chain
|
215
|
+
@#{callback}_callbacks ||= CallbackChain.new # @before_save_callbacks ||= CallbackChain.new
|
216
|
+
#
|
217
|
+
if superclass.respond_to?(:#{callback}_callback_chain) # if superclass.respond_to?(:before_save_callback_chain)
|
218
|
+
CallbackChain.new( # CallbackChain.new(
|
219
|
+
superclass.#{callback}_callback_chain + # superclass.before_save_callback_chain +
|
220
|
+
@#{callback}_callbacks # @before_save_callbacks
|
221
|
+
) # )
|
222
|
+
else # else
|
223
|
+
@#{callback}_callbacks # @before_save_callbacks
|
224
|
+
end # end
|
225
|
+
end # end
|
226
|
+
end_eval
|
227
|
+
end
|
46
228
|
end
|
47
229
|
end
|
230
|
+
|
231
|
+
# Runs all the callbacks defined for the given options.
|
232
|
+
#
|
233
|
+
# If a block is given it will be called after each callback receiving as arguments:
|
234
|
+
#
|
235
|
+
# * the result from the callback
|
236
|
+
# * the object which has the callback
|
237
|
+
#
|
238
|
+
# If the result from the block evaluates to false, the callback chain is stopped.
|
239
|
+
#
|
240
|
+
# Example:
|
241
|
+
# class Storage
|
242
|
+
# include CustomCallbacks::Callbacks
|
243
|
+
#
|
244
|
+
# define_callbacks :before_save, :after_save
|
245
|
+
# end
|
246
|
+
#
|
247
|
+
# class ConfigStorage < Storage
|
248
|
+
# before_save :pass
|
249
|
+
# before_save :pass
|
250
|
+
# before_save :stop
|
251
|
+
# before_save :pass
|
252
|
+
#
|
253
|
+
# def pass
|
254
|
+
# puts "pass"
|
255
|
+
# end
|
256
|
+
#
|
257
|
+
# def stop
|
258
|
+
# puts "stop"
|
259
|
+
# return false
|
260
|
+
# end
|
261
|
+
#
|
262
|
+
# def save
|
263
|
+
# result = run_callbacks(:before_save) { |result, object| result == false }
|
264
|
+
# puts "- save" if result
|
265
|
+
# end
|
266
|
+
# end
|
267
|
+
#
|
268
|
+
# config = ConfigStorage.new
|
269
|
+
# config.save
|
270
|
+
#
|
271
|
+
# Output:
|
272
|
+
# pass
|
273
|
+
# pass
|
274
|
+
# stop
|
275
|
+
def run_callbacks(kind, options = {}, &block)
|
276
|
+
self.class.send("#{kind}_callback_chain").run(self, options, &block)
|
277
|
+
end
|
48
278
|
end
|
49
|
-
end
|
279
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cassilds-model
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,11 +10,11 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2011-08-
|
13
|
+
date: 2011-08-19 00:00:00.000000000Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: shoulda
|
17
|
-
requirement: &
|
17
|
+
requirement: &24681920 !ruby/object:Gem::Requirement
|
18
18
|
none: false
|
19
19
|
requirements:
|
20
20
|
- - ! '>='
|
@@ -22,10 +22,10 @@ dependencies:
|
|
22
22
|
version: '0'
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
|
-
version_requirements: *
|
25
|
+
version_requirements: *24681920
|
26
26
|
- !ruby/object:Gem::Dependency
|
27
27
|
name: cassilds
|
28
|
-
requirement: &
|
28
|
+
requirement: &24681500 !ruby/object:Gem::Requirement
|
29
29
|
none: false
|
30
30
|
requirements:
|
31
31
|
- - ! '>='
|
@@ -33,10 +33,10 @@ dependencies:
|
|
33
33
|
version: '0'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
|
-
version_requirements: *
|
36
|
+
version_requirements: *24681500
|
37
37
|
- !ruby/object:Gem::Dependency
|
38
38
|
name: simple_uuid
|
39
|
-
requirement: &
|
39
|
+
requirement: &24680940 !ruby/object:Gem::Requirement
|
40
40
|
none: false
|
41
41
|
requirements:
|
42
42
|
- - ! '>='
|
@@ -44,7 +44,7 @@ dependencies:
|
|
44
44
|
version: '0'
|
45
45
|
type: :runtime
|
46
46
|
prerelease: false
|
47
|
-
version_requirements: *
|
47
|
+
version_requirements: *24680940
|
48
48
|
description: Cassandra-model allows you to map ColumnFamily/SuperColumnFamily in Cassandra
|
49
49
|
to Ruby objects. It was designed to be fast and simple.
|
50
50
|
email:
|