Class: Quo::Query

Inherits:
Object
  • Object
show all
Extended by:
Utilities::Compose, Utilities::Sanitize, Utilities::Wrap
Includes:
Utilities::Callstack
Defined in:
lib/quo/query.rb

Direct Known Subclasses

EagerQuery, MergedQuery, WrappedQuery

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Utilities::Compose

composable_with?

Methods included from Utilities::Sanitize

sanitize_sql_for_conditions, sanitize_sql_parameter, sanitize_sql_string

Methods included from Utilities::Wrap

wrap

Methods included from Utilities::Callstack

#debug_callstack

Constructor Details

#initialize(**options) ⇒ Query

Returns a new instance of Query.



28
29
30
31
32
# File 'lib/quo/query.rb', line 28

def initialize(**options)
  @options = options
  @current_page = options[:page]&.to_i || options[:current_page]&.to_i
  @page_size = options[:page_size]&.to_i || Quo.configuration.default_page_size || 20
end

Instance Attribute Details

#current_pageObject (readonly)

Returns the value of attribute current_page.



26
27
28
# File 'lib/quo/query.rb', line 26

def current_page
  @current_page
end

#optionsObject (readonly)

Returns the value of attribute options.



26
27
28
# File 'lib/quo/query.rb', line 26

def options
  @options
end

#page_sizeObject (readonly)

Returns the value of attribute page_size.



26
27
28
# File 'lib/quo/query.rb', line 26

def page_size
  @page_size
end

Class Method Details

.call(**options) ⇒ Object



17
18
19
# File 'lib/quo/query.rb', line 17

def call(**options)
  new(**options).first
end

.call!(**options) ⇒ Object



21
22
23
# File 'lib/quo/query.rb', line 21

def call!(**options)
  new(**options).first!
end

Instance Method Details

#compose(right, joins: nil) ⇒ Object Also known as: +

Combine (compose) this query object with another composeable entity, see notes for ‘.compose` above. Compose is aliased as `+`. Can optionally take `joins()` parameters to perform a joins before the merge



41
42
43
# File 'lib/quo/query.rb', line 41

def compose(right, joins: nil)
  Quo::QueryComposer.new(self, right, joins).compose
end

#copy(**options) ⇒ Object



47
48
49
# File 'lib/quo/query.rb', line 47

def copy(**options)
  self.class.new(**@options.merge(options))
end

#eager?Boolean

Is this query object eager loaded data under the hood? (ie not a relation)

Returns:

  • (Boolean)


186
187
188
# File 'lib/quo/query.rb', line 186

def eager?
  test_eager(configured_query)
end

#exists?Boolean

Are there any results for this query?

Returns:

  • (Boolean)


169
170
171
172
# File 'lib/quo/query.rb', line 169

def exists?
  return query_with_logging.exists? if relation?
  query_with_logging.present?
end

#first(limit = nil) ⇒ Object

Get first elements



96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/quo/query.rb', line 96

def first(limit = nil)
  if transform?
    res = query_with_logging.first(limit)
    if res.is_a? Array
      res.map.with_index { |r, i| transformer&.call(r, i) }
    elsif !res.nil?
      transformer&.call(query_with_logging.first(limit))
    end
  elsif limit
    query_with_logging.first(limit)
  else
    # Array#first will not take nil as a limit
    query_with_logging.first
  end
end

#first!(limit = nil) ⇒ Object

Raises:

  • (ActiveRecord::RecordNotFound)


112
113
114
115
116
# File 'lib/quo/query.rb', line 112

def first!(limit = nil)
  item = first(limit)
  raise ActiveRecord::RecordNotFound, "No item could be found!" unless item
  item
end

#group(*options) ⇒ Object



60
61
62
# File 'lib/quo/query.rb', line 60

def group(*options)
  copy(group: options)
end

#includes(*options) ⇒ Object



64
65
66
# File 'lib/quo/query.rb', line 64

def includes(*options)
  copy(includes: options)
end

#last(limit = nil) ⇒ Object

Get last elements



119
120
121
122
123
124
125
126
127
128
129
130
131
132
# File 'lib/quo/query.rb', line 119

def last(limit = nil)
  if transform?
    res = query_with_logging.last(limit)
    if res.is_a? Array
      res.map.with_index { |r, i| transformer&.call(r, i) }
    elsif !res.nil?
      transformer&.call(res)
    end
  elsif limit
    query_with_logging.last(limit)
  else
    query_with_logging.last
  end
end

#limit(limit) ⇒ Object

Methods to prepare the query



52
53
54
# File 'lib/quo/query.rb', line 52

def limit(limit)
  copy(limit: limit)
end

#none?Boolean Also known as: empty?

Are there no results for this query?

Returns:

  • (Boolean)


175
176
177
# File 'lib/quo/query.rb', line 175

def none?
  !exists?
end

#order(options) ⇒ Object



56
57
58
# File 'lib/quo/query.rb', line 56

def order(options)
  copy(order: options)
end

#page_countObject

Gets the actual count of elements in the page of results (assuming paging is being used, otherwise the count of all results)



88
89
90
# File 'lib/quo/query.rb', line 88

def page_count
  query_with_logging.count
end

#paged?Boolean

Is this query object paged? (ie is paging enabled)

Returns:

  • (Boolean)


191
192
193
# File 'lib/quo/query.rb', line 191

def paged?
  current_page.present?
end

#preload(*options) ⇒ Object



68
69
70
# File 'lib/quo/query.rb', line 68

def preload(*options)
  copy(preload: options)
end

#queryObject

Returns a active record query, or a Quo::Query instance

Raises:

  • (NotImplementedError)


35
36
37
# File 'lib/quo/query.rb', line 35

def query
  raise NotImplementedError, "Query objects must define a 'query' method"
end

#relation?Boolean

Is this query object a relation under the hood? (ie not eager loaded)

Returns:

  • (Boolean)


181
182
183
# File 'lib/quo/query.rb', line 181

def relation?
  test_relation(configured_query)
end

#resultsObject



145
146
147
# File 'lib/quo/query.rb', line 145

def results
  Quo::Results.new(self, transformer: transformer)
end

#select(*options) ⇒ Object



72
73
74
# File 'lib/quo/query.rb', line 72

def select(*options)
  copy(select: options)
end

#to_aObject

Convert to array



135
136
137
138
# File 'lib/quo/query.rb', line 135

def to_a
  arr = query_with_logging.to_a
  transform? ? arr.map.with_index { |r, i| transformer&.call(r, i) } : arr
end

#to_eager(more_opts = {}) ⇒ Object Also known as: load



140
141
142
# File 'lib/quo/query.rb', line 140

def to_eager(more_opts = {})
  Quo::LoadedQuery.new(to_a, **options.merge(more_opts))
end

#to_sqlObject

Return the SQL string for this query if its a relation type query object



201
202
203
# File 'lib/quo/query.rb', line 201

def to_sql
  configured_query.to_sql if relation?
end

#transform(&block) ⇒ Object

Set a block used to transform data after query fetching



163
164
165
166
# File 'lib/quo/query.rb', line 163

def transform(&block)
  @options[:__transformer] = block
  self
end

#transform?Boolean

Is this query object transforming results?

Returns:

  • (Boolean)


196
197
198
# File 'lib/quo/query.rb', line 196

def transform?
  transformer.present?
end

#unwrapObject

Unwrap the paginated query



206
207
208
# File 'lib/quo/query.rb', line 206

def unwrap
  configured_query
end

#unwrap_unpaginatedObject

Unwrap the un-paginated query



211
212
213
# File 'lib/quo/query.rb', line 211

def unwrap_unpaginated
  underlying_query
end