Class: Aliyun::Log::Record::Relation

Inherits:
Object
  • Object
show all
Defined in:
lib/aliyun/log/record/relation.rb

Instance Method Summary collapse

Constructor Details

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

Returns a new instance of Relation.



7
8
9
10
11
# File 'lib/aliyun/log/record/relation.rb', line 7

def initialize(klass, opts = {})
  @klass = klass
  @opts = opts
  @klass.auto_load_schema
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

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



356
357
358
359
360
361
362
# File 'lib/aliyun/log/record/relation.rb', line 356

def method_missing(method, *args, &block)
  if @klass.respond_to?(method)
    scoping { @klass.public_send(method, *args, &block) }
  else
    super
  end
end

Instance Method Details

#api(opts) ⇒ Object



104
105
106
107
# File 'lib/aliyun/log/record/relation.rb', line 104

def api(opts)
  @opts.merge!(opts)
  self
end

#countObject



164
165
166
167
168
169
170
171
172
173
174
175
176
177
# File 'lib/aliyun/log/record/relation.rb', line 164

def count
  query = @opts.dup
  if query[:select].blank?
    @opts[:select] = 'COUNT(*) as count'
    sql = to_sql
  else
    _sql = to_sql
    sql = "SELECT COUNT(*) as count"
    sql += " FROM(#{_sql})" if _sql.present?
  end
  query[:query] = "#{query[:search] || '*'}|#{sql}"
  res = execute(query)
  res.dig(0, 'count').to_i
end

#fifthObject



33
34
35
# File 'lib/aliyun/log/record/relation.rb', line 33

def fifth
  find_offset(4)
end

#find_offset(nth, line = 1, reverse = false) ⇒ Object



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/aliyun/log/record/relation.rb', line 42

def find_offset(nth, line = 1, reverse = false)
  # @opts[:select] = '*'
  @opts[:line] = line
  @opts[:offset] = nth
  if @opts[:order].present? && reverse
    conds = []
    @opts[:order].split(',').each do |field|
      field.gsub!(/\s+desc|asc.*/i, '')
      conds << "#{field.strip} DESC"
    end
    @opts[:order] = conds.join(', ')
  end
  @opts[:order] ||= reverse ? '__time__ DESC' : '__time__ ASC'
  if @opts[:select].blank?
    line <= 1 ? load[0] : load
  else
    line <= 1 ? result[0] : result
  end
end

#first(line = 1) ⇒ Object



17
18
19
# File 'lib/aliyun/log/record/relation.rb', line 17

def first(line = 1)
  find_offset(0, line, false)
end

#fourthObject



29
30
31
# File 'lib/aliyun/log/record/relation.rb', line 29

def fourth
  find_offset(3)
end

#from(from) ⇒ Object



70
71
72
73
74
# File 'lib/aliyun/log/record/relation.rb', line 70

def from(from)
  ts = from.is_a?(Integer) ? from : from.to_time.to_i
  @opts[:from] = ts
  self
end

#group(*fields) ⇒ Object



140
141
142
143
# File 'lib/aliyun/log/record/relation.rb', line 140

def group(*fields)
  @opts[:group] = fields.join(', ')
  self
end

#inspectObject



13
14
15
# File 'lib/aliyun/log/record/relation.rb', line 13

def inspect
  "#<#{self.class}>"
end

#last(line = 1) ⇒ Object



37
38
39
40
# File 'lib/aliyun/log/record/relation.rb', line 37

def last(line = 1)
  data = find_offset(0, line, true)
  line > 1 ? data.reverse : data
end

#line(val) ⇒ Object Also known as: limit



82
83
84
85
# File 'lib/aliyun/log/record/relation.rb', line 82

def line(val)
  @opts[:line] = val.to_i
  self
end

#loadObject



200
201
202
203
204
205
206
207
208
# File 'lib/aliyun/log/record/relation.rb', line 200

def load
  result.map do |json_attr|
    record = @klass.new
    json_attr.each do |key, value|
      record.send("#{key}=", value) if record.respond_to?("#{key}=")
    end
    record
  end
end

#offset(val) ⇒ Object



88
89
90
91
# File 'lib/aliyun/log/record/relation.rb', line 88

def offset(val)
  @opts[:offset] = val.to_i
  self
end

#order(*fields) ⇒ Object



145
146
147
148
149
150
151
152
153
154
155
156
157
# File 'lib/aliyun/log/record/relation.rb', line 145

