template::paginator::init (private)

 template::paginator::init statement_name name query [ print_p ]

Defined in packages/acs-templating/tcl/paginator-procs.tcl

Initialize a paginated query. Only called by create.

Parameters:
statement_name
name
query
print_p (defaults to "0")

Partial Call Graph (max 5 caller/called nodes):
%3 template::paginator::create template::paginator::create (public) template::paginator::init template::paginator::init template::paginator::create->template::paginator::init db_map db_map (public) template::paginator::init->db_map template::cache template::cache (public) template::paginator::init->template::cache template::list::get_reference template::list::get_reference (public) template::paginator::init->template::list::get_reference template::list::get_refname template::list::get_refname (public) template::paginator::init->template::list::get_refname template::paginator::get_reference template::paginator::get_reference (private) template::paginator::init->template::paginator::get_reference

Testcases:
No testcase defined.
Source code:
    get_reference

    # query for an ordered list of all row identifiers to cache
    # perform the query in the calling scope so bind variables have effect

    upvar 2 __paginator_ids ids
    set ids [list]

    set full_statement_name [uplevel 2 "db_qd_get_fullname $statement_name"]

    # Antonio Pisano 2015-11-17: to get the full rowcount of the records,
    # we need to wrap the original query into a count(*). The problem comes
    # with template::list, that builds the paginator query tampering with
    # the original one, so if we come here from a template::list we cannot
    # retrieve the real count anymore. I had to come out with a solution
    # that wouldn't break existing contract for public procs, or this would
    # have caused unpredictable regressions. Below is the strategy to get
    # the original query.

    # If query comes from an xql we get it from there...
    set original_query [db_map $full_statement_name]
    # ...otherwise we try to see if we come from a template::list...
    if {$original_query eq ""} {
    # ...which was slightly modified to keep the original query untampered.
        set list_name [lindex [split $name ,] 0]
        if {[info exists ::[template::list::get_refname -name $list_name]]} {
            template::list::get_reference -name $list_name
            set original_query $list_properties(page_query_original)
        }
    }
    # If any of the previous fail, we go for the explicit query
    if {$original_query eq ""} {
        set original_query $query
    }


    if { [info exists properties(contextual)] } {

    # query contains two columns, one for ID and one for context cue

        uplevel 2 "
        # Can't use db_foreach here, since we need to use the ns_set directly.
        db_with_handle db {
            set selection \[db_exec select \$db $full_statement_name {$query}\]

            set __paginator_ids \[list\]
            set total_so_far 1

            while { \[db_getrow \$db \$selection\] } {
                set this_result \[ns_set values \$selection\]
                if { $print_p } {
                    if { \$total_so_far % 250 == 0 } {
                        ns_write \"…\$total_so_far \"
                    }
                    if { \$total_so_far % 3000 == 0 } {
                        ns_write \"<br>\"
                    }
                }
                incr total_so_far
                lappend __paginator_ids \$this_result
            }

            if { $print_p } {
                ns_write \"&#133;\[expr \$total_so_far - 1\]\"
            }

        }
        "

        set i 0
        set page_size $properties(pagesize)
        set context_ids [list]
        set row_ids ""

        foreach row $ids {

            lappend row_ids [lindex $row 0]

            if { $i % $page_size == 0 } {
                lappend context_ids [lindex $row 1]
            }
            incr i
        }

        set properties(context_ids) $context_ids
        template::cache set $name:$query:context_ids $context_ids $properties(timeout)

        set properties(row_ids) $row_ids

        template::cache set $name:$query:row_ids $row_ids $properties(timeout)

    } else {

        uplevel 2 "
        # Can't use db_foreach here, since we need to use the ns_set directly.
        db_with_handle db {
            set selection \[db_exec select \$db $statement_name \"$query\"\]

            set __paginator_ids \[list\]
            set total_so_far 1

            while { \[db_getrow \$db \$selection\] } {
                set this_result \[ns_set values \$selection \]
                if { $print_p } {
                    if { \$total_so_far % 250 == 0 } {
                        ns_write \"...\$total_so_far \"
                    }
                    if { \$total_so_far % 3000 == 0 } {
                        ns_write \"<br>\"
                    }
                }
                incr total_so_far
                lappend __paginator_ids \$this_result
            }
            if { $print_p } {
                ns_write \"...\[expr \$total_so_far - 1\]\"
            }
        }
        "

        set properties(row_ids) $ids
        template::cache set $name:$query:row_ids $ids $properties(timeout)
    }

    # Get full number of rows retrieved by original paginator query
    set full_row_count [uplevel 3 [list db_string query [db_map count_query]]]
    set properties(full_row_count) $full_row_count
    template::cache set $name:$query:full_row_count $full_row_count $properties(timeout)
XQL Not present:
PostgreSQL, Oracle
Generic XQL file:
<fullquery name="template::paginator::init.count_query">
    <querytext>
      select count(*) from ($original_query) t
    </querytext>
</fullquery>
packages/acs-templating/tcl/paginator-procs.xql

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