redis-model-extension 0.3.8 → 0.4.0
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/Gemfile +4 -1
- data/README.markdown +62 -27
- data/Rakefile +0 -6
- data/VERSION +1 -1
- data/lib/redis-model-extension/attributes.rb +38 -0
- data/lib/redis-model-extension/autoincrement_id.rb +38 -0
- data/lib/redis-model-extension/config.rb +67 -0
- data/lib/redis-model-extension/get_find.rb +146 -0
- data/lib/redis-model-extension/initialize.rb +179 -0
- data/lib/redis-model-extension/old_initialize.rb +103 -0
- data/lib/redis-model-extension/redis_key.rb +119 -0
- data/lib/redis-model-extension/save_destroy.rb +104 -0
- data/lib/redis-model-extension/store_keys.rb +34 -0
- data/lib/redis-model-extension/validation.rb +84 -0
- data/lib/redis-model-extension/value_transform.rb +51 -0
- data/lib/redis-model-extension.rb +52 -320
- data/lib/redis-model.rb +14 -0
- data/redis-model-extension.gemspec +40 -6
- data/test/helper.rb +17 -2
- data/test/models.rb +83 -0
- data/test/redis_model_old/test_redis_model_old_config.rb +218 -0
- data/test/redis_model_parts/test_attributes.rb +34 -0
- data/test/redis_model_parts/test_autoincrement_id.rb +86 -0
- data/test/redis_model_parts/test_dynamic_alias.rb +147 -0
- data/test/redis_model_parts/test_get_find.rb +111 -0
- data/test/redis_model_parts/test_hooks.rb +36 -0
- data/test/redis_model_parts/test_initialize.rb +46 -0
- data/test/redis_model_parts/test_redis_key.rb +119 -0
- data/test/redis_model_parts/test_save_destroy.rb +102 -0
- data/test/redis_model_parts/test_validation.rb +72 -0
- data/test/redis_model_parts/test_variable_types.rb +91 -0
- data/test/test_redis-model-extension.rb +38 -200
- data/test/test_string_to_bool.rb +30 -0
- metadata +90 -32
data/Gemfile
CHANGED
@@ -3,13 +3,16 @@ source "http://rubygems.org"
|
|
3
3
|
gem "redis"
|
4
4
|
gem "i18n"
|
5
5
|
gem "activesupport"
|
6
|
+
gem "activemodel"
|
6
7
|
|
7
8
|
group :development do
|
8
9
|
gem "shoulda", ">= 0"
|
9
10
|
gem 'shoulda-context'
|
11
|
+
gem 'mocha'
|
12
|
+
gem "simplecov", "~> 0.6.4"
|
10
13
|
gem "rake"
|
11
14
|
gem "rack"
|
12
|
-
gem "
|
15
|
+
gem "sdoc" # sdoc -N .
|
13
16
|
gem "bundler"
|
14
17
|
gem "jeweler", "~> 1.8.3"
|
15
18
|
gem "turn", "~> 0.8.2"
|
data/README.markdown
CHANGED
@@ -2,6 +2,25 @@
|
|
2
2
|
|
3
3
|
Redis model is basic implementation of few methods for creating model which store data in Redis
|
4
4
|
|
5
|
+
## Instalation
|
6
|
+
|
7
|
+
Just in console
|
8
|
+
|
9
|
+
``` ruby
|
10
|
+
gem install redis-model-extension
|
11
|
+
```
|
12
|
+
|
13
|
+
Or put into Gemfile
|
14
|
+
|
15
|
+
``` ruby
|
16
|
+
gem "redis-model-extension"
|
17
|
+
```
|
18
|
+
|
19
|
+
and somewhere before use (not rails - they will require gem automaticaly)
|
20
|
+
``` ruby
|
21
|
+
require "redis-model-extension"
|
22
|
+
```
|
23
|
+
|
5
24
|
## Initialization
|
6
25
|
|
7
26
|
You can use yml config file `redis_config.yml` in `config` directory:
|
@@ -33,27 +52,43 @@ RedisModelExtension::Database.redis_config(:host => "127.0.0.1", :port => 6379,
|
|
33
52
|
|
34
53
|
## Usage
|
35
54
|
|
55
|
+
Your class needs to include RedisModel and there is your testing configuration:
|
56
|
+
([old initialization - still working :)](https://github.com/ondrejbartas/redis-model-extension/wiki/Old-initialization))
|
57
|
+
|
36
58
|
``` ruby
|
37
59
|
class TestRedisModel
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
60
|
+
include RedisModelExtension
|
61
|
+
|
62
|
+
#REQUIRED:
|
63
|
+
#redis_field :name_of_field, :filed_type, (:default_value - optional)
|
64
|
+
redis_field :field1, :integer
|
65
|
+
redis_field :field2, :bool
|
66
|
+
redis_field :field3, :string, "Default string"
|
67
|
+
redis_field :field4, :symbol
|
68
|
+
redis_field :field5, :array
|
69
|
+
redis_field :field6, :hash
|
70
|
+
redis_field :field7, :time
|
71
|
+
redis_field :field8, :date
|
72
|
+
|
73
|
+
# which columns are used for generating redis key - name_of_your_class:key:field1:field2...
|
74
|
+
redis_key :field1, :field2
|
75
|
+
|
76
|
+
#OPTIONALS:
|
77
|
+
|
78
|
+
# redis_validate :field1, :field2... #test your model, if all specified variables are not nil
|
79
|
+
redis_validate :field1, :field3
|
80
|
+
|
81
|
+
# reddis_key_normalize - when assembling redis key you can specify normalization actions for values
|
82
|
+
# :downcase - your_class:key:Value:FoO -> your_class:key:value:foo (find - case insensitive)
|
83
|
+
# :transliterate - your_class:key:VašíČek:FoO -> your_class:key:VasiCek:FoO (find - without á,č etc.)
|
84
|
+
# :downcase & :transliterate - your_class:key:VašíČek:FoO -> your_class:key:vasicek:foo
|
85
|
+
# this is crucial for find method
|
86
|
+
reddis_key_normalize :transliterate, :downcase
|
87
|
+
|
88
|
+
# redis alias is working as redis key, but it will only create alias to your main hash in redis
|
89
|
+
# specified is by combination of uniq value (you specify which fields to use)
|
90
|
+
# redis_alias :name_of_alias, <array of field names>
|
91
|
+
redis_alias :token, [:field4]
|
57
92
|
end
|
58
93
|
|
59
94
|
foo = TestRedisModel.new()
|
@@ -68,7 +103,7 @@ end
|
|
68
103
|
|
69
104
|
# custom errors in initialize etc.
|
70
105
|
#class declaration
|
71
|
-
def initialize args =
|
106
|
+
def initialize args = {}
|
72
107
|
error << "My custom error"
|
73
108
|
super args
|
74
109
|
end
|
@@ -76,9 +111,9 @@ end
|
|
76
111
|
|
77
112
|
|
78
113
|
#you can update more attributes at once
|
79
|
-
foo.update(:
|
114
|
+
foo.update(:field1 => 234, :field3 => "bar")
|
80
115
|
|
81
|
-
# !!! if you try to save invalid object you will get ArgumentError
|
116
|
+
# !!! if you try to save invalid object you will get ArgumentError exception !!!
|
82
117
|
|
83
118
|
# after save you can find and get object find_by_alias
|
84
119
|
|
@@ -86,24 +121,24 @@ foo.update(:integer => 234, :string => "bar")
|
|
86
121
|
#you can perfor find only with keys which are in redis key
|
87
122
|
#this is slow variant for redis but compared to other databases super fast :-)
|
88
123
|
#if you specify all keys from redis key it will perform faster method get
|
89
|
-
TestRedisModel.find(:
|
124
|
+
TestRedisModel.find(:field3 => "foo")
|
90
125
|
|
91
126
|
#you can use get method if you know all keys used in redis key
|
92
127
|
#this variant is super fast
|
93
|
-
TestRedisModel.get(:
|
128
|
+
TestRedisModel.get(:field3 => "foo", :field4=> true)
|
94
129
|
|
95
130
|
#you can ask redis if this item exists
|
96
|
-
TestRedisModel.exists?(:
|
131
|
+
TestRedisModel.exists?(:field3 => "foo", :field4=> true)
|
97
132
|
|
98
133
|
#you can try to find by alias - alias needs to be uniq
|
99
134
|
#use alias only for uniq combination of keys
|
100
|
-
TestRedisModel.find_by_alias(:token, :
|
135
|
+
TestRedisModel.find_by_alias(:token, :field4=> true)
|
101
136
|
|
102
137
|
```
|
103
138
|
|
104
139
|
Now you can easily access all attributes from TestRedisModel by `foo.integer` or exists? `foo.integer?` or set value by `foo.integer = 1234`
|
105
140
|
|
106
|
-
You can initialize model by `foo = TestRedisModel.new(:
|
141
|
+
You can initialize model by `foo = TestRedisModel.new(:field1 => 123, :field3 => "bar")` and then access it same as above.
|
107
142
|
|
108
143
|
Saving is easy too: `foo.save` -> It will raise exception if :required attributes aren't filled. Error message says what is missing.
|
109
144
|
|
data/Rakefile
CHANGED
@@ -58,12 +58,6 @@ task :startup => [:'redis:start']
|
|
58
58
|
desc "Teardown databases"
|
59
59
|
task :teardown => [:'redis:stop']
|
60
60
|
|
61
|
-
Rake::TestTask.new(:test) do |t|
|
62
|
-
t.test_files = FileList['test/functional/*_test.rb', 'test/unit/*_test.rb','test/integration/*_test.rb']
|
63
|
-
t.warning = false
|
64
|
-
t.verbose = false
|
65
|
-
end
|
66
|
-
|
67
61
|
namespace :redis do
|
68
62
|
desc "Start the Redis server"
|
69
63
|
task :start do
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.4.0
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
module RedisModelExtension
|
3
|
+
|
4
|
+
# == Attribues
|
5
|
+
# modul for easier getting all attributes
|
6
|
+
# also for setting ang getting value instance variable
|
7
|
+
module Attributes
|
8
|
+
|
9
|
+
#take all arguments and send them out
|
10
|
+
def to_arg
|
11
|
+
redis_fields_config.inject({}) do |args, (key, type)|
|
12
|
+
args[key] = self.send(key)
|
13
|
+
args
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
alias :args :to_arg
|
18
|
+
|
19
|
+
#put arguments into json
|
20
|
+
def to_json
|
21
|
+
to_arg.to_json
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
# get value from instance variable
|
28
|
+
def value_get name
|
29
|
+
instance_variable_get(:"@#{name}")
|
30
|
+
end
|
31
|
+
|
32
|
+
# set value into instance variable
|
33
|
+
def value_set name, value
|
34
|
+
instance_variable_set(:"@#{name}", value)
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
module RedisModelExtension
|
3
|
+
|
4
|
+
# == Class Autoincrement Id
|
5
|
+
# get last id
|
6
|
+
# generate autoincrement key
|
7
|
+
module ClassAutoincrementId
|
8
|
+
|
9
|
+
# get last id from redis
|
10
|
+
def get_last_id
|
11
|
+
Database.redis.get generate_autoincrement_key
|
12
|
+
end
|
13
|
+
|
14
|
+
#generate autoincrement key
|
15
|
+
def generate_autoincrement_key
|
16
|
+
"#{self.name.to_s.underscore.to_sym}:autoincrement_id"
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
# == Autoincrement Id
|
22
|
+
# increment id
|
23
|
+
module AutoincrementId
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
# get auto incremented id from redis
|
28
|
+
def increment_id
|
29
|
+
Database.redis.incr self.class.generate_autoincrement_key
|
30
|
+
end
|
31
|
+
|
32
|
+
# get last id from redis
|
33
|
+
def get_last_id
|
34
|
+
self.class.get_last_id
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
module RedisModelExtension
|
3
|
+
# == Config
|
4
|
+
# set private methods for accessing & storing class configurations
|
5
|
+
module ClassConfig
|
6
|
+
|
7
|
+
#store informations about saving nil values
|
8
|
+
def redis_save_fields_with_nil_conf
|
9
|
+
@redis_save_fields_with_nil_conf.nil? ? @redis_save_fields_with_nil_conf = true : @redis_save_fields_with_nil_conf
|
10
|
+
end
|
11
|
+
|
12
|
+
#store informations about current class fields settings
|
13
|
+
def redis_fields_config
|
14
|
+
@redis_model_config ||= {}
|
15
|
+
end
|
16
|
+
|
17
|
+
#store informations about current class fields defaults settings
|
18
|
+
def redis_fields_defaults_config
|
19
|
+
@redis_model_defaults_config ||= {}
|
20
|
+
end
|
21
|
+
|
22
|
+
#store informations about current class redis key fields
|
23
|
+
def redis_key_config
|
24
|
+
@redis_key_config ||= []
|
25
|
+
end
|
26
|
+
|
27
|
+
#store informations about current class aliases settings
|
28
|
+
def redis_alias_config
|
29
|
+
@redis_alias_config ||= {}
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
#store informations about all user defined fields settings
|
35
|
+
def redis_user_field_config
|
36
|
+
@redis_user_field_config ||= []
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
# == Config
|
42
|
+
# set private methods for accessing class configurations form instance
|
43
|
+
module Config
|
44
|
+
private
|
45
|
+
|
46
|
+
# pointer to class settings
|
47
|
+
def redis_key_config
|
48
|
+
self.class.redis_key_config
|
49
|
+
end
|
50
|
+
|
51
|
+
# pointer to class settings
|
52
|
+
def redis_fields_config
|
53
|
+
self.class.redis_fields_config
|
54
|
+
end
|
55
|
+
|
56
|
+
# pointer to class settings
|
57
|
+
def redis_fields_defaults_config
|
58
|
+
self.class.redis_fields_defaults_config
|
59
|
+
end
|
60
|
+
|
61
|
+
# pointer to class settings
|
62
|
+
def redis_alias_config
|
63
|
+
self.class.redis_alias_config
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,146 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
module RedisModelExtension
|
3
|
+
|
4
|
+
# == Get & Find
|
5
|
+
# * Model.all => Array of all instances
|
6
|
+
# * Model.find(1) => Array of one instance with id 1
|
7
|
+
# * Model.get(1) => Array of one instance with id 1
|
8
|
+
# * Model.find( id: 1 ) => Array of one instance with id 1
|
9
|
+
# * Model.find( field: "test" ) => Array of all instances with field == test [field must be in redis key]
|
10
|
+
module ClassGetFind
|
11
|
+
|
12
|
+
######################################
|
13
|
+
# FIND METHODS
|
14
|
+
######################################
|
15
|
+
|
16
|
+
#Find method for searching in redis
|
17
|
+
# * args (Integer) - search by id
|
18
|
+
# * args (Hash) - search by arguments in redis_key
|
19
|
+
def find(args = {})
|
20
|
+
# when argument is integer - search by id
|
21
|
+
args = { id: args } if args.is_a?(Integer)
|
22
|
+
#normalize input hash of arguments
|
23
|
+
args = HashWithIndifferentAccess.new(args)
|
24
|
+
|
25
|
+
out = []
|
26
|
+
klass = self.name.constantize
|
27
|
+
|
28
|
+
#is key specified directly? -> no needs of looking for other keys! -> faster
|
29
|
+
if klass.valid_key?(args)
|
30
|
+
if klass.exists?(args)
|
31
|
+
out << klass.new_by_key(klass.generate_key(args))
|
32
|
+
end
|
33
|
+
else
|
34
|
+
RedisModelExtension::Database.redis.keys(klass.generate_key(args)).each do |key|
|
35
|
+
out << klass.new_by_key(key)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
out
|
39
|
+
end
|
40
|
+
alias :all :find
|
41
|
+
|
42
|
+
#Find method for searching in redis
|
43
|
+
def find_by_alias(alias_name, args = {})
|
44
|
+
#check if asked dynamic alias exists
|
45
|
+
raise ArgumentError, "Unknown dynamic alias: '#{alias_name}', use: #{redis_alias_config.keys.join(", ")} " unless redis_alias_config.has_key?(alias_name.to_sym)
|
46
|
+
|
47
|
+
#normalize input hash of arguments
|
48
|
+
args = HashWithIndifferentAccess.new(args)
|
49
|
+
|
50
|
+
out = []
|
51
|
+
klass = self.name.constantize
|
52
|
+
#is key specified directly? -> no needs of looking for other keys! -> faster
|
53
|
+
if klass.valid_alias_key?(alias_name, args)
|
54
|
+
out << klass.get_by_alias(alias_name, args) if klass.alias_exists?(alias_name, args)
|
55
|
+
else
|
56
|
+
RedisModelExtension::Database.redis.keys(klass.generate_alias_key(alias_name, args)).each do |key|
|
57
|
+
out << klass.get_by_alias_key(key)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
out
|
61
|
+
end
|
62
|
+
|
63
|
+
######################################
|
64
|
+
# GET BY ARGUMENTS
|
65
|
+
######################################
|
66
|
+
|
67
|
+
#fastest method to get object from redis by getting it by arguments
|
68
|
+
# * args (Integer) - search by id
|
69
|
+
# * args (Hash) - search by arguments in redis_key
|
70
|
+
def get(args = {})
|
71
|
+
# when argument is integer - search by id
|
72
|
+
args = { id: args } if args.is_a?(Integer)
|
73
|
+
|
74
|
+
#normalize input hash of arguments
|
75
|
+
args = HashWithIndifferentAccess.new(args)
|
76
|
+
|
77
|
+
klass = self.name.constantize
|
78
|
+
if klass.valid_key?(args) && klass.exists?(args)
|
79
|
+
klass.new_by_key(klass.generate_key(args))
|
80
|
+
else
|
81
|
+
nil
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
######################################
|
86
|
+
# GET BY REDIS KEYS
|
87
|
+
######################################
|
88
|
+
|
89
|
+
#fastest method to get object from redis by getting it by dynamic alias and arguments
|
90
|
+
def get_by_alias(alias_name, args = {})
|
91
|
+
#check if asked dynamic alias exists
|
92
|
+
raise ArgumentError, "Unknown dynamic alias: '#{alias_name}', use: #{redis_alias_config.keys.join(", ")} " unless redis_alias_config.has_key?(alias_name.to_sym)
|
93
|
+
|
94
|
+
#normalize input hash of arguments
|
95
|
+
args = HashWithIndifferentAccess.new(args)
|
96
|
+
|
97
|
+
klass = self.name.constantize
|
98
|
+
if klass.valid_alias_key?(alias_name, args) && klass.alias_exists?(alias_name, args)
|
99
|
+
key = RedisModelExtension::Database.redis.get(klass.generate_alias_key(alias_name, args))
|
100
|
+
return klass.new_by_key(key) if RedisModelExtension::Database.redis.exists(key)
|
101
|
+
end
|
102
|
+
nil
|
103
|
+
end
|
104
|
+
|
105
|
+
|
106
|
+
######################################
|
107
|
+
# GET BY REDIS KEYS
|
108
|
+
######################################
|
109
|
+
|
110
|
+
#if you know redis key and would like to get object
|
111
|
+
def get_by_redis_key(redis_key)
|
112
|
+
if redis_key.is_a?(String) && RedisModelExtension::Database.redis.exists(redis_key)
|
113
|
+
klass = self.name.constantize
|
114
|
+
klass.new_by_key(redis_key)
|
115
|
+
else
|
116
|
+
nil
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
#fastest method to get object from redis by getting it by alias and arguments
|
121
|
+
def get_by_alias_key(alias_key)
|
122
|
+
klass = self.name.constantize
|
123
|
+
if RedisModelExtension::Database.redis.exists(alias_key)
|
124
|
+
key = RedisModelExtension::Database.redis.get(alias_key)
|
125
|
+
return klass.new_by_key(key) if RedisModelExtension::Database.redis.exists(key)
|
126
|
+
end
|
127
|
+
nil
|
128
|
+
end
|
129
|
+
|
130
|
+
|
131
|
+
######################################
|
132
|
+
# CREATE NEW OBJECT BY HASH VALUES
|
133
|
+
######################################
|
134
|
+
|
135
|
+
# read all data from redis and create new instance (used for Find & Get method)
|
136
|
+
def new_by_key(key)
|
137
|
+
args = HashWithIndifferentAccess.new(RedisModelExtension::Database.redis.hgetall(key))
|
138
|
+
|
139
|
+
new_instance = self.name.constantize.new(args)
|
140
|
+
new_instance.store_keys
|
141
|
+
|
142
|
+
return new_instance
|
143
|
+
end
|
144
|
+
|
145
|
+
end
|
146
|
+
end
|
@@ -0,0 +1,179 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
module RedisModelExtension
|
3
|
+
|
4
|
+
# == Class Initialize
|
5
|
+
# redis_field - defines fields to be stored into redis
|
6
|
+
# redis_alias - defines aliases for finding models
|
7
|
+
# redis_key - defines wich fields will be in redis key
|
8
|
+
# redis_key_normalize - normalization of redis key (downcase, transliterate)
|
9
|
+
# redis_save_fields_with_nil - enable/disable save of nil fields into redis
|
10
|
+
module ClassInitialize
|
11
|
+
VALID_NORMALIZATIONS = [:downcase, :transliterate]
|
12
|
+
|
13
|
+
#add new field which will be saved into redis
|
14
|
+
# * name - name of your variable
|
15
|
+
# * type - type of your variable (:integer, :float, :string, :array, :hash)
|
16
|
+
# * (default) - default value of your variable
|
17
|
+
def redis_field name, type, default = nil
|
18
|
+
redis_user_field_config << name
|
19
|
+
|
20
|
+
# remember field to save into redis
|
21
|
+
redis_fields_config[name] = type
|
22
|
+
# remember field default value
|
23
|
+
redis_fields_defaults_config[name] = default
|
24
|
+
|
25
|
+
# get value
|
26
|
+
define_method name do
|
27
|
+
value_get name
|
28
|
+
end
|
29
|
+
|
30
|
+
# assign new value
|
31
|
+
define_method "#{name}=" do |new_value|
|
32
|
+
value_set name, new_value
|
33
|
+
end
|
34
|
+
|
35
|
+
# value exists? (not nil and not blank?)
|
36
|
+
define_method "#{name}?" do
|
37
|
+
value_get(name) && !value_get(name).blank? ? true : false
|
38
|
+
end
|
39
|
+
|
40
|
+
# default saving nil values to redis
|
41
|
+
redis_save_fields_with_nil true
|
42
|
+
|
43
|
+
#set default key to autoincrement id
|
44
|
+
set_redis_autoincrement_key
|
45
|
+
end
|
46
|
+
|
47
|
+
def set_redis_autoincrement_key
|
48
|
+
@redis_key_config = [:id]
|
49
|
+
|
50
|
+
# get value
|
51
|
+
define_method :id do
|
52
|
+
value_get :id
|
53
|
+
end
|
54
|
+
|
55
|
+
# value exists? (not nil and not blank?)
|
56
|
+
define_method "id?" do
|
57
|
+
value_get(:id) && !value_get(:id).blank? ? true : false
|
58
|
+
end
|
59
|
+
|
60
|
+
# set value
|
61
|
+
define_method "id=" do |new_value|
|
62
|
+
value_set :id, new_value
|
63
|
+
end
|
64
|
+
private :id= #set it as private
|
65
|
+
|
66
|
+
redis_fields_config[:id] = :autoincrement
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
def remove_redis_autoincrement_key
|
71
|
+
|
72
|
+
puts "#{self.name} : remove"
|
73
|
+
# remove get value
|
74
|
+
remove_method :id
|
75
|
+
|
76
|
+
# remove value exists? (not nil and not blank?)
|
77
|
+
remove_method "id?"
|
78
|
+
|
79
|
+
# remove set value
|
80
|
+
remove_method "id="
|
81
|
+
|
82
|
+
redis_fields_config.delete(:id)
|
83
|
+
end
|
84
|
+
|
85
|
+
|
86
|
+
# set redis key which will be used for storing model
|
87
|
+
def redis_key *fields
|
88
|
+
@redis_key_config = fields.flatten
|
89
|
+
|
90
|
+
validate_redis_key
|
91
|
+
|
92
|
+
#own specification of redis key - delete autoincrement
|
93
|
+
remove_redis_autoincrement_key unless redis_user_field_config.include?(:id) || @redis_key_config.include?(:id)
|
94
|
+
|
95
|
+
# automaticaly add all fields from key to validation
|
96
|
+
# if any of fields in redis key is nil
|
97
|
+
# then prevent to save it
|
98
|
+
@redis_key_config.each do |field|
|
99
|
+
validates field, :presence => :true if field != :id
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
# set redis model to normalize redis keys
|
104
|
+
def redis_key_normalize *metrics
|
105
|
+
@redis_key_normalize_conf ||= []
|
106
|
+
metrics.each do |metric|
|
107
|
+
raise ArgumentError, "Please provide valid normalization: #{VALID_NORMALIZATIONS.join(", ")}" unless VALID_NORMALIZATIONS.include?(metric)
|
108
|
+
@redis_key_normalize_conf << metric
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
# store informations about redis aliases
|
113
|
+
def redis_alias name, main_fields, name_of_field_for_order = nil, name_of_field_for_args = nil
|
114
|
+
#set fields if they are not allready set!
|
115
|
+
if name_of_field_for_order && name_of_field_for_args
|
116
|
+
redis_field name_of_field_for_order, :array, [] unless redis_fields_config.has_key?(name_of_field_for_order)
|
117
|
+
redis_field name_of_field_for_args, :hash, {} unless redis_fields_config.has_key?(name_of_field_for_args)
|
118
|
+
end
|
119
|
+
|
120
|
+
@redis_alias_config ||= {}
|
121
|
+
#add specification of dynamic alias
|
122
|
+
@redis_alias_config[name] = {
|
123
|
+
main_fields: main_fields,
|
124
|
+
order_field: name_of_field_for_order,
|
125
|
+
args_field: name_of_field_for_args,
|
126
|
+
}
|
127
|
+
|
128
|
+
#create alias methods for find and get (find_by_name, get_by_name)
|
129
|
+
create_class_alias_method(name)
|
130
|
+
end
|
131
|
+
|
132
|
+
# store informations about saving nil values
|
133
|
+
def redis_save_fields_with_nil store
|
134
|
+
@redis_save_fields_with_nil_conf = store
|
135
|
+
end
|
136
|
+
|
137
|
+
# store informations about redis key normalization
|
138
|
+
def redis_key_normalize_conf
|
139
|
+
@redis_key_normalize_conf ||= []
|
140
|
+
end
|
141
|
+
|
142
|
+
private
|
143
|
+
|
144
|
+
def create_class_alias_method(name)
|
145
|
+
self.class.instance_eval do
|
146
|
+
define_method("find_by_#{name}") do |args|
|
147
|
+
find_by_alias(name, args)
|
148
|
+
end
|
149
|
+
define_method("get_by_#{name}") do |args|
|
150
|
+
get_by_alias(name, args)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
end
|
156
|
+
|
157
|
+
module Initialize
|
158
|
+
|
159
|
+
# initialize instance
|
160
|
+
def initialize(args={})
|
161
|
+
args = HashWithIndifferentAccess.new(args)
|
162
|
+
# look for fields in input hash
|
163
|
+
redis_fields_config.each do |key, type|
|
164
|
+
# disable to set nonexisting ID!
|
165
|
+
raise ArgumentError, "You cannot specify #{key} (it is auto incremented)" if args[key] && type == :autoincrement && get_last_id.to_i < args[key].to_i
|
166
|
+
|
167
|
+
# input hash has known field
|
168
|
+
if args.has_key?(key)
|
169
|
+
value_set key, value_parse(args[key], type)
|
170
|
+
else #there is no value set default valued
|
171
|
+
value_set key, redis_fields_defaults_config[key]
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
return self
|
176
|
+
end
|
177
|
+
|
178
|
+
end
|
179
|
+
end
|