influxer 1.1.4 → 1.2.2

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 +5 -5
  2. data/CHANGELOG.md +98 -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 +1 -1
  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 +19 -11
  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 +30 -95
  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 -111
  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 -477
  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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 34d7516d9e613074dcc24cf1c401bf69af544fa8
4
- data.tar.gz: ea286c505a09b55058dc00fa05bebd1786c2de20
2
+ SHA256:
3
+ metadata.gz: cee4a4e35b41eda0936d8f7344a2a06d1dc251a0c9a7303723413f1c3a702d25
4
+ data.tar.gz: 8d027da03e9bae2a76351f1cdd0a21f7f5ccf32eb73282fac95a09fbd8771aad
5
5
  SHA512:
6
- metadata.gz: 96fbc0c09e0127c7be545ffab4e0108a9ea26c7d471678c74095d35ce55827103357ce584b371e86cdd82200ff0ea86a63fb1f4ff61890e6d841b59de1618d35
7
- data.tar.gz: 5e580bcbfebb8ca2d731cd658e81d7cd418dc90a4e423aac8ea47d5cb06ccdd409b4e938d6752be4f9b5955bbcede839a004c3ee77dd7fd103c01471a51e1a22
6
+ metadata.gz: 34fab113906dfeb113cff12cc6bfb0654891502d8ee8382717a1cae7b90d484cdf2933d283a9497a9fd2c2b946ad77f647c0096822d5c61f41368f21fd898f68
7
+ data.tar.gz: 8c30816022d49e8aa74db8945fc9f7bcd5cf73334cf92f886d469f6cc6ca7b11bbe855a876a17bd3898b2db434c2e5b29712606b5c5685ed1bb93e0982e959f6
@@ -0,0 +1,98 @@
1
+ # Change log
2
+
3
+ ## master (unreleased)
4
+
5
+ ## 1.2.2 (2020-10-27)
6
+
7
+ - Fixes [#49](https://github.com/palkan/influxer/issues/49) Cache hash configuration cannot be applied.([@AlexanderShvaykin][])
8
+ - Fixes [#47](https://github.com/palkan/influxer/issues/47) Can't delete data when retention policy is set for a metric. ([@MPursche][])
9
+
10
+ ## 1.2.1 (2020-07-09)
11
+
12
+ - Support for setting timezone in queries to configure influx time calculations, e.g., time epoch aggregation ([@jklimke][])
13
+
14
+ [PR](https://github.com/palkan/influxer/pull/46)
15
+
16
+ ## 1.2.0 (2019-05-20)
17
+
18
+ - **Require Ruby 2.4+**
19
+
20
+ ## 1.1.6
21
+
22
+ - [Fixes [#41](https://github.com/palkan/influxer/issues/41)] Fix query building with empty arrays in `where` clause ([@dimiii][])
23
+
24
+ [PR](https://github.com/palkan/influxer/pull/44)
25
+
26
+ **BREAKING:** `where.not` now returns non-empty result for an empty array.
27
+
28
+ - Support of year alias in queries ([@dimiii][])
29
+
30
+ - [Fixes [#40](https://github.com/palkan/influxer/issues/40)] Avoid adding precision suffix to write queries. ([@palkan][])
31
+
32
+ ## 1.1.5
33
+
34
+ - [Fixes [#37](https://github.com/palkan/influxer/issues/37)] Timestamp ranges are quoted again. ([@jklimke][])
35
+
36
+ ## 1.1.4
37
+
38
+ - [Fixes [#35](https://github.com/palkan/influxer/issues/35)] Support time duration suffix and handle `'s'` and `'ms'` precision. ([@palkan][])
39
+
40
+ [PR](https://github.com/palkan/influxer/pull/36)
41
+
42
+ **BREAKING:** `Time`-like value are only type-casted for `time` key.
43
+
44
+ ## 1.1.2
45
+
46
+ - Support exclusive ranges as `where` arguments. ([@MPursche][])
47
+
48
+ ```ruby
49
+ # range including the end
50
+ where(a: 1..4)
51
+ #=> ... WHERE a >= 1 AND a <= 4
52
+
53
+ #range excluding the end
54
+ where(a: 1...4)
55
+ #=> ... WHERE a >= 1 AND a < 4
56
+ ```
57
+
58
+ ## 1.1.1
59
+
60
+ - [Fixes [#31](https://github.com/palkan/influxer/issues/31)] Fix bug with empty arrays in `where` clause
61
+
62
+ - Introduce `Relation#none` method
63
+
64
+ ## 1.1.0
65
+
66
+ ### Features
67
+
68
+ - Add ability to specify per-metrics retention-policy, precision and database
69
+
70
+ Now you can override default configuration for a specific metrics class:
71
+
72
+ ```ruby
73
+ class CustomMetrics < Influxer::Metrics
74
+ set_database "custom_db"
75
+ set_retention_policy :yearly
76
+ set_precision "ms"
77
+ end
78
+ ```
79
+
80
+ ### Fixes
81
+
82
+ - [Fixes [#30](https://github.com/palkan/influxer/issues/30)] Fix writing points with custom retention policy
83
+
84
+ ### Misc
85
+
86
+ - Update Rubocop configuration and add Rubocop Rake task to defaults
87
+
88
+ ## 1.0.1
89
+
90
+ - Fix missing `#delegate` in ActiveRecord 3.2
91
+
92
+ See [changelog](https://github.com/palkan/influxer/blob/1.0.0/Changelog.md) for earlier versions.
93
+
94
+ [@palkan]: https://github.com/palkan
95
+ [@MPursche]: https://github.com/MPursche
96
+ [@jklimke]: https://github.com/jklimke
97
+ [@dimiii]: https://github.com/dimiii
98
+ [@AlexanderShvaykin]: https://github.com/AlexanderShvaykin
@@ -1,4 +1,4 @@
1
- Copyright 2014 palkan
1
+ Copyright 2014-2020 Vladimir Dementyev
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -1,50 +1,109 @@
1
- [![Gem Version](https://badge.fury.io/rb/influxer.svg)](https://rubygems.org/gems/influxer) [![Build Status](https://travis-ci.org/palkan/influxer.svg?branch=master)](https://travis-ci.org/palkan/influxer) [![Dependency Status](https://dependencyci.com/github/palkan/influxer/badge)](https://dependencyci.com/github/palkan/influxer)
2
- ## Influxer
1
+ ![Build](https://github.com/palkan/influxer/workflows/Build/badge.svg)
3
2
 
4
- **NOTE**: Version 0.3.x supports InfluxDB >= 0.9.0. For InfluxDB 0.8.x use [version 0.2.5](https://github.com/palkan/influxer/tree/0.2.5).
5
-
6
- **NOTE**: Influxer is Rails 3, 4, 5 compatible!
3
+ # Influxer
7
4
 
8
5
  Influxer provides an ActiveRecord-style way to work with [InfluxDB](https://influxdb.com/) with many useful features, such as:
9
- - Familar query language (use `select`, `where`, `not`, `group` etc).
10
- - Support for Regex conditions: `where(page_id: /^home\/.*/) #=> select * ... where page_id=~/^home\/.*/`.
11
- - Special query methods for InfluxDB:
12
- - `time` - group by time (e.g. `Metrics.time(:hour) => # select * ... group by time(1h)`);
13
- - `past` - get only points for last hour/minute/whatever (e.g. `Metrics.past(:day) => # select * ... where time > now() - 1d`);
14
- - `since` - get only points since date (e.g. `Metrics.since(Time.utc(2014,12,31)) => # select * ... where time > 1419984000s`);
15
- - `merge` - merge series.
16
- - Scopes support
17
- ```ruby
18
- class Metrics < Influxer::Metrics
19
- default_scope -> { time(:hour).limit(1000) }
20
- tags :account_id
21
- attributes :value
22
- scope :unlimited, -> { limit(nil) }
23
- scope :by_account, -> (id) { where(account_id: id) if id.present? }
24
- end
25
-
26
- Metrics.by_account(1)
27
- # => select * from "metrics" group by time(1h) where account_id=1 limit 1000
28
-
29
- Metrics.unlimited.by_account(1).time(:week)
30
- # => select * from "metrics" group by time(1w) where account_id=1
31
-
32
- ```
33
- - Integrate with your model:
34
- ```ruby
35
- class UserVisits < Influxer::Metrics
36
- end
37
-
38
- class User < ActiveRecord::Base
39
- has_metrics :visits
40
- end
41
-
42
- user = User.find(1)
43
- user.visits.write(page_id: 'home')
44
- #=> < creates point {user_id: 1, page_id: 'home'} in 'user_visits' series >
45
-
46
- user.visits.where(page_id: 'home')
47
- #=> select * from user_visits where page_id='home'
48
- ```
49
-
50
- Find more on [Wiki](https://github.com/palkan/influxer/wiki).
6
+
7
+ ## Installation
8
+
9
+ Adding to a gem:
10
+
11
+ ```ruby
12
+ # my-cool-gem.gemspec
13
+ Gem::Specification.new do |spec|
14
+ # ...
15
+ spec.add_dependency "influxer", ">= 1.2.0"
16
+ # ...
17
+ end
18
+ ```
19
+
20
+ Or adding to your project:
21
+
22
+ ```ruby
23
+ # Gemfile
24
+ gem "influxer", "~> 1.2"
25
+ ```
26
+
27
+ ## Usage
28
+
29
+ ### Metrics classes
30
+
31
+ To query InfluxDB or write to it, you should define a metrics class first. Each metrics class represents a measurement/series (or multiple related measurements):
32
+
33
+ ```ruby
34
+ class VisitsMetrics < Influxer::Metrics
35
+ # Define tags...
36
+ tags :account_id, :page_id
37
+ # ...and attributes
38
+ attributes :user_id, :browser
39
+ end
40
+ ```
41
+
42
+ ### Querying
43
+
44
+ Now you can use your metrics classes in a similar way to Active Record models to build queries. For example:
45
+
46
+ ```ruby
47
+ VisitsMetrics.select(:account_id, :user_id).where(page_id: /^home\/.*/)
48
+ ```
49
+
50
+ Influxer provides special query methods for dealing with time series:
51
+
52
+ - Group by time: `Metrics.time(:hour) => # select * ... group by time(1h)`.
53
+ - Select only points for the last hour/minute/whatever: `Metrics.past(:day) => # select * ... where time > now() - 1d`.
54
+ - Select only points since the specified time: `Metrics.since(Time.utc(2014,12,31)) => # select * ... where time > 1419984000s`.
55
+ - and more.
56
+
57
+ See [our Wiki](https://github.com/palkan/influxer/wiki/Query-methods) for more.
58
+
59
+ ### Scopes support
60
+
61
+ You can define scopes to re-use query conditions:
62
+
63
+ ```ruby
64
+ class Metrics < Influxer::Metrics
65
+ tags :account_id
66
+ attributes :value
67
+
68
+ default_scope -> { time(:hour).limit(1000) }
69
+
70
+ scope :unlimited, -> { limit(nil) }
71
+ scope :by_account, ->(id) { where(account_id: id) if id.present? }
72
+ end
73
+
74
+ Metrics.by_account(1)
75
+ # => select * from "metrics" group by time(1h) where account_id=1 limit 1000
76
+
77
+ Metrics.unlimited.by_account(1).time(:week)
78
+ # => select * from "metrics" group by time(1w) where account_id=1
79
+ ```
80
+
81
+ ### Active Record integration
82
+
83
+ You can association metrics with Active Record models:
84
+
85
+ ```ruby
86
+ class UserVisits < Influxer::Metrics
87
+ end
88
+
89
+ class User < ActiveRecord::Base
90
+ has_metrics :visits
91
+ end
92
+
93
+ user = User.find(1)
94
+ user.visits.write(page_id: "home")
95
+ #=> < creates point {user_id: 1, page_id: 'home'} in 'user_visits' series >
96
+
97
+ user.visits.where(page_id: "home")
98
+ #=> select * from user_visits where page_id='home'
99
+ ```
100
+
101
+ Find more on [Wiki](https://github.com/palkan/influxer/wiki/ActiveRecord-integration).
102
+
103
+ ## Contributing
104
+
105
+ Bug reports and pull requests are welcome on GitHub at [https://github.com/palkan/influxer](https://github.com/palkan/influxer).
106
+
107
+ ## License
108
+
109
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -1,7 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'influxer/version'
4
- require 'active_model'
3
+ require "influxer/version"
4
+ require "active_model"
5
+ require "active_support/core_ext"
5
6
 
6
7
  # Rails client for InfluxDB
7
8
  module Influxer
@@ -9,16 +10,16 @@ module Influxer
9
10
  ActiveModel::VERSION::MAJOR == 3
10
11
  end
11
12
 
12
- require 'influxer/config'
13
- require 'influxer/client'
14
- require 'influxer/metrics/metrics'
13
+ require "influxer/config"
14
+ require "influxer/client"
15
+ require "influxer/metrics/metrics"
15
16
 
16
17
  module Model # :nodoc:
17
- require 'influxer/model'
18
+ require "influxer/model"
18
19
  end
19
20
 
20
- require 'influxer/rails/client' if defined?(Rails)
21
- require 'influxer/engine' if defined?(Rails)
21
+ require "influxer/rails/client" if defined?(Rails)
22
+ require "influxer/engine" if defined?(Rails)
22
23
 
23
24
  def self.config
24
25
  @config ||= Config.new
@@ -33,7 +34,7 @@ module Influxer
33
34
  end
34
35
 
35
36
  def self.reset!
36
- @client.stop! unless @client.nil?
37
+ @client&.stop!
37
38
  @config = nil
38
39
  @client = nil
39
40
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'influxdb'
3
+ require "influxdb"
4
4
 
5
5
  module Influxer
6
6
  # InfluxDB API client
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'anyway_config'
3
+ require "anyway_config"
4
4
 
5
5
  module Influxer
6
6
  # Influxer configuration
@@ -28,15 +28,28 @@ module Influxer
28
28
  :denormalize,
29
29
  :udp,
30
30
  :async,
31
- database: 'db',
32
- time_precision: 'ns',
33
- cache: false,
31
+ :cache_enabled,
32
+ :cache,
33
+ database: "db",
34
+ time_precision: "ns",
34
35
  time_duration_suffix_enabled: false
35
36
 
36
37
  def load(*)
37
38
  super
38
- # we want pass @cache value as options to cache store, so we want it to be a Hash
39
- @cache = {}.with_indifferent_access if @cache == true
39
+ if cache_enabled.nil?
40
+ self.cache_enabled = cache_enabled_value
41
+ end
42
+ end
43
+
44
+ def cache=(value)
45
+ super
46
+ self.cache_enabled = cache_enabled_value
47
+ end
48
+
49
+ private
50
+
51
+ def cache_enabled_value
52
+ !!cache
40
53
  end
41
54
  end
42
55
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'influxer'
3
+ require "influxer"
4
4
 
5
5
  module Influxer
6
6
  class Engine < Rails::Engine # :nodoc:
@@ -5,10 +5,8 @@ module Influxer
5
5
  # Replacement of ActiveModel::Model for ActiveModel 3
6
6
  module Model
7
7
  def initialize(attributes = {})
8
- if attributes
9
- attributes.each do |attr, value|
10
- public_send("#{attr}=", value)
11
- end
8
+ attributes&.each do |attr, value|
9
+ public_send("#{attr}=", value)
12
10
  end
13
11
 
14
12
  super()
@@ -1,16 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'influxer/metrics/relation'
4
- require 'influxer/metrics/scoping'
5
- require 'influxer/metrics/quoting/timestamp'
6
- require 'influxer/metrics/active_model3/model'
3
+ require "influxer/metrics/relation"
4
+ require "influxer/metrics/scoping"
5
+ require "influxer/metrics/quoting/timestamp"
6
+ require "influxer/metrics/active_model3/model"
7
7
 
8
8
  module Influxer
9
9
  class MetricsError < StandardError; end
10
10
  class MetricsInvalid < MetricsError; end
11
11
 
12
12
  # Base class for InfluxDB querying and writing
13
- # rubocop:disable Metrics/ClassLength
14
13
  class Metrics
15
14
  TIME_FACTOR = 1_000_000_000
16
15
  if Influxer.active_model3?
@@ -18,7 +17,6 @@ module Influxer
18
17
  else
19
18
  include ActiveModel::Model
20
19
  end
21
- # rubocop:enable Style/MixinUsage
22
20
 
23
21
  include ActiveModel::Validations
24
22
  extend ActiveModel::Callbacks
@@ -35,7 +33,7 @@ module Influxer
35
33
  [
36
34
  :write, :write!, :select, :where,
37
35
  :group, :time, :past, :since,
38
- :limit, :offset, :fill, :delete_all, :epoch
36
+ :limit, :offset, :fill, :delete_all, :epoch, :timezone
39
37
  ] + Influxer::Calculations::CALCULATION_METHODS
40
38
  ),
41
39
  to: :all
@@ -125,7 +123,7 @@ module Influxer
125
123
  quoted_series(val.call(instance), write: write)
126
124
  when Array
127
125
  if val.length > 1
128
- "merge(#{val.map { |s| quoted_series(s, write: write) }.join(',')})"
126
+ "merge(#{val.map { |s| quoted_series(s, write: write) }.join(",")})"
129
127
  else
130
128
  quoted_series(val.first, write: write)
131
129
  end
@@ -133,7 +131,7 @@ module Influxer
133
131
  # Only add retention policy when selecting points
134
132
  # and not writing
135
133
  if !write && retention_policy.present?
136
- [quote(@retention_policy), quote(val)].join('.')
134
+ [quote(@retention_policy), quote(val)].join(".")
137
135
  else
138
136
  quote(val)
139
137
  end
@@ -169,6 +167,7 @@ module Influxer
169
167
 
170
168
  def write!
171
169
  raise MetricsInvalid if invalid?
170
+
172
171
  write
173
172
  end
174
173
 
@@ -225,13 +224,11 @@ module Influxer
225
224
  end
226
225
 
227
226
  def parsed_timestamp
228
- quote_timestamp @timestamp, client
227
+ quote_timestamp_for_write @timestamp, client
229
228
  end
230
- # rubocop:enable Metrics/MethodLength
231
- # rubocop:enable Metrics/AbcSize
232
229
 
233
230
  def unquote(name)
234
- name.gsub(/(\A['"]|['"]\z)/, '')
231
+ name.gsub(/(\A['"]|['"]\z)/, "")
235
232
  end
236
233
  end
237
234
  end