Class: Queries::Query

Inherits:
Object
  • Object
show all
Includes:
Arel::Nodes
Defined in:
lib/queries/query.rb

Direct Known Subclasses

BiologicalRelationship::Autocomplete, ControlledVocabularyTerm::Autocomplete, Descriptor::Autocomplete, Otu::Autocomplete, Otu::Filter, BiologicalCollectionObjectAutocompleteQuery, CollectingEvent::Autocomplete, CollectionObjectFilterQuery, ContainerAutocompleteQuery, DocumentAutocompleteQuery, GeographicAreaAutocompleteQuery, NamespaceAutocompleteQuery, Person::Autocomplete, RepositoryAutocompleteQuery, Serial::Autocomplete, Source::Autocomplete, Source::Filter, TagAutocompleteQuery, TaxonDetermination::Filter, TaxonName::Autocomplete, TaxonNameRelationshipsFilterQuery, TypeMaterialAutocompleteQuery

Instance Attribute Summary (collapse)

Instance Method Summary (collapse)

Constructor Details

- (Query) initialize(string, project_id: nil, **keyword_args)

Returns a new instance of Query

Parameters:

  • args (Hash)


30
31
32
33
34
35
# File 'lib/queries/query.rb', line 30

def initialize(string, project_id: nil, **keyword_args)
  @options = keyword_args
  @query_string = string
  @project_id = project_id
  build_terms
end

Instance Attribute Details

- (Integer) dynamic_limit

Returns:

  • (Integer)


27
28
29
# File 'lib/queries/query.rb', line 27

def dynamic_limit
  @dynamic_limit
end

- (Object) options

parameters from keyword_args, used to group and pass along things like annotator params



24
25
26
# File 'lib/queries/query.rb', line 24

def options
  @options
end

- (Object) project_id

Returns the value of attribute project_id



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

def project_id
  @project_id
end

- (Object) query_string

Returns the value of attribute query_string



19
20
21
# File 'lib/queries/query.rb', line 19

def query_string
  @query_string
end

- (Array) terms

Returns:

  • (Array)


57
58
59
# File 'lib/queries/query.rb', line 57

def terms
  @terms
end

Instance Method Details

- (Array) alphabetic_strings

Returns:

  • (Array)


84
85
86
# File 'lib/queries/query.rb', line 84

def alphabetic_strings
  Utilities::Strings.alphabetic_strings(query_string)
end

- (Array) autocomplete

Returns default the autocomplete result to all

Returns:

  • (Array)

    default the autocomplete result to all



309
310
311
# File 'lib/queries/query.rb', line 309

def autocomplete
  all.to_a
end

- (ActiveRecord::Relation) autocomplete_cached

Returns:

  • (ActiveRecord::Relation)


327
328
329
330
331
# File 'lib/queries/query.rb', line 327

def autocomplete_cached
  a = cached
  return nil if a.nil?
  base_query.where(a.to_sql).limit(20)
end

- (ActiveRecord::Relation) autocomplete_cached_wildcard_anywhere

Returns removes years/integers!

Returns:

  • (ActiveRecord::Relation)

    removes years/integers!



320
321
322
323
324
# File 'lib/queries/query.rb', line 320

def autocomplete_cached_wildcard_anywhere
  a = match_wildcard_cached
  return nil if a.nil?
  base_query.where(a.to_sql).limit(20)
end

- (Object) autocomplete_identifier_cached_exact



333
334
335
# File 'lib/queries/query.rb', line 333

def autocomplete_identifier_cached_exact
  base_query.joins(:identifiers).where(with_identifier.to_sql)
end

- (Object) autocomplete_identifier_cached_like



337
338
339
# File 'lib/queries/query.rb', line 337

def autocomplete_identifier_cached_like
  base_query.joins(:identifiers).where(with_identifier_like.to_sql)
end

- (ActiveRecord::Relation) autocomplete_ordered_wildcard_pieces_in_cached

Returns:

  • (ActiveRecord::Relation)


314
315
316
# File 'lib/queries/query.rb', line 314

def autocomplete_ordered_wildcard_pieces_in_cached
  base_query.where(match_ordered_wildcard_pieces_in_cached.to_sql).limit(5)
end

- (Object) autocomplete_start_date



341
342
343
344
345
# File 'lib/queries/query.rb', line 341

def autocomplete_start_date
  a = with_start_date 
  return nil if a.nil?
  base_query.where(a.to_sql).limit(20)
end

- (Array) build_terms

Ultimately we should replace this concept with full text indexing.

Returns:

  • (Array)

    a reasonable (starting) interpretation of any query string



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

