active_redis_orm 0.0.1

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 0a3b7f868710c028f3d75dfc45ceed2c744c09fa
4
+ data.tar.gz: 8416a2080bcf63c28c1fd62c6326f54fcd1e1148
5
+ SHA512:
6
+ metadata.gz: e21996c2ec2bf8ebf299590cecb579c85838b668a09aac0cb38ee84ebfd33d2b6ff145c00e4d42746c7c43b7be991628a20d06dad8cc7f9a3c5ff53d5c90fea4
7
+ data.tar.gz: 6602b1f0a98a312f73c5f1f8087526e4c20cff4b442020dac713c2ef5eefefb8e12c26bb5e56c03259a87b495151ad7c35d704da514e8b12241ba82cf01719c6
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in active_redis_orm.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Tom Caspy
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # ActiveRedisOrm
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'active_redis_orm'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install active_redis_orm
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it ( http://github.com/<my-github-username>/active_redis_orm/fork )
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,23 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'active_redis/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "active_redis_orm"
8
+ spec.version = ActiveRedisOrm::VERSION
9
+ spec.authors = ["Tom Caspy"]
10
+ spec.email = ["tom@tikalk.com"]
11
+ spec.summary = %q{ActiveRedis is an ORM for redis written in Ruby.}
12
+ spec.description = %q{ActiveRedis is a Ruby ORM for Redis, using ActiveModel, heavily influenced by the ActiveRecord and Mongoid gems}
13
+ spec.homepage = "https://github.com/SpotIM/active_redis_orm"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.5"
22
+ spec.add_development_dependency "rake"
23
+ end
@@ -0,0 +1,70 @@
1
+ module ActiveRedis
2
+ module AllList
3
+ def self.included(base)
4
+ base.extend(ClassMethods)
5
+ base.after_create :add_to_all_lists
6
+ base.after_destroy :remove_from_all_lists
7
+ class << base
8
+ attr_accessor :all_lists
9
+ end
10
+ end
11
+
12
+ def add_to_all_lists
13
+ self.class.all_lists ||= []
14
+ self.class.all_lists.each do |name, options|
15
+ ListWriter.new(self, name, options).add
16
+ end
17
+ end
18
+
19
+ def remove_from_all_lists
20
+ self.class.all_lists ||= []
21
+ self.class.all_lists.each do |name, options|
22
+ ListWriter.new(self, name, options).remove
23
+ end
24
+ end
25
+
26
+ module ClassMethods
27
+ def list(name, options={})
28
+ self.all_lists ||= {}
29
+ self.all_lists[name.to_sym] ||= options
30
+ class_eval %Q{
31
+ def self.#{name}_ids
32
+ Redis::SortedSet.new(list_key(:#{name}))
33
+ end
34
+ }
35
+ end
36
+
37
+ def list_key(name)
38
+ "#{redis_namespace.pluralize}:#{name}"
39
+ end
40
+ end
41
+
42
+ class ListWriter
43
+ def initialize(object, name, options = {})
44
+ @object, @name, @options = object, name, options
45
+ end
46
+
47
+ def add
48
+ ActiveRedis.redis.zadd(key, Time.now.to_f, @object.id) if should_add?
49
+ end
50
+
51
+ def remove
52
+ ActiveRedis.redis.zrem(key, @object.id)
53
+ end
54
+
55
+ def key
56
+ @object.class.list_key(@name)
57
+ end
58
+
59
+ private
60
+
61
+ def should_add?
62
+ if @options[:if].present?
63
+ @options[:if].call(@object)
64
+ else
65
+ true
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,423 @@
1
+ module ActiveRedis
2
+ module AttributeMethods
3
+ def allow_mass_assignment?(attr)
4
+ self.class.attr_accessible?(attr)
5
+ end
6
+
7
+ def set_attributes(attrs)
8
+ if attrs
9
+ attrs.each do |attr, value|
10
+ send("#{attr}=", value) if allow_mass_assignment?(attr) && respond_to?("#{attr}=")
11
+ end
12
+ end
13
+ end
14
+
15
+ def update_attributes(attrs)
16
+ set_attributes(attrs)
17
+ save
18
+ end
19
+
20
+ def after_set(field_name)
21
+ expire_field(field_name)
22
+ end
23
+
24
+ def expire_field(field_name)
25
+ expires_in = self.class.attribute_options[field_name.to_sym][:expires_in]
26
+ if expires_in.to_i > 0
27
+ ActiveRedis.redis.expire(send("#{field_name}_redis_key"), expires_in.to_i)
28
+ end
29
+ end
30
+ end
31
+
32
+ module Attributes
33
+ def attr_accessible(*attrs)
34
+ @attr_accessible = attrs
35
+ end
36
+
37
+ def attr_accessible?(attr)
38
+ @attr_accessible.nil? || @attr_accessible.include?(attr)
39
+ end
40
+
41
+ def define_field(field_name, options)
42
+ define_attribute_methods field_name
43
+ class_eval %Q{
44
+ def #{field_name}_redis_key
45
+ "#{self.redis_namespace}:\#{id}:#{field_name}"
46
+ end
47
+
48
+ def refresh_#{field_name}!
49
+ @attributes[:#{field_name}] = nil
50
+ #{field_name}
51
+ end
52
+
53
+ def destroy_#{field_name}
54
+ Redis::Value.new(#{field_name}_redis_key).delete
55
+ end
56
+ }
57
+ if options[:finder_field]
58
+ finder_field(field_name, options)
59
+ end
60
+ case options[:type]
61
+ when :set
62
+ set_field(field_name, options)
63
+ when :sorted_set
64
+ sorted_set_field(field_name, options)
65
+ when :list
66
+ list_field(field_name, options)
67
+ when :hash
68
+ hash_field(field_name, options)
69
+ when :float
70
+ float_field(field_name, options)
71
+ when :int, :integer
72
+ integer_field(field_name, options)
73
+ when :counter
74
+ counter_field(field_name, options)
75
+ when :boolean
76
+ boolean_field(field_name, options)
77
+ when :date
78
+ date_field(field_name, options)
79
+ when :time, :datetime, :timestamp
80
+ time_field(field_name, options)
81
+ else
82
+ string_field(field_name, options)
83
+ end
84
+ end
85
+
86
+ def string_field(field_name, options)
87
+ class_eval %Q{
88
+ def #{field_name}_object
89
+ Redis::Value.new(#{field_name}_redis_key)
90
+ end
91
+
92
+ def #{field_name}
93
+ @attributes[:#{field_name}] ||= begin
94
+ value = #{field_name}_object.value
95
+ value.nil? ? value : value.to_s
96
+ end
97
+ end
98
+
99
+ def #{field_name}=(value)
100
+ #{field_name}_will_change!
101
+ @attributes[:#{field_name}] = value
102
+ end
103
+
104
+ def set_#{field_name}(value)
105
+ #{field_name}_object.value = value.last
106
+ after_set(:#{field_name})
107
+ end
108
+ }
109
+ end
110
+
111
+ def integer_field(field_name, options)
112
+ class_eval %Q{
113
+ def #{field_name}_object
114
+ Redis::Value.new(#{field_name}_redis_key)
115
+ end
116
+
117
+ def #{field_name}
118
+ @attributes[:#{field_name}] ||= begin
119
+ value = #{field_name}_object.value
120
+ value.nil? ? value : value.to_i
121
+ end
122
+ end
123
+
124
+ def #{field_name}=(value)
125
+ #{field_name}_will_change!
126
+ @attributes[:#{field_name}] = value.to_i
127
+ end
128
+
129
+ def set_#{field_name}(value)
130
+ #{field_name}_object.value = value.last.to_i
131
+ after_set(:#{field_name})
132
+ end
133
+ }
134
+ end
135
+
136
+ def float_field(field_name, options)
137
+ class_eval %Q{
138
+ def #{field_name}_object
139
+ Redis::Value.new(#{field_name}_redis_key)
140
+ end
141
+
142
+ def #{field_name}
143
+ @attributes[:#{field_name}] ||= begin
144
+ value = #{field_name}_object.value
145
+ value.nil? ? value : value.to_f
146
+ end
147
+ end
148
+
149
+ def #{field_name}=(value)
150
+ #{field_name}_will_change!
151
+ @attributes[:#{field_name}] = value.to_f
152
+ end
153
+
154
+ def set_#{field_name}(value)
155
+ #{field_name}_object.value = value.last.to_f
156
+ after_set(:#{field_name})
157
+ end
158
+ }
159
+ end
160
+
161
+ def boolean_field(field_name, options)
162
+ class_eval %Q{
163
+ def #{field_name}_object
164
+ Redis::Value.new(#{field_name}_redis_key)
165
+ end
166
+
167
+ def #{field_name}
168
+ return @attributes[:#{field_name}] if @attributes[:#{field_name}].boolean?
169
+ @attributes[:#{field_name}] ||= begin
170
+ value = #{field_name}_object.value
171
+ value = "false" unless value.present?
172
+ value.to_bool
173
+ end
174
+ end
175
+
176
+ def #{field_name}?
177
+ !!#{field_name}
178
+ end
179
+
180
+ def #{field_name}=(value)
181
+ #{field_name}_will_change!
182
+ if !value.boolean?
183
+ value = value.to_bool
184
+ else
185
+ value = value
186
+ end
187
+
188
+ @attributes[:#{field_name}] = value
189
+ end
190
+
191
+ def set_#{field_name}(value)
192
+ #{field_name}_object.value = value.last.to_s
193
+ after_set(:#{field_name})
194
+ end
195
+ }
196
+ end
197
+
198
+ def counter_field(field_name, options)
199
+ class_eval %Q{
200
+ def #{field_name}_object
201
+ Redis::Counter.new(#{field_name}_redis_key)
202
+ end
203
+
204
+ def #{field_name}
205
+ @attributes[:#{field_name}] ||= #{field_name}_object.value.to_i
206
+ end
207
+
208
+ def #{field_name}=(#{field_name})
209
+ #{field_name}_will_change!
210
+ @attributes[:#{field_name}] = #{field_name}.to_i
211
+ end
212
+
213
+ def set_#{field_name}(value)
214
+ #{field_name}_object.value = value.last.to_i
215
+ after_set(:#{field_name})
216
+ end
217
+
218
+ def #{field_name}_inc(count)
219
+ @attributes[:#{field_name}] = #{field_name}_object.increment(count)
220
+ end
221
+
222
+ def #{field_name}_dec(count)
223
+ @attributes[:#{field_name}] = #{field_name}_object.decrement(count)
224
+ end
225
+ }
226
+ end
227
+
228
+ def list_field(field_name, options)
229
+ class_eval %Q{
230
+ def #{field_name}_object
231
+ Redis::List.new(#{field_name}_redis_key)
232
+ end
233
+
234
+ def #{field_name}
235
+ @attributes[:#{field_name}] ||= begin
236
+ ActiveRedis::DirtyObjects::Array.new(#{field_name}_object.values)
237
+ end
238
+ end
239
+
240
+ def #{field_name}=(array)
241
+ if !array.is_a?(Array) && array.present?
242
+ array = [array]
243
+ end
244
+ #{field_name}.replace(array) if array.is_a?(Array)
245
+
246
+ #{field_name}
247
+ end
248
+
249
+ def #{field_name}_force_load
250
+ @attributes[:#{field_name}] = #{field_name}_object.values
251
+ end
252
+
253
+ def #{field_name}_count
254
+ #{field_name}_object.count
255
+ end
256
+
257
+ def set_#{field_name}(value)
258
+ changes = value.first.last
259
+ changes[:additions].each do |addition|
260
+ #{field_name}_object.push(addition)
261
+ end
262
+ changes[:drops].each do |drop|
263
+ #{field_name}_object.delete(drop)
264
+ end
265
+ after_set(:#{field_name})
266
+ end
267
+ }
268
+ end
269
+
270
+ def set_field(field_name, options)
271
+ class_eval %Q{
272
+ def #{field_name}_object
273
+ Redis::Set.new(#{field_name}_redis_key)
274
+ end
275
+
276
+ def #{field_name}
277
+ @attributes[:#{field_name}] ||= begin
278
+ ActiveRedis::DirtyObjects::Array.new(#{field_name}_object.members)
279
+ end
280
+ end
281
+
282
+ def #{field_name}=(array)
283
+ #{field_name}.replace(array)
284
+ end
285
+
286
+ def #{field_name}_count
287
+ #{field_name}_object.count
288
+ end
289
+
290
+ def set_#{field_name}(value)
291
+ changes = value.first.last
292
+ changes[:additions].each do |addition|
293
+ #{field_name}_object.add(addition)
294
+ end
295
+ changes[:drops].each do |drop|
296
+ #{field_name}_object.delete(drop)
297
+ end
298
+ after_set(:#{field_name})
299
+ end
300
+ }
301
+ end
302
+
303
+ def sorted_set_field(field_name, options)
304
+ class_eval %Q{
305
+ def #{field_name}_object
306
+ Redis::SortedSet.new(#{field_name}_redis_key)
307
+ end
308
+
309
+ def #{field_name}
310
+ @attributes[:#{field_name}] ||= begin
311
+ ActiveRedis::DirtyObjects::SortedSet.new(#{field_name}_object.members)
312
+ end
313
+ end
314
+
315
+ def #{field_name}_count
316
+ #{field_name}_object.count
317
+ end
318
+
319
+ def set_#{field_name}(value)
320
+ changes = value.first.last
321
+ changes[:additions].each do |addition|
322
+ #{field_name}_object[changes[:hash].key(addition)] = addition
323
+ end
324
+ changes[:drops].each do |drop|
325
+ #{field_name}_object.delete(drop)
326
+ end
327
+ after_set(:#{field_name})
328
+ end
329
+ }
330
+ end
331
+
332
+ def hash_field(field_name, options)
333
+ class_eval %Q{
334
+ def #{field_name}_hash_set
335
+ Redis::HashKey.new(#{field_name}_redis_key)
336
+ end
337
+
338
+ def #{field_name}
339
+ @attributes[:#{field_name}] ||= begin
340
+ ActiveRedis::DirtyObjects::Hash[#{field_name}_hash_set.all]
341
+ end
342
+ end
343
+
344
+ def #{field_name}=(value)
345
+ #{field_name}.replace(value)
346
+ end
347
+
348
+ def set_#{field_name}(value)
349
+ changes = value.first.last
350
+ changes[:additions].each do |addition|
351
+ #{field_name}_hash_set[addition] = changes[:hash][addition]
352
+ end
353
+ changes[:drops].each do |drop|
354
+ #{field_name}_hash_set.delete(drop)
355
+ end
356
+ after_set(:#{field_name})
357
+ end
358
+ }
359
+ end
360
+
361
+ def date_field(field_name, options)
362
+ string_field(field_name, options)
363
+ class_eval %Q{
364
+ def #{field_name}
365
+ @attributes[:#{field_name}] ||= begin
366
+ value = #{field_name}_object.value
367
+ if value.blank?
368
+ nil
369
+ else
370
+ Date.parse(value)
371
+ end
372
+ end
373
+ end
374
+
375
+ def set_#{field_name}(value)
376
+ #{field_name}_object.value = value.last.to_s
377
+ after_set(:#{field_name})
378
+ end
379
+ }
380
+ end
381
+
382
+ def time_field(field_name, options)
383
+ string_field(field_name, options)
384
+ class_eval %Q{
385
+ def #{field_name}
386
+ @attributes[:#{field_name}] ||= begin
387
+ value = #{field_name}_object.value
388
+ if value.blank?
389
+ nil
390
+ else
391
+ Time.at(value.to_i)
392
+ end
393
+ end
394
+ end
395
+
396
+ def set_#{field_name}(value)
397
+ #{field_name}_object.value = value.last.to_i
398
+ after_set(:#{field_name})
399
+ end
400
+ }
401
+ end
402
+
403
+ def finder_field(field_name, options)
404
+ before_save do
405
+ if send("#{field_name}_changed?")
406
+ ActiveRedis.redis.del(self.class.finder_key(field_name, send("#{field_name}_was")))
407
+ ActiveRedis.redis.set(self.class.finder_key(field_name, send(field_name)), id)
408
+ end
409
+ end
410
+
411
+ class_eval %Q{
412
+ def self.find_by_#{field_name}(value)
413
+ id = Redis.current.get(finder_key("#{field_name}", value))
414
+ if id.present?
415
+ self.find(id)
416
+ else
417
+ nil
418
+ end
419
+ end
420
+ }
421
+ end
422
+ end
423
+ end
@@ -0,0 +1,16 @@
1
+ module ActiveRedis
2
+ module DirtyAttributes
3
+ def check_for_changes
4
+ @changed_attributes ||= {}
5
+ self.class.attribute_definitions.each do |attribute, options|
6
+ next unless @attributes.key?(attribute.to_sym)
7
+ value = send(attribute)
8
+ if value.class.name.start_with?("ActiveRedis::DirtyObjects")
9
+ if value.dirty?
10
+ @changed_attributes[attribute.to_s] = [value.original, value.changes]
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,19 @@
1
+ module ActiveRedis
2
+ module DirtyObjects
3
+ class Array < ::Array
4
+ attr_reader :original
5
+ def initialize(*args)
6
+ super
7
+ @original = dup
8
+ end
9
+
10
+ def dirty?
11
+ @original != self
12
+ end
13
+
14
+ def changes
15
+ {additions: self - @original, drops: @original - self}
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,31 @@
1
+ module ActiveRedis
2
+ module DirtyObjects
3
+ class Hash < ::Hash
4
+ def self.[](*args)
5
+ hash = super
6
+ hash.original = hash.dup
7
+ hash
8
+ end
9
+
10
+ attr_accessor :original
11
+
12
+ def dirty?
13
+ @original != self
14
+ end
15
+
16
+ def changes
17
+ {additions: updated_keys, drops: dropped_keys, hash: self}
18
+ end
19
+
20
+ def dropped_keys
21
+ @original.keys - self.keys
22
+ end
23
+
24
+ def updated_keys
25
+ self.keys.select do |key|
26
+ @original[key] != self[key]
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,18 @@
1
+ module ActiveRedis
2
+ module DirtyObjects
3
+ class SortedSet < ActiveRedis::DirtyObjects::Array
4
+ attr_accessor :hash
5
+ attr_reader :original
6
+
7
+ def []=(score, value)
8
+ self.push(score)
9
+ @hash ||= {}
10
+ @hash[value] = score
11
+ end
12
+
13
+ def changes
14
+ super.merge(hash: @hash)
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,62 @@
1
+ module ActiveRedis
2
+ module Save
3
+ #TODO: add if valid?
4
+ def save(options={})
5
+ unless options[:validate] == false
6
+ return false if invalid?(save_context)
7
+ end
8
+
9
+ if dirty?
10
+ case save_context
11
+ when :create
12
+ perform_create
13
+ when :update
14
+ perform_update
15
+ end
16
+ true
17
+ else
18
+ false
19
+ end
20
+ end
21
+
22
+ def new_record?
23
+ !!@new_record
24
+ end
25
+
26
+ private
27
+
28
+ def perform_save
29
+ run_callbacks :save do
30
+ Redis.current.pipelined do
31
+ self.changes.each do |key, value|
32
+ send("set_#{key}", value)
33
+ end
34
+ end
35
+ @new_record = false
36
+ @changed_attributes.clear
37
+ end
38
+ end
39
+
40
+ def perform_update
41
+ run_callbacks :update do
42
+ perform_save
43
+ end
44
+ end
45
+
46
+ def perform_create
47
+ run_callbacks :create do
48
+ #TODO: check if no object exists under that id
49
+ @id ||= SecureRandom.uuid().delete('-')
50
+ perform_save
51
+ end
52
+ end
53
+
54
+ def save_context
55
+ if new_record?
56
+ :create
57
+ else
58
+ :update
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,23 @@
1
+ module ActiveRedis
2
+ module Timestamps
3
+ def self.included(base)
4
+ base.class_eval do
5
+ field :created_at, type: :time
6
+ field :updated_at, type: :time
7
+
8
+ before_save :set_updated_at_to_now
9
+ before_create :set_created_at_to_now
10
+ end
11
+ end
12
+
13
+ private
14
+
15
+ def set_updated_at_to_now
16
+ self.updated_at = Time.now
17
+ end
18
+
19
+ def set_created_at_to_now
20
+ self.created_at = Time.now
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,3 @@
1
+ module ActiveRedisOrm
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,112 @@
1
+ require "active_redis/attributes"
2
+ require "active_redis/save"
3
+ require "active_redis/dirty_attributes"
4
+ require "active_redis/dirty_objects/array"
5
+ require "active_redis/dirty_objects/hash"
6
+ require "active_redis/dirty_objects/sorted_set"
7
+ require "active_redis/all_list"
8
+ require "active_redis/timestamps"
9
+
10
+ module ActiveRedis
11
+ mattr_accessor :redis
12
+ self.redis ||= Redis.current
13
+ class Base
14
+ include ActiveModel::Model
15
+ extend ActiveModel::Callbacks
16
+ extend ActiveModel::Naming
17
+ include ActiveModel::Serialization
18
+ include ActiveModel::Dirty
19
+ include ActiveModel::Validations
20
+
21
+ include ActiveRedis::DirtyAttributes
22
+ include ActiveRedis::Save
23
+ include ActiveRedis::AttributeMethods
24
+
25
+ attr_accessor :id
26
+ attr_reader :attributes
27
+
28
+ define_model_callbacks :create, :update, :save, :destroy
29
+ include ActiveRedis::AllList
30
+
31
+ #initialize with hash
32
+ def initialize(*args)
33
+ @attributes = {}
34
+ if args.first.is_a?(Hash) || args.empty?
35
+ set_attributes(args.first)
36
+ @new_record = true
37
+ elsif args.first.is_a?(String)
38
+ @id = args.first
39
+ end
40
+ end
41
+
42
+ def ==(other)
43
+ self.class == other.class && self.id == other.id && id.present?
44
+ end
45
+
46
+ def reload!
47
+ @attributes = {}
48
+ self
49
+ end
50
+
51
+ def dirty?
52
+ check_for_changes
53
+ self.changes.present?
54
+ end
55
+
56
+ def destroy
57
+ run_callbacks :destroy do
58
+ self.class.attributes.each do |attribute|
59
+ send("destroy_#{attribute}")
60
+ end
61
+ end
62
+ end
63
+
64
+ class << self
65
+ include ActiveRedis::Attributes
66
+ attr_accessor :attribute_definitions
67
+
68
+ def find(id)
69
+ new(id)
70
+ end
71
+
72
+ def create(*args)
73
+ object = new(*args)
74
+ object.save
75
+ object
76
+ end
77
+
78
+ def field(field_name, options = {})
79
+ self.attribute_definitions ||= {}
80
+ self.attribute_definitions[field_name.to_sym] = options
81
+ define_field(field_name, options)
82
+ end
83
+
84
+ def redis_namespace
85
+ self.name.underscore
86
+ end
87
+
88
+ def finder_key(field_name, value)
89
+ "#{redis_namespace.pluralize}:#{field_name}_to_#{redis_namespace}_id:#{value}"
90
+ end
91
+
92
+ def attributes
93
+ attribute_options.keys
94
+ end
95
+
96
+ def attribute_options
97
+ self.attribute_definitions ||= {}
98
+ attribute_definitions
99
+ end
100
+
101
+ def inherited(klass)
102
+ class << klass
103
+ self.class_eval do
104
+ define_method :attribute_options do
105
+ self.attribute_definitions.merge(superclass.attribute_options)
106
+ end
107
+ end
108
+ end
109
+ end
110
+ end
111
+ end
112
+ end
metadata ADDED
@@ -0,0 +1,89 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: active_redis_orm
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Tom Caspy
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-06-30 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.5'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.5'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: ActiveRedis is a Ruby ORM for Redis, using ActiveModel, heavily influenced
42
+ by the ActiveRecord and Mongoid gems
43
+ email:
44
+ - tom@tikalk.com
45
+ executables: []
46
+ extensions: []
47
+ extra_rdoc_files: []
48
+ files:
49
+ - .gitignore
50
+ - Gemfile
51
+ - LICENSE.txt
52
+ - README.md
53
+ - Rakefile
54
+ - active_redis_orm.gemspec
55
+ - lib/active_redis/all_list.rb
56
+ - lib/active_redis/attributes.rb
57
+ - lib/active_redis/dirty_attributes.rb
58
+ - lib/active_redis/dirty_objects/array.rb
59
+ - lib/active_redis/dirty_objects/hash.rb
60
+ - lib/active_redis/dirty_objects/sorted_set.rb
61
+ - lib/active_redis/save.rb
62
+ - lib/active_redis/timestamps.rb
63
+ - lib/active_redis/version.rb
64
+ - lib/active_redis_orm.rb
65
+ homepage: https://github.com/SpotIM/active_redis_orm
66
+ licenses:
67
+ - MIT
68
+ metadata: {}
69
+ post_install_message:
70
+ rdoc_options: []
71
+ require_paths:
72
+ - lib
73
+ required_ruby_version: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ required_rubygems_version: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ requirements: []
84
+ rubyforge_project:
85
+ rubygems_version: 2.2.2
86
+ signing_key:
87
+ specification_version: 4
88
+ summary: ActiveRedis is an ORM for redis written in Ruby.
89
+ test_files: []