ad_category_parentage_list db category_idWhat it does:
Returns a list of lists, where each sublist is one line of parentage up from the specified category to the hierarchy root. In turn, each parentage line list consists of two-item lists: category_id and category. A list of lists is needed since a category can have multiple parents. If this category has no parents, then return the empty list.Defined in: /web/philip/tcl/ad-categories.tcl
Source code:
set n_parents [database_to_tcl_string $db "select count(*) from category_hierarchy where child_category_id = $category_id and parent_category_id is not null"] if { $n_parents == 0 } { return [list] } # (2000-04-05 Seb) Note that we have one big problem: suppose that # we have 1 parent for this category. But its parent has 2 parents. # That leads us to question: how many parentage lines does this # category actually have? My vote is 1. But then the UI is # misleading, because we don't know which parentage line to # display ... but what if we replace all above ill-behaving parent # with ellipsis? # OK, seems like a good idea. So, we should build parentage tree # for category and follow the changes of LEVEL. If equal to 1, we # have direct parent. Check if the LEVEL is increasing until it # drops to 1 again. If it was increasing all the time until next # level==1 is reached, we have 'direct' parentage line (no-problem). # Otherwise, print only the portion up to the line with the highest # non-repeating value of LEVEL. set category_name [database_to_tcl_string $db "select c.category from categories c where c.category_id='$category_id'"] set selection [ns_db select $db " SELECT c.category_id AS parent_id, c.category AS parent_category, hc.level_col FROM categories c, (SELECT h.parent_category_id, LEVEL AS level_col, ROWNUM AS row_col FROM category_hierarchy h START WITH h.child_category_id = $category_id CONNECT BY h.child_category_id = PRIOR h.parent_category_id) hc WHERE c.category_id = hc.parent_category_id ORDER BY hc.row_col"] set parentage_list [list] set parentage_line [list [list $category_id $category_name]] set prior_level 0 set forking_level 9999 while {[ns_db getrow $db $selection]} { set_variables_after_query if {$level_col <= $prior_level} { if {$level_col == 1} { # Parent line is now completed, flush it: # Take only up to the last non-forking parent # (level increases from right to left) lappend parentage_list [lrange $parentage_line [expr [llength $parentage_line] - $forking_level] end] set parentage_line [list [list $category_id $category_name]] set forking_level 9999 } else { # We have problematic parent (i.e. that is itself # multi-parented) if {$level_col < $forking_level} { set forking_level $level_col # Add (...) in front of category name at $level_col - 1 set last_nonforking_level [expr [llength $parentage_line] - $forking_level] set problematic_category [lindex $parentage_line $last_nonforking_level] set probl_cat_id [lindex $problematic_category 0] set probl_cat_name "(...) [lindex $problematic_category 1]" # Put it back set parentage_line [lreplace $parentage_line $last_nonforking_level $last_nonforking_level [list $probl_cat_id $probl_cat_name]] } } } set prior_level $level_col # We're moving up the hierarchy so put this category at # the beginning of the parentage line. # set parentage_line [concat [list [list $parent_id $parent_category]] $parentage_line] } # Don't forget the last parentage line lappend parentage_list [lrange $parentage_line [expr [llength $parentage_line] - $forking_level] end]