influxer 1.1.5 → 1.3.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.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +102 -0
  3. data/{MIT-LICENSE → LICENSE.txt} +1 -1
  4. data/README.md +106 -47
  5. data/lib/influxer.rb +10 -9
  6. data/lib/influxer/client.rb +2 -2
  7. data/lib/influxer/config.rb +19 -6
  8. data/lib/influxer/engine.rb +1 -1
  9. data/lib/influxer/metrics/active_model3/model.rb +2 -4
  10. data/lib/influxer/metrics/metrics.rb +10 -13
  11. data/lib/influxer/metrics/quoting/timestamp.rb +23 -11
  12. data/lib/influxer/metrics/relation.rb +33 -17
  13. data/lib/influxer/metrics/relation/calculations.rb +1 -1
  14. data/lib/influxer/metrics/relation/time_query.rb +15 -13
  15. data/lib/influxer/metrics/relation/where_clause.rb +15 -7
  16. data/lib/influxer/metrics/scoping.rb +4 -4
  17. data/lib/influxer/metrics/scoping/current_scope.rb +2 -1
  18. data/lib/influxer/metrics/scoping/default.rb +1 -1
  19. data/lib/influxer/metrics/scoping/named.rb +2 -1
  20. data/lib/influxer/model.rb +4 -9
  21. data/lib/influxer/rails/client.rb +6 -6
  22. data/lib/influxer/version.rb +1 -1
  23. metadata +32 -97
  24. data/.gitignore +0 -37
  25. data/.rspec +0 -2
  26. data/.rubocop.yml +0 -77
  27. data/.travis.yml +0 -10
  28. data/Changelog.md +0 -116
  29. data/Gemfile +0 -10
  30. data/Rakefile +0 -13
  31. data/gemfiles/rails32.gemfile +0 -7
  32. data/gemfiles/rails42.gemfile +0 -7
  33. data/gemfiles/rails5.gemfile +0 -7
  34. data/influxer.gemspec +0 -33
  35. data/spec/cases/points_spec.rb +0 -36
  36. data/spec/cases/write_points_spec.rb +0 -85
  37. data/spec/client_spec.rb +0 -46
  38. data/spec/fixtures/empty_result.json +0 -21
  39. data/spec/fixtures/single_series.json +0 -29
  40. data/spec/metrics/metrics_spec.rb +0 -283
  41. data/spec/metrics/relation_spec.rb +0 -485
  42. data/spec/metrics/scoping_spec.rb +0 -66
  43. data/spec/model/user_spec.rb +0 -46
  44. data/spec/spec_helper.rb +0 -64
  45. data/spec/support/metrics/action_metrics.rb +0 -5
  46. data/spec/support/metrics/custom_metrics.rb +0 -6
  47. data/spec/support/metrics/dummy_metrics.rb +0 -12
  48. data/spec/support/metrics/user_metrics.rb +0 -6
  49. data/spec/support/metrics/visits_metrics.rb +0 -8
  50. data/spec/support/shared_contexts/shared_query.rb +0 -16
  51. data/spec/support/user.rb +0 -16
