lib/fertile_forest/modules/finders.rb
#
# Find any kind of kinship from base node.
#
# @param base_obj [Entity|Integer] Base node|id to find.
# @param branch_level [Integer] Branch distance of finding nodes from base nodes.
# @param depth_offset [Integer] Offset of kinship level of finding nodes from base nodes.
# @param columns [Array] Columns for SELECT clause.
# @return [ActiveRecord::Relation] Basic query for finding kinship nodes.
# @return [nil] No kinship nodes.
# @since 1.1.0
#
Find any kind of kinship from base node.
Find any kind of kinship from base node .
def kinships(
            base_obj,
            branch_level = KINSHIPS_BRANCH_LEVEL_ONE,
            depth_offset = KINSHIPS_SAME_DEPTH,
            columns = nil
          )
            base_node = ff_resolve_nodes(base_obj)
            return nil if base_node.blank?
            aim_queue = base_node.ff_queue
            aim_depth = base_node.ff_depth
            aim_grove = base_node.ff_grove  
            top_depth = aim_depth - branch_level
            return nil if top_depth < ROOT_DEPTH
            return nil if branch_level + depth_offset < 0
            ffqq = arel_table[@_ff_queue]
            ffdd = arel_table[@_ff_depth]
            ffgg = arel_table[@_ff_grove]
            before_nodes_subquery = ff_usual_projection(aim_grove)
                .project(ffqq.maximum.to_sql + " + 1 AS head_queue")
                .where(ffqq.lt(aim_queue))
                .where(ffdd.lteq(top_depth))
            after_nodes_subquery = ff_usual_projection(aim_grove)
                .project(ffqq.minimum.to_sql + " - 1 AS tail_queue")
                .where(ffqq.gt(aim_queue))
                .where(ffdd.lteq(top_depth))
            func_maker = Arel::Nodes::NamedFunction
            before_coalesce_condition = func_maker.new(
                'COALESCE',
                [before_nodes_subquery, 0]
            )
            after_coalesce_condition = func_maker.new(
                'COALESCE',
                [after_nodes_subquery, QUEUE_MAX_VALUE]
            )
             create column of ff_branch_level
            increment_branch_level_case = ff_create_case_expression(
              [ffqq.eq(aim_queue).to_sql, 0],
              1
            )
            branch_for_level_subqueries = [increment_branch_level_case]
            ((top_depth + 1) .. (aim_depth - 1)).each do |d|
              before_nodes_branch_for_lavel_subquery = ff_usual_projection(aim_grove)
                  .project("{ffqq.maximum.to_sql} AS head_queue_{d}")
                  .where(ffqq.lt(aim_queue))
                  .where(ffdd.lteq(d))
              after_nodes_branch_far_level_subquery = ff_usual_projection(aim_grove)
                  .project("{ffqq.minimum.to_sql} - 1 AS tail_queue_{d}")
                  .where(ffqq.gt(aim_queue))
                  .where(ffdd.lteq(d))
              before_condition = func_maker.new(
                  'COALESCE',
                  [before_nodes_branch_for_lavel_subquery, 0]
              )
              after_condition = func_maker.new(
                  'COALESCE',
                  [after_nodes_branch_far_level_subquery, QUEUE_MAX_VALUE]
              )
              branch_for_level_subqueries << ff_create_case_expression(
                [ffqq.lt(before_condition).to_sql, 1],
                [ffqq.gt(after_condition).to_sql, 1],
                0
              )
            end
            ff_branch_level = branch_for_level_subqueries.join(' + ') + " AS {@_ff_branch_level}";
             create columns
            base_columns = ff_all_optional_columns(columns);
            base_columns << ff_branch_level
             find nodes by ancestor queues
            ff_required_columns_scope()
                .ff_usual_conditions_scope(aim_grove)
                .ff_usual_order_scope()
                .where(ffdd.eq(aim_depth + depth_offset))
                .where(ffqq.gteq(before_coalesce_condition))
                .where(ffqq.lteq(after_coalesce_condition))
                .select(base_columns)
          end
