influxer 0.2.4 → 0.3.1
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/.gitignore +1 -0
- data/.rubocop.yml +12 -0
- data/.travis.yml +1 -17
- data/Changelog.md +7 -0
- data/Gemfile +7 -0
- data/README.md +6 -20
- data/Rakefile +4 -0
- data/gemfiles/rails42.gemfile +4 -1
- data/influxer.gemspec +6 -6
- data/lib/influxer/client.rb +4 -44
- data/lib/influxer/config.rb +23 -14
- data/lib/influxer/engine.rb +0 -1
- data/lib/influxer/metrics/metrics.rb +40 -7
- data/lib/influxer/metrics/relation/calculations.rb +13 -7
- data/lib/influxer/metrics/relation/time_query.rb +14 -8
- data/lib/influxer/metrics/relation/where_clause.rb +62 -0
- data/lib/influxer/metrics/relation.rb +67 -76
- data/lib/influxer/metrics/scoping.rb +4 -4
- data/lib/influxer/model.rb +4 -0
- data/lib/influxer/rails/client.rb +47 -0
- data/lib/influxer/version.rb +1 -1
- data/lib/influxer.rb +4 -2
- data/spec/cases/points_spec.rb +34 -0
- data/spec/client_spec.rb +21 -24
- data/spec/fixtures/empty_result.json +21 -0
- data/spec/fixtures/single_series.json +29 -0
- data/spec/metrics/metrics_spec.rb +139 -113
- data/spec/metrics/relation_spec.rb +160 -105
- data/spec/metrics/scoping_spec.rb +11 -17
- data/spec/model/user_spec.rb +44 -0
- data/spec/spec_helper.rb +38 -8
- data/spec/support/metrics/action_metrics.rb +3 -0
- data/spec/support/metrics/custom_metrics.rb +4 -0
- data/spec/support/{dummy_metrics.rb → metrics/dummy_metrics.rb} +2 -1
- data/spec/support/metrics/user_metrics.rb +4 -0
- data/spec/support/metrics/visits_metrics.rb +4 -0
- data/spec/support/shared_contexts/shared_query.rb +16 -0
- data/spec/support/user.rb +14 -0
- metadata +42 -71
- data/gemfiles/rails40.gemfile +0 -7
- data/gemfiles/rails41.gemfile +0 -7
- data/lib/influxer/metrics/fanout.rb +0 -65
- data/lib/influxer/metrics/relation/fanout_query.rb +0 -49
- data/lib/tasks/influxer_tasks.rake +0 -4
- data/spec/config_spec.rb +0 -17
- data/spec/dummy/README.rdoc +0 -28
- data/spec/dummy/Rakefile +0 -6
- data/spec/dummy/app/assets/images/.keep +0 -0
- data/spec/dummy/app/assets/javascripts/application.js +0 -13
- data/spec/dummy/app/assets/stylesheets/application.css +0 -15
- data/spec/dummy/app/controllers/application_controller.rb +0 -5
- data/spec/dummy/app/controllers/concerns/.keep +0 -0
- data/spec/dummy/app/helpers/application_helper.rb +0 -2
- data/spec/dummy/app/mailers/.keep +0 -0
- data/spec/dummy/app/metrics/testo_metrics.rb +0 -3
- data/spec/dummy/app/models/.keep +0 -0
- data/spec/dummy/app/models/concerns/.keep +0 -0
- data/spec/dummy/app/models/testo.rb +0 -6
- data/spec/dummy/app/views/layouts/application.html.erb +0 -14
- data/spec/dummy/bin/bundle +0 -3
- data/spec/dummy/bin/rails +0 -4
- data/spec/dummy/bin/rake +0 -4
- data/spec/dummy/config/application.rb +0 -23
- data/spec/dummy/config/boot.rb +0 -5
- data/spec/dummy/config/database.yml +0 -25
- data/spec/dummy/config/environment.rb +0 -5
- data/spec/dummy/config/environments/development.rb +0 -37
- data/spec/dummy/config/environments/production.rb +0 -83
- data/spec/dummy/config/environments/test.rb +0 -38
- data/spec/dummy/config/influxdb.yml +0 -5
- data/spec/dummy/config/initializers/backtrace_silencers.rb +0 -7
- data/spec/dummy/config/initializers/cookies_serializer.rb +0 -3
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +0 -4
- data/spec/dummy/config/initializers/inflections.rb +0 -16
- data/spec/dummy/config/initializers/mime_types.rb +0 -4
- data/spec/dummy/config/initializers/session_store.rb +0 -3
- data/spec/dummy/config/initializers/wrap_parameters.rb +0 -14
- data/spec/dummy/config/locales/en.yml +0 -23
- data/spec/dummy/config/routes.rb +0 -56
- data/spec/dummy/config/secrets.yml +0 -25
- data/spec/dummy/config.ru +0 -4
- data/spec/dummy/db/migrate/20140730133818_add_testos.rb +0 -11
- data/spec/dummy/db/migrate/20140731162044_add_column_to_testos.rb +0 -5
- data/spec/dummy/db/schema.rb +0 -22
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/lib/assets/.keep +0 -0
- data/spec/dummy/log/.keep +0 -0
- data/spec/dummy/public/404.html +0 -67
- data/spec/dummy/public/422.html +0 -67
- data/spec/dummy/public/500.html +0 -66
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/fixtures/fanout_series.json +0 -23
- data/spec/metrics/fanout_spec.rb +0 -61
- data/spec/model/testo_spec.rb +0 -27
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ed8a85c7e2c801bd415689ccfbf4bddf020df2b6
|
4
|
+
data.tar.gz: 9b42fc50e6dec5f287f193e0dbdb26ad983e533f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 11ce8b4eb589f2a701603271b219f9c69004ed3854bc6c00cffb3b34ea7fd67faecfa5596c93af95b33f335c8105e390d2b9d5bf649164a1cf5b293cf3a79f36
|
7
|
+
data.tar.gz: c6711090feeef17151a69282a42d8db28ca4b90115571d17023b44b93453d5a843cd0200d4fa5b586807f86d682146ef77236d6c1665396ac7ce74224a2f1511
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
@@ -11,6 +11,12 @@ AllCops:
|
|
11
11
|
DisplayCopNames: true
|
12
12
|
StyleGuideCopsOnly: false
|
13
13
|
|
14
|
+
Style/AccessorMethodName:
|
15
|
+
Enabled: false
|
16
|
+
|
17
|
+
Style/TrivialAccessors:
|
18
|
+
Enabled: false
|
19
|
+
|
14
20
|
Style/Documentation:
|
15
21
|
Exclude:
|
16
22
|
- 'spec/**/*.rb'
|
@@ -18,10 +24,16 @@ Style/Documentation:
|
|
18
24
|
Style/StringLiterals:
|
19
25
|
Enabled: false
|
20
26
|
|
27
|
+
Style/SpaceInsideStringInterpolation:
|
28
|
+
EnforcedStyle: no_space
|
29
|
+
|
21
30
|
Style/BlockDelimiters:
|
22
31
|
Exclude:
|
23
32
|
- 'spec/**/*.rb'
|
24
33
|
|
34
|
+
Lint/AmbiguousRegexpLiteral:
|
35
|
+
Enabled: false
|
36
|
+
|
25
37
|
Metrics/MethodLength:
|
26
38
|
Exclude:
|
27
39
|
- 'spec/**/*.rb'
|
data/.travis.yml
CHANGED
@@ -1,22 +1,6 @@
|
|
1
1
|
language: ruby
|
2
2
|
cache: bundler
|
3
|
-
rvm:
|
4
|
-
- 2.0.0
|
5
|
-
- 2.1
|
6
|
-
|
7
|
-
gemfile:
|
8
|
-
- Gemfile
|
9
|
-
|
10
3
|
matrix:
|
11
4
|
include:
|
12
|
-
- rvm: 2.
|
13
|
-
gemfile: gemfiles/rails40.gemfile
|
14
|
-
|
15
|
-
- rvm: 2.1
|
16
|
-
gemfile: gemfiles/rails40.gemfile
|
17
|
-
|
18
|
-
- rvm: 2.1
|
19
|
-
gemfile: gemfiles/rails41.gemfile
|
20
|
-
|
21
|
-
- rvm: 2.1
|
5
|
+
- rvm: 2.2.2
|
22
6
|
gemfile: gemfiles/rails42.gemfile
|
data/Changelog.md
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,7 +1,8 @@
|
|
1
|
-
[](https://travis-ci.org/palkan/influxer)
|
2
|
-
|
1
|
+
[](https://travis-ci.org/palkan/influxer) [](https://ci.vexor.io/ui/projects/55e92786-f1de-4e69-8f58-889453c2d71c/builds)
|
3
2
|
## Influxer
|
4
3
|
|
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
|
+
|
5
6
|
Influxer provides an ActiveRecord-style way to work with [InfluxDB](https://influxdb.com/) with many useful features, such as:
|
6
7
|
- Familar query language (use `select`, `where`, `not`, `group` etc).
|
7
8
|
- Support for Regex conditions: `where(page_id: /^home\/.*/) #=> select * ... where page_id=~/^home\/.*/`.
|
@@ -14,6 +15,8 @@ Influxer provides an ActiveRecord-style way to work with [InfluxDB](https://infl
|
|
14
15
|
```ruby
|
15
16
|
class Metrics < Influxer::Metrics
|
16
17
|
default_scope -> { time(:hour).limit(1000) }
|
18
|
+
tags :account_id
|
19
|
+
attributes :value
|
17
20
|
scope :unlimited, -> { limit(nil) }
|
18
21
|
scope :by_account, -> (id) { where(account_id: id) if id.present? }
|
19
22
|
end
|
@@ -25,23 +28,6 @@ Influxer provides an ActiveRecord-style way to work with [InfluxDB](https://infl
|
|
25
28
|
# => select * from "metrics" group by time(1w) where account_id=1
|
26
29
|
|
27
30
|
```
|
28
|
-
- Support for handling fanout series as one metrics.
|
29
|
-
```ruby
|
30
|
-
class Metrics < Influxer::Metrics
|
31
|
-
fanout :account, :user, :page
|
32
|
-
end
|
33
|
-
|
34
|
-
Metrics.where(account: 1)
|
35
|
-
# => select * from "metrics_account_1"
|
36
|
-
|
37
|
-
|
38
|
-
Metrics.where(page: 'home').where(user: 12)
|
39
|
-
# => select * from "metrics_user_12_page_home"
|
40
|
-
|
41
|
-
Metrics.where(page: /(home|faq)/).where(account: 1).where(user: 12)
|
42
|
-
# => select * from /^metrics_account_1_user_12_page_(home|faq)$/
|
43
|
-
|
44
|
-
```
|
45
31
|
- Integrate with your model:
|
46
32
|
```ruby
|
47
33
|
class UserVisits < Influxer::Metrics
|
@@ -59,4 +45,4 @@ Influxer provides an ActiveRecord-style way to work with [InfluxDB](https://infl
|
|
59
45
|
#=> select * from user_visits where page_id='home'
|
60
46
|
```
|
61
47
|
|
62
|
-
Find more on [Wiki](/palkan/influxer/wiki).
|
48
|
+
Find more on [Wiki](https://github.com/palkan/influxer/wiki).
|
data/Rakefile
CHANGED
data/gemfiles/rails42.gemfile
CHANGED
@@ -2,6 +2,9 @@ source 'https://rubygems.org'
|
|
2
2
|
|
3
3
|
gem 'sqlite3', platform: :mri
|
4
4
|
gem 'activerecord-jdbcsqlite3-adapter', platform: :jruby
|
5
|
-
gem '
|
5
|
+
gem 'activerecord', '~> 4.2.0'
|
6
|
+
|
7
|
+
# TEMP
|
8
|
+
gem 'influxdb', github: 'influxdb/influxdb-ruby'
|
6
9
|
|
7
10
|
gemspec path: '..'
|
data/influxer.gemspec
CHANGED
@@ -15,16 +15,16 @@ Gem::Specification.new do |s|
|
|
15
15
|
s.files = `git ls-files`.split($/)
|
16
16
|
s.require_paths = ["lib"]
|
17
17
|
|
18
|
-
s.
|
19
|
-
s.add_dependency "influxdb", "~> 0.
|
20
|
-
s.add_dependency "anyway_config", "~>0.3"
|
18
|
+
s.add_dependency "activemodel", '>= 4.0'
|
19
|
+
s.add_dependency "influxdb", "~> 0.2.2"
|
20
|
+
s.add_dependency "anyway_config", "~>0.3.0"
|
21
21
|
|
22
22
|
s.add_development_dependency "timecop"
|
23
23
|
s.add_development_dependency "simplecov", ">= 0.3.8"
|
24
|
-
|
24
|
+
s.add_development_dependency 'rake', '~> 10.1'
|
25
25
|
s.add_development_dependency 'sqlite3'
|
26
|
-
s.add_development_dependency '
|
26
|
+
s.add_development_dependency 'activerecord', '>= 4.0'
|
27
27
|
s.add_development_dependency 'pry-byebug'
|
28
28
|
s.add_development_dependency "rspec", "~> 3.1.0"
|
29
|
-
s.add_development_dependency "
|
29
|
+
s.add_development_dependency "webmock", "~> 1.21.0"
|
30
30
|
end
|
data/lib/influxer/client.rb
CHANGED
@@ -4,52 +4,12 @@ module Influxer
|
|
4
4
|
# InfluxDB API client
|
5
5
|
class Client < ::InfluxDB::Client
|
6
6
|
def initialize
|
7
|
-
|
8
|
-
super Influxer.config.database, Influxer.config.as_json.symbolize_keys!
|
7
|
+
super Influxer.config.as_json.symbolize_keys!
|
9
8
|
end
|
10
9
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
query(sql)
|
15
|
-
else
|
16
|
-
Rails.cache.fetch(normalized_cache_key(sql), cache_options(sql)) { query(sql) }
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
private
|
22
|
-
|
23
|
-
def log(sql)
|
24
|
-
return yield unless logger.debug?
|
25
|
-
|
26
|
-
start_ts = Time.now
|
27
|
-
res = yield
|
28
|
-
duration = (Time.now - start_ts) * 1000
|
29
|
-
|
30
|
-
name = "InfluxDB SQL (#{duration.round(1)}ms)"
|
31
|
-
|
32
|
-
# bold black name and blue query string
|
33
|
-
msg = "\e[1m\e[30m#{name}\e[0m \e[34m#{sql}\e[0m"
|
34
|
-
logger.debug msg
|
35
|
-
res
|
36
|
-
end
|
37
|
-
|
38
|
-
# if sql contains 'now()' set expires to 1 minute or :cache_now_for value
|
39
|
-
# of config.cache if defined
|
40
|
-
def cache_options(sql = nil)
|
41
|
-
options = Influxer.config.cache.dup
|
42
|
-
options[:expires_in] = (options[:cache_now_for] || 60) if sql =~ /\snow\(\)/
|
43
|
-
options
|
44
|
-
end
|
45
|
-
|
46
|
-
# add prefix; remove whitespaces
|
47
|
-
def normalized_cache_key(sql)
|
48
|
-
"influxer:#{sql.gsub(/\s*/, '')}"
|
49
|
-
end
|
50
|
-
|
51
|
-
def logger
|
52
|
-
Rails.logger
|
10
|
+
# Public #execute
|
11
|
+
def exec(sql)
|
12
|
+
execute(sql)
|
53
13
|
end
|
54
14
|
end
|
55
15
|
end
|
data/lib/influxer/config.rb
CHANGED
@@ -5,20 +5,29 @@ module Influxer
|
|
5
5
|
class Config < Anyway::Config
|
6
6
|
config_name :influxdb
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
8
|
+
# influxdb-ruby configuration parameters + cache option
|
9
|
+
attr_config :hosts,
|
10
|
+
:host,
|
11
|
+
:port,
|
12
|
+
:username,
|
13
|
+
:password,
|
14
|
+
:database,
|
15
|
+
:time_precision,
|
16
|
+
:use_ssl,
|
17
|
+
:verify_ssl,
|
18
|
+
:ssl_ca_cert,
|
19
|
+
:auth_method,
|
20
|
+
:initial_delay,
|
21
|
+
:max_delay,
|
22
|
+
:open_timeout,
|
23
|
+
:read_timeout,
|
24
|
+
:retry,
|
25
|
+
:prefix,
|
26
|
+
:denormalize,
|
27
|
+
:udp,
|
28
|
+
:async,
|
29
|
+
database: 'db',
|
30
|
+
cache: false
|
22
31
|
|
23
32
|
def load
|
24
33
|
super
|
data/lib/influxer/engine.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
require 'influxer/metrics/relation'
|
2
2
|
require 'influxer/metrics/scoping'
|
3
|
-
require 'influxer/metrics/fanout'
|
4
3
|
require 'active_model'
|
5
4
|
|
6
5
|
module Influxer
|
@@ -8,13 +7,13 @@ module Influxer
|
|
8
7
|
class MetricsInvalid < MetricsError; end
|
9
8
|
|
10
9
|
# Base class for InfluxDB querying and writing
|
10
|
+
# rubocop:disable Metrics/ClassLength
|
11
11
|
class Metrics
|
12
12
|
include ActiveModel::Model
|
13
13
|
include ActiveModel::Validations
|
14
14
|
extend ActiveModel::Callbacks
|
15
15
|
|
16
16
|
include Influxer::Scoping
|
17
|
-
include Influxer::Fanout
|
18
17
|
|
19
18
|
define_model_callbacks :write
|
20
19
|
|
@@ -23,15 +22,16 @@ module Influxer
|
|
23
22
|
delegate(
|
24
23
|
*(
|
25
24
|
[
|
26
|
-
:write, :select, :where,
|
27
|
-
:
|
28
|
-
:fill, :delete_all
|
25
|
+
:write, :write!, :select, :where,
|
26
|
+
:group, :time, :past, :since,
|
27
|
+
:limit, :offset, :fill, :delete_all
|
29
28
|
] + Influxer::Calculations::CALCULATION_METHODS
|
30
29
|
),
|
31
30
|
to: :all
|
32
31
|
)
|
33
32
|
|
34
33
|
attr_reader :series
|
34
|
+
attr_accessor :tag_names
|
35
35
|
|
36
36
|
def attributes(*attrs)
|
37
37
|
attrs.each do |name|
|
@@ -45,10 +45,23 @@ module Influxer
|
|
45
45
|
end
|
46
46
|
end
|
47
47
|
|
48
|
+
def tags(*attrs)
|
49
|
+
attributes(*attrs)
|
50
|
+
self.tag_names ||= []
|
51
|
+
self.tag_names += attrs.map(&:to_s)
|
52
|
+
end
|
53
|
+
|
54
|
+
def tag?(name)
|
55
|
+
tag_names.include?(name.to_s)
|
56
|
+
end
|
57
|
+
|
48
58
|
def inherited(subclass)
|
49
59
|
subclass.set_series
|
60
|
+
subclass.tag_names = tag_names.nil? ? [] : tag_names.dup
|
50
61
|
end
|
51
62
|
|
63
|
+
# rubocop:disable Metrics/MethodLength
|
64
|
+
# rubocop:disable Metrics/AbcSize
|
52
65
|
def set_series(*args)
|
53
66
|
if args.empty?
|
54
67
|
matches = to_s.match(/^(.*)Metrics$/)
|
@@ -63,6 +76,8 @@ module Influxer
|
|
63
76
|
@series = args
|
64
77
|
end
|
65
78
|
end
|
79
|
+
# rubocop:enable Metrics/MethodLength
|
80
|
+
# rubocop:enable Metrics/AbcSize
|
66
81
|
|
67
82
|
def all
|
68
83
|
if current_scope
|
@@ -72,6 +87,7 @@ module Influxer
|
|
72
87
|
end
|
73
88
|
end
|
74
89
|
|
90
|
+
# rubocop:disable Metrics/MethodLength
|
75
91
|
def quoted_series(val = @series, instance = nil)
|
76
92
|
case val
|
77
93
|
when Regexp
|
@@ -80,7 +96,7 @@ module Influxer
|
|
80
96
|
quoted_series(val.call(instance))
|
81
97
|
when Array
|
82
98
|
if val.length > 1
|
83
|
-
"merge(#{
|
99
|
+
"merge(#{val.map { |s| quoted_series(s) }.join(',')})"
|
84
100
|
else
|
85
101
|
quoted_series(val.first)
|
86
102
|
end
|
@@ -88,8 +104,11 @@ module Influxer
|
|
88
104
|
'"' + val.to_s.gsub(/\"/) { %q(\") } + '"'
|
89
105
|
end
|
90
106
|
end
|
107
|
+
# rubocop:enable Metrics/MethodLength
|
91
108
|
end
|
92
109
|
|
110
|
+
delegate :tag_names, to: :class
|
111
|
+
|
93
112
|
def initialize(attributes = {})
|
94
113
|
@attributes = {}
|
95
114
|
@persisted = false
|
@@ -113,7 +132,7 @@ module Influxer
|
|
113
132
|
end
|
114
133
|
|
115
134
|
def write_point
|
116
|
-
client.write_point unquote(series),
|
135
|
+
client.write_point unquote(series), values: values, tags: tags
|
117
136
|
@persisted = true
|
118
137
|
end
|
119
138
|
|
@@ -129,6 +148,20 @@ module Influxer
|
|
129
148
|
Influxer.client
|
130
149
|
end
|
131
150
|
|
151
|
+
def dup
|
152
|
+
self.class.new(@attributes)
|
153
|
+
end
|
154
|
+
|
155
|
+
# Returns hash with metrics values
|
156
|
+
def values
|
157
|
+
@attributes.reject { |k, _| tag_names.include?(k.to_s) }
|
158
|
+
end
|
159
|
+
|
160
|
+
# Returns hash with metrics tags
|
161
|
+
def tags
|
162
|
+
@attributes.select { |k, _| tag_names.include?(k.to_s) }
|
163
|
+
end
|
164
|
+
|
132
165
|
attributes :time
|
133
166
|
|
134
167
|
private
|
@@ -4,18 +4,24 @@ module Influxer
|
|
4
4
|
[
|
5
5
|
:count, :min, :max, :mean,
|
6
6
|
:mode, :median, :distinct, :derivative,
|
7
|
-
:stddev, :sum, :first, :last
|
8
|
-
:percentile, :histogram, :top, :bottom
|
7
|
+
:stddev, :sum, :first, :last
|
9
8
|
]
|
10
9
|
|
10
|
+
# rubocop:disable Metrics/LineLength
|
11
11
|
CALCULATION_METHODS.each do |name|
|
12
12
|
class_eval <<-CODE, __FILE__, __LINE__ + 1
|
13
|
-
def #{name}(val,
|
14
|
-
@values[:has_calculations] = true
|
15
|
-
select_values << "#{name}(\#\{val\}\#\{
|
16
|
-
self
|
17
|
-
end
|
13
|
+
def #{name}(val, alias_name = nil) # def count(val)
|
14
|
+
@values[:has_calculations] = true # @values[:has_calculations] = true
|
15
|
+
select_values << "#{name}(\#\{val\})\#\{alias_name ? ' as '+alias_name.to_s : ''\}" # select_values << "count(\#\{val\})"
|
16
|
+
self # self
|
17
|
+
end # end
|
18
18
|
CODE
|
19
19
|
end
|
20
|
+
|
21
|
+
def percentile(name, val, alias_name = nil)
|
22
|
+
@values[:has_calculations] = true
|
23
|
+
select_values << "percentile(#{name},#{val})#{alias_name ? ' as ' + alias_name.to_s : ''}"
|
24
|
+
self
|
25
|
+
end
|
20
26
|
end
|
21
27
|
end
|
@@ -4,11 +4,14 @@ module Influxer
|
|
4
4
|
hour: '1h',
|
5
5
|
minute: '1m',
|
6
6
|
second: '1s',
|
7
|
-
ms: '
|
7
|
+
ms: '1ms',
|
8
|
+
u: '1u',
|
8
9
|
week: '1w',
|
9
10
|
day: '1d',
|
10
11
|
month: '30d'
|
11
|
-
}
|
12
|
+
}.freeze
|
13
|
+
|
14
|
+
FILL_RESERVED = %i(null previous none).freeze
|
12
15
|
|
13
16
|
# Add group value to relation. To be used instead of `group("time(...)").
|
14
17
|
# Accepts symbols and strings.
|
@@ -20,7 +23,6 @@ module Influxer
|
|
20
23
|
#
|
21
24
|
# Metrics.time("4d", fill: 0)
|
22
25
|
# # select * from metrics group by time(4d) fill(0)
|
23
|
-
|
24
26
|
def time(val, options = {})
|
25
27
|
if val.is_a?(Symbol)
|
26
28
|
@values[:time] = TIME_ALIASES[val] || '1' + val.to_s
|
@@ -28,9 +30,7 @@ module Influxer
|
|
28
30
|
@values[:time] = val
|
29
31
|
end
|
30
32
|
|
31
|
-
|
32
|
-
fill((options[:fill] == :null) ? 'null' : options[:fill].to_i)
|
33
|
-
end
|
33
|
+
build_fill(options[:fill])
|
34
34
|
self
|
35
35
|
end
|
36
36
|
|
@@ -45,11 +45,10 @@ module Influxer
|
|
45
45
|
#
|
46
46
|
# Metrics.past(2.days)
|
47
47
|
# # select * from metrics where time > now() - 172800s
|
48
|
-
|
49
48
|
def past(val)
|
50
49
|
case val
|
51
50
|
when Symbol
|
52
|
-
where("time > now() - #{
|
51
|
+
where("time > now() - #{TIME_ALIASES[val] || ('1' + val.to_s)}")
|
53
52
|
when String
|
54
53
|
where("time > now() - #{val}")
|
55
54
|
else
|
@@ -69,5 +68,12 @@ module Influxer
|
|
69
68
|
def since(val)
|
70
69
|
where("time > #{val.to_i}s")
|
71
70
|
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def build_fill(val)
|
75
|
+
return if val.nil?
|
76
|
+
fill(FILL_RESERVED.include?(val) ? val.to_s : val.to_i)
|
77
|
+
end
|
72
78
|
end
|
73
79
|
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module Influxer
|
2
|
+
module WhereClause #:nodoc:
|
3
|
+
# accepts hash or strings conditions
|
4
|
+
def where(*args, **hargs)
|
5
|
+
build_where(args, hargs, false)
|
6
|
+
self
|
7
|
+
end
|
8
|
+
|
9
|
+
def not(*args, **hargs)
|
10
|
+
build_where(args, hargs, true)
|
11
|
+
self
|
12
|
+
end
|
13
|
+
|
14
|
+
protected
|
15
|
+
|
16
|
+
def build_where(args, hargs, negate)
|
17
|
+
case
|
18
|
+
when (args.present? && args[0].is_a?(String))
|
19
|
+
where_values.concat args.map { |str| "(#{str})" }
|
20
|
+
when hargs.present?
|
21
|
+
build_hash_where(hargs, negate)
|
22
|
+
else
|
23
|
+
false
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def build_hash_where(hargs, negate = false)
|
28
|
+
hargs.each do |key, val|
|
29
|
+
where_values << "(#{build_eql(key, val, negate)})"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def build_eql(key, val, negate)
|
34
|
+
case val
|
35
|
+
when Regexp
|
36
|
+
"#{key}#{negate ? '!~' : '=~'}#{val.inspect}"
|
37
|
+
when Array
|
38
|
+
build_in(key, val, negate)
|
39
|
+
when Range
|
40
|
+
build_range(key, val, negate)
|
41
|
+
else
|
42
|
+
"#{key}#{negate ? '<>' : '='}#{quoted(val, key)}"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def build_in(key, arr, negate)
|
47
|
+
buf = []
|
48
|
+
arr.each do |val|
|
49
|
+
buf << build_eql(key, val, negate)
|
50
|
+
end
|
51
|
+
"#{buf.join(negate ? ' and ' : ' or ')}"
|
52
|
+
end
|
53
|
+
|
54
|
+
def build_range(key, val, negate)
|
55
|
+
if negate
|
56
|
+
"#{key}<#{quoted(val.begin)} and #{key}>#{quoted(val.end)}"
|
57
|
+
else
|
58
|
+
"#{key}>#{quoted(val.begin)} and #{key}<#{quoted(val.end)}"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|