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.
Files changed (95) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.rubocop.yml +12 -0
  4. data/.travis.yml +1 -17
  5. data/Changelog.md +7 -0
  6. data/Gemfile +7 -0
  7. data/README.md +6 -20
  8. data/Rakefile +4 -0
  9. data/gemfiles/rails42.gemfile +4 -1
  10. data/influxer.gemspec +6 -6
  11. data/lib/influxer/client.rb +4 -44
  12. data/lib/influxer/config.rb +23 -14
  13. data/lib/influxer/engine.rb +0 -1
  14. data/lib/influxer/metrics/metrics.rb +40 -7
  15. data/lib/influxer/metrics/relation/calculations.rb +13 -7
  16. data/lib/influxer/metrics/relation/time_query.rb +14 -8
  17. data/lib/influxer/metrics/relation/where_clause.rb +62 -0
  18. data/lib/influxer/metrics/relation.rb +67 -76
  19. data/lib/influxer/metrics/scoping.rb +4 -4
  20. data/lib/influxer/model.rb +4 -0
  21. data/lib/influxer/rails/client.rb +47 -0
  22. data/lib/influxer/version.rb +1 -1
  23. data/lib/influxer.rb +4 -2
  24. data/spec/cases/points_spec.rb +34 -0
  25. data/spec/client_spec.rb +21 -24
  26. data/spec/fixtures/empty_result.json +21 -0
  27. data/spec/fixtures/single_series.json +29 -0
  28. data/spec/metrics/metrics_spec.rb +139 -113
  29. data/spec/metrics/relation_spec.rb +160 -105
  30. data/spec/metrics/scoping_spec.rb +11 -17
  31. data/spec/model/user_spec.rb +44 -0
  32. data/spec/spec_helper.rb +38 -8
  33. data/spec/support/metrics/action_metrics.rb +3 -0
  34. data/spec/support/metrics/custom_metrics.rb +4 -0
  35. data/spec/support/{dummy_metrics.rb → metrics/dummy_metrics.rb} +2 -1
  36. data/spec/support/metrics/user_metrics.rb +4 -0
  37. data/spec/support/metrics/visits_metrics.rb +4 -0
  38. data/spec/support/shared_contexts/shared_query.rb +16 -0
  39. data/spec/support/user.rb +14 -0
  40. metadata +42 -71
  41. data/gemfiles/rails40.gemfile +0 -7
  42. data/gemfiles/rails41.gemfile +0 -7
  43. data/lib/influxer/metrics/fanout.rb +0 -65
  44. data/lib/influxer/metrics/relation/fanout_query.rb +0 -49
  45. data/lib/tasks/influxer_tasks.rake +0 -4
  46. data/spec/config_spec.rb +0 -17
  47. data/spec/dummy/README.rdoc +0 -28
  48. data/spec/dummy/Rakefile +0 -6
  49. data/spec/dummy/app/assets/images/.keep +0 -0
  50. data/spec/dummy/app/assets/javascripts/application.js +0 -13
  51. data/spec/dummy/app/assets/stylesheets/application.css +0 -15
  52. data/spec/dummy/app/controllers/application_controller.rb +0 -5
  53. data/spec/dummy/app/controllers/concerns/.keep +0 -0
  54. data/spec/dummy/app/helpers/application_helper.rb +0 -2
  55. data/spec/dummy/app/mailers/.keep +0 -0
  56. data/spec/dummy/app/metrics/testo_metrics.rb +0 -3
  57. data/spec/dummy/app/models/.keep +0 -0
  58. data/spec/dummy/app/models/concerns/.keep +0 -0
  59. data/spec/dummy/app/models/testo.rb +0 -6
  60. data/spec/dummy/app/views/layouts/application.html.erb +0 -14
  61. data/spec/dummy/bin/bundle +0 -3
  62. data/spec/dummy/bin/rails +0 -4
  63. data/spec/dummy/bin/rake +0 -4
  64. data/spec/dummy/config/application.rb +0 -23
  65. data/spec/dummy/config/boot.rb +0 -5
  66. data/spec/dummy/config/database.yml +0 -25
  67. data/spec/dummy/config/environment.rb +0 -5
  68. data/spec/dummy/config/environments/development.rb +0 -37
  69. data/spec/dummy/config/environments/production.rb +0 -83
  70. data/spec/dummy/config/environments/test.rb +0 -38
  71. data/spec/dummy/config/influxdb.yml +0 -5
  72. data/spec/dummy/config/initializers/backtrace_silencers.rb +0 -7
  73. data/spec/dummy/config/initializers/cookies_serializer.rb +0 -3
  74. data/spec/dummy/config/initializers/filter_parameter_logging.rb +0 -4
  75. data/spec/dummy/config/initializers/inflections.rb +0 -16
  76. data/spec/dummy/config/initializers/mime_types.rb +0 -4
  77. data/spec/dummy/config/initializers/session_store.rb +0 -3
  78. data/spec/dummy/config/initializers/wrap_parameters.rb +0 -14
  79. data/spec/dummy/config/locales/en.yml +0 -23
  80. data/spec/dummy/config/routes.rb +0 -56
  81. data/spec/dummy/config/secrets.yml +0 -25
  82. data/spec/dummy/config.ru +0 -4
  83. data/spec/dummy/db/migrate/20140730133818_add_testos.rb +0 -11
  84. data/spec/dummy/db/migrate/20140731162044_add_column_to_testos.rb +0 -5
  85. data/spec/dummy/db/schema.rb +0 -22
  86. data/spec/dummy/db/test.sqlite3 +0 -0
  87. data/spec/dummy/lib/assets/.keep +0 -0
  88. data/spec/dummy/log/.keep +0 -0
  89. data/spec/dummy/public/404.html +0 -67
  90. data/spec/dummy/public/422.html +0 -67
  91. data/spec/dummy/public/500.html +0 -66
  92. data/spec/dummy/public/favicon.ico +0 -0
  93. data/spec/fixtures/fanout_series.json +0 -23
  94. data/spec/metrics/fanout_spec.rb +0 -61
  95. data/spec/model/testo_spec.rb +0 -27
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a70e770a10a4ba180183d675081265ed34c96a18
4
- data.tar.gz: ce6d3d39937bc7eeabc4b4076bb9095e6b9eac59
3
+ metadata.gz: ed8a85c7e2c801bd415689ccfbf4bddf020df2b6
4
+ data.tar.gz: 9b42fc50e6dec5f287f193e0dbdb26ad983e533f
5
5
  SHA512:
