Class: ActiveRecord::Refined::AST::JsonAggregate

Inherits:
Node
  • Object
show all
Includes:
ComputedJson, JsonComparable, Predications, Windowing
Defined in:
lib/active_record/refined/ast.rb

Overview

Rows gathered into one JSON document: json_arrayagg collects a value from each row into an array, json_objectagg a key and a value into an object. Every adapter has the pair under a name of its own; what PostgreSQL gets is the jsonb one, whose documents the other JSON operations here read.

Constant Summary collapse

NAMES =

The standard names, which are also the DSL's own and MySQL's, serve any adapter the table does not list.

{
  arrayagg: { sqlite: "json_group_array", postgresql: "jsonb_agg" },
  objectagg: { sqlite: "json_group_object",
               postgresql: "jsonb_object_agg" },
}.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Windowing

#over

Methods included from ComputedJson

#json_value?

Methods included from JsonComparable

#between?, #in?, #not_between?, #not_in?, #~

Methods included from Predications

#!=, #!~, #<, #<=, #==, #=~, #>, #>=, #between?, #bury, #casecmp?, #contains?, #dig, #dig_text, #distinct_from?, #end_with?, #except, #false?, #ilike?, #in?, #include?, #intersect?, #key?, #keys, #like?, #member?, #not_between?, #not_distinct_from?, #not_false?, #not_ilike?, #not_in?, #not_like?, #not_null?, #not_true?, #null?, #start_with?, #subset?, #superset?, #true?, #when

Methods inherited from Node

#as, #asc, #desc

Constructor Details

#initialize(kind, operands, condition: nil) ⇒ JsonAggregate

Returns a new instance of JsonAggregate.



1553
1554
1555
1556
1557
# File 'lib/active_record/refined/ast.rb', line 1553

def initialize(kind, operands, condition: nil)
  @kind = kind
  @operands = operands
  @condition = condition
end

Instance Attribute Details

#conditionObject (readonly)

Returns the value of attribute condition.



1551
1552
1553
# File 'lib/active_record/refined/ast.rb', line 1551

def condition
  @condition
end

#kindObject (readonly)

Returns the value of attribute kind.



1551
1552
1553
# File 'lib/active_record/refined/ast.rb', line 1551

def kind
  @kind
end

#operandsObject (readonly)

Returns the value of attribute operands.



1551
1552
1553
# File 'lib/active_record/refined/ast.rb', line 1551

def operands
  @operands
end

Instance Method Details

#check_window(model) ⇒ Object

MariaDB takes every other aggregate as a window function, but not these two; Over asks here before writing one.

Raises:

  • (NotImplementedError)


1566
1567
1568
1569
1570
1571
# File 'lib/active_record/refined/ast.rb', line 1566

def check_window(model)
  return unless AST.adapter_family(model) == :mysql
  return unless model.with_connection { |connection| connection.mariadb? }
  raise NotImplementedError,
    "#{json_source} over a window has no equivalent on MariaDB"
end

#filter(condition = nil, &block) ⇒ Object



1559
1560
1561
1562
# File 'lib/active_record/refined/ast.rb', line 1559

def filter(condition = nil, &block)
  JsonAggregate.new(kind, operands,
                    condition: Case.argument(:filter, condition, block))
end

#to_arel(table, model) ⇒ Object



1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
# File 'lib/active_record/refined/ast.rb', line 1573

def to_arel(table, model)
  family = AST.adapter_family(model)
  call = Arel::Nodes::NamedFunction.new(
    NAMES.fetch(kind).fetch(family) { "JSON_#{kind.to_s.upcase}" },
    operands.map { |operand| to_arel_argument(operand, table, model) })
  return call unless condition

  # The CASE that stands in for FILTER elsewhere hands the aggregate
  # a NULL for every row the condition misses, and these two keep a
  # NULL -- as JSON null -- rather than passing over it.
  if family == :mysql
    raise NotImplementedError,
      "#{json_source}.filter has no equivalent on " \
      "#{model.connection_db_config.adapter}; a CASE would leave a " \
      "null in the document for every row it drops"
  end
  call.filter(condition.to_arel(table, model))
end