Index: openacs-4/packages/acs-templating/tcl/paginator-procs.tcl
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/acs-templating/tcl/paginator-procs.tcl,v
diff -u -r1.11 -r1.12
--- openacs-4/packages/acs-templating/tcl/paginator-procs.tcl 17 May 2003 10:05:27 -0000 1.11
+++ openacs-4/packages/acs-templating/tcl/paginator-procs.tcl 28 Aug 2003 09:41:45 -0000 1.12
@@ -16,19 +16,21 @@
@see template::paginator
@see template::paginator::create
@see template::paginator::get_context
- @see template::paginator::get_data
+ @see template::paginator::get_data
+ @see template::paginator::get_query
@see template::paginator::get_display_info
@see template::paginator::get_group
@see template::paginator::get_group_count
@see template::paginator::get_groups
@see template::paginator::get_page
@see template::paginator::get_page_count
@see template::paginator::get_pages
- @see template::paginator::get_pages_info
+ @see template::paginator::get_pages_info
@see template::paginator::get_row
@see template::paginator::get_row_count
@see template::paginator::get_row_ids
@see template::paginator::get_row_last
+ @see template::paginator::reset
} {
eval paginator::$command $args
}
@@ -46,7 +48,7 @@
the results. Bind variables may be used.
@option timeout The lifetime of a query result in seconds, after which
- the query must be refreshed.
+ the query must be refreshed (if not reset).
@option pagesize The number of rows to display on a single page.
@@ -80,8 +82,57 @@
set cache_key $name:$query
set row_ids [cache get $cache_key:row_ids]
- if { [string equal $row_ids {}] } {
- init $statement_name $name $query
+ if { ([string equal $row_ids {}] && ![nsv_exists __template_cache_timeout $cache_key]) || ([info exists opts(flush_p)] && [string equal $opts(flush_p) "t"]) } {
+ if { [info exists opts(printing_prefs)] && ![empty_string_p $opts(printing_prefs)] } {
+ ReturnHeadersNoCache "text/html"
+ ns_write "
+
+
"
+ set title [lindex $opts(printing_prefs) 0]
+ ns_write "$title
+ "
+ set stylesheet [lindex $opts(printing_prefs) 1]
+ if { ![empty_string_p $stylesheet] } {
+ ns_write ""
+ }
+ ns_write ""
+ ns_write ""
+ set header_file [lindex $opts(printing_prefs) 3]
+ if { ![empty_string_p $header_file] } {
+ ns_write [ns_adp_parse -file $header_file]
+ }
+ ns_write [lindex $opts(printing_prefs) 6]
+ init $statement_name $name $query 1
+ ns_write [lindex $opts(printing_prefs) 7]
+ set footer_file [lindex $opts(printing_prefs) 4]
+ if { ![empty_string_p $footer_file] } {
+ ns_write [ns_adp_parse -file $footer_file]
+ }
+ set return_url [lindex $opts(printing_prefs) 5]
+ if { ![empty_string_p $return_url] } {
+ if { [llength $opts(row_ids)]==0 } {
+ nsv_set __template_cache_timeout $cache_key $opts(timeout)
+ }
+ ns_write "
+
+ "
+ }
+ ns_write [ad_footer]
+ ad_script_abort
+ } else {
+ init $statement_name $name $query
+ }
} else {
set opts(row_ids) $row_ids
set opts(context_ids) [cache get $cache_key:context_ids]
@@ -92,21 +143,55 @@
set opts(group_count) [get_group $name $opts(page_count)]
}
-ad_proc -private template::paginator::init { statement_name name query } {
+ad_proc -private template::paginator::init { statement_name name query {print_p 0} } {
Initialize a paginated query. Only called by create.
} {
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 3 __paginator_ids ids
+ upvar 2 __paginator_ids ids
+ set ids [list]
if { [info exists properties(contextual)] } {
# query contains two columns, one for ID and one for context cue
- uplevel 3 "set __paginator_ids \[db_list_of_lists $statement_name \"$query\"\]"
+ uplevel 2 "
+ set full_statement_name \[db_qd_get_fullname $statement_name\]
+
+ # 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 \[list\]
+ for { set i 0 } { \$i < \[ns_set size \$selection\] } { incr i } {
+ lappend this_result \[ns_set value \$selection \$i\]
+ }
+ if { $print_p } {
+ if { \$total_so_far % 250 == 0 } {
+ ns_write \"
\$total_so_far \"
+ }
+ if { \$total_so_far % 3000 == 0 } {
+ ns_write \"
\"
+ }
+ }
+ incr total_so_far
+ lappend __paginator_ids \$this_result
+ }
+
+ if { $print_p } {
+ ns_write \"
\[expr \$total_so_far - 1\]\"
+ }
+
+ }
+ "
+
set i 0
set page_size $properties(pagesize)
set context_ids [list]
@@ -120,7 +205,7 @@
}
incr i
}
-
+
set properties(context_ids) $context_ids
cache set $name:$query:context_ids $context_ids $properties(timeout)
@@ -130,14 +215,41 @@
}
set properties(row_ids) $row_ids
+
cache set $name:$query:row_ids $row_ids $properties(timeout)
-
} else {
- # no extra column specified for paging by contextual cues
- uplevel 3 "set __paginator_ids \[db_list $statement_name \"$query\"\]"
+ 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 \[list\]
+ for { set i 0 } { \$i < \[ns_set size \$selection\] } { incr i } {
+ lappend this_result \[ns_set value \$selection \$i\]
+ }
+ if { $print_p } {
+ if { \$total_so_far % 250 == 0 } {
+ ns_write \"...\$total_so_far \"
+ }
+ if { \$total_so_far % 3000 == 0 } {
+ ns_write \"
\"
+ }
+ }
+ incr total_so_far
+ lappend __paginator_ids \$this_result
+ }
+ if { $print_p } {
+ ns_write \"...\[expr \$total_so_far - 1\]\"
+ }
+ }
+ "
+
set properties(row_ids) $ids
cache set $name:$query:row_ids $ids $properties(timeout)
}
@@ -243,6 +355,19 @@
return $ids
}
+ad_proc -public template::paginator::get_all_row_ids { name } {
+ Gets a list of IDs in the master ID list
+ generated by the initial query submitted for pagination. IDs are
+ typically primary key values.
+
+ @param name The reference to the paginator object.
+
+ @return A Tcl list of row identifiers.
+} {
+ get_reference
+ return $properties(row_ids)
+}
+
ad_proc -public template::paginator::get_pages { name group } {
Gets a list of pages in a group, truncating if appropriate at the end.
@@ -268,7 +393,7 @@
set start [expr ($group - 1) * $group_size + 1]
set end [expr $start + $group_size]
- if { $end > $page_count } { set end $page_count }
+ if { $end > $page_count } { set end [expr $page_count] }
set pages [list]
@@ -344,6 +469,9 @@
upvar 2 $datasource:rowcount rowcount
set rowcount 0
+ upvar 2 $datasource:columns columns
+ set columns { page context }
+
foreach page $pages {
incr rowcount
@@ -376,6 +504,9 @@
upvar 2 $datasource:rowcount rowcount
set rowcount 0
+ upvar 2 $datasource:columns columns
+ set columns { page }
+
foreach page $pages {
incr rowcount
@@ -458,10 +589,28 @@
get_reference
upvar 2 $datasource info
+ if { $page > $properties(page_count) } {
+ set page $properties(page_count)
+ }
+
+ set group [get_group $name $page]
+ set groupsize $properties(groupsize)
+
set info(page_count) $properties(page_count)
+ set info(group_count) $properties(group_count)
+ set info(current_page) $page
+ set info(current_group) $group
- array set info [list next_page {} previous_page {} \
- next_group {} previous_group {}]
+ array set info {
+ next_page {}
+ previous_page {}
+ next_group {}
+ previous_group {}
+ next_page_context {}
+ previous_page_context {}
+ next_group_context {}
+ previous_group_context {}
+ }
if { $page > 1 } {
set info(previous_page) [expr $page - 1]
@@ -471,8 +620,6 @@
set info(next_page) [expr $page + 1]
}
- set group [get_group $name $page]
- set groupsize $properties(groupsize)
if { $group > 1 } {
set info(previous_group) [expr ($group - 2) * $groupsize + 1]
@@ -481,6 +628,15 @@
if { $group < $properties(group_count) } {
set info(next_group) [expr $group * $groupsize + 1]
}
+
+ # If the paginator is contextual, set the context
+ if { [info exists properties(context_ids)] } {
+ foreach elm { next_page previous_page next_group previous_group } {
+ if { [exists_and_not_null info($elm)] } {
+ set info(${elm}_context) [lindex $properties(context_ids) [expr $info($elm) -1]]
+ }
+ }
+ }
}
ad_proc -public template::paginator::get_data { statement_name name datasource query id_column page } {
@@ -505,7 +661,9 @@
template::util::list_to_lookup $ids row_order
# substitute the current page set
- set query [uplevel 2 "db_map ${statement_name}_partial"]
+ if { [empty_string_p $query] } {
+ set query [uplevel 2 "db_map ${statement_name}_partial"]
+ }
# DEDS: quote the ids so that we are not
# necessarily limited to integer keys
@@ -558,6 +716,57 @@
}
+ad_proc -public template::paginator::get_query { name id_column page } {
+ Returns a query with the data for the rows on the current page.
+
+ @param name The reference to the paginator object.
+ @param query The query to execute, containing IN (CURRENT_PAGE_SET).
+ @param id_column The name of the ID column in the display query (required
+ to order rows properly).
+} {
+ set ids [get_row_ids $name $page]
+
+ if { ![empty_string_p $ids] } {
+ # calculate the base row number for the page
+ upvar 2 __page_firstrow firstrow
+ set firstrow [get_row $name $page]
+
+ # build a hash of row order to order the rows on the page
+ upvar 2 __page_order row_order
+ template::util::list_to_lookup $ids row_order
+
+ set query "CURRENT_PAGE_SET"
+
+ # DEDS: quote the ids so that we are not
+ # necessarily limited to integer keys
+ set quoted_ids [list]
+ foreach one_id $ids {
+ lappend quoted_ids "'[DoubleApos $one_id]'"
+ }
+ set in_list [join $quoted_ids ","]
+ if { ! [regsub CURRENT_PAGE_SET $query $in_list query] } {
+ error "Token CURRENT_PAGE_SET not found."
+ }
+
+ if { [llength $in_list] == 0 } {
+ uplevel 2 "set $datasource:rowcount 0"
+ return
+ }
+
+ # Return the query with CURRENT_PAGE_SET slugged
+ return $query
+ } else {
+ return "null"
+ }
+}
+
+ad_proc -public template::paginator::reset { name query } {
+ Resets the cache for a query.
+} {
+ cache flush $name:$query:context_ids
+ cache flush $name:$query:row_ids
+}
+
ad_proc -private template::paginator::get_reference {} {
Get a reference to the paginator properties (internal helper)
} {