6
- metadata.gz: 23a20e2f8130fa8ad58c1ad961afd71f8bfa3a55ed744dc999857c6dd505b69ddcfa659cc2a885175a6e21005f836e1ee1f6d01850e9fbf898234e8ff6108562
7
- data.tar.gz: 0373880b57e571673420d63297b81d4ffd8af6dee289adb2c9ccc8332447e736b841c92a0b2f6b11ec04e72ddd066a7ede9742d545706d1607d0a6891e3037b4
6
+ metadata.gz: 11ce8b4eb589f2a701603271b219f9c69004ed3854bc6c00cffb3b34ea7fd67faecfa5596c93af95b33f335c8105e390d2b9d5bf649164a1cf5b293cf3a79f36
7
+ data.tar.gz: c6711090feeef17151a69282a42d8db28ca4b90115571d17023b44b93453d5a843cd0200d4fa5b586807f86d682146ef77236d6c1665396ac7ce74224a2f1511
data/.gitignore CHANGED
@@ -32,5 +32,6 @@ spec/dummy/db/*.sqlite3-journal
32
32
  spec/dummy/tmp/
33
33
 
34
34
  Gemfile.lock
35
+ Gemfile.local
35
36
  .rspec
36
37
  *.gem
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.0.0
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
@@ -1,3 +1,10 @@
1
+ ## 0.3.1
2
+ - Add order, soffset, slimit methods to Relation
3
+ - Fix query statements order
4
+
5
+ ## 0.3.0
6
+ - Upgrade to InfluxDB 0.9.x
7
+
1
8
  ## 0.2.3
2
9
  - Parse fanout queries points to handle _fanouted_ values
3
10
  - Add Rubocop config and cleanup code style
data/Gemfile CHANGED
@@ -1,3 +1,10 @@
1
1
  source "https://rubygems.org"
2
2
  gemspec
3
3
 
4
+ local_gemfile = 'Gemfile.local'
5
+
6
+ if File.exist?(local_gemfile)
7
+ eval(File.read(local_gemfile)) # rubocop:disable Lint/Eval
8
+ else
9
+ gem 'activerecord', '~>4.2'
10
+ end
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
@@ -4,3 +4,7 @@ require 'rspec/core/rake_task'
4
4
  RSpec::Core::RakeTask.new(:spec)
5
5
 
6
6
  task :default => :spec
7
+
8
+ task :console do
9
+ sh 'pry -r ./lib/influxer.rb'
10
+ end
@@ -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 'rails', '~> 4.2.0'
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.add_runtime_dependency "rails", '~> 4.0'
19
- s.add_dependency "influxdb", "~> 0.1.8"
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 'pry'
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 "rspec-rails", "~> 3.1.0"
29
+ s.add_development_dependency "webmock", "~> 1.21.0"
30
30
  end
@@ -4,52 +4,12 @@ module Influxer
4
4
  # InfluxDB API client
5
5
  class Client < ::InfluxDB::Client
6
6
  def initialize
7
- @instrumenter = ActiveSupport::Notifications.instrumenter
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
- def cached_query(sql)
12
- log(sql) do
13
- if Influxer.config.cache == false
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
@@ -5,20 +5,29 @@ module Influxer
5
5
  class Config < Anyway::Config
6
6
  config_name :influxdb
7
7
 
8
- attr_config database: 'db',
9
- host: 'localhost',
10
- port: 8086,
11
- username: 'root',
12
- password: 'root',
13
- use_ssl: false,
14
- async: true,
15
- cache: false,
16
- retry: false,
17
- time_precision: 's',
18
- initial_delay: 0.01,
19
- max_delay: 30,
20
- read_timeout: 30,
21
- write_timeout: 5
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
@@ -1,5 +1,4 @@
1
1
  require 'influxer'
2
- require 'rails'
3
2
 
4
3
  module Influxer
5
4
  class Engine < Rails::Engine # :nodoc:
@@ -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, :group,
27
- :merge, :time, :past, :since, :limit,
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(#{ val.map { |s| quoted_series(s) }.join(',') })"
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), @attributes
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, :difference,
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, option=nil) # def count(val)
14
- @values[:has_calculations] = true # @values[:has_calculations] = true
15
- select_values << "#{name}(\#\{val\}\#\{option ? ','+option.to_s : ''\})" # select_values << "count(\#\{val\})"
16
- self # self
17
- end # 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: '1u',
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
- unless options[:fill].nil?
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() - #{ TIME_ALIASES[val] || ('1'+val.to_s) }")
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