Class ::acs::SiteNode (public)

 ::nx::Class ::acs::SiteNode[i]

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

[ hide source ] | [ make this the default ]
Show another procedure: