module Ancestry::MaterializedPath

def self.extended(base)

def self.extended(base)
  base.send(:include, InstanceMethods)
end

def ancestors_of(object)

def ancestors_of(object)
  t = arel_table
  node = to_node(object)
  where(t[primary_key].in(node.ancestor_ids))
end

def children_of(object)

def children_of(object)
  t = arel_table
  node = to_node(object)
  where(t[ancestry_column].eq(node.child_ancestry))
end

def descendant_conditions(object)

deprecated
def descendant_conditions(object)
  t = arel_table
  node = to_node(object)
  t[ancestry_column].matches("#{node.child_ancestry}/%", nil, true).or(t[ancestry_column].eq(node.child_ancestry))
end

def descendants_of(object)

def descendants_of(object)
  where(descendant_conditions(object))
end

def indirects_of(object)

indirect = anyone who is a descendant, but not a child
def indirects_of(object)
  t = arel_table
  node = to_node(object)
  where(t[ancestry_column].matches("#{node.child_ancestry}/%", nil, true))
end

def inpath_of(object)

def inpath_of(object)
  t = arel_table
  node = to_node(object)
  where(t[primary_key].in(node.path_ids))
end

def ordered_by_ancestry(order = nil)

def ordered_by_ancestry(order = nil)
  if %w(mysql mysql2 sqlite sqlite3).include?(connection.adapter_name.downcase)
    reorder(arel_table[ancestry_column], order)
  elsif %w(postgresql oracleenhanced).include?(connection.adapter_name.downcase) && ActiveRecord::VERSION::STRING >= "6.1"
    reorder(Arel::Nodes::Ascending.new(arel_table[ancestry_column]).nulls_first, order)
  else
    reorder(
      Arel::Nodes::Ascending.new(Arel::Nodes::NamedFunction.new('COALESCE', [arel_table[ancestry_column], Arel.sql("''")])),
      order
    )
  end
end

def ordered_by_ancestry_and(order)

def ordered_by_ancestry_and(order)
  ordered_by_ancestry(order)
end

def path_of(object)

def path_of(object)
  to_node(object).path
end

def roots

def roots
  where(arel_table[ancestry_column].eq(nil))
end

def siblings_of(object)

def siblings_of(object)
  t = arel_table
  node = to_node(object)
  where(t[ancestry_column].eq(node[ancestry_column].presence))
end

def subtree_of(object)

def subtree_of(object)
  t = arel_table
  node = to_node(object)
  where(descendant_conditions(node).or(t[primary_key].eq(node.id)))
end