Class: Influxer::Relation

Inherits:
Object
  • Object
show all
Includes:
Calculations, TimeQuery, TimestampQuoting, WhereClause
Defined in:
lib/influxer/metrics/relation.rb

Overview

Relation is used to build queries

Constant Summary collapse

SUPPORTED_EPOCH_FORMAT =
%i[h m s ms u ns].freeze
MULTI_VALUE_METHODS =
%i[select where group order].freeze
MULTI_KEY_METHODS =
%i[fanout].freeze
SINGLE_VALUE_METHODS =
%i[fill time limit offset slimit soffset from normalized timezone].freeze
MULTI_VALUE_SIMPLE_METHODS =
%i[select group].freeze
SINGLE_VALUE_SIMPLE_METHODS =
%i[fill limit offset slimit soffset from timezone].freeze

Constants included from TimestampQuoting

TimestampQuoting::DEFAULT_PRECISION, TimestampQuoting::TIME_FACTORS

Constants included from Calculations

Calculations::CALCULATION_METHODS

Constants included from TimeQuery

TimeQuery::FILL_RESERVED, TimeQuery::TIME_ALIASES

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from TimestampQuoting

#factorize_timestamp, #quote_timestamp, #quote_timestamp_for_write, #quote_timestamp_with_suffix

Methods included from Calculations

#percentile

Methods included from TimeQuery

#past, #since, #time

Methods included from WhereClause

#none, #not, #where

Constructor Details

#initialize(klass, params = {}) ⇒ Relation

Initialize new Relation for ‘klass’ (Class) metrics.

Available params:

:attributes - hash of attributes to be included to new Metrics object
and where clause of Relation


83
84
85
86
87
88
# File 'lib/influxer/metrics/relation.rb', line 83

def initialize(klass, params = {})
  @klass = klass
  @instance = klass.new params[:attributes]
  reset
  where(params[:attributes]) if params[:attributes].present?
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method, *args, &block) ⇒ Object (protected)



306
307
308
309
310
# File 'lib/influxer/metrics/relation.rb', line 306

def method_missing(method, *args, &block)
  return super unless @klass.respond_to?(method)

  merge!(scoping { @klass.public_send(method, *args, &block) })
end

Instance Attribute Details

#valuesObject (readonly)

Returns the value of attribute values.



17
18
19
# File 'lib/influxer/metrics/relation.rb', line 17

def values
  @values
end

Instance Method Details

#as_json(options = nil) ⇒ Object



199
200
201
# File 'lib/influxer/metrics/relation.rb', line 199

def as_json(options = nil)
  to_a.as_json(options)
end

#build(params = {}) ⇒ Object Also known as: new



98
99
100
101
102
103
104
# File 'lib/influxer/metrics/relation.rb', line 98

def build(params = {})
  point = @instance.dup
  params.each do |key, val|
    point.send("#{key}=", val) if point.respond_to?(key)
  end
  point
end

#delete_allObject



215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
# File 'lib/influxer/metrics/relation.rb', line 215

def delete_all
  sql = if where_contains_time?
    ["delete"]
  else
    ["drop series"]
  end

  sql << "from #{@instance.series(write: true)}"

  sql << "where #{where_values.join(" and ")}" unless where_values.empty?

  sql = sql.join " "

  @instance.client.query sql
end

#empty?Boolean

Returns:

  • (Boolean)


190
191
192
193
194
195
196
197
# File 'lib/influxer/metrics/relation.rb', line 190

def empty?
  unless loaded?
    # we don't need selects here
    select_values.clear
    limit(1).load
  end
  @records.empty?
end

#epoch(val) ⇒ Object



117
118
119
120
121
122
# File 'lib/influxer/metrics/relation.rb', line 117

def epoch(val)
  return self unless SUPPORTED_EPOCH_FORMAT.include? val

  @values[:epoch] = val
  self
end

#inspectObject



183
184
185
186
187
188
# File 'lib/influxer/metrics/relation.rb', line 183

def inspect
  entries = to_a.take(11).map!(&:inspect)
  entries[10] = "..." if entries.size == 11

  "#<#{self.class.name} [#{entries.join(", ")}]>"
