influxer 0.2.4 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
-
[![Build Status](https://travis-ci.org/palkan/influxer.svg?branch=master)](https://travis-ci.org/palkan/influxer)
|
2
|
-
|
1
|
+
[![Build Status](https://travis-ci.org/palkan/influxer.svg?branch=master)](https://travis-ci.org/palkan/influxer) [![Vexor Status](https://ci.vexor.io/projects/55e92786-f1de-4e69-8f58-889453c2d71c/status.svg)](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
|