def order(*fields)
  if fields[0].is_a?(Hash)
    @opts[:order] = fields[0].map do |k, v|
      unless %w[asc desc].include?(v.to_s)
        raise ArgumentError, "Direction \"#{v}\" is invalid. Valid directions are: [:asc, :desc, :ASC, :DESC]" 
      end
      "#{k} #{v}"
    end.join(', ')
  else
    @opts[:order] = fields.join(', ')
  end
  self
end

#page(val) ⇒ Object



93
94
95
96
97
98
99
100
101
102
# File 'lib/aliyun/log/record/relation.rb', line 93

def page(val)
  @opts[:page] = val - 1 if val >= 1
  singleton_class.send(:define_method, :total_count) do
    @total_count ||= count
  end
  singleton_class.send(:define_method, :total_pages) do
    (total_count.to_f / (@opts[:line] || 100)).ceil
  end
  self
end

#query(opts = {}) ⇒ Object



159
160
161
162
# File 'lib/aliyun/log/record/relation.rb', line 159

def query(opts = {})
  @opts[:query] = opts
  self
end

#resultObject



187
188
189
190
191
192
193
194
195
196
197
198
# File 'lib/aliyun/log/record/relation.rb', line 187

def result
  query = @opts.dup
  query[:query] = query[:search] || '*'
  sql = to_sql
  if sql.present?
    query[:query] += "|#{sql}"
    @opts[:line] = nil
    @opts[:offset] = nil
    @opts[:page] = nil
  end
  execute(query)
end

#scopingObject



62
63
64
65
66
67
68
# File 'lib/aliyun/log/record/relation.rb', line 62

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

#search(*statement) ⇒ Object



109
110
111
112
113
# File 'lib/aliyun/log/record/relation.rb', line 109

def search(*statement)
  ql = statement_ql(*statement)
  @opts[:search] = ql if ql.present?
  self
end

#secondObject



21
22
23
# File 'lib/aliyun/log/record/relation.rb', line 21

def second
  find_offset(1)
end

#select(*fields) ⇒ Object



135
136
137
138
# File 'lib/aliyun/log/record/relation.rb', line 135

def select(*fields)
  @opts[:select] = fields.join(', ')
  self
end

#sql(*statement) ⇒ Object



115
116
117
118
119
120
121
122
# File 'lib/aliyun/log/record/relation.rb', line 115

def sql(*statement)
  unless statement[0].is_a?(String)
    raise ParseStatementInvalid, 'Only support string statement'
  end
  ql = sanitize_array(*statement)
  @opts[:sql] = ql if ql.present?
  self
end

#sum(field) ⇒ Object



179
180
181
182
183
184
185
# File 'lib/aliyun/log/record/relation.rb', line 179

def sum(field)
  @opts[:select] = "SUM(#{field}) as sum"
  query = @opts.dup
  query[:query] = "#{query[:search] || '*'}|#{to_sql}"
  res = execute(query)
  res.dig(0, 'sum').to_f
end

#thirdObject



25
26
27
# File 'lib/aliyun/log/record/relation.rb', line 25

def third
  find_offset(2)
end

#to(to) ⇒ Object



76
77
78
79
80
# File 'lib/aliyun/log/record/relation.rb', line 76

def to(to)
  ts = to.is_a?(Integer) ? to : to.to_time.to_i
  @opts[:to] = ts
  self
end

#to_sqlObject



210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
# File 'lib/aliyun/log/record/relation.rb', line 210

def to_sql
  return @opts[:sql] if @opts[:sql].present?
  opts = @opts.dup
  sql_query = []
  sql_query << "WHERE #{opts[:where]}" if opts[:where].present?
  sql_query << "GROUP BY #{opts[:group]}" if opts[:group].present?
  sql_query << "ORDER BY #{opts[:order]}" if opts[:order].present?
  if sql_query.present? || opts[:select].present?
    sql_query.insert(0, "SELECT #{opts[:select] || '*'}")
    sql_query.insert(1, 'FROM log') unless opts[:select]&.match?(/from\s+log/i)
    if opts[:line] || opts[:page] || opts[:offset]
      parse_page
      sql_query << "LIMIT #{@opts[:offset]},#{@opts[:line]}"
    end
  end
  "#{opts[:query]}#{sql_query.join(' ')}"
end

#where(*statement) ⇒ Object



124
125
126
127
128
129
130
131
132
133
# File 'lib/aliyun/log/record/relation.rb', line 124

def where(*statement)
  if statement[0].is_a?(String)
    ql = sanitize_array(*statement)
    @opts[:where] = ql
  else
    ql = statement_ql(*statement)
    @opts[:search] = ql
  end
  self
end