Index: openacs-4/packages/xowiki/tcl/includelet-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/tcl/includelet-procs.tcl,v diff -u -r1.26 -r1.27 --- openacs-4/packages/xowiki/tcl/includelet-procs.tcl 15 Apr 2008 09:12:44 -0000 1.26 +++ openacs-4/packages/xowiki/tcl/includelet-procs.tcl 17 Apr 2008 11:45:55 -0000 1.27 @@ -2623,10 +2623,10 @@ {-form_item_id:integer} {-form} {-orderby "_last_modified,desc"} - {-all:boolean false} - {-publish_states "ready|life"} + {-publish_status "ready"} {-field_names} {-unless} + {-where} {-csv true} }} } @@ -2635,7 +2635,7 @@ my get_parameters my instvar __including_page set o $__including_page - + my log "start render" ::xo::Page requireCSS "/resources/acs-templating/lists.css" set return_url [::xo::cc url]?[::xo::cc actual_query] @@ -2657,63 +2657,14 @@ set field_names {_name _last_modified _creation_user} } - set sql_atts [list instance_attributes ci.name] - foreach att [::xowiki::FormPage array names db_slot] {set __att($att) 1} - set common_atts [list last_modified creation_user] - foreach att $common_atts { - lappend sql_atts p.$att - set __att($att) 1 - } - #my msg __att=[array names __att], - #my msg sql_atts=$sql_atts - #my msg field_names=$field_names - - # set cr_field_spec [::xowiki::PageInstance get_short_spec_from_form_constraints \ - # -name @cr_fields \ - # -form_constraints $form_constraints] - # if some fields are hidden in the form, there might still be values (creation_user, etc) - # maybe filter hidden? ignore for the time being. - set cr_field_spec "" - # - set field_spec [::xowiki::PageInstance get_short_spec_from_form_constraints \ - -name @fields \ - -form_constraints $form_constraints] - - foreach spec_name $field_names { - set short_spec [::xowiki::PageInstance get_short_spec_from_form_constraints \ - -name $spec_name \ + set form_fields [::xowiki::FormPage get_table_form_fields \ + -base_item $form_item \ + -field_names $field_names \ -form_constraints $form_constraints] + # $form_item show_fields $form_fields + foreach f $form_fields {set __ff([$f name]) $f} + my log "get form_fields done" - switch -glob -- $spec_name { - __* {error not_allowed} - _* { - set varname [string range $spec_name 1 end] - if {![info exists __att($varname)]} { - error "unknown attribute $spec_name" - } - set f [$form_item create_raw_form_field \ - -name $spec_name \ - -slot [$form_item find_slot $varname] \ - -spec $cr_field_spec,$short_spec] - if {$spec_name eq "_text"} { - lappend sql_atts "bt.content as text" - } elseif {$spec_name ne "_name"} { - lappend sql_atts p.$varname - } - } - default { - set f [$form_item create_raw_form_field \ - -name $spec_name \ - -slot "" \ - -spec $field_spec,$short_spec] - } - } - lappend form_fields $f - set __ff($spec_name) $f - } - #my msg ff=[array names __ff] - #$form_item show_fields $form_fields - if {[info exists __ff(_creation_user)]} {$__ff(_creation_user) label "By User"} set cols "" @@ -2725,76 +2676,56 @@ -orderby $fn] \n } append cols [list ImageField_DeleteIcon delete -label "" ] \n - TableWidget t1 -volatile -columns $cols # - # Sorting is done for the time being in tcl. This has the advantage - # that page_orders can be sorted with the special mixin and that + # Sorting is done for the time being in Tcl. This has the advantage + # that page_order can be sorted with the special mixin and that # instance attributes can be used for sorting as well. # foreach {att order} [split $orderby ,] break if {$att eq "_page_order"} { t1 mixin add ::xo::OrderedComposite::IndexCompare } + #my msg "order=[expr {$order eq {asc} ? {increasing} : {decreasing}}] $att" t1 orderby -order [expr {$order eq "asc" ? "increasing" : "decreasing"}] $att - # - # build SQL query and iterate over the results - # maybe this could be slightly faster by using instantiate_objects # - if {$all} { - # legacy - set publish_status_clause "" - } elseif [info exists publish_states] { - array set valid_state [list production 1 ready 1 life 1 expired 1] - set clauses [list] - foreach state [split $publish_states |] { - if {![info exists valid_state($state)]} { - error "no such state: '$state'; valid states are: production, ready, life, expired" - } - lappend clauses "ci.publish_status='$state'" - } - set publish_status_clause " and ([join $clauses { or }])" - } else { - set publish_status_clause [expr {$all ? "" : " and ci.publish_status <> 'production' "}] + # Compute filter clauses + # + set init_vars [list] + array set uc {tcl false h ""} + if {[info exists unless]} { + array set uc [::xowiki::FormPage filter_expression $unless ||] + set init_vars [concat $init_vars $uc(vars)] } + array set wc {tcl true h ""} + if {[info exists where]} { + array set wc [::xowiki::FormPage filter_expression $where &&] + set init_vars [concat $init_vars $wc(vars)] + } + #my msg uc=[array get uc] + #my msg wc=[array get wc] - set items [::xowiki::FormPage get_instances_from_db \ - -select_attributes $sql_atts \ - -from_clause ", xowiki_form_pagei p" \ - -with_subtypes false \ - -where_clause " p.page_template = $form_item_id \ - and p.xowiki_form_page_id = bt.revision_id \ - $publish_status_clause" \ + # + # build SQL query and iterate over the results + # + set items [::xowiki::FormPage get_children \ + -base_item_id $form_item_id \ + -form_fields $form_fields \ + -publish_status $publish_status \ + -always_queried_attributes [list _name _last_modified _creation_user] \ + -h_where $wc(h) \ -folder_id [$package_id folder_id]] - $items destroy_on_cleanup + my log "query done" - if {[info exists unless]} { - #my msg unless=$unless - #example for unless: wf_current_state = closed|accepted || x = 1 - set expr_clause [list] - foreach clause [split [string map [list || \x00] $unless] \x00] { - if {[regexp {^(.+)\s*([=])\s*(.*)$} $clause _ lhs op rhs_expr]} { - set lhs "\$__ia([string trim $lhs])" - set op eq - foreach p [split $rhs_expr |] { - lappend expr_clause "$lhs $op {$p}" - } - } else { - my msg "ignoring $clause" - } - } - set unless_clause [join $expr_clause ||] - #my msg $unless_clause - } else { - set unless_clause false - } - + my log "insert into table" foreach p [$items children] { $p set package_id $package_id - array set __ia [$p set instance_attributes] - if {[expr $unless_clause]} continue + array set __ia $init_vars + array set __ia [$p instance_attributes] + if {[expr $uc(tcl)]} continue + if {![expr $wc(tcl)]} continue set page_link [$package_id pretty_link [$p name]] t1 add \ @@ -2810,21 +2741,10 @@ $__c set _last_modified [$p set last_modified] foreach __fn $field_names { - switch -glob -- $__fn { - __* {error not_allowed} - _* {set __value [$p set [string range $__fn 1 end]]} - default { - if {[info exists __ia($__fn)]} { - set __value $__ia($__fn) - } else { - # the field was added after the current entry was created - set __value "" - } - } - } - $__c set $__fn [$__ff($__fn) pretty_value $__value] + $__c set $__fn [$__ff($__fn) pretty_value [$p property $__fn]] } } + my log "insert into table done" my instvar name set includelet_key "" @@ -2849,6 +2769,7 @@ set csv_href "[::xo::cc url]?[::xo::cc actual_query]&includelet_key=[ns_urlencode $includelet_key]" append html "csv" } + my log "render done" return $html } } Index: openacs-4/packages/xowiki/tcl/xowiki-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/tcl/xowiki-procs.tcl,v diff -u -r1.227 -r1.228 --- openacs-4/packages/xowiki/tcl/xowiki-procs.tcl 16 Apr 2008 20:22:39 -0000 1.227 +++ openacs-4/packages/xowiki/tcl/xowiki-procs.tcl 17 Apr 2008 11:45:55 -0000 1.228 @@ -1486,6 +1486,82 @@ next } + FormPage proc get_children { + -base_item_id + -folder_id + -form_fields + {-publish_status ready} + {-h_where} + {-always_queried_attributes {_name _last_modified _creation_user}} + } { + # + # Get query attributes for all tables (to allow e.g. sorting by time) + # + set sql_atts [list bt.instance_attributes] + foreach att $always_queried_attributes { + set name [string range $att 1 end] + if {$name eq "name"} { + lappend sql_atts ci.$name + } else { + lappend sql_atts bt.$name + } + } + # + # Collect SQL attributes from form_fields + # + foreach f $form_fields { + if {![$f exists __base_field]} continue + set field_name [$f name] + if {$field_name eq "_text"} { + lappend sql_atts "bt.content as text" + } elseif {[lsearch -exact $always_queried_attributes $field_name] == -1} { + lappend sql_atts bt.[$f set __base_field] + } + } + #my msg sql_atts=$sql_atts + + # + # Build WHERE clause + # + if {$publish_status eq "all"} { + # legacy + set publish_status_clause "" + } else { + array set valid_state [list production 1 ready 1 life 1 expired 1] + set clauses [list] + foreach state [split $publish_status |] { + if {![info exists valid_state($state)]} { + error "no such state: '$state'; valid states are: production, ready, life, expired" + } + lappend clauses "ci.publish_status='$state'" + } + set publish_status_clause " and ([join $clauses { or }])" + } + set filter_clause "" + if {[info exists h_where] && [::xo::db::has_hstore]} { + #set filter_clause " and '$h_where' <@ bt.hkey" + } + + set orderby ""; set page_size 20; set page_number ""; set base_table "cr_revisions" + set sql [::xowiki::FormPage instance_select_query \ + -select_attributes $sql_atts \ + -from_clause "" \ + -where_clause " bt.page_template = $base_item_id \ + $publish_status_clause $filter_clause" \ + -orderby $orderby \ + -with_subtypes false \ + -folder_id $folder_id \ + -page_size $page_size \ + -page_number $page_number \ + -base_table xowiki_form_pagei \ + ] + my log $sql + set items [::xowiki::FormPage instantiate_objects -sql $sql \ + -object_class ::xowiki::FormPage] + return $items + } + + FormPage instproc property {name {default ""}} { if {[string match "_*" $name]} { set key [string range $name 1 end] Index: openacs-4/packages/xowiki/tcl/xowiki-www-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/tcl/xowiki-www-procs.tcl,v diff -u -r1.142 -r1.143 --- openacs-4/packages/xowiki/tcl/xowiki-www-procs.tcl 16 Apr 2008 10:32:38 -0000 1.142 +++ openacs-4/packages/xowiki/tcl/xowiki-www-procs.tcl 17 Apr 2008 11:45:55 -0000 1.143 @@ -416,6 +416,95 @@ namespace eval ::xowiki { + FormPage proc get_table_form_fields { + -base_item + -field_names + -form_constraints + } { + + #set sql_atts [list ci.name bt.instance_attributes] + foreach att [::xowiki::FormPage array names db_slot] {set __att($att) 1} + foreach att [list last_modified creation_user] { + lappend sql_atts bt.$att + set __att($att) 1 + } + + # set cr_field_spec [::xowiki::PageInstance get_short_spec_from_form_constraints \ + # -name @cr_fields \ + # -form_constraints $form_constraints] + # if some fields are hidden in the form, there might still be values (creation_user, etc) + # maybe filter hidden? ignore for the time being. + + set cr_field_spec "" + set field_spec [::xowiki::PageInstance get_short_spec_from_form_constraints \ + -name @fields \ + -form_constraints $form_constraints] + + foreach field_name $field_names { + set short_spec [::xowiki::PageInstance get_short_spec_from_form_constraints \ + -name $field_name \ + -form_constraints $form_constraints] + + switch -glob -- $field_name { + __* {error not_allowed} + _* { + set varname [string range $field_name 1 end] + if {![info exists __att($varname)]} { + error "unknown attribute $field_name" + } + set f [$base_item create_raw_form_field \ + -name $field_name \ + -slot [$base_item find_slot $varname] \ + -spec $cr_field_spec,$short_spec] + $f set __base_field $varname + } + default { + set f [$base_item create_raw_form_field \ + -name $field_name \ + -slot "" \ + -spec $field_spec,$short_spec] + } + } + lappend form_fields $f + } + return $form_fields + } + + FormPage proc h_double_quote {value} { + if {[regexp {[ ,\"\\=>]} $value]} { + set value \"[string map [list \" \\\\\" \\ \\\\ ' \\\\'] $value]\" + } + return $value + } + + FormPage proc filter_expression { + input_expr + logical_op + } { + #my msg unless=$unless + #example for unless: wf_current_state = closed|accepted || x = 1 + set tcl_clause [list] + set h_clause [list] + set vars [list] + foreach clause [split [string map [list $logical_op \x00] $input_expr] \x00] { + if {[regexp {^(.+)\s*([=])\s*(.*)$} $clause _ lhs op rhs_expr]} { + set lhs [string trim $lhs] + set hleft [my h_double_quote $lhs] + set tleft "\$__ia($lhs)" + lappend vars $lhs "" + set op eq + foreach p [split $rhs_expr |] { + lappend tcl_clause "$tleft $op {$p}" + lappend h_clause "$hleft=>[my h_double_quote $p]" + } + } else { + my msg "ignoring $clause" + } + } + return [list tcl [join $tcl_clause $logical_op] h [join $h_clause ,] vars $vars] + #my msg $expression + } + FormPage instproc create_category_fields {} { set category_spec [my get_short_spec @categories] foreach f [split $category_spec ,] {