Class: Praxis::Extensions::FieldSelection::SequelQuerySelector

Inherits:
Object
  • Object
show all
Defined in:
lib/praxis/extensions/field_selection/sequel_query_selector.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(query:, selectors:, debug: false) ⇒ SequelQuerySelector

Gets a dataset, a selector…and should return a dataset with the selector definition applied.



12
13
14
15
16
# File 'lib/praxis/extensions/field_selection/sequel_query_selector.rb', line 12

def initialize(query:, selectors:, debug: false)
  @selector = selectors
  @query = query
  @logger = debug ? Logger.new($stdout) : nil
end

Instance Attribute Details

#queryObject (readonly)

Returns the value of attribute query.



9
10
11
# File 'lib/praxis/extensions/field_selection/sequel_query_selector.rb', line 9

def query
  @query
end

#selectorObject (readonly)

Returns the value of attribute selector.



9
10
11
# File 'lib/praxis/extensions/field_selection/sequel_query_selector.rb', line 9

def selector
  @selector
end

Instance Method Details

#_eager(selector_node) ⇒ Object



29
30
31
32
33
34
35
36
37
# File 'lib/praxis/extensions/field_selection/sequel_query_selector.rb', line 29

def _eager(selector_node)
  lambda do |dset|
    dset = add_select(query: dset, selector_node: selector_node)

    selector_node.tracks.inject(dset) do |ds, (track_name, track_node)|
      ds.eager(track_name => _eager(track_node))
    end
  end
end

#add_select(query:, selector_node:) ⇒ Object



39
40
41
42
43
44
45
46
47
48
# File 'lib/praxis/extensions/field_selection/sequel_query_selector.rb', line 39

def add_select(query:, selector_node:)
  # We're gonna always require the PK of the model, as it is a special case for Sequel, and the app itself
  # might assume it is always there and not be surprised by the fact that if it isn't, it won't blow up
  # in the same way as any other attribute not being loaded...i.e., NoMethodError: undefined method `foobar' for #<...>
  select_fields = selector_node.select + [selector_node.resource.model.primary_key.to_sym]

  table_name = selector_node.resource.model.table_name
  qualified = select_fields.map { |f| Sequel.qualify(table_name, f) }
  query.select(*qualified)
end

#explain_query(dataset) ⇒ Object



50
51
52
53
54
# File 'lib/praxis/extensions/field_selection/sequel_query_selector.rb', line 50

def explain_query(dataset)
  @logger.debug("Query plan for ...#{selector.resource.model} with selectors: #{JSON.generate(selector.dump)}")
  dataset.all
  @logger.debug('Query plan end')
end

#generateObject



18
19
20
21
22
23
24
25
26
27
# File 'lib/praxis/extensions/field_selection/sequel_query_selector.rb', line 18

def generate
  @query = add_select(query: query, selector_node: @selector)

  @query = @selector.tracks.inject(@query) do |ds, (track_name, track_node)|
    ds.eager(track_name => _eager(track_node))
  end

  explain_query(query) if @logger
  @query
end