Class ::acs::SiteNode (public)
::nx::Class ::acs::SiteNode
Defined in packages/acs-tcl/tcl/site-nodes-procs.tcl
This class capsulates access to site-nodes stored in the database. It is written in a style to support the needs of the traditional Tcl-based API.
- Author:
- Gustaf Neumann
- Testcases:
- No testcase defined.
Source code: :public method get { {-url ""} {-node_id ""} } { # # @return a site node from url or site-node with all its context info # if {$url eq "" && $node_id eq ""} { error "site_node::get \"must pass in either url or node_id\"" } # # Make sure, we have a node_id. # if {$node_id eq ""} { set node_id [:get_node_id -url $url] } return [:properties -node_id $node_id] } # # @method properties # returns a site node from node_id with all its context info # :protected method properties { -node_id:integer,required } { # # Get URL, since it is not returned by the later query. # TODO: I did not want to modify the query for the time # being. When doing the Oracle support, the retrieval of the URL # should be moved into the query below.... # set url [:get_url -node_id $node_id] # # get site-node with context from the database # ::db_1row dbqd.acs-tcl.tcl.site-nodes-procs.site_node::update_cache.select_site_node {} set object_type [expr {$package_id eq "" ? "" : "apm_package"}] set list [list url $url node_id $node_id parent_id $parent_id name $name directory_p $directory_p pattern_p $pattern_p object_id $object_id object_type $object_type package_key $package_key package_id $package_id instance_name $instance_name package_type $package_type] return $list } # # @method get_children # get children of a site node # :public method get_children { -node_id:required -all:switch {-package_type ""} {-package_key ""} {-filters ""} {-element ""} } { # # Filtering happens here exactly like in the nsv-based # version. If should be possible to realize (at least # some of the) filtering via the SQL query. # if {$all} { # # The following query is just for PG. Note that # the query should not return the root of the # tree. # set sql [subst { WITH RECURSIVE site_node_tree(node_id, parent_id) AS ( select node_id, parent_id from site_nodes where node_id = :node_id UNION ALL select child.node_id, child.parent_id from site_node_tree, site_nodes child where child.parent_id = site_node_tree.node_id ) select [acs::dc map_function_name site_node__url(node_id)] from site_node_tree where node_id != :node_id }] if {[db_driverkey ""] eq "oracle"} { set sql [string map [list "WITH RECURSIVE" "WITH"] $sql] } set child_urls [::acs::dc list -prepare integer dbqd..[current method]-all $sql] } else { if {$package_key ne ""} { # # Simple optimization for package_keys; seems to be frequently used. # We leave the logic below unmodified, which could be optimized as well. # set package_key_clause "and package_id = object_id and package_key = :package_key" set from "site_nodes, apm_packages" } else { set package_key_clause "" set from "site_nodes" } set sql [subst { select [::acs::dc map_function_name {site_node__url(node_id)}] from $from where parent_id = :node_id $package_key_clause }] set child_urls [::acs::dc list dbqd..[current method] $sql] } if { $package_type ne "" } { lappend filters package_type $package_type } elseif { $package_key ne "" } { lappend filters package_key $package_key } if { [llength $filters] > 0 } { set return_val [list] foreach child_url $child_urls { if {![catch {set site_node [:get -url $child_url]}]} { set passed_p 1 foreach { elm val } $filters { if { [dict get $site_node $elm] ne $val } { set passed_p 0 break } } if { $passed_p } { if { $element ne "" } { lappend return_val [dict get $site_node $element] } else { lappend return_val $child_url } } } } } elseif { $element ne "" } { set return_val [list] foreach child_url $child_urls { if {![catch {set site_node [:get -url $child_url]}]} { lappend return_val [dict get $site_node $element] } } } else { set return_val $child_urls } return $return_val } :method has_children { -node_id:required,integer,1..1 } { # # Check, if the provided site-node has children. # # @return boolean value. # # ns_log notice "non-cached version of has_children called with $node_id" set children [::acs::dc list -prepare integer dbqd..has_children { select 1 from site_nodes where parent_id = :node_id FETCH NEXT 1 ROWS ONLY }] return [llength $children] } # # @method get_urls_from_object_id # :public method get_urls_from_object_id { -object_id:required,integer } { # # Return a list of URLs for site_nodes that have the given # object mounted or the empty list if there are none. The # URLs are returned in descending order meaning any # children will come before their parents. This ordering # is useful when deleting site nodes as we must delete # child site nodes before their parents. # set child_urls [::acs::dc list -prepare integer dbqd..[current method]-all [subst { select [acs::dc map_function_name site_node__url(node_id)] as url from site_nodes where object_id = :object_id order by url desc }]] } :public method get_urls_from_package_key { -package_key:required } { # # Return potentially multiple URLs based on a package key. # # @param package_key # return [::acs::dc list -prepare varchar dbqd..[current method]-urls-from-package-key [subst { select [acs::dc map_function_name site_node__url(node_id)] from site_nodes n, apm_packages p where p.package_key = :package_key and n.object_id = p.package_id }]] } :public method get_package_url { -package_key:required } { # # Legacy interface: previous implementations of the # site-nodes assumed, that there is just one site-node # entry available for a package-key. This method # returns just the first answer form # get_urls_from_package_key # return [lindex [:get_urls_from_package_key -package_key $package_key] 0] } # # @method get_node_id # obtain node id from url, using directly the stored procedure # site_node.node_id # # ::acs::dc call site_node node_id -url url ?-parent_id parent_id? # :public forward get_node_id ::acs::dc call site_node node_id # # @method get_url # obtain url from node-id, using directly the stored procedure # site_node.url # # ::acs::dc call site_node url -node_id node_id # :public forward get_url ::acs::dc call site_node url :public method flush_cache { -node_id:required,1..1 {-with_subtree:boolean} {-url ""} } { # # This is a stub method to be overloaded by some # cache managers. # } :create site_node { # # Object to interact with the ::acs::SiteNode class. The # intention is to provide an API interface highly # compatible with the classical OpenACS interface. # # @see Class ::acs::SiteNode # }Generic XQL file: packages/acs-tcl/tcl/site-nodes-procs.xql
PostgreSQL XQL file: packages/acs-tcl/tcl/site-nodes-procs-postgresql.xql
Oracle XQL file: packages/acs-tcl/tcl/site-nodes-procs-oracle.xql