Module: HasHelpers::Query::Provider

Included in:
Elasticsearch, Sql
Defined in:
app/lib/has_helpers/query/provider.rb

Overview

TODO: I think none of the providers are maintaining state, so they can be converted to modules. Need to evaluate this further. •

Defined Under Namespace

Modules: ClassMethods

Constant Summary collapse

PAGINATION_ATTRS =
%i[current_page per_page total_entries]

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.allObject

Returns a list of names of all provider classes



16
17
18
# File 'app/lib/has_helpers/query/provider.rb', line 16

def self.all
  @all ||= Set.new
end

.from_short_name(short_name) ⇒ Object

Returns an provider class instance which matches the given short name.

Examples

from_short_name("Sphinx") # => HasHelpers::Query::Sphinx from_short_name("Unknown") # => nil

Parameters:

  • String

    short_name - The short name for a provider, e.g. "Sphinx" or "SQL"



60
61
62
63
64
65
66
67
# File 'app/lib/has_helpers/query/provider.rb', line 60

def self.from_short_name(short_name)
  all.lazy.
    select do |provider_name|
    provider_name == "#{ name.deconstantize }::#{ short_name }"
  end.
    map(&:constantize).
    first
end

.included(klass) ⇒ Object



10
11
12
13
# File 'app/lib/has_helpers/query/provider.rb', line 10

def self.included(klass)
  klass.extend(ClassMethods)
  all << klass.name
end

.owner_relation_from_scope(scope) ⇒ Object

Returns a triple of scope relation name, owner relation name, and an ActiveRecord::Relation object built from the given scope (Relation or model class) which includes the joined owner view, as well as the relation names related to the owner view. If no owner view is detected then nil is returned as the relation.

Examples

scope_with_owner_view(Advisor) # => ["advisors", "owner_advisors_view", <#ActiveRecord::Relation>]

# Hierarchy does _not_ have an owner view.
scope_with_owner_view(Hierarchy) # => ["hierarchies", "owner_hierarchies_view", nil]


33
34
35
36
37
38
39
40
41
42
43
# File 'app/lib/has_helpers/query/provider.rb', line 33

def self.owner_relation_from_scope(scope)
  scope_relation_name = scope.table_name
  owner_relation_name = "owner_#{ scope_relation_name }_view"

  if relation_exists?(owner_relation_name) # Check if the owner view is present.
    owner_relation = scope.joins("LEFT OUTER JOIN #{ owner_relation_name } ON #{ owner_relation_name }.id = #{ scope_relation_name }.id")
    owner_relation.select_values = ["#{ scope_relation_name }.*"]
  end

  [scope_relation_name, owner_relation_name, owner_relation]
end

.relation_exists?(table, schema: "public") ⇒ Boolean

NOTE: This method is currently intended for internal use only. Schema and table names are NOT being sanitized, so values from user input are not currently safe to use here.

Returns:

  • (Boolean)


48
49
50
51
52
# File 'app/lib/has_helpers/query/provider.rb', line 48

def self.relation_exists?(table, schema: "public")
  query = "SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_schema = '#{ schema }' AND table_name = '#{ table }');"
  result = ::ActiveRecord::Base.connection.execute(query)
  result.first["exists"].to_bool
end

Instance Method Details

#query_options(resource: nil, query: nil, options: {}) ⇒ Object

rubocop:disable Lint/UnusedMethodArgument



69
70
71
# File 'app/lib/has_helpers/query/provider.rb', line 69

def query_options(resource: nil, query: nil, options: {}) # rubocop:disable Lint/UnusedMethodArgument
  options
end

#search(resource:, query:, options: {}) ⇒ Object



73
74
75
76
77
78
79
# File 'app/lib/has_helpers/query/provider.rb', line 73

def search(resource:, query:, options: {})
  exec_query(
    resource: resource,
    query: sanitize_query(query),
    options: query_options(resource: resource, query: query, options: options)
  )
end