def build_terms
  @terms = @query_string.blank? ? [] : [end_wildcard, start_and_end_wildcard]
end

- (ActiveRecord::Relation?) cached

Returns cached matches full query string wildcarded

Returns:

  • (ActiveRecord::Relation, nil)

    cached matches full query string wildcarded



250
251
252
253
254
255
256
# File 'lib/queries/query.rb', line 250

def cached
  if !terms.empty?
    table[:cached].matches_any(terms)
  else
    nil
  end
end

- (Arel::Nodes::Grouping) combine_or_clauses(clauses)

Returns:

  • (Arel::Nodes::Grouping)

Raises:

  • (TaxonWorks::Error)


272
273
274
275
276
277
278
279
280
# File 'lib/queries/query.rb', line 272

def combine_or_clauses(clauses)
  clauses.compact!
  raise TaxonWorks::Error, 'combine_or_clauses called without a clause, ensure at least one exists' unless !clauses.empty?
  a = clauses.shift
  clauses.each do |b|
    a = a.or(b)
  end
  a
end

- (String) end_wildcard

Returns:

  • (String)


74
75
76
# File 'lib/queries/query.rb', line 74

def end_wildcard
  query_string + '%'
end

- (Arel::Nodes::Matches) exactly_named

Returns:

  • (Arel::Nodes::Matches)


229
230
231
# File 'lib/queries/query.rb', line 229

def exactly_named
  table[:name].eq(query_string)
end

- (Array) fragments

Used in unordered AND searches

Returns:

  • (Array)

    if 1-5 alphabetic_strings, those alphabetic_strings wrapped in wildcards, else none.



117
118
119
120
121
122
123
124
# File 'lib/queries/query.rb', line 117

def fragments
  a = alphabetic_strings
  if a.size > 0 && a.size < 6
    a.collect{|a| "%#{a}%"}
  else
    []
  end
end

- (Arel::Table) identifier_table

Returns:

  • (Arel::Table)


287
288
289
# File 'lib/queries/query.rb', line 287

def identifier_table
  ::Identifier.arel_table
end

- (Array) integers

Returns of strings representing integers

Returns:

  • (Array)

    of strings representing integers



103
104
105
106
# File 'lib/queries/query.rb', line 103

def integers
  return [] if query_string.blank?
  query_string.split(/\s+/).select{|t| Utilities::Strings.is_i?(t)}
end

- (Arel::Nodes::Matches) match_ordered_wildcard_pieces_in_cached

Returns:

  • (Arel::Nodes::Matches)


267
268
269
# File 'lib/queries/query.rb', line 267

def match_ordered_wildcard_pieces_in_cached
  a = table[:cached].matches(wildcard_pieces)
end

- (Arel::Nodes::Matches) match_wildcard_cached

match ALL wildcards, but unordered, if 2 - 6 pieces provided

Returns:

  • (Arel::Nodes::Matches)


260
261
262
263
264
# File 'lib/queries/query.rb', line 260

def match_wildcard_cached
  b = fragments
  return nil if b.empty?
  a = table[:cached].matches_all(b)
end

- (Arel::Nodes::Matches) named

Returns:

  • (Arel::Nodes::Matches)


224
225
226
# File 'lib/queries/query.rb', line 224

def named
  table[:name].matches_any(terms)
end

- (String) no_digits

Returns:

  • (String)


144
145
146
# File 'lib/queries/query.rb', line 144

def no_digits
  query_string.gsub(/\d/, '').strip
end

- (Query?) only_ids

Returns used in or_clauses, match on id only if integers alone provided.

Returns:

  • (Query, nil)

    used in or_clauses, match on id only if integers alone provided.



189
190
191
192
193
194
195
# File 'lib/queries/query.rb', line 189

def only_ids
  if only_integers?
    with_id
  else
    nil
  end
end

- (Boolean) only_integers?

Returns true if the query string only contains integers

Returns:

  • (Boolean)

    true if the query string only contains integers



110
111
112
# File 'lib/queries/query.rb', line 110

def only_integers?
  !(query_string =~ /[^\d\s]/i) && !integers.empty?
end

- (Arel::Nodes::TableAlias) parent

Returns:

  • (Arel::Nodes::TableAlias)


234
235
236
# File 'lib/queries/query.rb', line 234

def parent
  table.alias
end

- (Scope) parent_child_join

Returns:

  • (Scope)


165
166
167
# File 'lib/queries/query.rb', line 165

def parent_child_join
  table.join(parent).on(table[:parent_id].eq(parent[:id])).join_sources # !! join_sources ftw
end

- (Arel::Nodes::Grouping) parent_child_where

