Class: MudisQL::Scope

Inherits:
Object
  • Object
show all
Defined in:
lib/mudis-ql/scope.rb

Overview

Scope provides a chainable DSL for querying mudis cache data

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(store) ⇒ Scope

Returns a new instance of Scope.



8
9
10
11
12
13
14
15
# File 'lib/mudis-ql/scope.rb', line 8

def initialize(store)
  @store = store
  @conditions = []
  @order_by = nil
  @order_direction = :asc
  @limit_value = nil
  @offset_value = 0
end

Instance Attribute Details

#storeObject (readonly)

Returns the value of attribute store.



6
7
8
# File 'lib/mudis-ql/scope.rb', line 6

def store
  @store
end

Instance Method Details

#allArray<Hash>

Execute the query and return all matching records

Returns:

  • (Array<Hash>)

    array of matching records



80
81
82
83
84
85
# File 'lib/mudis-ql/scope.rb', line 80

def all
  results = store.all
  results = apply_conditions(results)
  results = apply_order(results)
  apply_pagination(results)
end

#average(field) ⇒ Float

Calculate average of numeric values for a field across matching records

Parameters:

  • field (Symbol, String)

    the field to average

Returns:

  • (Float)

    average of numeric values, 0.0 if no records



131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/mudis-ql/scope.rb', line 131

def average(field)
  field_str = field.to_s
  results = apply_conditions(store.all)
  return 0.0 if results.empty?

  total = results.sum do |record|
    value = record[field_str]
    value.is_a?(Numeric) ? value : 0
  end

  (total.to_f / results.size).round(2)
end

#cloneObject

Create a new independent scope instance



18
19
20
21
22
23
24
25
26
# File 'lib/mudis-ql/scope.rb', line 18

def clone
  cloned = self.class.new(@store)
  cloned.instance_variable_set(:@conditions, @conditions.dup)
  cloned.instance_variable_set(:@order_by, @order_by)
  cloned.instance_variable_set(:@order_direction, @order_direction)
  cloned.instance_variable_set(:@limit_value, @limit_value)
  cloned.instance_variable_set(:@offset_value, @offset_value)
  cloned
end

#countInteger

Count matching records

Returns:

  • (Integer)

    number of matching records



104
105
106
# File 'lib/mudis-ql/scope.rb', line 104

def count
  apply_conditions(store.all).size
end

#exists?Boolean

Check if any records match

Returns:

  • (Boolean)

    true if at least one record matches



111
112
113
# File 'lib/mudis-ql/scope.rb', line 111

def exists?
  count.positive?
end

#firstHash?

Execute query and return first result

Returns:

  • (Hash, nil)

    first matching record or nil



90
91
92
# File 'lib/mudis-ql/scope.rb', line 90

def first
  clone.limit(1).all.first
end

#group_by(field) ⇒ Hash

Group matching records by the value of a field

Parameters:

  • field (Symbol, String)

    the field to group by

Returns:

  • (Hash)

    hash of field_value => array of records



148
149
150
151
152
153
154
155
# File 'lib/mudis-ql/scope.rb', line 148

def group_by(field)
  field_str = field.to_s
  filtered = apply_conditions(store.all)

  filtered.group_by do |record|
    record[field_str]
  end
end

#lastHash?

Execute query and return last result

Returns:

  • (Hash, nil)

    last matching record or nil



97
98
99
# File 'lib/mudis-ql/scope.rb', line 97

def last
  all.last
end

#limit(value) ⇒ Scope

Limit the number of results

Parameters:

  • value (Integer)

    maximum number of results

Returns:

  • (Scope)

    self for chaining



61
62
63
64
65
# File 'lib/mudis-ql/scope.rb', line 61

def limit(value)
  cloned = clone
  cloned.instance_variable_set(:@limit_value, value)
  cloned
end

#offset(value) ⇒ Scope

Skip the first N results

Parameters:

  • value (Integer)

    number of results to skip

Returns:

  • (Scope)

    self for chaining



71
72
73
74
75
# File 'lib/mudis-ql/scope.rb', line 71

def offset(value)
  cloned = clone
  cloned.instance_variable_set(:@offset_value, value)
  cloned
end

#order(field, direction = :asc) ⇒ Scope

Order results by a field

Parameters:

  • field (Symbol, String)

    the field to order by

  • direction (Symbol) (defaults to: :asc)

    :asc or :desc

Returns:

  • (Scope)

    self for chaining



50
51
52
53
54
55
# File 'lib/mudis-ql/scope.rb', line 50

def order(field, direction = :asc)
  cloned = clone
  cloned.instance_variable_set(:@order_by, field.to_s)
  cloned.instance_variable_set(:@order_direction, direction)
  cloned
end

#pluck(*fields) ⇒ Array

Pluck specific fields from results

Parameters:

  • fields (Array<Symbol, String>)

    fields to extract

Returns:

  • (Array)

    array of field values or arrays of values



161
162
163
164
165
166
167
168
169
170
# File 'lib/mudis-ql/scope.rb', line 161

def pluck(*fields)
  fields = fields.map(&:to_s)
  results = all

  if fields.size == 1
    results.map { |record| record[fields.first] }
  else
    results.map { |record| fields.map { |f| record[f] } }
  end
end

#sum(field) ⇒ Integer, Float

Sum numeric values of a field across matching records

Parameters:

  • field (Symbol, String)

    the field to sum

Returns:

  • (Integer, Float)

    sum of numeric values, 0 if none found



119
120
121
122
123
124
125
# File 'lib/mudis-ql/scope.rb', line 119

def sum(field)
  field_str = field.to_s
  apply_conditions(store.all).sum do |record|
    value = record[field_str]
    value.is_a?(Numeric) ? value : 0
  end
end

#where(conditions) ⇒ Scope

Filter records by conditions

Examples:

query.where(status: "active")
query.where(age: ->(v) { v > 18 })
query.where(name: /^A/)

Parameters:

  • conditions (Hash)

    hash of field => value or field => proc

Returns:

  • (Scope)

    self for chaining



37
38
39
40
41
42
43
# File 'lib/mudis-ql/scope.rb', line 37

def where(conditions)
  cloned = clone
  cloned_conditions = cloned.instance_variable_get(:@conditions).dup
  cloned_conditions << conditions
  cloned.instance_variable_set(:@conditions, cloned_conditions)
  cloned
end