Index: openacs-4/packages/xowiki/xowiki.info =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/xowiki.info,v diff -u -r1.148.2.26 -r1.148.2.27 --- openacs-4/packages/xowiki/xowiki.info 19 Mar 2015 10:15:12 -0000 1.148.2.26 +++ openacs-4/packages/xowiki/xowiki.info 23 Mar 2015 11:54:42 -0000 1.148.2.27 @@ -10,7 +10,7 @@ t xowiki - + Gustaf Neumann A xotcl-based enterprise wiki system with multiple object types 2015-02-11 @@ -55,14 +55,14 @@ BSD-Style 2 - + - + Index: openacs-4/packages/xowiki/tcl/folder-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/tcl/folder-procs.tcl,v diff -u -r1.27.2.11 -r1.27.2.12 --- openacs-4/packages/xowiki/tcl/folder-procs.tcl 19 Mar 2015 10:15:12 -0000 1.27.2.11 +++ openacs-4/packages/xowiki/tcl/folder-procs.tcl 23 Mar 2015 11:54:42 -0000 1.27.2.12 @@ -55,10 +55,32 @@ return [$tree render -style yuitree -js $js] } + folders instproc folder_query { + -form_id:required + -package_id:required + {-parent_id ""} + } { + if {$parent_id eq ""} { + return [subst { + select * from xowiki_form_instance_item_view + where page_template = '$form_id' and package_id = '$package_id' + and publish_status = 'ready' + }] + } + return [subst { + select * from xowiki_form_instance_children ch + left join xowiki_form_instance_attributes xa on (ch.item_id = xa.item_id) + where page_template = '$form_id' and package_id = '$package_id' + and root_item_id = '$parent_id' + and publish_status = 'ready' + }] + } + folders instproc collect_folders { -package_id:required -folder_form_id:required -link_form_id:required + {-parent_id ""} {-subtree_query ""} {-depth 3} } { @@ -70,17 +92,25 @@ # # get folders # - set folder_pages [::xowiki::FormPage get_form_entries \ - -base_item_ids $folder_form_id -form_fields "" \ - -extra_where_clause $subtree_query \ - -publish_status ready -package_id $package_id] + set sql [my folder_query -form_id $folder_form_id \ + -parent_id $parent_id \ + -package_id $package_id] + ns_log notice "folder_pages:\n$sql" + set folder_pages [::xowiki::FormPage instantiate_objects -sql $sql \ + -named_objects true -object_named_after "item_id" \ + -object_class ::xowiki::FormPage -initialize true] + # # get links # - set links [::xowiki::FormPage get_form_entries \ - -base_item_ids $link_form_id -form_fields "" \ - -extra_where_clause $subtree_query \ - -publish_status ready -package_id $package_id] + set sql [my folder_query -form_id $link_form_id \ + -parent_id $parent_id \ + -package_id $package_id] + ns_log notice "links:\n$sql" + set links [::xowiki::FormPage instantiate_objects -sql $sql \ + -named_objects true -object_named_after "item_id" \ + -object_class ::xowiki::FormPage -initialize true] + #my msg "[llength [$links children]] links" set folders [$folder_pages children] @@ -101,28 +131,10 @@ # we found a cross-package link. These kind of links require further queries # set target [$l get_target_from_link_page] - - # the following clause needs an oracle counter-part - if {[::xo::pg_version] < 9} { - set tree_sortkey [::xo::dc get_value get_tree_sort_key \ - "select tree_sortkey from acs_objects where object_id = [$target item_id]"] - set extra_where "and bt.item_id in (select object_id from acs_objects \ - where tree_sortkey between '$tree_sortkey' and tree_right('$tree_sortkey') \ - and object_type = 'content_item')" - } else { - ns_log notice "$target item_id = [$target item_id]" - set root_node [$target item_id] - set extra_where "and bt.item_id in ( - With RECURSIVE child_items AS ( - select item_id from cr_items where item_id = $root_node - UNION ALL - select ci.item_id from cr_items ci, child_items where ci.parent_id = child_items.item_id - ) select item_id from child_items)" - } - set sub_folders [my collect_folders -package_id [$target physical_package_id] \ -folder_form_id $folder_form_id -link_form_id $link_form_id \ - -subtree_query $extra_where -depth [expr {$depth -1}]] + -parent_id [$target item_id] \ + -depth [expr {$depth -1}]] foreach f $sub_folders { @@ -141,12 +153,12 @@ # TODO we could save the double-fetch by collecing in # get_form_entries via item-ids, not via new-objects # - ::xo::db::CrClass get_instance_from_db -item_id [$f item_id] + #::xo::db::CrClass get_instance_from_db -item_id [$f item_id] [$f item_id] set_resolve_context -package_id [$l package_id] -parent_id [$l item_id] } else { #my msg "2 found child [$f name] and reset parent_id from [$f parent_id] to [$f parent_id], package id [$l package_id]" $f set_resolve_context -package_id [$l package_id] -parent_id [$f parent_id] - ::xo::db::CrClass get_instance_from_db -item_id [$f item_id] + #::xo::db::CrClass get_instance_from_db -item_id [$f item_id] [$f item_id] set_resolve_context -package_id [$l package_id] -parent_id [$f parent_id] } 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.191.2.24 -r1.191.2.25 --- openacs-4/packages/xowiki/tcl/includelet-procs.tcl 4 Mar 2015 15:12:54 -0000 1.191.2.24 +++ openacs-4/packages/xowiki/tcl/includelet-procs.tcl 23 Mar 2015 11:54:42 -0000 1.191.2.25 @@ -126,6 +126,10 @@ } ::xowiki::Includelet proc publish_status_clause {{-base_table ci} value} { + set table_prefix "" + if {$base_table ne ""} { + set table_prefix "$base_table." + } if {$value eq "all"} { # legacy set publish_status_clause "" @@ -136,7 +140,7 @@ if {![info exists valid_state($state)]} { error "no such state: '$state'; valid states are: production, ready, live, expired" } - lappend clauses "$base_table.publish_status='$state'" + lappend clauses "${table_prefix}publish_status='$state'" } set publish_status_clause " and ([join $clauses { or }])" } @@ -3947,7 +3951,7 @@ #my log "exists category_id [info exists category_id]" set extra_where_clause "" if {[info exists category_id]} { - lassign [my category_clause $category_id bt.item_id] cnames extra_where_clause + lassign [my category_clause $category_id item_id] cnames extra_where_clause } set items [::xowiki::FormPage get_form_entries \ Index: openacs-4/packages/xowiki/tcl/weblog-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/tcl/weblog-procs.tcl,v diff -u -r1.63.2.6 -r1.63.2.7 --- openacs-4/packages/xowiki/tcl/weblog-procs.tcl 27 May 2014 07:11:25 -0000 1.63.2.6 +++ openacs-4/packages/xowiki/tcl/weblog-procs.tcl 23 Mar 2015 11:54:42 -0000 1.63.2.7 @@ -77,8 +77,6 @@ } if {$category_id ne ""} { set cnames [list] - #append extra_where_clause "and c.object_id = ci.item_id and c.category_id = $category_id " - #append extra_from_clause ",category_object_map c " foreach cid [split $category_id ,] { if {![string is integer -strict $category_id]} { ns_log warning "weblog: ignoring invalid category_id $cid" @@ -173,30 +171,42 @@ set query_parent_id $folder_id } - set sql \ + set sqlParams \ [list -parent_id :query_parent_id \ -select_attributes $attributes \ -orderby "publish_date desc" \ -base_table $base_table \ - -from_clause "\ - left outer join syndication s on s.object_id = bt.revision_id \ - left join xowiki_page_instance pi on (bt.revision_id = pi.page_instance_id) \ - left join xowiki_form_page fp on (bt.revision_id = fp.xowiki_form_page_id) \ - $extra_from_clause" \ -where_clause "ci.item_id not in ([my exclude_item_ids]) \ and ci.name != '::$folder_id' and ci.name not like '%weblog%' $date_clause \ - [::xowiki::Page container_already_rendered ci.item_id] \ + [::xowiki::Page container_already_rendered ci.item_id] \ $class_clause \ and ci.publish_status <> 'production' \ - $extra_where_clause" ] - + $extra_where_clause"] + if {$page_number ne ""} { lappend sql -page_number $page_number -page_size $page_size } + # + # Since there is no filtering on the left join tables, there is no + # need to incude these in the count query. + # set nr_items [::xo::dc get_value count-weblog-entries \ - [$base_type instance_select_query {*}$sql -count true]] + [$base_type instance_select_query \ + -from_clause $extra_from_clause \ + {*}$sqlParams -count true]] #my msg count=$nr_items - set s [$base_type instantiate_objects -sql [$base_type instance_select_query {*}$sql]] + + # + # Obtain the set of answers + # + set s [$base_type instantiate_objects \ + -sql [$base_type instance_select_query \ + -from_clause "\ + left outer join syndication s on s.object_id = bt.revision_id \ + left outer join xowiki_page_instance pi on (bt.revision_id = pi.page_instance_id) \ + left outer join xowiki_form_page fp on (bt.revision_id = fp.xowiki_form_page_id) \ + $extra_from_clause" \ + {*}$sqlParams]] foreach c [$s children] { $c instvar revision_id publish_date title name item_id creator creation_user \ 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.472.2.38 -r1.472.2.39 --- openacs-4/packages/xowiki/tcl/xowiki-procs.tcl 3 Mar 2015 16:08:22 -0000 1.472.2.38 +++ openacs-4/packages/xowiki/tcl/xowiki-procs.tcl 23 Mar 2015 11:54:42 -0000 1.472.2.39 @@ -142,9 +142,10 @@ -spec "hidden" ::xo::db::CrAttribute create state -default "" } - - # create various extra tables, indices and views + # + # Create various extra tables, indices and views + # ::xo::db::require index -table xowiki_form_page -col assignee ::xo::db::require index -table xowiki_page_instance -col page_template @@ -190,6 +191,10 @@ ::xo::db::require index -table xowiki_page -col page_order \ -using [expr {[::xo::dc has_ltree] ? "gist" : ""}] + # + # view: xowiki_page_live_revision + # + set sortkeys [expr {[db_driverkey ""] eq "oracle" ? "" : ", ci.tree_sortkey, ci.max_child_sortkey"}] ::xo::db::require view xowiki_page_live_revision \ "select p.*, cr.*,ci.parent_id, ci.name, ci.locale, ci.live_revision, \ @@ -200,14 +205,207 @@ and p.page_id = cr.revision_id \ and ci.publish_status <> 'production'" + # + # xowiki_form_instance_item_index: + # + # A materialized table of xowiki formpage instances, containing + # just the item information, but combined with other attributes + # frequently used for indexing (like page_id, paren_id, ... hkey). + # + # Rationale: The quality of indices on cr_revisions tend to + # decrease when there are many revisions stored in the database, + # since the number of duplicates increases due to non-live + # revisions. This table can be used for indexing just the live + # revision on the item level. Example query combining package_id + # and page_template: + # + # select count(*) from xowiki_form_instance_item_index + # where package_id = 18255683 + # and page_template = 20260757 + # and publish_status='ready'; + # + # In order to get rid of this helper table (may be to regenerate it + # on the next load) use + # + # drop table xowiki_form_instance_item_index cascade; + # + # + #ns_logctl severity Debug(sql) on + # + # $populate is a dml statement to populate the materialized index + # xowiki_form_instance_item_index, when it does not exist. + # + set popuplate { + insert into xowiki_form_instance_item_index ( + item_id, name, package_id, parent_id, publish_status, + page_template, assignee, state ) + select ci.item_id, ci.name, o.package_id, ci.parent_id, ci.publish_status, + xpi.page_template, xfp.assignee, xfp.state + from cr_items ci + join xowiki_page_instance xpi on (ci.live_revision = xpi.page_instance_id) + join xowiki_form_page xfp on (ci.live_revision = xfp.xowiki_form_page_id) + join acs_objects o on (o.object_id = ci.item_id) + } + + if {[::xo::dc has_hstore]} { + ::xo::db::require table xowiki_form_instance_item_index { + item_id {integer references cr_items(item_id) on delete cascade} + name {character varying(400)} + package_id {integer} + parent_id {integer references cr_items(item_id) on delete cascade} + publish_status {text} + page_template {integer references cr_items(item_id) on delete cascade} + hkey {hstore} + assignee {integer references parties(party_id) on delete cascade} + state {text} + } $popuplate + ::xo::db::require index -table xowiki_form_instance_item_index -col hkey -using gist + set hkey_in_view "xi.hkey," + } else { + ::xo::db::require table xowiki_form_instance_item_index { + item_id {integer references cr_items(item_id) on delete cascade} + name {character varying(400)} + package_id {integer} + parent_id {integer references cr_items(item_id) on delete cascade} + publish_status {text} + page_template {integer references cr_items(item_id) on delete cascade} + assignee {integer references parties(party_id) on delete cascade} + state {text} + } $popuplate + set hkey_in_view "" + } + + ::xo::db::require index -table xowiki_form_instance_item_index -col item_id -unique true + ::xo::db::require index -table xowiki_form_instance_item_index -col parent_id,name -unique true + ::xo::db::require index -table xowiki_form_instance_item_index -col page_template + ::xo::db::require index -table xowiki_form_instance_item_index -col page_template,package_id + ::xo::db::require index -table xowiki_form_instance_item_index -col parent_id + ::xo::db::require index -table xowiki_form_instance_item_index -col parent_id,page_template + + # + # Define helper views in connection with the form_instance_item_index: + # + # - xowiki_form_instance_item_view + # - xowiki_form_instance_children + # - xowiki_form_instance_attributes + + # + # - xowiki_form_instance_item_view: + # + # A view similar to xowiki_form_pagei, but containing already + # often extra-joined attributes like parent_id. This view returns + # only the values of the live revisions, and uses the + # form_instance_item_index for quick lookup. Example query to + # obtain all attributes necessary for object creation based on + # package_id and page_template. + # + # select * from xowiki_form_instance_item_view + # where package_id = 18255683 + # and page_template = 20260757 + # and publish_status='ready'; + # + ::xo::db::require view xowiki_form_instance_item_view [subst { + SELECT + xi.package_id, xi.parent_id, xi.name, + $hkey_in_view xi.publish_status, xi.assignee, xi.state, xi.page_template, xi.item_id, + o.object_id, o.object_type, o.title AS object_title, o.context_id, + o.security_inherit_p, o.creation_user, o.creation_date, o.creation_ip, + o.last_modified, o.modifying_user, o.modifying_ip, o.tree_sortkey, o.max_child_sortkey, + cr.revision_id, cr.title, content_revision__get_content(cr.revision_id) AS data, + cr_text.text_data AS text, cr.description, cr.publish_date, cr.mime_type, cr.nls_language, + xowiki_form_page.xowiki_form_page_id, + xowiki_page_instance.page_instance_id, + xowiki_page_instance.instance_attributes, + xowiki_page.page_id, + xowiki_page.page_order, + xowiki_page.creator + FROM cr_text, + xowiki_form_instance_item_index xi + left join cr_items ci on (ci.item_id = xi.item_id) + left join cr_revisions cr on (cr.revision_id = ci.live_revision) + left join acs_objects o on (o.object_id = ci.live_revision) + left join xowiki_page on (o.object_id = xowiki_page.page_id) + left join xowiki_page_instance on (o.object_id = xowiki_page_instance.page_instance_id) + left join xowiki_form_page on (o.object_id = xowiki_form_page.xowiki_form_page_id) + }] + + # xowiki_form_instance_children: + # + # Return the root_item_id and all attributes of the + # form_instance_item_index of all child items under the tree based + # on parent_ids. Use a query like the following to count the + # children of an item having a certain page_template (e.g. + # find all the folders/links/... having the the specified item + # as parent): + # + # select count(*) from xowiki_form_instance_children + # where root_item_id = 18255779 + # and page_template = 20260757 + # and publish_status='ready'; + # + # Note: this query needs an oracle counter-part + + ::xo::db::require view xowiki_form_instance_children { + With RECURSIVE child_items AS ( + select item_id as root_item_id, * from xowiki_form_instance_item_index + UNION ALL + select child_items.root_item_id, xi.* from xowiki_form_instance_item_index xi, child_items + where xi.parent_id = child_items.item_id + ) + select * from child_items + } + + # xowiki_form_instance_attributes + # + # Return for a given item_id the full set of attributes like the + # one returned from xowiki_form_instance_item_view. The idea is to + # make it convenient to obtain from a query all attributes + # necessary for creating instances. The same view can be used to + # complete either values from the xowiki_form_instance_item_index + # + # select * from xowiki_form_instance_item_index xi + # left join xowiki_form_instance_attributes xa on xi.item_id = xa.item_id; + # + # or from xowiki_form_instance_children + # + # select * from xowiki_form_instance_children ch + # left join xowiki_form_instance_attributes xa on ch.item_id = xa.item_id; + # + # + ::xo::db::require view xowiki_form_instance_attributes { + SELECT + ci.item_id, + o.package_id, + o.object_id, o.object_type, o.title AS object_title, o.context_id, + o.security_inherit_p, o.creation_user, o.creation_date, o.creation_ip, + o.last_modified, o.modifying_user, o.modifying_ip, o.tree_sortkey, o.max_child_sortkey, + cr.revision_id, cr.title, content_revision__get_content(cr.revision_id) AS data, + cr_text.text_data AS text, cr.description, cr.publish_date, cr.mime_type, cr.nls_language, + xowiki_form_page.xowiki_form_page_id, + xowiki_page_instance.page_instance_id, + xowiki_page_instance.instance_attributes, + xowiki_page.page_id, + xowiki_page.page_order, + xowiki_page.creator + FROM cr_text, cr_items ci + left join cr_revisions cr on (cr.revision_id = ci.live_revision) + left join acs_objects o on (o.object_id = ci.live_revision) + left join xowiki_page on (o.object_id = xowiki_page.page_id) + left join xowiki_page_instance on (o.object_id = xowiki_page_instance.page_instance_id) + left join xowiki_form_page on (o.object_id = xowiki_form_page.xowiki_form_page_id) + } + + #ns_logctl severity Debug(sql) off + + ############################# # # A simple autoname handler # # The autoname handler has the purpose to generate new names based # on a stem and a parent_id. Typically this is used for the - # autonaming of FormPages. The goal is to generate "nice" names, + # auto-naming of FormPages. The goal is to generate "nice" names, # i.e. with rather small numbers. # # Instead of using the table below, another option would be to use @@ -1065,7 +1263,49 @@ return [my exists_property form_constraints] } + FormPage instproc hstore_attributes {} { + # Per default, we save all instance attributes in hstore, but a + # subclass/object might have different requirements. + return [my instance_attributes] + } + # + # Update helper for xowiki_form_instance_item_index (called from + # cr_procs, whenever a live-revision becomes updated). + # + FormPage ad_instproc update_item_index {} { + } { + my instvar item_id package_id parent_id publish_status \ + page_template instance_attributes assignee state + + set rows [xo::dc dml update_xowiki_form_instance_item_index { + update xowiki_form_instance_item_index + set item_id = :item_id, name = :name, package_id = :package_id, + parent_id = :parent_id, publish_status = :publish_status, + page_template = :page_template, assignee = :assignee, + state = :state + where item_id = :item_id + }] + if {$rows ne "" && $rows < 1} { + ::xo::dc dml insert_xowiki_form_instance_item_index { + insert into xowiki_form_instance_item_index ( + item_id, name, package_id, parent_id, publish_status, + page_template, assignee, state + ) values ( + :item_id, :name, :package_id, :parent_id, :publish_status, + :page_template, :assignee, :state + ) + } + } + if {[$package_id get_parameter use_hstore 0]} { + set hkey [::xowiki::hstore::dict_as_hkey [my hstore_attributes]] + xo::dc dml update_hstore "update xowiki_form_instance_item_index \ + set hkey = '$hkey' \ + where item_id = :item_id" + } + } + + # # helper for nls and lang # @@ -3079,13 +3319,6 @@ return 0 } - FormPage proc h_double_quote {value} { - if {[regexp {[ ,\"\\=>]} $value]} { - set value \"[string map [list \" \\\\\" \\ \\\\ ' \\\\'] $value]\" - } - return $value - } - FormPage proc filter_expression { {-sql true} input_expr @@ -3125,7 +3358,7 @@ lappend tcl_clause "\[my property $lhs\] $tcl_op($op) {$rhs}" } } else { - set hleft [my h_double_quote $lhs] + set hleft [::xowiki::hstore::double_quote $lhs] lappend vars $lhs "" if {$op eq "contains"} { #make approximate query @@ -3144,7 +3377,7 @@ # TODO: think about a solution for other operators with # hstore maybe: extracting it by a query via hstore and # compare in plain SQL - lappend h_clause "$hleft=>[my h_double_quote $rhs]" + lappend h_clause "$hleft=>[::xowiki::hstore::double_quote $rhs]" } } } @@ -3193,33 +3426,35 @@ # "-always_queried_attributes *" means to obtain enough attributes # to allow a save operatons etc. on the instances. # - - set sql_atts [list ci.parent_id bt.revision_id bt.instance_attributes \ - bt.creation_date bt.creation_user bt.last_modified \ - "bt.object_package_id as package_id" bt.title \ - bt.page_template bt.state bt.assignee - ] + + set sql_atts { + item_id name publish_status object_type + parent_id revision_id instance_attributes + creation_date creation_user last_modified + package_id title page_template state assignee + } + if {$always_queried_attributes eq "*"} { lappend sql_atts \ - bt.object_type bt.object_id \ - bt.description bt.publish_date bt.mime_type nls_language "bt.data as text" \ - bt.creator bt.page_order bt.page_id \ - bt.page_instance_id bt.xowiki_form_page_id + object_type object_id \ + description publish_date mime_type nls_language "data as text" \ + creator page_order page_id \ + page_instance_id xowiki_form_page_id } else { foreach att $always_queried_attributes { set name [string range $att 1 end] - lappend sql_atts bt.$name + lappend sql_atts $name } - } + } # # Compute the list of field_names from the already covered sql # attributes # set covered_attributes [list _name _publish_status _item_id _object_type] foreach att $sql_atts { - regexp {[.]([^ ]+)} $att _ name - lappend covered_attributes _$name + #regexp {[.]([^ ]+)} $att _ name + lappend covered_attributes _$att } # @@ -3234,16 +3469,16 @@ if {$field_name eq "_text"} { lappend sql_atts "bt.data as text" } else { - lappend sql_atts bt.[$f set __base_field] + lappend sql_atts [$f set __base_field] } } #my msg sql_atts=$sql_atts # # Build parts of WHERE clause # - set publish_status_clause [::xowiki::Includelet publish_status_clause -base_table ci $publish_status] - + set publish_status_clause [::xowiki::Includelet publish_status_clause \ + -base_table "" $publish_status] # # Build filter clause (uses hstore if configured) # @@ -3253,7 +3488,7 @@ [$package_id get_parameter use_hstore 0] }] if {$use_hstore && $wc(h) ne ""} { - set filter_clause " and '$wc(h)' <@ bt.hkey" + set filter_clause " and '$wc(h)' <@ hkey" } #my msg "exists sql=[info exists wc(sql)]" if {$wc(sql) ne "" && $wc(h) ne ""} { @@ -3267,37 +3502,43 @@ # Build package clause # if {$from_package_ids eq ""} { - set package_clause "and object_package_id = :package_id" + set package_clause "and package_id = :package_id" } elseif {$from_package_ids eq "*"} { set package_clause "" } elseif {[llength $from_package_ids] == 1} { - set package_clause "and object_package_id = :from_package_ids" + set package_clause "and package_id = :from_package_ids" } else { - set package_clause "and object_package_id in ([join $from_package_ids ,])" + set package_clause "and package_id in ([join $from_package_ids ,])" } if {$parent_id eq "*"} { # instance_select_query expects "" for all parents, but for the semantics # of this method, "*" looks more appropriate set parent_id "" } + + if {[llength $base_item_ids] == 0} { + error "base_item_ids must not be empty" + } # # transform all into an SQL query # - set sql [::xowiki::FormPage instance_select_query \ - -select_attributes $sql_atts \ - -from_clause "" \ - -where_clause " bt.page_template in ([join $base_item_ids ,]) \ + if {$page_number ne ""} { + set limit $page_size + set offset [expr {$page_size*($page_number-1)}] + } else { + set limit "" + set offset "" + } + set sql [::xo::dc select \ + -vars [join $sql_atts ", "] \ + -from xowiki_form_instance_item_view \ + -where " page_template in ([join $base_item_ids ,]) \ $publish_status_clause $filter_clause $package_clause \ $extra_where_clause" \ - -orderby $orderby \ - -with_subtypes false \ - -parent_id $parent_id \ - -page_size $page_size \ - -page_number $page_number \ - -base_table xowiki_form_pagei \ - ] - #my ds $sql + -orderby $orderby \ + -limit $limit -offset $offset] + #ns_log notice "NEW SQL:\n\n$sql\n" # # When we query all attributes, we return objects named after the Index: openacs-4/packages/xowiki/tcl/xowiki-utility-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/tcl/xowiki-utility-procs.tcl,v diff -u -r1.31.2.10 -r1.31.2.11 --- openacs-4/packages/xowiki/tcl/xowiki-utility-procs.tcl 3 Mar 2015 16:08:22 -0000 1.31.2.10 +++ openacs-4/packages/xowiki/tcl/xowiki-utility-procs.tcl 23 Mar 2015 11:54:42 -0000 1.31.2.11 @@ -33,7 +33,6 @@ } # - # # Helper for tidying up HTML # ::xotcl::Object create tidy @@ -59,11 +58,15 @@ # # Helper for virus checks # + # Install clamav daemon with + # FC21: yum install clamav-scanner + # Ununtu: apt-get install clamav-daemon + # ::xotcl::Object create virus virus proc check {fn} { if {[[::xo::cc package_id] get_parameter clamav 1] && [info commands ::util::which] ne ""} { - set clamscanCmd [::util::which clamscan] + set clamscanCmd [::util::which clamdscan] if {$clamscanCmd ne "" && [file readable $fn]} { if {[catch {exec $clamscanCmd $fn 2>@1} result]} { ns_log warning "[self] virus found:\n$result" @@ -73,7 +76,79 @@ } return 0 } +} +namespace eval ::xowiki::hstore { + # + # Helper functions for hstore + # + ad_proc double_quote {value} { + @return double_quoted value as appropriate for hstore + } { + if {[regexp {[ ,\"\\=>\n\']} $value]} { + set value \"[string map [list \" \\\" \\ \\\\ ' ''] $value]\" + } + return $value + } + + ad_proc dict_as_hkey {dict} { + @return dict value in form of a hstore key. + } { + set keys {} + foreach {key value} $dict { + set v [double_quote $value] + if {$v eq ""} continue + lappend keys [double_quote $key]=>$v + } + return [join $keys ,] + } + + ad_proc update_form_instance_item_index { + {-package_id} + {-object_class ::xowiki::FormPage} + {-initialize false} + } { + update all instance attributes in hstore + } { + # + # This proc can be used from ds/shell as follows + # + # ::xowiki::hstore::update_form_instance_item_index -package_id $package_id + # + # Check the packages which do not have the hkey set: + # + # select hkey from xowiki_form_instance_item_index where hkey is null; + # + + ::xo::Package initialize -package_id $package_id + if {![::xo::dc has_hstore] && [$package_id get_parameter use_hstore 0] } {return 0} + + set sql { + select * from xowiki_form_instance_item_view + where package_id = :package_id + } + set items [::xowiki::FormPage instantiate_objects -sql $sql \ + -object_class $object_class -initialize $initialize] + set count 0 + foreach p [$items children] { + set hkey [::xowiki::hstore::dict_as_hkey [$p hstore_attributes]] + set item_id [$p item_id] + xo::dc dml update_hstore "update xowiki_form_instance_item_index \ + set hkey = '$hkey' \ + where item_id = :item_id" + incr count + } + + $items log "updated $count objects from package $package_id" + return $count + } +} + + +namespace eval ::xowiki { + # + # Functions used by upgrade procs. + # proc copy_parameter {from to} { set parameter_obj [::xo::parameter get_parameter_object \ -parameter_name $from -package_key xowiki]