Match at two levels, for example, 'wa te“ will match ”Washington Co., Texas“

Returns:

  • (Arel::Nodes::Grouping)


171
172
173
174
175
# File 'lib/queries/query.rb', line 171

def parent_child_where
  a,b = query_string.split(/\s+/, 2)
  return table[:id].eq(-1) if a.nil? || b.nil?
  table[:name].matches("#{a}%").and(parent[:name].matches("#{b}%"))
end

- (Array) pieces

Returns split on whitespace

Returns:

  • (Array)

    split on whitespace



128
129
130
# File 'lib/queries/query.rb', line 128

def pieces
  query_string.split(/\s+/)
end

- (Array) result

Returns the results of the query as ActiveRecord objects

Returns:

  • (Array)

    the results of the query as ActiveRecord objects



39
40
41
# File 'lib/queries/query.rb', line 39

def result
  []
end

- (Scope) scope

stub

Returns:

  • (Scope)


45
46
47
# File 'lib/queries/query.rb', line 45

def scope
  where('1 = 2')
end

- (Date.new?) simple_date

Returns:

  • (Date.new, nil)


198
199
200
201
202
203
204
# File 'lib/queries/query.rb', line 198

def simple_date
  begin
    Date.parse(query_string)
  rescue ArgumentError
    return nil
  end
end

- (String) start_and_end_wildcard

Returns:

  • (String)


79
80
81
# File 'lib/queries/query.rb', line 79

def start_and_end_wildcard
  '%' + query_string + '%'
end

- (String) start_wildcard

Returns:

  • (String)


69
70
71
# File 'lib/queries/query.rb', line 69

def start_wildcard
  '%' + query_string
end

- (String) wildcard_pieces

Returns if `foo, and 123 and stuff` then %foo%and%123%and%stuff%

Returns:

  • (String)

    if `foo, and 123 and stuff` then %foo%and%123%and%stuff%



139
140
141
# File 'lib/queries/query.rb', line 139

def wildcard_pieces
  '%' + query_string.gsub(/[\s\W]+/, '%') + '%'
end

- (Array) wildcard_wrapped_integers

Returns:

  • (Array)


133
134
135
# File 'lib/queries/query.rb', line 133

def wildcard_wrapped_integers
  integers.collect{|i| "%#{i}%"}
end

- (Query?) with_id

Returns used in or_clauses

Returns:

  • (Query, nil)

    used in or_clauses



179
180
181
182
183
184
185
# File 'lib/queries/query.rb', line 179

def with_id
  if integers.any?
    table[:id].eq_any(integers)
  else
    nil
  end
end

- (Arel::Nodes::Equality) with_identifier

Returns:

  • (Arel::Nodes::Equality)


299
300
301
# File 'lib/queries/query.rb', line 299

def with_identifier
  identifier_table[:cached].eq(query_string)
end

- (Arel::Nodes::Grouping) with_identifier_like

Returns:

  • (Arel::Nodes::Grouping)


292
293
294
295
296
# File 'lib/queries/query.rb', line 292

def with_identifier_like
  a = [ start_and_end_wildcard ]
  a = a + wildcard_wrapped_integers
  identifier_table[:cached].matches_any(a)
end

- (Arel::Nodes::Equality) with_project_id

TODO: nil/or clause this

Returns:

  • (Arel::Nodes::Equality)


240
241
242
243
244
245
246
# File 'lib/queries/query.rb', line 240

def with_project_id
  if project_id
    table[:project_id].eq(project_id)
  else
    nil
  end
end

- (Object) with_start_date



206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
# File 'lib/queries/query.rb', line 206

def with_start_date
  if d = simple_date
    r = []
    r.push(table[:start_date_day].eq(d.day)) if d.day
    r.push(table[:start_date_month].eq(d.month)) if d.month
    r.push(table[:start_date_year].eq(d.year)) if d.year

    q = r.pop
    r.each do |z|
      q = q.and(z)
    end
    q
  else
    nil
  end
end

- (String?) year_letter

Returns the first letter recognized as coming directly past the first year

`Smith, 1920a. ... ` returns `a`

Returns:

  • (String, nil)

    the first letter recognized as coming directly past the first year

    `Smith, 1920a. ... ` returns `a`


97
98
99
# File 'lib/queries/query.rb', line 97

def year_letter
  query_string.match(/\d{4}([a-zAZ]+)/).to_a.last
end

- (Array) years

Returns those strings that represent years

Returns:

  • (Array)

    those strings that represent years



90
91
92
# File 'lib/queries/query.rb', line 90

def years
  query_string.scan(/\d{4}/).to_a.uniq
end