active_redis 0.0.5 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +6 -14
- data/README.md +9 -5
- data/Rakefile +7 -0
- data/active_redis.gemspec +3 -0
- data/lib/active_redis.rb +9 -0
- data/lib/active_redis/associations.rb +25 -24
- data/lib/active_redis/associations/association.rb +36 -0
- data/lib/active_redis/associations/belongs_to_association.rb +32 -0
- data/lib/active_redis/associations/has_many_association.rb +26 -0
- data/lib/active_redis/associations/has_one_association.rb +24 -0
- data/lib/active_redis/attributes.rb +5 -4
- data/lib/active_redis/attributes/integer_attribute.rb +2 -2
- data/lib/active_redis/attributes/string_attribute.rb +2 -2
- data/lib/active_redis/attributes/time_attribute.rb +2 -2
- data/lib/active_redis/base.rb +4 -4
- data/lib/active_redis/config.rb +13 -10
- data/lib/active_redis/connection_ext/finders_layer.rb +12 -3
- data/lib/active_redis/constants.rb +2 -0
- data/lib/active_redis/errors.rb +6 -0
- data/lib/active_redis/helpers/lua_scripts.rb +7 -0
- data/lib/active_redis/inspector.rb +1 -1
- data/lib/active_redis/logs/basic_log.rb +11 -0
- data/lib/active_redis/logs/console_log.rb +14 -0
- data/lib/active_redis/logs/query_logger.rb +29 -0
- data/lib/active_redis/lua_scripts/main.lua +127 -50
- data/lib/active_redis/naming.rb +2 -0
- data/lib/active_redis/persistence.rb +12 -1
- data/lib/active_redis/query_chainer.rb +61 -0
- data/lib/active_redis/query_executor.rb +24 -0
- data/lib/active_redis/query_iterator.rb +27 -0
- data/lib/active_redis/railtie.rb +4 -2
- data/lib/active_redis/relation.rb +18 -0
- data/lib/active_redis/version.rb +1 -1
- data/specs/associations_spec.rb +94 -0
- data/specs/attributes_spec.rb +221 -0
- data/specs/calculations_spec.rb +28 -0
- data/specs/config_spec.rb +27 -0
- data/specs/inspector_spec.rb +45 -0
- data/specs/naming_spec.rb +56 -0
- data/specs/test_helper.rb +7 -0
- metadata +77 -18
- data/lib/active_redis/finders.rb +0 -22
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
metadata.gz: !binary |-
|
9
|
-
MTliYzEyZDQxOTgxY2MyZWVhZjlmOTg5MTZkMjk3OWMwZjVhMmU4MzQyMDJj
|
10
|
-
Y2U0YzA3MTEyYTk5ZWU2OWQwYWM1ZWFhMTU1ZTIzNzY0ZDBkNDFkMjIyMWU5
|
11
|
-
NGM5NzEzOGFmZjA2MDU1MDIzNzNkYWVjNmRkNjg1M2VmNGM0NjQ=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
Y2ZlMzRiYzAzNjJkMmRmY2RkZjFkNGFlMmEzMWFkNWMxYWE3NGVhZTVlNWVh
|
14
|
-
ZDY5Yjk4ZWFlZTU4MmUyZmI2ZDUxOGQyNjkxM2IyNTY3OWJlMWQzZmNhZDJk
|
15
|
-
YThiMmE4ZDMyMGI5YjY3Yjk0MmI5NzliYWI3NTc0ODlkZGVmYmU=
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 045f4c85e0aeb767fd6391f797427c932771c9b7
|
4
|
+
data.tar.gz: 9e250673aa1a847c1bdd33a1f85550ea9cedc8e1
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 3f54e5432066d8cd19c9844e84dc37b68d4a15bc02c2b13dc7ee618a9934c0edae3aa23685f835a45fdf69dd50b01ed64e20f6bbb41916da8f417a400c26961b
|
7
|
+
data.tar.gz: 91f1c901ff380025adc212ff0adb214d7f2c6577cffbd0017f3cf4f99752d4c4ded90efd9a74112cbad9350315f66421fd9a6b502b65b0df5faed39bbd7c3598
|
data/README.md
CHANGED
@@ -83,7 +83,7 @@ p Article.count # => 0
|
|
83
83
|
|
84
84
|
#### belongs_to association
|
85
85
|
|
86
|
-
### Finders
|
86
|
+
### Finders
|
87
87
|
|
88
88
|
You may find 'row' by it's id
|
89
89
|
|
@@ -101,10 +101,6 @@ end
|
|
101
101
|
Article.create(views: 1000, link: "http://someblog.com/1", title: "Title article")
|
102
102
|
Article.create(views: 3000, link: "http://someblog.com/2", title: "Title article")
|
103
103
|
|
104
|
-
Article.sum(:views) # => 4000
|
105
|
-
Article.min(:views) # => 1000
|
106
|
-
Article.max(:views) # => 3000
|
107
|
-
Article.pluck(:id) # => ["1", "2"]
|
108
104
|
```
|
109
105
|
|
110
106
|
From version 0.0.2 you are able to search item by multiple attributes using method __where__
|
@@ -136,6 +132,14 @@ class User < ActiveRedis::Base
|
|
136
132
|
end
|
137
133
|
```
|
138
134
|
|
135
|
+
## NEW IN VERSION 0.0.7
|
136
|
+
|
137
|
+
Method chaining. Now you may calling __where__, __order__, __limit__ something like this:
|
138
|
+
|
139
|
+
```ruby
|
140
|
+
Article.where(title: "Article title").where(views: 1000).order(title: :asc).limit(per_page: 20, page: 3)
|
141
|
+
```
|
142
|
+
|
139
143
|
## Contributing
|
140
144
|
|
141
145
|
1. Fork it
|
data/Rakefile
CHANGED
data/active_redis.gemspec
CHANGED
@@ -20,8 +20,11 @@ Gem::Specification.new do |spec|
|
|
20
20
|
|
21
21
|
spec.add_dependency "redis"
|
22
22
|
spec.add_dependency "activesupport"
|
23
|
+
spec.add_dependency "colorize"
|
23
24
|
|
24
25
|
spec.add_development_dependency "bundler", "~> 1.3"
|
25
26
|
spec.add_development_dependency "rake"
|
26
27
|
spec.add_development_dependency "rake-notes"
|
28
|
+
spec.add_development_dependency "mocha"
|
29
|
+
spec.add_development_dependency "turn"
|
27
30
|
end
|
data/lib/active_redis.rb
CHANGED
@@ -1,40 +1,41 @@
|
|
1
|
+
Dir[File.dirname(__FILE__) + '/associations/*.rb'].each {|file| require file }
|
2
|
+
require 'active_redis/constants'
|
3
|
+
require 'active_redis/errors'
|
4
|
+
|
1
5
|
module ActiveRedis
|
2
6
|
module Associations
|
3
7
|
|
4
8
|
def self.included(base)
|
5
9
|
base.extend ClassMethods
|
10
|
+
class << base; attr_accessor :associations; end
|
11
|
+
base.send :alias_method_chain, :save, :associations
|
12
|
+
end
|
13
|
+
|
14
|
+
def save_with_associations
|
15
|
+
self.class.associations.each { |key, a| a.save(self) }
|
16
|
+
save_without_associations
|
6
17
|
end
|
7
18
|
|
8
19
|
module ClassMethods
|
9
20
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
end
|
21
|
+
ActiveRedis::Constants::ASSOCIATIONS.each do |assoc|
|
22
|
+
class_eval <<-CODE
|
23
|
+
def #{assoc.to_s}(name, options = {})
|
24
|
+
register_association name, :#{assoc.to_s}, options
|
25
|
+
end
|
26
|
+
CODE
|
17
27
|
end
|
18
28
|
|
19
|
-
def
|
20
|
-
|
21
|
-
|
22
|
-
end
|
23
|
-
define_method "#{name.to_s}=" do |value|
|
24
|
-
value.each do |object|
|
25
|
-
object.send "#{self.class.foreign_key_name}=", self.id
|
26
|
-
end
|
27
|
-
end
|
29
|
+
def association(name)
|
30
|
+
raise UnregisteredAssociationError, "Unknown association :#{name}!" unless self.associations.has_key? name.to_sym
|
31
|
+
self.associations[name.to_sym]
|
28
32
|
end
|
29
33
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
define_method "#{name.to_s}=" do |value|
|
36
|
-
self.send "#{name.to_s}_id=", value.id
|
37
|
-
end
|
34
|
+
private
|
35
|
+
|
36
|
+
def register_association(name, type, options)
|
37
|
+
self.associations ||= {}
|
38
|
+
self.associations[name.to_sym] = "ActiveRedis::Associations::#{type.to_s.classify}Association".constantize.new(name, self, options)
|
38
39
|
end
|
39
40
|
|
40
41
|
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module ActiveRedis
|
2
|
+
module Associations
|
3
|
+
|
4
|
+
class Association
|
5
|
+
|
6
|
+
def initialize(name, target, options = {})
|
7
|
+
@name, @target = name, target
|
8
|
+
define_read_association
|
9
|
+
define_write_association
|
10
|
+
end
|
11
|
+
|
12
|
+
def reload(object)
|
13
|
+
object.send :instance_variable_set, "@assoc_#{@name}", nil
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def define_read_association
|
19
|
+
@target.class_eval <<-CODE
|
20
|
+
def #{@name}
|
21
|
+
@assoc_#{@name} ||= self.class.association(:#{@name}).read(self)
|
22
|
+
end
|
23
|
+
CODE
|
24
|
+
end
|
25
|
+
|
26
|
+
def define_write_association
|
27
|
+
@target.class_eval <<-CODE
|
28
|
+
def #{@name}=(value)
|
29
|
+
@assoc_#{@name} = value
|
30
|
+
end
|
31
|
+
CODE
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module ActiveRedis
|
2
|
+
module Associations
|
3
|
+
|
4
|
+
class BelongsToAssociation < Association
|
5
|
+
|
6
|
+
DEFAULT_OPTIONS = {touch: false}
|
7
|
+
|
8
|
+
def initialize(name, target, options = {})
|
9
|
+
super
|
10
|
+
@options ||= DEFAULT_OPTIONS.merge(options)
|
11
|
+
target.define_attributes_accessors("#{@name.to_s}_id" => :integer)
|
12
|
+
end
|
13
|
+
|
14
|
+
def read(object)
|
15
|
+
@name.to_s.capitalize.constantize.where(id: object.send("#{@name.to_s}_id")).top
|
16
|
+
end
|
17
|
+
|
18
|
+
def write(object, value)
|
19
|
+
object.send "#{@name.to_s}_id=", value.id
|
20
|
+
end
|
21
|
+
|
22
|
+
def save(object)
|
23
|
+
value = object.send :instance_variable_get, "@assoc_#{@name}"
|
24
|
+
return unless value
|
25
|
+
write(object, value)
|
26
|
+
value.touch if @options[:touch]
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module ActiveRedis
|
2
|
+
module Associations
|
3
|
+
|
4
|
+
class HasManyAssociation < Association
|
5
|
+
|
6
|
+
def read(object)
|
7
|
+
@name.to_s.singularize.capitalize.constantize.where("#{@target.foreign_key_name}" => object.id)
|
8
|
+
end
|
9
|
+
|
10
|
+
def write(object, value)
|
11
|
+
value.each do |assoc_object|
|
12
|
+
assoc_object.send "#{@target.foreign_key_name}=", object.id
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def save(object)
|
17
|
+
value = object.send :instance_variable_get, "@assoc_#{@name}"
|
18
|
+
return unless value
|
19
|
+
write object, value
|
20
|
+
value.each { |v| v.save }
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module ActiveRedis
|
2
|
+
module Associations
|
3
|
+
|
4
|
+
class HasOneAssociation < Association
|
5
|
+
|
6
|
+
def read(object)
|
7
|
+
@name.to_s.capitalize.constantize.where("#{@target.foreign_key_name}" => object.id).top
|
8
|
+
end
|
9
|
+
|
10
|
+
def write(object, value)
|
11
|
+
value.send "#{@target.foreign_key_name}=", object.id
|
12
|
+
end
|
13
|
+
|
14
|
+
def save(object)
|
15
|
+
value = object.send :instance_variable_get, "@assoc_#{@name}"
|
16
|
+
return unless value
|
17
|
+
write object, value
|
18
|
+
value.save
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
@@ -23,7 +23,7 @@ module ActiveRedis
|
|
23
23
|
|
24
24
|
module ClassMethods
|
25
25
|
|
26
|
-
def attributes(attrs)
|
26
|
+
def attributes(attrs = {})
|
27
27
|
raise ActiveRedis::InvalidArgumentError, "Value must be a Hash!" unless attrs.is_a?(Hash)
|
28
28
|
attrs = attrs.merge(ActiveRedis::Constants::DEFAULT_ATTRIBUTES)
|
29
29
|
class << self; attr_accessor :defined_attributes; end
|
@@ -46,15 +46,16 @@ module ActiveRedis
|
|
46
46
|
private
|
47
47
|
|
48
48
|
def register_attribute(attribute, type)
|
49
|
-
return if self.defined_attributes.has_key? attribute.to_sym
|
49
|
+
return false if self.defined_attributes.has_key? attribute.to_sym
|
50
50
|
self.defined_attributes[attribute.to_sym] = {
|
51
51
|
class: "ActiveRedis::Attributes::#{type.to_s.capitalize}Attribute".constantize,
|
52
52
|
type: type
|
53
53
|
}
|
54
|
+
true
|
54
55
|
end
|
55
56
|
|
56
57
|
def attribute_class(attribute)
|
57
|
-
|
58
|
+
self.defined_attributes[attribute.to_sym][:class]
|
58
59
|
end
|
59
60
|
|
60
61
|
def read_attribute(attribute)
|
@@ -67,7 +68,7 @@ module ActiveRedis
|
|
67
68
|
def write_attribute(attribute)
|
68
69
|
define_method "#{attribute}=" do |value|
|
69
70
|
klass = self.class.send :attribute_class, attribute
|
70
|
-
|
71
|
+
instance_variable_set("@#{attribute}", klass.dump(value))
|
71
72
|
end
|
72
73
|
end
|
73
74
|
|
@@ -3,11 +3,11 @@ module ActiveRedis
|
|
3
3
|
class TimeAttribute < Attribute
|
4
4
|
|
5
5
|
def self.load(value)
|
6
|
-
Time.at(value.to_i)
|
6
|
+
value.nil? || value.empty? ? nil : Time.at(value.to_i)
|
7
7
|
end
|
8
8
|
|
9
9
|
def self.dump(value)
|
10
|
-
value.to_i.to_s
|
10
|
+
value ? value.to_i.to_s : nil
|
11
11
|
end
|
12
12
|
|
13
13
|
end
|
data/lib/active_redis/base.rb
CHANGED
@@ -3,20 +3,20 @@ require 'active_redis/associations'
|
|
3
3
|
require 'active_redis/persistence'
|
4
4
|
require 'active_redis/naming'
|
5
5
|
require 'active_redis/calculations'
|
6
|
-
require 'active_redis/finders'
|
7
6
|
require 'active_redis/inspector'
|
7
|
+
require 'active_redis/relation'
|
8
8
|
|
9
9
|
# TODO: Add Expiring module
|
10
10
|
|
11
11
|
module ActiveRedis
|
12
12
|
class Base
|
13
13
|
extend Naming
|
14
|
-
extend Calculations
|
15
|
-
extend
|
14
|
+
# extend Calculations
|
15
|
+
extend Relation
|
16
16
|
|
17
17
|
include Attributes
|
18
|
-
include Associations
|
19
18
|
include Persistence
|
19
|
+
include Associations
|
20
20
|
include Inspector
|
21
21
|
|
22
22
|
end
|
data/lib/active_redis/config.rb
CHANGED
@@ -1,14 +1,17 @@
|
|
1
1
|
class ActiveRedis::Config
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
2
|
+
# Specify connection string to Redis. To check all available options please see redis-rb library.
|
3
|
+
#
|
4
|
+
# Some samples:
|
5
|
+
# ActiveRedis.config.connection_options = {host: 10.10.1.1, port: 6380}
|
6
|
+
# or
|
7
|
+
# ActiveRedis.config.connection_options = {path: '/tmp/redis.sock'}
|
8
|
+
attr_accessor :connection_options
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
10
|
+
# Specify adapter for connection to DB
|
11
|
+
# By default it's ActiveRedis::Adapters::BasicAdapter
|
12
|
+
attr_accessor :adapter
|
13
13
|
|
14
|
+
# Specify log
|
15
|
+
# By default it's ActiveRedis::Logs::ConsoleLog
|
16
|
+
attr_accessor :log
|
14
17
|
end
|
@@ -1,20 +1,29 @@
|
|
1
|
+
require 'active_redis/logs/query_logger'
|
2
|
+
|
1
3
|
module ActiveRedis::ConnectionExt
|
2
4
|
module FindersLayer
|
3
5
|
|
6
|
+
def self.included(base)
|
7
|
+
base.send :extend, ActiveRedis::Logs::QueryLogger
|
8
|
+
base.loggable :run_query_analyzer
|
9
|
+
end
|
10
|
+
|
4
11
|
def fetch_row(model, id)
|
5
|
-
|
12
|
+
fetch_where(model, id: id).first
|
6
13
|
end
|
7
14
|
|
8
15
|
def fetch_keys(model)
|
16
|
+
ActiveRedis.log.write "Calling ActiveRedis::ConnectionExt::FindersLayer::fetch_keys(#{model.name})"
|
9
17
|
adapter.keys model.key_name
|
10
18
|
end
|
11
19
|
|
12
20
|
def fetch_where(model, params)
|
21
|
+
ActiveRedis.log.write "Calling ActiveRedis::ConnectionExt::FindersLayer::fetch_where(#{model.name}, #{params})"
|
13
22
|
run_eval :where, [model.key_name], params.flatten
|
14
23
|
end
|
15
24
|
|
16
|
-
def
|
17
|
-
|
25
|
+
def run_query_analyzer(model, params = ["", "", ""])
|
26
|
+
run_eval :query_analyzer, [model.key_name, Time.now.to_i], params
|
18
27
|
end
|
19
28
|
|
20
29
|
end
|