def kinships ( base_obj , branch_level = KINSHIPS_BRANCH_LEVEL_ONE , depth_offset = KINSHIPS_SAME_DEPTH , columns = nil ) base_node = ff_resolve_nodes ( base_obj ) return nil if base_node . blank? aim_queue = base_node . ff_queue aim_depth = base_node . ff_depth aim_grove = base_node . ff_grove top_depth = aim_depth - branch_level return nil if top_depth < ROOT_DEPTH return nil if branch_level + depth_offset < 0 ffqq = arel_table [ @_ff_queue ] ffdd = arel_table [ @_ff_depth ] ffgg = arel_table [ @_ff_grove ] before_nodes_subquery = ff_usual_projection ( aim_grove ) . project ( ffqq . maximum . to_sql + " + 1 AS head_queue" ) . where ( ffqq . lt ( aim_queue ) ) . where ( ffdd . lteq ( top_depth ) ) after_nodes_subquery = ff_usual_projection ( aim_grove ) . project ( ffqq . minimum . to_sql + " - 1 AS tail_queue" ) . where ( ffqq . gt ( aim_queue ) ) . where ( ffdd . lteq ( top_depth ) ) func_maker = Arel :: Nodes :: NamedFunction before_coalesce_condition = func_maker . new ( 'COALESCE' , [ before_nodes_subquery , 0 ] ) after_coalesce_condition = func_maker . new ( 'COALESCE' , [ after_nodes_subquery , QUEUE_MAX_VALUE ] ) increment_branch_level_case = ff_create_case_expression ( [ ffqq . eq ( aim_queue ) . to_sql , 0 ] , 1 ) branch_for_level_subqueries = [ increment_branch_level_case ] ( ( top_depth + 1 ) .. ( aim_depth - 1 ) ) . each do | d | before_nodes_branch_for_lavel_subquery = ff_usual_projection ( aim_grove ) . project ( "#{ffqq.maximum.to_sql} AS head_queue_#{d}" ) . where ( ffqq . lt ( aim_queue ) ) . where ( ffdd . lteq ( d ) ) after_nodes_branch_far_level_subquery = ff_usual_projection ( aim_grove ) . project ( "#{ffqq.minimum.to_sql} - 1 AS tail_queue_#{d}" ) . where ( ffqq . gt ( aim_queue ) ) . where ( ffdd . lteq ( d ) ) before_condition = func_maker . new ( 'COALESCE' , [ before_nodes_branch_for_lavel_subquery , 0 ] ) after_condition = func_maker . new ( 'COALESCE' , [ after_nodes_branch_far_level_subquery , QUEUE_MAX_VALUE ] ) branch_for_level_subqueries << ff_create_case_expression ( [ ffqq . lt ( before_condition ) . to_sql , 1 ] , [ ffqq . gt ( after_condition ) . to_sql , 1 ] , 0 ) end ff_branch_level = branch_for_level_subqueries . join ( ' + ' ) + " AS #{@_ff_branch_level}" ; base_columns = ff_all_optional_columns ( columns ) ; base_columns << ff_branch_level ff_required_columns_scope ( ) . ff_usual_conditions_scope ( aim_grove ) . ff_usual_order_scope ( ) . where ( ffdd . eq ( aim_depth + depth_offset ) ) . where ( ffqq . gteq ( before_coalesce_condition ) ) . where ( ffqq . lteq ( after_coalesce_condition ) ) . select ( base_columns ) end
Find any kind of kinship from base node.
Find any kind of kinship from base node .
# When no grove, nil # Impossible to find. # create subquery # # create column of ff_branch_level # # # create columns # # find nodes by ancestor queues
Basic query for finding kinship nodes.
Basic query for finding kinship nodes .
ActiveRecord::Relation
No kinship nodes.
No kinship nodes .
nil
base_obj
Base node|id to find.
Base node|id to find .
branch_level
Branch distance of finding nodes from base nodes.
Branch distance of finding nodes from base nodes .
depth_offset
Offset of kinship level of finding nodes from base nodes.
Offset of kinship level of finding nodes from base nodes .
columns
Columns for SELECT clause.
Columns for SELECT clause .
since
None