redis-model-extension 0.3.8 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|