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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 045f4c85e0aeb767fd6391f797427c932771c9b7
4
- data.tar.gz: 9e250673aa1a847c1bdd33a1f85550ea9cedc8e1
3
+ metadata.gz: 15b35e41e228279d6ebc16ce99d25115d786074f
4
+ data.tar.gz: 150c894dcd3e562549d4ee6a52a005020f262cc5
5
5
  SHA512:
6
- metadata.gz: 3f54e5432066d8cd19c9844e84dc37b68d4a15bc02c2b13dc7ee618a9934c0edae3aa23685f835a45fdf69dd50b01ed64e20f6bbb41916da8f417a400c26961b
7
- data.tar.gz: 91f1c901ff380025adc212ff0adb214d7f2c6577cffbd0017f3cf4f99752d4c4ded90efd9a74112cbad9350315f66421fd9a6b502b65b0df5faed39bbd7c3598
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
 
@@ -9,5 +9,9 @@ module ActiveRedis
9
9
 
10
10
  ASSOCIATIONS = [:has_one, :has_many, :belongs_to]
11
11
 
12
+ RELATION_METHODS = %w{where order limit first all}
13
+
14
+ QUERY_METHODS = CALCULATION_METHODS + RELATION_METHODS
15
+
12
16
  end
13
17
  end
@@ -131,11 +131,11 @@ local fetch_row = function(key, id)
131
131
  return redis.call("HGETALL", name)
132
132
  end
133
133
 
134
- -- Query analyzer for searching
134
+ -- Fetching objects collection by query params
135
135
  --
136
136
  -- key - table name
137
- -- argv - array with query parameters WHERE, ORDER, LIMIT
138
- local query_analyzer = function (keys, argv)
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 = {per_page: 10, page: 0}
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 if options.any?
33
+ @limit_options = options
30
34
  self
31
35
  end
32
36
 
33
- def apply_top(options)
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(@target, @where_options, @order_options, @limit_options)
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
- top_limit? ? res.first : res
72
+ first_limit? ? res.first : res
54
73
  end
55
74
 
56
- def top_limit?
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(target, where, order, limit)
5
- ActiveRedis.connection.run_query_analyzer target, [prepare_where(where), prepare_order(order), prepare_limit(limit)]
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,6 +1,5 @@
1
1
  module ActiveRedis
2
2
  module QueryIterator
3
- include Enumerable
4
3
 
5
4
  def method_missing(method, *args)
6
5
  unless linked_objects.is_a? Array
@@ -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
- %w{where order limit top}.each do |method|
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"
@@ -1,3 +1,3 @@
1
1
  module ActiveRedis
2
- VERSION = "0.0.7"
2
+ VERSION = "0.0.8"
3
3
  end
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.7
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-16 00:00:00.000000000 Z
11
+ date: 2013-11-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: redis