end

#loadObject



203
204
205
206
207
208
209
210
211
212
213
# File 'lib/influxer/metrics/relation.rb', line 203

def load
  @records = get_points(
    @instance.client.query(
      to_sql,
      denormalize: !normalized?,
      epoch: @values[:epoch]
    )
  )
  @loaded = true
  @records
end

#merge!(rel) ⇒ Object

rubocop:disable Metrics/AbcSize rubocop:disable Metrics/MethodLength



241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
# File 'lib/influxer/metrics/relation.rb', line 241

def merge!(rel)
  return self if rel.nil?

  MULTI_VALUE_METHODS.each do |method|
    (@values[method] ||= []).concat(rel.values[method]).uniq! unless rel.values[method].nil?
  end

  MULTI_KEY_METHODS.each do |method|
    (@values[method] ||= {}).merge!(rel.values[method]) unless rel.values[method].nil?
  end

  SINGLE_VALUE_METHODS.each do |method|
    @values[method] = rel.values[method] unless rel.values[method].nil?
  end

  self
end

#normalizedObject



108
109
110
111
# File 'lib/influxer/metrics/relation.rb', line 108

def normalized
  @values[:normalized] = true
  self
end

#normalized?Boolean

Returns:

  • (Boolean)


113
114
115
# File 'lib/influxer/metrics/relation.rb', line 113

def normalized?
  @values[:normalized] == true
end

#order(val) ⇒ Object



131
132
133
134
135
136
137
138
139
# File 'lib/influxer/metrics/relation.rb', line 131

def order(val)
  case val
  when Hash
    val.each { |k, v| order_values << "#{k} #{v}" }
  when String
    order_values << val
  end
  self
end

#scopingObject



231
232
233
234
235
236
237
# File 'lib/influxer/metrics/relation.rb', line 231

def scoping
  previous = @klass.current_scope
  @klass.current_scope = self
  yield
ensure
  @klass.current_scope = previous
end

#timezone(val) ⇒ Object



124
125
126
127
128
129
# File 'lib/influxer/metrics/relation.rb', line 124

def timezone(val)
  return self if val.blank?

  @values[:timezone] = val
  self
end

#to_aObject

rubocop:enable Metrics/AbcSize rubocop:enable Metrics/CyclomaticComplexity rubocop:enable Metrics/MethodLength rubocop:enable Metrics/PerceivedComplexity



177
178
179
180
181
# File 'lib/influxer/metrics/relation.rb', line 177

def to_a
  return @records if loaded?

  load
end

#to_sqlObject

rubocop:disable Metrics/AbcSize rubocop:disable Metrics/CyclomaticComplexity rubocop:disable Metrics/MethodLength rubocop:disable Metrics/PerceivedComplexity



145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
# File 'lib/influxer/metrics/relation.rb', line 145

def to_sql
  sql = ["select"]
  select_values << "*" if select_values.empty?

  sql << select_values.uniq.join(", ")

  sql << "from #{build_series_name}"

  sql << "where #{where_values.join(" and ")}" unless where_values.empty?

  unless group_values.empty? && time_value.nil?
    group_fields = (time_value.nil? ? [] : ["time(" + @values[:time] + ")"]) + group_values
    group_fields.uniq!
    sql << "group by #{group_fields.join(", ")}"
  end

  sql << "fill(#{fill_value})" unless fill_value.nil?

  sql << "order by #{order_values.uniq.join(",")}" unless order_values.empty?

  sql << "limit #{limit_value}" unless limit_value.nil?
  sql << "offset #{offset_value}" unless offset_value.nil?
  sql << "slimit #{slimit_value}" unless slimit_value.nil?
  sql << "soffset #{soffset_value}" unless soffset_value.nil?
  sql << "TZ('#{timezone_value}')" unless timezone_value.blank?
  sql.join " "
end

#write(params = {}) ⇒ Object



90
91
92
# File 'lib/influxer/metrics/relation.rb', line 90

def write(params = {})
  build(params).write
end

#write!(params = {}) ⇒ Object



94
95
96
# File 'lib/influxer/metrics/relation.rb', line 94

def write!(params = {})
  build(params).write!
end