@@ -1,46 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
-
5
- describe Influxer::Client do
6
- let(:conf) { Influxer.config }
7
- subject { Influxer.client }
8
-
9
- describe "#initialize" do
10
- it "sets config database value" do
11
- expect(subject.config.database).to eq conf.database
12
- end
13
-
14
- it "passes config params" do
15
- conf.username = 'admin'
16
- conf.port = 2222
17
- expect(subject.config.username).to eq 'admin'
18
- expect(subject.config.port).to eq 2222
19
- end
20
- end
21
-
22
- describe "cache", :query do
23
- let(:q) { "list series" }
24
- after { Rails.cache.clear }
25
-
26
- it "writes data to cache" do
27
- conf.cache = {}
28
-
29
- subject.query(q)
30
- expect(Rails.cache.exist?("influxer:listseries")).to be_truthy
31
- end
32
-
33
- it "should write data to cache with expiration" do
34
- conf.cache = { expires_in: 90 }
35
-
36
- subject.query(q)
37
- expect(Rails.cache.exist?("influxer:listseries")).to be_truthy
38
-
39
- Timecop.travel(1.minute.from_now)
40
- expect(Rails.cache.exist?("influxer:listseries")).to be_truthy
41
-
42
- Timecop.travel(2.minutes.from_now)
43
- expect(Rails.cache.exist?("influxer:listseries")).to be_falsey
44
- end
45
- end
46
- end
@@ -1,21 +0,0 @@
1
- {
2
- "results": [
3
- {
4
- "series": [
5
- {
6
- "name": "cpu_load_short",
7
- "tags": {
8
- "host": "server01",
9
- "region": "us-west"
10
- },
11
- "columns": [
12
- "time",
13
- "value"
14
- ],
15
- "values": [
16
- ]
17
- }
18
- ]
19
- }
20
- ]
21
- }
@@ -1,29 +0,0 @@
1
- {
2
- "results": [
3
- {
4
- "series": [
5
- {
6
- "name": "cpu_load_short",
7
- "tags": {
8
- "host": "server01",
9
- "region": "us-west"
10
- },
11
- "columns": [
12
- "time",
13
- "value"
14
- ],
15
- "values": [
16
- [
17
- "2015-01-29T21:51:28.968422294Z",
18
- 0.64
19
- ],
20
- [
21
- "2015-01-29T21:51:38.968422294Z",
22
- 0.93
23
- ]
24
- ]
25
- }
26
- ]
27
- }
28
- ]
29
- }
@@ -1,283 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
-
5
- describe Influxer::Metrics, :query do
6
- let(:metrics) { described_class.new }
7
- let(:dummy_metrics) { DummyMetrics.new dummy_id: 1, user_id: 1 }
8
-
9
- subject { metrics }
10
-
11
- context "class methods" do
12
- subject { described_class }
13
-
14
- specify { is_expected.to respond_to :attributes }
15
- specify { is_expected.to respond_to :set_series }
16
- specify { is_expected.to respond_to :set_retention_policy }
17
- specify { is_expected.to respond_to :series }
18
- specify { is_expected.to respond_to :write }
19
- specify { is_expected.to respond_to :write! }
20
-
21
- specify { is_expected.to respond_to :all }
22
- specify { is_expected.to respond_to :where }
23
- specify { is_expected.to respond_to :offset }
24
- specify { is_expected.to respond_to :time }
25
- specify { is_expected.to respond_to :past }
26
- specify { is_expected.to respond_to :since }
27
- specify { is_expected.to respond_to :limit }
28
- specify { is_expected.to respond_to :select }
29
- specify { is_expected.to respond_to :delete_all }
30
- end
31
-
32
- context "instance methods" do
33
- specify { is_expected.to respond_to :write }
34
- specify { is_expected.to respond_to :write! }
35
- specify { is_expected.to respond_to :persisted? }
36
- specify { is_expected.to respond_to :series }
37
- if Influxer.active_model3?
38
- specify { is_expected.to be_a Influxer::ActiveModel3::Model }
39
- else
40
- specify { is_expected.to be_a ActiveModel::Model }
41
- end
42
- end
43
-
44
- describe "#initialize" do
45
- it "assigns initial values in constructor" do
46
- m = DummyMetrics.new(dummy_id: 1)
47
- expect(m.dummy_id).to eq 1
48
- end
49
- end
50
-
51
- describe "#write" do
52
- it "doesn't write if required attribute is missing" do
53
- m = DummyMetrics.new(dummy_id: 1)
54
- expect(client).not_to receive(:write_point)
55
- expect(m.write).to be false
56
- expect(m.errors.size).to eq(1)
57
- end
58
-
59
- it "raises error if required attribute is missing" do
60
- expect { DummyMetrics.new(user_id: 1).write! }.to raise_error(Influxer::MetricsInvalid)
61
- end
62
-
63
- it "raises error if you want to write twice" do
64
- expect(dummy_metrics.write).to be_truthy
65
- expect { dummy_metrics.write! }.to raise_error(Influxer::MetricsError)
66
- end
67
-
68
- it "writes successfully" do
69
- expect(client).to receive(:write_point).with("dummy", anything, nil, nil, nil)
70
- expect(dummy_metrics.write).to be_truthy
71
- expect(dummy_metrics.persisted?).to be_truthy
72
- end
73
-
74
- context "after_write callback" do
75
- it "sets current time" do
76
- Timecop.freeze(Time.local(2015))
77
- dummy_metrics.write!
78
- expect(dummy_metrics.timestamp).to eq Time.local(2015)
79
- end
80
- end
81
- end
82
-
83
- describe "#series" do
84
- let(:dummy_metrics) do
85
- Class.new(described_class) do
86
- set_series :dummies
87
- attributes :user_id, :dummy_id
88
- end
89
- end
90
-
91
- let(:dummy_metrics_2) do
92
- Class.new(described_class) do
93
- set_series "dummy \"A\""
94
- end
95
- end
96
-
97
- let(:dummy_metrics_3) do
98
- Class.new(described_class) do
99
- set_series /^.*$/
100
- end
101
- end
102
-
103
- let(:dummy_with_2_series) do
104
- Class.new(described_class) do
105
- set_series :events, :errors
106
- end
107
- end
108
-
109
- let(:dummy_with_2_series_quoted) do
110
- Class.new(described_class) do
111
- set_series "dummy \"A\"", "dummy \"B\""
112
- end
113
- end
114
-
115
- let(:dummy_with_proc_series) do
116
- Class.new(described_class) do
117
- attributes :user_id, :test_id
118
- set_series ->(metrics) { "test/#{metrics.test_id}/user/#{metrics.user_id}" }
119
- end
120
- end
121
-
122
- it "sets series name from class name by default" do
123
- expect(DummyMetrics.new.series).to eq "\"dummy\""
124
- end
125
-
126
- it "sets series from subclass" do
127
- expect(dummy_metrics.new.series).to eq "\"dummies\""
128
- end
129
-
130
- it "sets series as regexp" do
131
- expect(dummy_metrics_3.new.series).to eq '/^.*$/'
132
- end
133
-
134
- it "quotes series" do
135
- expect(dummy_metrics_2.new.series).to eq "\"dummy \\\"A\\\"\""
136
- end
137
-
138
- it "set several series" do
139
- expect(dummy_with_2_series.new.series).to eq "merge(\"events\",\"errors\")"
140
- end
141
-
142
- it "quotes several series" do
143
- expect(dummy_with_2_series_quoted.new.series)
144
- .to eq "merge(\"dummy \\\"A\\\"\",\"dummy \\\"B\\\"\")"
145
- end
146
-
147
- it "sets series from proc" do
148
- expect(dummy_with_proc_series.series).to be_an_instance_of Proc
149
-
150
- m = dummy_with_proc_series.new user_id: 2, test_id: 123
151
- expect(m.series).to eq "\"test/123/user/2\""
152
- end
153
- end
154
-
155
- describe "#quoted_series" do
156
- context "with retention policy" do
157
- let(:dummy_with_retention_policy) do
158
- Class.new(described_class) do
159
- attributes :user_id, :test_id
160
- set_series :dummies
161
- set_retention_policy :week
162
- end
163
- end
164
-
165
- it "sets retention policy" do
166
- expect(dummy_with_retention_policy.retention_policy).to eq :week
167
- end
168
-
169
- it "sets quoted series with retention policy" do
170
- expect(dummy_with_retention_policy.quoted_series).to eq "\"week\".\"dummies\""
171
- end
172
- end
173
- end
174
-
175
- describe ".tags" do
176
- let(:dummy1) { Class.new(DummyMetrics) }
177
- let!(:dummy2) do
178
- Class.new(dummy1) do
179
- tags :zone
180
- end
181
- end
182
-
183
- it "inherits tags" do
184
- expect(dummy2.tag_names).to include('dummy_id', 'host', 'zone')
185
- end
186
-
187
- it "clones tags" do
188
- dummy1.tags :status
189
- expect(dummy1.tag_names).to include('status')
190
- expect(dummy2.tag_names).not_to include('status')
191
- end
192
- end
193
-
194
- describe "#dup" do
195
- let(:point) { DummyMetrics.new(user_id: 1, dummy_id: 2) }
196
- subject { point.dup }
197
-
198
- specify { expect(subject.user_id).to eq 1 }
199
- specify { expect(subject.dummy_id).to eq 2 }
200
-
201
- context "dup is not persisted" do
202
- before { point.write }
203
- specify { expect(subject.persisted?).to be_falsey }
204
- end
205
- end
206
-
207
- describe ".write" do
208
- let(:dummy_metrics) do
209
- Class.new(described_class) do
210
- set_series :dummies
211
- tags :dummy_id, :host
212
- attributes :user_id
213
- end
214
- end
215
-
216
- it "write data and return point" do
217
- expect(client)
218
- .to receive(:write_point).with(
219
- "dummies",
220
- { tags: { dummy_id: 2, host: 'test' }, values: { user_id: 1 }, timestamp: nil },
221
- nil,
222
- nil,
223
- nil
224
- )
225
-
226
- point = dummy_metrics.write(user_id: 1, dummy_id: 2, host: 'test')
227
- expect(point.persisted?).to be_truthy
228
- expect(point.user_id).to eq 1
229
- expect(point.dummy_id).to eq 2
230
- end
231
-
232
- it "test write data with time and return point" do
233
- timestamp_test = Time.now
234
- expected_time = (timestamp_test.to_r * 1_000_000_000).to_i
235
-
236
- expect(client)
237
- .to receive(:write_point).with(
238
- "dummies",
239
- { tags: { dummy_id: 2, host: 'test' }, values: { user_id: 1 }, timestamp: expected_time },
240
- nil,
241
- nil,
242
- nil
243
- )
244
-
245
- point = dummy_metrics.write(user_id: 1, dummy_id: 2, host: 'test', timestamp: timestamp_test)
246
- expect(point.persisted?).to be_truthy
247
- expect(point.user_id).to eq 1
248
- expect(point.dummy_id).to eq 2
249
- expect(point.timestamp).to eq timestamp_test
250
- end
251
-
252
- it "test write data with string time" do
253
- base_time = Time.now
254
- timestamp_test = base_time.to_s
255
-
256
- expect(client)
257
- .to receive(:write_point).with(
258
- "dummies",
259
- { tags: { dummy_id: 2, host: 'test' }, values: { user_id: 1 }, timestamp: (base_time.to_i * 1_000_000_000).to_i },
260
- nil,
261
- nil,
262
- nil
263
- )
264
-
265
- point = dummy_metrics.write(user_id: 1, dummy_id: 2, host: 'test', timestamp: timestamp_test)
266
- expect(point.persisted?).to be_truthy
267
- expect(point.user_id).to eq 1
268
- expect(point.dummy_id).to eq 2
269
- expect(point.timestamp).to eq(timestamp_test)
270
- end
271
-
272
- it "doesn't write data and return false if invalid" do
273
- expect(client).not_to receive(:write_point)
274
- expect(DummyMetrics.write(dummy_id: 2)).to be false
275
- end
276
- end
277
-
278
- describe ".all" do
279
- it "responds with relation" do
280
- expect(described_class.all).to be_a Influxer::Relation
281
- end
282
- end
283
- end
@@ -1,485 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
-
5
- describe Influxer::Relation, :query do
6
- let(:rel) { Influxer::Relation.new DummyMetrics }
7
- let(:rel2) { Influxer::Relation.new DummyComplexMetrics }
8
-
9
- context "instance methods" do
10
- subject { rel }
11
-
12
- specify { is_expected.to respond_to :write }
13
- specify { is_expected.to respond_to :select }
14
- specify { is_expected.to respond_to :where }
15
- specify { is_expected.to respond_to :limit }
16
- specify { is_expected.to respond_to :group }
17
- specify { is_expected.to respond_to :delete_all }
18
- specify { is_expected.to respond_to :to_sql }
19
- end
20
-
21
- describe "#build" do
22
- specify { expect(rel.build).to be_a DummyMetrics }
23
- specify { expect(rel.new).to be_a DummyMetrics }
24
- end
25
-
26
- describe "#merge!" do
27
- it "merge multi values" do
28
- r1 = rel.where(id: [1, 2], dummy: 'qwe').time(:hour)
29
- r2 = Influxer::Relation.new(DummyMetrics).where.not(user_id: 0).group(:user_id).order(user_id: :asc)
30
- r1.merge!(r2)
31
- expect(r1.to_sql)
32
- .to eq "select * from \"dummy\" where (id = 1 or id = 2) and (dummy = 'qwe') and (user_id <> 0) " \
33
- "group by time(1h), user_id order by user_id asc"
34
- end
35
-
36
- it "merge single values" do
37
- r1 = rel.time(:hour, fill: 0).slimit(10)
38
- r2 = Influxer::Relation.new(DummyMetrics).group(:dummy_id).offset(10).slimit(5)
39
- r1.merge!(r2)
40
- expect(r1.to_sql).to eq "select * from \"dummy\" group by time(1h), dummy_id fill(0) offset 10 slimit 5"
41
- end
42
- end
43
-
44
- context "sql generation" do
45
- describe "#from" do
46
- it "generates valid from if no conditions" do
47
- expect(rel.to_sql).to eq "select * from \"dummy\""
48
- end
49
-
50
- it "generates sql using custom from clause" do
51
- expect(rel.from(:doomy).to_sql).to eq "select * from \"doomy\""
52
- end
53
- end
54
-
55
- describe "#select" do
56
- it "select array of symbols" do
57
- expect(rel.select(:user_id, :dummy_id).to_sql).to eq "select user_id, dummy_id from \"dummy\""
58
- end
59
-
60
- it "select string" do
61
- expect(rel.select("count(user_id)").to_sql).to eq "select count(user_id) from \"dummy\""
62
- end
63
-
64
- it "select expression" do
65
- expect(rel.select("(value + 6) / 10").to_sql).to eq "select (value + 6) / 10 from \"dummy\""
66
- end
67
- end
68
-
69
- describe "#where" do
70
- it "generate valid conditions from hash" do
71
- Timecop.freeze(Time.now)
72
- expect(rel.where(user_id: 1, dummy: 'q', time: Time.now).to_sql).to eq "select * from \"dummy\" where (user_id = 1) and (dummy = 'q') and (time = #{(Time.now.to_r * 1_000_000_000).to_i})"
73
- end
74
-
75
- it "generate valid conditions from strings" do
76
- expect(rel.where("time > now() - 1d").to_sql).to eq "select * from \"dummy\" where (time > now() - 1d)"
77
- end
78
-
79
- it "handle regexps" do
80
- expect(rel.where(user_id: 1, dummy: /^du.*/).to_sql).to eq "select * from \"dummy\" where (user_id = 1) and (dummy =~ /^du.*/)"
81
- end
82
-
83
- it "handle dates" do
84
- expect(rel.where(time: Date.new(2015)).to_sql).to eq "select * from \"dummy\" where (time = #{(Date.new(2015).to_time.to_r * 1_000_000_000).to_i})"
85
- end
86
-
87
- it "handle date times" do
88
- expect(rel.where(time: DateTime.new(2015)).to_sql).to eq "select * from \"dummy\" where (time = #{(DateTime.new(2015).to_time.to_r * 1_000_000_000).to_i})"
89
- end
90
-
91
- it "handle date ranges" do
92
- expect(rel.where(time: Date.new(2015)..Date.new(2016)).to_sql).to eq "select * from \"dummy\" where (time >= #{(Date.new(2015).to_time.to_r * 1_000_000_000).to_i} and time <= #{(Date.new(2016).to_time.to_r * 1_000_000_000).to_i})"
93
- end
94
-
95
- it "handle date time ranges" do
96
- expect(rel.where(time: DateTime.new(2015)..DateTime.new(2016)).to_sql).to eq "select * from \"dummy\" where (time >= #{(DateTime.new(2015).to_time.to_r * 1_000_000_000).to_i} and time <= #{(DateTime.new(2016).to_time.to_r * 1_000_000_000).to_i})"
97
- end
98
-
99
- it "handle inclusive ranges" do
100
- expect(rel.where(user_id: 1..4).to_sql).to eq "select * from \"dummy\" where (user_id >= 1 and user_id <= 4)"
101
- end
102
-
103
- it "handle exclusive range" do
104
- expect(rel.where(user_id: 1...4).to_sql).to eq "select * from \"dummy\" where (user_id >= 1 and user_id < 4)"
105
- end
106
-
107
- it "handle arrays" do
108
- expect(rel.where(user_id: [1, 2, 3]).to_sql).to eq "select * from \"dummy\" where (user_id = 1 or user_id = 2 or user_id = 3)"
109
- end
110
-
111
- it "handle empty arrays", :aggregate_failures do
112
- expect(rel.where(user_id: []).to_sql).to eq "select * from \"dummy\" where (1 = 0)"
113
- expect(rel.to_a).to eq []
114
- end
115
-
116
- context "with timestamp duration" do
117
- around do |ex|
118
- old_duration = Influxer.config.time_duration_suffix_enabled
119
- Influxer.config.time_duration_suffix_enabled = true
120
- ex.run
121
- Influxer.config.time_duration_suffix_enabled = old_duration
122
- end
123
-
124
- it "adds ns suffix to times" do
125
- expect(rel.where(time: DateTime.new(2015)).to_sql).to eq "select * from \"dummy\" where (time = #{(DateTime.new(2015).to_time.to_r * 1_000_000_000).to_i}ns)"
126
- end
127
-
128
- context "with different time_precision" do
129
- around do |ex|
130
- old_precision = Influxer.config.time_precision
131
- Influxer.config.time_precision = 's'
132
- ex.run
133
- Influxer.config.time_precision = old_precision
134
- end
135
-
136
- it "adds s suffix to times" do
137
- expect(rel.where(time: DateTime.new(2015)).to_sql).to eq "select * from \"dummy\" where (time = #{DateTime.new(2015).to_time.to_i}s)"
138
- end
139
- end
140
-
141
- context "with unsupported time_precision" do
142
- around do |ex|
143
- old_precision = Influxer.config.time_precision
144
- Influxer.config.time_precision = 'h'
145
- ex.run
146
- Influxer.config.time_precision = old_precision
147
- end
148
-
149
- it "casts to ns with suffix" do
150
- expect(rel.where(time: DateTime.new(2015)).to_sql).to eq "select * from \"dummy\" where (time = #{(DateTime.new(2015).to_time.to_r * 1_000_000_000).to_i}ns)"
151
- end
152
- end
153
- end
154
-
155
- context "with different time_precision" do
156
- around do |ex|
157
- old_precision = Influxer.config.time_precision
158
- Influxer.config.time_precision = 's'
159
- ex.run
160
- Influxer.config.time_precision = old_precision
161
- end
162
-
163
- it "casts to correct numeric representation" do
164
- expect(rel.where(time: DateTime.new(2015)).to_sql).to eq "select * from \"dummy\" where (time = #{DateTime.new(2015).to_time.to_i})"
165
- end
166
- end
167
-
168
- context "with tags" do
169
- it "integer tag values" do
170
- expect(rel.where(dummy_id: 10).to_sql).to eq "select * from \"dummy\" where (dummy_id = '10')"
171
- end
172
-
173
- it "array tag values" do
174
- expect(rel.where(dummy_id: [10, 'some']).to_sql).to eq "select * from \"dummy\" where (dummy_id = '10' or dummy_id = 'some')"
175
- end
176
-
177
- it "nil value" do
178
- expect(rel.where(dummy_id: nil).to_sql).to eq "select * from \"dummy\" where (dummy_id !~ /.*/)"
179
- end
180
- end
181
- end
182
-
183
- describe "#not" do
184
- it "negate simple values" do
185
- expect(rel.where.not(user_id: 1, dummy: :a).to_sql).to eq "select * from \"dummy\" where (user_id <> 1) and (dummy <> 'a')"
186
- end
187
-
188
- it "handle regexp" do
189
- expect(rel.where.not(user_id: 1, dummy: /^du.*/).to_sql).to eq "select * from \"dummy\" where (user_id <> 1) and (dummy !~ /^du.*/)"
190
- end
191
-
192
- it "handle inclusive ranges" do
193
- expect(rel.where.not(user_id: 1..4).to_sql).to eq "select * from \"dummy\" where (user_id < 1 or user_id > 4)"
194
- end
195
-
196
- it "handle exclusive ranges" do
197
- expect(rel.where.not(user_id: 1...4).to_sql).to eq "select * from \"dummy\" where (user_id < 1 or user_id >= 4)"
198
- end
199
-
200
- it "handle arrays" do
201
- expect(rel.where.not(user_id: [1, 2, 3]).to_sql).to eq "select * from \"dummy\" where (user_id <> 1 and user_id <> 2 and user_id <> 3)"
202
- end
203
-
204
- it "handle empty arrays", :aggregate_failures do
205
- expect(rel.where.not(user_id: []).to_sql).to eq "select * from \"dummy\" where (1 = 0)"
206
- expect(rel.to_a).to eq []
207
- end
208
-
209
- context "with tags" do
210
- it "nil value" do
211
- expect(rel.not(dummy_id: nil).to_sql).to eq "select * from \"dummy\" where (dummy_id =~ /.*/)"
212
- end
213
- end
214
- end
215
-
216
- describe "#none" do
217
- it "returns empty array", :aggregate_failures do
218
- expect(rel.none.to_sql).to eq "select * from \"dummy\" where (1 = 0)"
219
- expect(rel.to_a).to eq []
220
- end
221
-
222
- it "works with chaining", :aggregate_failures do
223
- expect(rel.none.where.not(user_id: 1, dummy: :a).to_sql)
224
- .to eq "select * from \"dummy\" where (1 = 0) and (user_id <> 1) and (dummy <> 'a')"
225
- expect(rel.to_a).to eq []
226
- end
227
- end
228
-
229
- describe "#past" do
230
- it "work with predefined symbols" do
231
- expect(rel.past(:hour).to_sql).to eq "select * from \"dummy\" where (time > now() - 1h)"
232
- end
233
-
234
- it "work with any symbols" do
235
- expect(rel.past(:s).to_sql).to eq "select * from \"dummy\" where (time > now() - 1s)"
236
- end
237
-
238
- it "work with strings" do
239
- expect(rel.past("3d").to_sql).to eq "select * from \"dummy\" where (time > now() - 3d)"
240
- end
241
-
242
- it "work with numbers" do
243
- expect(rel.past(1.day).to_sql).to eq "select * from \"dummy\" where (time > now() - 86400s)"
244
- end
245
- end
246
-
247
- describe "#since" do
248
- it "work with datetime" do
249
- expect(rel.since(Time.utc(2014, 12, 31)).to_sql).to eq "select * from \"dummy\" where (time > 1419984000s)"
250
- end
251
- end
252
-
253
- describe "#group" do
254
- it "generate valid groups" do
255
- expect(rel.group(:user_id, "time(1m) fill(0)").to_sql).to eq "select * from \"dummy\" group by user_id, time(1m) fill(0)"
256
- end
257
-
258
- context "group by time predefined values" do
259
- it "group by hour" do
260
- expect(rel.time(:hour).to_sql).to eq "select * from \"dummy\" group by time(1h)"
261
- end
262
-
263
- it "group by minute" do
264
- expect(rel.time(:minute).to_sql).to eq "select * from \"dummy\" group by time(1m)"
265
- end
266
-
267
- it "group by second" do
268
- expect(rel.time(:second).to_sql).to eq "select * from \"dummy\" group by time(1s)"
269
- end
270
-
271
- it "group by millisecond" do
272
- expect(rel.time(:ms).to_sql).to eq "select * from \"dummy\" group by time(1ms)"
273
- end
274
-
275
- it "group by microsecond" do
276
- expect(rel.time(:u).to_sql).to eq "select * from \"dummy\" group by time(1u)"
277
- end
278
-
279
- it "group by day" do
280
- expect(rel.time(:day).to_sql).to eq "select * from \"dummy\" group by time(1d)"
281
- end
282
-
283
- it "group by week" do
284
- expect(rel.time(:week).to_sql).to eq "select * from \"dummy\" group by time(1w)"
285
- end
286
-
287
- it "group by month" do
288
- expect(rel.time(:month).to_sql).to eq "select * from \"dummy\" group by time(30d)"
289
- end
290
-
291
- it "group by hour and fill" do
292
- expect(rel.time(:month, fill: 0).to_sql).to eq "select * from \"dummy\" group by time(30d) fill(0)"
293
- end
294
- end
295
-
296
- it "group by time with string value" do
297
- expect(rel.time("4d").to_sql).to eq "select * from \"dummy\" group by time(4d)"
298
- end
299
-
300
- %w[null previous none].each do |val|
301
- it "group by time with string value and fill #{val}" do
302
- expect(rel.time("4d", fill: val.to_sym).to_sql).to eq "select * from \"dummy\" group by time(4d) fill(#{val})"
303
- end
304
- end
305
-
306
- it "group by time and other fields with fill zero" do
307
- expect(rel.time("4d", fill: 0).group(:dummy_id).to_sql).to eq "select * from \"dummy\" group by time(4d), dummy_id fill(0)"
308
- end
309
-
310
- it "group by time and other fields with fill negative" do
311
- expect(rel.time("4d", fill: -1).group(:dummy_id).to_sql).to eq "select * from \"dummy\" group by time(4d), dummy_id fill(-1)"
312
- end
313
- end
314
-
315
- describe "#order" do
316
- it "generate valid order" do
317
- expect(rel.order(time_spent: :asc).to_sql).to eq "select * from \"dummy\" order by time_spent asc"
318
- end
319
-
320
- it "generate order from string" do
321
- expect(rel.order('cpu desc, val asc').to_sql).to eq "select * from \"dummy\" order by cpu desc, val asc"
322
- end
323
- end
324
-
325
- describe "#limit" do
326
- it "generate valid limit" do
327
- expect(rel.limit(100).to_sql).to eq "select * from \"dummy\" limit 100"
328
- end
329
- end
330
-
331
- describe "#slimit" do
332
- it "generate valid slimit" do
333
- expect(rel.slimit(100).to_sql).to eq "select * from \"dummy\" slimit 100"
334
- end
335
- end
336
-
337
- describe "#offset" do
338
- it "generate valid offset" do
339
- expect(rel.limit(100).offset(10).to_sql).to eq "select * from \"dummy\" limit 100 offset 10"
340
- end
341
- end
342
-
343
- describe "#soffset" do
344
- it "generate valid soffset" do
345
- expect(rel.soffset(10).to_sql).to eq "select * from \"dummy\" soffset 10"
346
- end
347
- end
348
-
349
- context "calculations" do
350
- context "one arg calculation methods" do
351
- [
352
- :count, :min, :max, :mean,
353
- :mode, :median, :distinct, :derivative,
354
- :stddev, :sum, :first, :last
355
- ].each do |method|
356
- describe "##{method}" do
357
- specify do
358
- expect(rel.where(user_id: 1).calc(method, :column_name).to_sql)
359
- .to eq "select #{method}(column_name) from \"dummy\" where (user_id = 1)"
360
- end
361
- end
362
- end
363
- end
364
-
365
- context "with aliases" do
366
- it "select count as alias" do
367
- expect(rel.count(:val, 'total').to_sql).to eq "select count(val) as total from \"dummy\""
368
- end
369
-
370
- it "select percentile as alias" do
371
- expect(rel.percentile(:val, 90, 'p1').to_sql).to eq "select percentile(val, 90) as p1 from \"dummy\""
372
- end
373
- end
374
- end
375
-
376
- context "complex queries" do
377
- it "group + where" do
378
- expect(rel.count('user_id').group(:traffic_source).fill(0).where(user_id: 123).past('28d').to_sql)
379
- .to eq "select count(user_id) from \"dummy\" where (user_id = 123) and (time > now() - 28d) " \
380
- "group by traffic_source fill(0)"
381
- end
382
-
383
- it "where + group + order + limit" do
384
- expect(rel.group(:user_id).where(account_id: 123).order(account_id: :desc).limit(10).offset(10).to_sql)
385
- .to eq "select * from \"dummy\" where (account_id = 123) group by user_id " \
386
- "order by account_id desc limit 10 offset 10"
387
- end
388
-
389
- it "offset + slimit" do
390
- expect(rel.where(account_id: 123).slimit(10).offset(10).to_sql)
391
- .to eq "select * from \"dummy\" where (account_id = 123) " \
392
- "offset 10 slimit 10"
393
- end
394
- end
395
- end
396
-
397
- describe "#empty?" do
398
- it "return false if has points" do
399
- allow(client).to receive(:query) { [{ "values" => [{ time: 1, id: 2 }] }] }
400
- expect(rel.empty?).to be_falsey
401
- expect(rel.present?).to be_truthy
402
- end
403
-
404
- it "return true if no points" do
405
- allow(client).to receive(:query) { [] }
406
- expect(rel.empty?).to be_truthy
407
- expect(rel.present?).to be_falsey
408
- end
409
- end
410
-
411
- describe "#delete_all" do
412
- it "client expects to execute query method" do
413
- expected_query = "drop series from \"dummy\""
414
-
415
- expect(client)
416
- .to receive(:query).with(expected_query)
417
-
418
- rel.delete_all
419
- end
420
-
421
- it "without tags" do
422
- expect(rel.delete_all)
423
- .to eq "drop series from \"dummy\""
424
- end
425
-
426
- it "with tags" do
427
- expect(rel.where(dummy_id: 1, host: 'eu').delete_all)
428
- .to eq "drop series from \"dummy\" where (dummy_id = '1') and (host = 'eu')"
429
- end
430
- end
431
-
432
- describe "#inspect" do
433
- it "return correct String represantation of empty relation" do
434
- allow(rel).to receive(:to_a) { [] }
435
- expect(rel.inspect).to eq "#<Influxer::Relation []>"
436
- end
437
-
438
- it "return correct String represantation of non-empty relation" do
439
- allow(rel).to receive(:to_a) { [1, 2, 3] }
440
- expect(rel.inspect).to eq "#<Influxer::Relation [1, 2, 3]>"
441
- end
442
-
443
- it "return correct String represantation of non-empty large (>11) relation" do
444
- allow(rel).to receive(:to_a) { [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13] }
445
- expect(rel.inspect).to eq "#<Influxer::Relation [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ...]>"
446
- end
447
- end
448
-
449
- describe "#epoch" do
450
- it "format :h" do
451
- expect(client).to receive(:query).with('select * from "dummy"', denormalize: true, epoch: :h).and_return []
452
- DummyMetrics.epoch(:h).all.to_a
453
- end
454
-
455
- it "format :m" do
456
- expect(client).to receive(:query).with('select * from "dummy"', denormalize: true, epoch: :m).and_return []
457
- DummyMetrics.epoch(:m).all.to_a
458
- end
459
-
460
- it "format :s" do
461
- expect(client).to receive(:query).with('select * from "dummy"', denormalize: true, epoch: :s).and_return []
462
- DummyMetrics.epoch(:s).all.to_a
463
- end
464
-
465
- it "format :ms" do
466
- expect(client).to receive(:query).with('select * from "dummy"', denormalize: true, epoch: :ms).and_return []
467
- DummyMetrics.epoch(:ms).all.to_a
468
- end
469
-
470
- it "format :u" do
471
- expect(client).to receive(:query).with('select * from "dummy"', denormalize: true, epoch: :u).and_return []
472
- DummyMetrics.epoch(:u).all.to_a
473
- end
474
-
475
- it "format :ns" do
476
- expect(client).to receive(:query).with('select * from "dummy"', denormalize: true, epoch: :ns).and_return []
477
- DummyMetrics.epoch(:ns).all.to_a
478
- end
479
-
480
- it "invalid epoch format" do
481
- expect(client).to receive(:query).with('select * from "dummy"', denormalize: true, epoch: nil).and_return []
482
- DummyMetrics.epoch(:invalid).all.to_a
483
- end
484
- end
485
- end