influxer 0.2.2 → 0.2.4
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/.hound.yml +11 -1
- data/.rubocop.yml +38 -0
- data/Changelog.md +4 -0
- data/influxer.gemspec +3 -3
- data/lib/influxer/client.rb +32 -32
- data/lib/influxer/config.rb +5 -6
- data/lib/influxer/engine.rb +4 -4
- data/lib/influxer/metrics/fanout.rb +29 -17
- data/lib/influxer/metrics/metrics.rb +38 -39
- data/lib/influxer/metrics/relation/calculations.rb +7 -7
- data/lib/influxer/metrics/relation/fanout_query.rb +23 -7
- data/lib/influxer/metrics/relation/time_query.rb +13 -13
- data/lib/influxer/metrics/relation.rb +101 -114
- data/lib/influxer/metrics/scoping/default.rb +6 -4
- data/lib/influxer/metrics/scoping/named.rb +5 -3
- data/lib/influxer/metrics/scoping.rb +8 -7
- data/lib/influxer/model.rb +11 -12
- data/lib/influxer/version.rb +2 -2
- data/lib/influxer.rb +2 -1
- data/spec/client_spec.rb +4 -5
- data/spec/config_spec.rb +2 -3
- data/spec/dummy/app/metrics/testo_metrics.rb +1 -1
- data/spec/dummy/app/models/testo.rb +1 -1
- data/spec/dummy/config/application.rb +0 -1
- data/spec/dummy/config/initializers/cookies_serializer.rb +1 -1
- data/spec/fixtures/fanout_series.json +23 -0
- data/spec/metrics/fanout_spec.rb +18 -3
- data/spec/metrics/metrics_spec.rb +40 -47
- data/spec/metrics/relation_spec.rb +47 -43
- data/spec/metrics/scoping_spec.rb +8 -6
- data/spec/model/testo_spec.rb +6 -6
- data/spec/spec_helper.rb +2 -2
- data/spec/support/dummy_metrics.rb +3 -3
- metadata +4 -14
@@ -3,13 +3,14 @@ require 'influxer/metrics/relation/fanout_query'
|
|
3
3
|
require 'influxer/metrics/relation/calculations'
|
4
4
|
|
5
5
|
module Influxer
|
6
|
+
# Relation is used to build queries
|
6
7
|
class Relation
|
7
|
-
attr_reader :values
|
8
|
-
|
9
8
|
include Influxer::TimeQuery
|
10
9
|
include Influxer::FanoutQuery
|
11
10
|
include Influxer::Calculations
|
12
|
-
|
11
|
+
|
12
|
+
attr_reader :values
|
13
|
+
|
13
14
|
MULTI_VALUE_METHODS = [:select, :where, :group]
|
14
15
|
|
15
16
|
MULTI_KEY_METHODS = [:fanout]
|
@@ -62,40 +63,38 @@ module Influxer
|
|
62
63
|
CODE
|
63
64
|
end
|
64
65
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
delegate :to_xml, :to_yaml, :length, :collect, :map, :each, :all?, :include?, :to_ary, :join, to: :to_a
|
69
|
-
end
|
66
|
+
# delegate array methods to to_a
|
67
|
+
delegate :to_xml, :to_yaml, :length, :collect, :map, :each, :all?, :include?, :to_ary, :join,
|
68
|
+
to: :to_a
|
70
69
|
|
71
70
|
# Initialize new Relation for 'klass' (Class) metrics.
|
72
|
-
#
|
71
|
+
#
|
73
72
|
# Available params:
|
74
|
-
# :attributes - hash of attributes to be included to new Metrics object
|
75
|
-
#
|
73
|
+
# :attributes - hash of attributes to be included to new Metrics object
|
74
|
+
# and where clause of Relation
|
75
|
+
#
|
76
76
|
def initialize(klass, params = {})
|
77
77
|
@klass = klass
|
78
78
|
@instance = klass.new params[:attributes]
|
79
|
-
|
80
|
-
|
79
|
+
reset
|
80
|
+
where(params[:attributes]) if params[:attributes].present?
|
81
81
|
self
|
82
82
|
end
|
83
83
|
|
84
|
-
|
85
84
|
def write(params = {})
|
86
85
|
build params
|
87
86
|
@instance.write
|
88
87
|
end
|
89
88
|
|
90
89
|
def build(params = {})
|
91
|
-
params.each do |key,val|
|
90
|
+
params.each do |key, val|
|
92
91
|
@instance.send("#{key}=", val) if @instance.respond_to?(key)
|
93
92
|
end
|
94
93
|
@instance
|
95
94
|
end
|
96
95
|
|
97
96
|
# accepts hash or strings conditions
|
98
|
-
def where(*args
|
97
|
+
def where(*args, **hargs)
|
99
98
|
build_where(args, hargs, false)
|
100
99
|
self
|
101
100
|
end
|
@@ -107,34 +106,24 @@ module Influxer
|
|
107
106
|
|
108
107
|
def to_sql
|
109
108
|
sql = ["select"]
|
109
|
+
select_values << "*" if select_values.empty?
|
110
110
|
|
111
|
-
|
112
|
-
sql << "*"
|
113
|
-
else
|
114
|
-
sql << select_values.uniq.join(",")
|
115
|
-
end
|
111
|
+
sql << select_values.uniq.join(",")
|
116
112
|
|
117
113
|
sql << "from #{ build_series_name }"
|
114
|
+
sql << "merge #{ @klass.quoted_series(merge_value) }" unless merge_value.nil?
|
118
115
|
|
119
|
-
unless
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
unless group_values.empty? and time_value.nil?
|
124
|
-
sql << "group by #{ (time_value.nil? ? [] : ['time('+@values[:time]+')']).concat(group_values).uniq.join(",") }"
|
116
|
+
unless group_values.empty? && time_value.nil?
|
117
|
+
group_fields = (time_value.nil? ? [] : ['time(' + @values[:time] + ')']) + group_values
|
118
|
+
group_fields.uniq!
|
119
|
+
sql << "group by #{ group_fields.join(',') }"
|
125
120
|
end
|
126
121
|
|
127
|
-
unless fill_value.nil?
|
128
|
-
sql << "fill(#{ fill_value })"
|
129
|
-
end
|
122
|
+
sql << "fill(#{ fill_value })" unless fill_value.nil?
|
130
123
|
|
131
|
-
unless where_values.empty?
|
132
|
-
sql << "where #{ where_values.join(" and ") }"
|
133
|
-
end
|
124
|
+
sql << "where #{ where_values.join(' and ') }" unless where_values.empty?
|
134
125
|
|
135
|
-
unless limit_value.nil?
|
136
|
-
sql << "limit #{ limit_value }"
|
137
|
-
end
|
126
|
+
sql << "limit #{ limit_value }" unless limit_value.nil?
|
138
127
|
sql.join " "
|
139
128
|
end
|
140
129
|
|
@@ -156,10 +145,10 @@ module Influxer
|
|
156
145
|
select_values.clear
|
157
146
|
limit(1).load
|
158
147
|
end
|
159
|
-
|
148
|
+
@records.empty?
|
160
149
|
end
|
161
150
|
|
162
|
-
def as_json(options=nil)
|
151
|
+
def as_json(options = nil)
|
163
152
|
to_a.as_json(options)
|
164
153
|
end
|
165
154
|
|
@@ -174,9 +163,7 @@ module Influxer
|
|
174
163
|
|
175
164
|
sql << "from #{@instance.series}"
|
176
165
|
|
177
|
-
unless where_values.empty?
|
178
|
-
sql << "where #{where_values.join(" and ")}"
|
179
|
-
end
|
166
|
+
sql << "where #{where_values.join(' and ')}" unless where_values.empty?
|
180
167
|
|
181
168
|
sql = sql.join " "
|
182
169
|
|
@@ -193,11 +180,11 @@ module Influxer
|
|
193
180
|
def merge!(rel)
|
194
181
|
return self if rel.nil?
|
195
182
|
MULTI_VALUE_METHODS.each do |method|
|
196
|
-
(@values[method]||=[]).concat(rel.values[method]).uniq! unless rel.values[method].nil?
|
183
|
+
(@values[method] ||= []).concat(rel.values[method]).uniq! unless rel.values[method].nil?
|
197
184
|
end
|
198
185
|
|
199
186
|
MULTI_KEY_METHODS.each do |method|
|
200
|
-
(@values[method]||={}).merge!(rel.values[method]) unless rel.values[method].nil?
|
187
|
+
(@values[method] ||= {}).merge!(rel.values[method]) unless rel.values[method].nil?
|
201
188
|
end
|
202
189
|
|
203
190
|
SINGLE_VALUE_METHODS.each do |method|
|
@@ -207,93 +194,93 @@ module Influxer
|
|
207
194
|
self
|
208
195
|
end
|
209
196
|
|
210
|
-
|
211
197
|
protected
|
212
|
-
def build_where(args, hargs, negate)
|
213
|
-
case
|
214
|
-
when (args.present? and args[0].is_a?(String))
|
215
|
-
where_values.concat args.map{|str| "(#{str})"}
|
216
|
-
when hargs.present?
|
217
|
-
build_hash_where(hargs, negate)
|
218
|
-
else
|
219
|
-
false
|
220
|
-
end
|
221
|
-
end
|
222
198
|
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
199
|
+
def build_where(args, hargs, negate)
|
200
|
+
case
|
201
|
+
when (args.present? && args[0].is_a?(String))
|
202
|
+
where_values.concat args.map { |str| "(#{str})" }
|
203
|
+
when hargs.present?
|
204
|
+
build_hash_where(hargs, negate)
|
205
|
+
else
|
206
|
+
false
|
231
207
|
end
|
208
|
+
end
|
232
209
|
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
when Array
|
238
|
-
build_in(key,val,negate)
|
239
|
-
when Range
|
240
|
-
build_range(key,val,negate)
|
210
|
+
def build_hash_where(hargs, negate = false)
|
211
|
+
hargs.each do |key, val|
|
212
|
+
if @klass.fanout?(key)
|
213
|
+
build_fanout(key, val)
|
241
214
|
else
|
242
|
-
"#{key
|
243
|
-
end
|
244
|
-
end
|
245
|
-
|
246
|
-
def build_in(key, arr, negate)
|
247
|
-
buf = []
|
248
|
-
arr.each do |val|
|
249
|
-
buf << build_eql(key,val,negate)
|
215
|
+
where_values << "(#{ build_eql(key, val, negate) })"
|
250
216
|
end
|
251
|
-
"#{ buf.join( negate ? ' and ' : ' or ') }"
|
252
217
|
end
|
218
|
+
end
|
253
219
|
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
220
|
+
def build_eql(key, val, negate)
|
221
|
+
case val
|
222
|
+
when Regexp
|
223
|
+
"#{key}#{ negate ? '!~' : '=~'}#{val.inspect}"
|
224
|
+
when Array
|
225
|
+
build_in(key, val, negate)
|
226
|
+
when Range
|
227
|
+
build_range(key, val, negate)
|
228
|
+
else
|
229
|
+
"#{key}#{ negate ? '<>' : '='}#{quoted(val)}"
|
260
230
|
end
|
231
|
+
end
|
261
232
|
|
262
|
-
|
263
|
-
|
233
|
+
def build_in(key, arr, negate)
|
234
|
+
buf = []
|
235
|
+
arr.each do |val|
|
236
|
+
buf << build_eql(key, val, negate)
|
264
237
|
end
|
238
|
+
"#{ buf.join(negate ? ' and ' : ' or ') }"
|
239
|
+
end
|
265
240
|
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
241
|
+
def build_range(key, val, negate)
|
242
|
+
if negate
|
243
|
+
"#{key}<#{quoted(val.begin)} and #{key}>#{quoted(val.end)}"
|
244
|
+
else
|
245
|
+
"#{key}>#{quoted(val.begin)} and #{key}<#{quoted(val.end)}"
|
271
246
|
end
|
247
|
+
end
|
272
248
|
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
self
|
277
|
-
end
|
249
|
+
def loaded?
|
250
|
+
@loaded
|
251
|
+
end
|
278
252
|
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
val.to_s
|
286
|
-
end
|
287
|
-
end
|
253
|
+
def reset
|
254
|
+
@values = {}
|
255
|
+
@records = nil
|
256
|
+
@loaded = false
|
257
|
+
self
|
258
|
+
end
|
288
259
|
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
260
|
+
def reload
|
261
|
+
reset
|
262
|
+
load
|
263
|
+
self
|
264
|
+
end
|
294
265
|
|
295
|
-
|
296
|
-
|
266
|
+
def quoted(val)
|
267
|
+
if val.is_a?(String) || val.is_a?(Symbol)
|
268
|
+
"'#{val}'"
|
269
|
+
elsif val.is_a?(Time) || val.is_a?(DateTime)
|
270
|
+
"#{val.to_i}s"
|
271
|
+
else
|
272
|
+
val.to_s
|
297
273
|
end
|
274
|
+
end
|
275
|
+
|
276
|
+
def get_points(hash)
|
277
|
+
prepare_fanout_points(hash) if @values[:has_fanout] == true
|
278
|
+
hash.values.reduce([], :+)
|
279
|
+
end
|
280
|
+
|
281
|
+
def method_missing(method, *args, &block)
|
282
|
+
return super unless @klass.respond_to?(method)
|
283
|
+
merge!(scoping { @klass.public_send(method, *args, &block) })
|
284
|
+
end
|
298
285
|
end
|
299
|
-
end
|
286
|
+
end
|
@@ -1,6 +1,8 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
|
1
3
|
module Influxer
|
2
4
|
module Scoping
|
3
|
-
module Default
|
5
|
+
module Default # :nodoc: all
|
4
6
|
extend ActiveSupport::Concern
|
5
7
|
|
6
8
|
included do
|
@@ -18,11 +20,11 @@ module Influxer
|
|
18
20
|
end
|
19
21
|
|
20
22
|
def default_scoped
|
21
|
-
self.default_scopes.inject(Relation.new(self)) do |rel, scope|
|
22
|
-
rel.merge!(rel.scoping{ scope.call })
|
23
|
+
self.default_scopes.inject(Relation.new(self)) do |rel, scope|
|
24
|
+
rel.merge!(rel.scoping { scope.call })
|
23
25
|
end
|
24
26
|
end
|
25
27
|
end
|
26
28
|
end
|
27
29
|
end
|
28
|
-
end
|
30
|
+
end
|
@@ -1,11 +1,13 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
|
1
3
|
module Influxer
|
2
4
|
module Scoping
|
3
|
-
module Named
|
5
|
+
module Named # :nodoc: all
|
4
6
|
extend ActiveSupport::Concern
|
5
7
|
|
6
8
|
module ClassMethods
|
7
9
|
def scope(name, scope)
|
8
|
-
|
10
|
+
fail "Scope not defined: #{name}" if scope.nil? || !scope.respond_to?(:call)
|
9
11
|
singleton_class.send(:define_method, name) do |*args|
|
10
12
|
rel = all
|
11
13
|
rel.merge!(rel.scoping { scope.call(*args) })
|
@@ -15,4 +17,4 @@ module Influxer
|
|
15
17
|
end
|
16
18
|
end
|
17
19
|
end
|
18
|
-
end
|
20
|
+
end
|
@@ -3,22 +3,22 @@ require 'influxer/metrics/scoping/default'
|
|
3
3
|
require 'influxer/metrics/scoping/named'
|
4
4
|
|
5
5
|
module Influxer
|
6
|
-
module Scoping
|
6
|
+
module Scoping # :nodoc:
|
7
7
|
extend ActiveSupport::Concern
|
8
8
|
|
9
|
-
class Error < StandardError; end
|
9
|
+
class Error < StandardError; end
|
10
10
|
|
11
11
|
included do
|
12
12
|
include Default
|
13
13
|
include Named
|
14
14
|
end
|
15
15
|
|
16
|
-
module ClassMethods
|
17
|
-
def current_scope
|
16
|
+
module ClassMethods # :nodoc:
|
17
|
+
def current_scope
|
18
18
|
ScopeRegistry.value_for(:current_scope, name)
|
19
19
|
end
|
20
20
|
|
21
|
-
def current_scope=(scope)
|
21
|
+
def current_scope=(scope)
|
22
22
|
ScopeRegistry.set_value_for(:current_scope, name, scope)
|
23
23
|
end
|
24
24
|
end
|
@@ -48,9 +48,10 @@ module Influxer
|
|
48
48
|
|
49
49
|
def raise_invalid_scope_type!(scope_type)
|
50
50
|
if !VALID_SCOPE_TYPES.include?(scope_type)
|
51
|
-
raise ArgumentError, "Invalid scope type '#{scope_type}' sent to the registry.
|
51
|
+
raise ArgumentError, "Invalid scope type '#{scope_type}' sent to the registry. \
|
52
|
+
Scope types must be included in VALID_SCOPE_TYPES"
|
52
53
|
end
|
53
54
|
end
|
54
55
|
end
|
55
56
|
end
|
56
|
-
end
|
57
|
+
end
|
data/lib/influxer/model.rb
CHANGED
@@ -1,35 +1,34 @@
|
|
1
1
|
require 'active_support'
|
2
2
|
|
3
3
|
module Influxer
|
4
|
+
# Add `has_metrics` method to AR::Base
|
4
5
|
module Model
|
5
6
|
extend ActiveSupport::Concern
|
6
|
-
|
7
|
-
module ClassMethods
|
7
|
+
|
8
|
+
module ClassMethods # :nodoc:
|
8
9
|
def has_metrics(*args, **params)
|
9
10
|
metrics_name = args.empty? ? "metrics" : args.first.to_s
|
10
11
|
|
11
|
-
klass = params[:class_name].present? ? params[:class_name] : "#{self}Metrics"
|
12
|
+
klass = params[:class_name].present? ? params[:class_name] : "#{self}Metrics"
|
12
13
|
klass = klass.constantize
|
13
14
|
|
14
15
|
attrs = nil
|
15
16
|
|
16
|
-
if params[:inherits].present?
|
17
|
-
attrs = params[:inherits]
|
18
|
-
end
|
17
|
+
attrs = params[:inherits] if params[:inherits].present?
|
19
18
|
|
20
|
-
|
19
|
+
foreign_key = params.key?(:foreign_key) ? params[:foreign_key] : to_s.foreign_key
|
21
20
|
|
22
21
|
define_method(metrics_name) do
|
23
|
-
rel_attrs =
|
24
|
-
|
22
|
+
rel_attrs = foreign_key ? { foreign_key => id } : {}
|
23
|
+
|
25
24
|
unless attrs.nil?
|
26
25
|
attrs.each do |key|
|
27
|
-
rel_attrs[key] =
|
28
|
-
end
|
26
|
+
rel_attrs[key] = send(key)
|
27
|
+
end
|
29
28
|
end
|
30
29
|
Relation.new klass, attributes: rel_attrs
|
31
30
|
end
|
32
31
|
end
|
33
32
|
end
|
34
33
|
end
|
35
|
-
end
|
34
|
+
end
|
data/lib/influxer/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
module Influxer
|
2
|
-
VERSION = "0.2.
|
1
|
+
module Influxer # :nodoc:
|
2
|
+
VERSION = "0.2.4"
|
3
3
|
end
|
data/lib/influxer.rb
CHANGED
data/spec/client_spec.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Influxer::Client do
|
4
|
-
|
5
4
|
after(:each) do
|
6
5
|
Rails.cache.clear
|
7
6
|
end
|
@@ -17,7 +16,7 @@ describe Influxer::Client do
|
|
17
16
|
|
18
17
|
describe "cache" do
|
19
18
|
before do
|
20
|
-
allow_any_instance_of(Influxer::Client).to receive(:query) do |_, sql|
|
19
|
+
allow_any_instance_of(Influxer::Client).to receive(:query) do |_, sql|
|
21
20
|
sql
|
22
21
|
end
|
23
22
|
end
|
@@ -36,13 +35,13 @@ describe Influxer::Client do
|
|
36
35
|
end
|
37
36
|
|
38
37
|
it "should write data to cache with expiration" do
|
39
|
-
conf.cache = {expires_in: 1}
|
38
|
+
conf.cache = { expires_in: 1 }
|
40
39
|
|
41
40
|
client.cached_query(q)
|
42
41
|
expect(Rails.cache.exist?("influxer:listseries")).to be_truthy
|
43
|
-
|
42
|
+
|
44
43
|
sleep 2
|
45
44
|
expect(Rails.cache.exist?("influxer:listseries")).to be_falsey
|
46
45
|
end
|
47
46
|
end
|
48
|
-
end
|
47
|
+
end
|
data/spec/config_spec.rb
CHANGED
@@ -1,18 +1,17 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Influxer::Config do
|
4
|
-
|
5
4
|
let(:conf) { Influxer.config }
|
6
5
|
|
7
6
|
it "should load config from file" do
|
8
7
|
expect(conf.retry).to eq 5
|
9
|
-
expect(conf.host).to eq "test.host"
|
8
|
+
expect(conf.host).to eq "test.host"
|
10
9
|
end
|
11
10
|
|
12
11
|
unless Rails.application.try(:secrets).nil?
|
13
12
|
it "should load config from secrets" do
|
14
13
|
expect(conf.username).to eq "test"
|
15
|
-
expect(conf.password).to eq "test"
|
14
|
+
expect(conf.password).to eq "test"
|
16
15
|
end
|
17
16
|
end
|
18
17
|
end
|
@@ -3,4 +3,4 @@ class Testo < ActiveRecord::Base
|
|
3
3
|
has_metrics :testo_metrics, class_name: "TestoMetrics", inherits: [:receipt_id]
|
4
4
|
has_metrics :testo2_metrics, class_name: "TestoMetrics", foreign_key: :testo
|
5
5
|
has_metrics :custom_metrics, class_name: "TestoMetrics", foreign_key: nil
|
6
|
-
end
|
6
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
{
|
2
|
+
"dummy_by_day_user_6":
|
3
|
+
[
|
4
|
+
{
|
5
|
+
"time": 1430092800,
|
6
|
+
"sequence_number": 1,
|
7
|
+
"time_spent": 100
|
8
|
+
}
|
9
|
+
],
|
10
|
+
"dummy_by_day_user_2":
|
11
|
+
[
|
12
|
+
{
|
13
|
+
"time": 1430092800,
|
14
|
+
"sequence_number": 1,
|
15
|
+
"time_spent": 50
|
16
|
+
},
|
17
|
+
{
|
18
|
+
"time": 1430094800,
|
19
|
+
"sequence_number": 2,
|
20
|
+
"time_spent": 150
|
21
|
+
}
|
22
|
+
]
|
23
|
+
}
|
data/spec/metrics/fanout_spec.rb
CHANGED
@@ -2,7 +2,7 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Influxer::Metrics do
|
4
4
|
before do
|
5
|
-
allow_any_instance_of(Influxer::Client).to receive(:query) do |_, sql|
|
5
|
+
allow_any_instance_of(Influxer::Client).to receive(:query) do |_, sql|
|
6
6
|
sql
|
7
7
|
end
|
8
8
|
end
|
@@ -40,7 +40,22 @@ describe Influxer::Metrics do
|
|
40
40
|
end
|
41
41
|
|
42
42
|
it "should work with regexp fanouts" do
|
43
|
-
expect(dappy.where(dummy_id: 100).by_user(/[1-3]/).daily.to_sql)
|
43
|
+
expect(dappy.where(dummy_id: 100).by_user(/[1-3]/).daily.to_sql)
|
44
|
+
.to eq "select * from /^dummy_by_day_user_[1-3]$/ where (dummy_id=100)"
|
44
45
|
end
|
45
46
|
end
|
46
|
-
|
47
|
+
|
48
|
+
describe "#prepare_fanout_points" do
|
49
|
+
before do
|
50
|
+
allow_any_instance_of(Influxer::Client).to receive(:query) do |_, _sql|
|
51
|
+
JSON.parse(File.read('./spec/fixtures/fanout_series.json'))
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
it "sets fanout fields values" do
|
56
|
+
res = dappy.by_user(/\d+/).daily.to_a
|
57
|
+
expect(res.detect { |v| v["user"] == '6' }).to include('time_spent' => 100, 'by' => 'day')
|
58
|
+
expect(res.select { |v| v["user"] == '2' }.size).to eq 2
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|