active_redis 0.0.7 → 0.0.8
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 +4 -4
- data/README.md +4 -0
- data/lib/active_redis/connection_ext/finders_layer.rb +1 -1
- data/lib/active_redis/constants.rb +4 -0
- data/lib/active_redis/lua_scripts/main.lua +109 -3
- data/lib/active_redis/query_chainer.rb +25 -6
- data/lib/active_redis/query_executor.rb +10 -2
- data/lib/active_redis/query_iterator.rb +0 -1
- data/lib/active_redis/relation.rb +3 -1
- data/lib/active_redis/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 15b35e41e228279d6ebc16ce99d25115d786074f
|
4
|
+
data.tar.gz: 150c894dcd3e562549d4ee6a52a005020f262cc5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 288bb1c18077d83a21a80d846d520f5a9f0539a31ce9dfeb24c76bf64d4b5c90a9adac9fcb69e601c2c9a2ca43724ad8c6266a9a714eb44301802bff56f7906d
|
7
|
+
data.tar.gz: fa32af2552935029c263779f957a592fe29763ac7d997ea10a5b2c5ec53e4c755d3f2753f4ea52452939381a9a2044d25d94a5107b15dccd0784de84c08e5827
|
data/README.md
CHANGED
@@ -140,6 +140,10 @@ Method chaining. Now you may calling __where__, __order__, __limit__ something l
|
|
140
140
|
Article.where(title: "Article title").where(views: 1000).order(title: :asc).limit(per_page: 20, page: 3)
|
141
141
|
```
|
142
142
|
|
143
|
+
## NEW IN VERSION 0.0.8
|
144
|
+
|
145
|
+
Using aggregation functions with method chaining functional.
|
146
|
+
|
143
147
|
## Contributing
|
144
148
|
|
145
149
|
1. Fork it
|
@@ -22,7 +22,7 @@ module ActiveRedis::ConnectionExt
|
|
22
22
|
run_eval :where, [model.key_name], params.flatten
|
23
23
|
end
|
24
24
|
|
25
|
-
def run_query_analyzer(model, params = ["", "", ""])
|
25
|
+
def run_query_analyzer(model, params = ["", "", "", ""])
|
26
26
|
run_eval :query_analyzer, [model.key_name, Time.now.to_i], params
|
27
27
|
end
|
28
28
|
|
@@ -131,11 +131,11 @@ local fetch_row = function(key, id)
|
|
131
131
|
return redis.call("HGETALL", name)
|
132
132
|
end
|
133
133
|
|
134
|
-
--
|
134
|
+
-- Fetching objects collection by query params
|
135
135
|
--
|
136
136
|
-- key - table name
|
137
|
-
-- argv - array with query
|
138
|
-
local
|
137
|
+
-- argv - array with query params
|
138
|
+
local fetch_collection = function(keys, argv)
|
139
139
|
local temp_list = apply_where(keys[1], argv[1], tonumber(keys[2]))
|
140
140
|
local sort_command = {"SORT", temp_list}
|
141
141
|
sort_command = apply_order(keys[1], sort_command, argv[2])
|
@@ -147,3 +147,109 @@ local query_analyzer = function (keys, argv)
|
|
147
147
|
end
|
148
148
|
return result
|
149
149
|
end
|
150
|
+
|
151
|
+
-- Fetching value from record by field name
|
152
|
+
--
|
153
|
+
-- record - record array
|
154
|
+
-- field - field name
|
155
|
+
local fetch_value_by_field = function(record, field)
|
156
|
+
for i = 1, #record, 2 do
|
157
|
+
if record[i] == field then
|
158
|
+
return record[i+1]
|
159
|
+
end
|
160
|
+
end
|
161
|
+
return ""
|
162
|
+
end
|
163
|
+
|
164
|
+
-- Fetching values from specified field to array
|
165
|
+
--
|
166
|
+
-- collection - array of objects
|
167
|
+
-- param - field name
|
168
|
+
local fetch_field_values_array = function(collection, field)
|
169
|
+
local result = {}
|
170
|
+
for index, record in pairs(collection) do
|
171
|
+
table.insert(result, fetch_value_by_field(record, param))
|
172
|
+
end
|
173
|
+
return result
|
174
|
+
end
|
175
|
+
|
176
|
+
local aggregation_functions = {
|
177
|
+
-- Applying count aggregation function
|
178
|
+
--
|
179
|
+
-- collection - array of objects for processing
|
180
|
+
-- param - particular param for aggregation function
|
181
|
+
aggregation_count = function(collection, param)
|
182
|
+
return #collection
|
183
|
+
end,
|
184
|
+
|
185
|
+
-- Applying sum aggregation function
|
186
|
+
--
|
187
|
+
-- collection - array of objects for processing
|
188
|
+
-- param - particular param for aggregation function
|
189
|
+
aggregation_sum = function(collection, param)
|
190
|
+
local sum = 0
|
191
|
+
for index, record in pairs(collection) do
|
192
|
+
sum = sum + tonumber(fetch_value_by_field(record, param))
|
193
|
+
end
|
194
|
+
return sum
|
195
|
+
end,
|
196
|
+
|
197
|
+
-- Applying pluck aggregation function
|
198
|
+
--
|
199
|
+
-- collection - array of objects for processing
|
200
|
+
-- param - particular param for aggregation function
|
201
|
+
aggregation_pluck = function(collection, param)
|
202
|
+
return fetch_field_values_array(collection, param)
|
203
|
+
end,
|
204
|
+
|
205
|
+
-- Applying min aggregation function
|
206
|
+
--
|
207
|
+
-- collection - array of objects for processing
|
208
|
+
-- param - particular param for aggregation function
|
209
|
+
aggregation_min = function(collection, param)
|
210
|
+
local result = fetch_field_values_array(collection, param)
|
211
|
+
table.sort(result)
|
212
|
+
return result[1]
|
213
|
+
end,
|
214
|
+
|
215
|
+
-- Applying max aggregation function
|
216
|
+
--
|
217
|
+
-- collection - array of objects for processing
|
218
|
+
-- param - particular param for aggregation function
|
219
|
+
aggregation_max = function(collection, param)
|
220
|
+
local result = fetch_field_values_array(collection, param)
|
221
|
+
table.sort(result)
|
222
|
+
return result[#result]
|
223
|
+
end
|
224
|
+
}
|
225
|
+
|
226
|
+
-- Applying aggregation functions to collection
|
227
|
+
--
|
228
|
+
-- collection - array of objects for processing
|
229
|
+
-- aggr_options - string with aggregation information
|
230
|
+
local process_aggregation = function(collection, aggr_options)
|
231
|
+
local aggr_arr = split(aggr_options, "=")
|
232
|
+
local aggr_function_name = "aggregation_"..aggr_arr[1]
|
233
|
+
--return _G[aggr_function_name](collection, aggr_arr[2])
|
234
|
+
return aggregation_functions[aggr_function_name](collection, aggr_arr[2])
|
235
|
+
end
|
236
|
+
|
237
|
+
-- Checking if query is single value
|
238
|
+
--
|
239
|
+
-- argv - array with query parameters
|
240
|
+
local is_single_value_query = function(argv)
|
241
|
+
return string.len(argv[4]) ~= 0
|
242
|
+
end
|
243
|
+
|
244
|
+
-- Query analyzer for searching
|
245
|
+
--
|
246
|
+
-- key - table name
|
247
|
+
-- argv - array with query parameters WHERE, ORDER, LIMIT, AGGREGATION
|
248
|
+
local query_analyzer = function (keys, argv)
|
249
|
+
local collection = fetch_collection(keys, argv)
|
250
|
+
if is_single_value_query(argv) == true then
|
251
|
+
return process_aggregation(collection, argv[4])
|
252
|
+
else
|
253
|
+
return collection
|
254
|
+
end
|
255
|
+
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'active_redis/relation'
|
2
2
|
require 'active_redis/query_iterator'
|
3
|
+
require 'active_redis/constants'
|
3
4
|
|
4
5
|
module ActiveRedis
|
5
6
|
autoload :QueryExecutor, 'active_redis/query_executor'
|
@@ -8,10 +9,13 @@ module ActiveRedis
|
|
8
9
|
include Relation
|
9
10
|
include QueryIterator
|
10
11
|
|
12
|
+
attr_reader :where_options, :order_options, :limit_options, :aggregation_options, :target
|
13
|
+
|
11
14
|
def initialize(target)
|
12
15
|
@where_options = {}
|
13
16
|
@order_options = {id: :asc}
|
14
|
-
@limit_options = {
|
17
|
+
@limit_options = {}
|
18
|
+
@aggregation_options = {}
|
15
19
|
@target = target
|
16
20
|
end
|
17
21
|
|
@@ -26,14 +30,24 @@ module ActiveRedis
|
|
26
30
|
end
|
27
31
|
|
28
32
|
def apply_limit(options)
|
29
|
-
@limit_options = options
|
33
|
+
@limit_options = options
|
30
34
|
self
|
31
35
|
end
|
32
36
|
|
33
|
-
def
|
37
|
+
def apply_first(options)
|
34
38
|
apply_limit per_page: 1, page: 0
|
35
39
|
end
|
36
40
|
|
41
|
+
def apply_all(options)
|
42
|
+
apply_limit Hash.new
|
43
|
+
end
|
44
|
+
|
45
|
+
ActiveRedis::Constants::CALCULATION_METHODS.each do |method|
|
46
|
+
define_method "apply_#{method}" do |field|
|
47
|
+
apply_aggregation(method, field)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
37
51
|
def reload
|
38
52
|
@collection = nil
|
39
53
|
end
|
@@ -44,16 +58,21 @@ module ActiveRedis
|
|
44
58
|
|
45
59
|
private
|
46
60
|
|
61
|
+
def apply_aggregation(type, field)
|
62
|
+
@aggregation_options = {type => field}
|
63
|
+
execute_query
|
64
|
+
end
|
65
|
+
|
47
66
|
def execute_query
|
48
|
-
QueryExecutor.execute
|
67
|
+
QueryExecutor.execute self
|
49
68
|
end
|
50
69
|
|
51
70
|
def objects_by_query
|
52
71
|
res = execute_query.inject([]) { |arr, attrs| arr << @target.new(attrs) if attrs && attrs.any?; arr }
|
53
|
-
|
72
|
+
first_limit? ? res.first : res
|
54
73
|
end
|
55
74
|
|
56
|
-
def
|
75
|
+
def first_limit?
|
57
76
|
@limit_options[:per_page] == 1 && @limit_options[:page] == 0
|
58
77
|
end
|
59
78
|
|
@@ -1,12 +1,16 @@
|
|
1
1
|
module ActiveRedis
|
2
2
|
class QueryExecutor
|
3
3
|
|
4
|
-
def self.execute(
|
5
|
-
ActiveRedis.connection.run_query_analyzer
|
4
|
+
def self.execute(chainer)
|
5
|
+
ActiveRedis.connection.run_query_analyzer(chainer.target, prepare_params(chainer))
|
6
6
|
end
|
7
7
|
|
8
8
|
private
|
9
9
|
|
10
|
+
def self.prepare_params(chainer)
|
11
|
+
[prepare_where(chainer.where_options), prepare_order(chainer.order_options), prepare_limit(chainer.limit_options), prepare_aggregation(chainer.aggregation_options)]
|
12
|
+
end
|
13
|
+
|
10
14
|
def self.prepare_where(where)
|
11
15
|
where.keys.map{|key| "#{key}=#{where[key]}" }.join(",")
|
12
16
|
end
|
@@ -20,5 +24,9 @@ module ActiveRedis
|
|
20
24
|
limit.any? ? "#{limit[:page]}=#{limit[:per_page]}" : ""
|
21
25
|
end
|
22
26
|
|
27
|
+
def self.prepare_aggregation(aggregation)
|
28
|
+
aggregation.inject("") {|str, (k, v)| str = "#{k}=#{v}" }
|
29
|
+
end
|
30
|
+
|
23
31
|
end
|
24
32
|
end
|
@@ -1,8 +1,10 @@
|
|
1
|
+
require 'active_redis/constants'
|
2
|
+
|
1
3
|
module ActiveRedis
|
2
4
|
autoload :QueryChainer, 'active_redis/query_chainer'
|
3
5
|
module Relation
|
4
6
|
|
5
|
-
|
7
|
+
ActiveRedis::Constants::QUERY_METHODS.each do |method|
|
6
8
|
class_eval <<-CODE
|
7
9
|
def #{method}(options = {})
|
8
10
|
if self.class.name == "ActiveRedis::QueryChainer"
|
data/lib/active_redis/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active_redis
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sergey Gernyak
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-11-
|
11
|
+
date: 2013-11-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: redis
|