Index: openacs-4/packages/acs-content-repository/acs-content-repository.info =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-content-repository/acs-content-repository.info,v diff -u -r1.2 -r1.3 --- openacs-4/packages/acs-content-repository/acs-content-repository.info 5 Apr 2001 18:23:38 -0000 1.2 +++ openacs-4/packages/acs-content-repository/acs-content-repository.info 27 Apr 2001 02:27:09 -0000 1.3 @@ -83,8 +83,15 @@ + + + + + + + Index: openacs-4/packages/acs-content-repository/sql/postgresql/content-revision.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-content-repository/sql/postgresql/content-revision.sql,v diff -u -r1.11 -r1.12 --- openacs-4/packages/acs-content-repository/sql/postgresql/content-revision.sql 18 Apr 2001 23:27:46 -0000 1.11 +++ openacs-4/packages/acs-content-repository/sql/postgresql/content-revision.sql 27 Apr 2001 02:27:09 -0000 1.12 @@ -64,10 +64,10 @@ create function content_revision__new(varchar,varchar,timestamp,varchar,text,integer) returns integer as ' declare new__title alias for $1; - new__description alias for $2; - new__publish_date alias for $3; - new__mime_type alias for $4; - new__text alias for $5; + new__description alias for $2; -- default null + new__publish_date alias for $3; -- default now() + new__mime_type alias for $4; -- default ''text/plain'' + new__text alias for $5; -- default '' '' new__item_id alias for $6; begin return content_revision__new(new__title, Index: openacs-4/packages/acs-content-repository/tcl/doc-procs-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-content-repository/tcl/doc-procs-oracle.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/acs-content-repository/tcl/doc-procs-oracle.xql 27 Apr 2001 02:27:09 -0000 1.1 @@ -0,0 +1,81 @@ + + + oracle8.1.6 + + + + + select doc.get_package_header(:package_name) from dual + + + + + + + + select doc.get_proc_header(:proc_name, :package_name) from dual + + + + + + + + select distinct + lower(name) as label, + lower(name) as value + from + user_source + where + type='PACKAGE' + and + line=1 + order by label + + + + + + + + select distinct + lower(text) as line_header + from + user_source + where + type='PACKAGE' + and + lower(name) = lower(:package_name) + and ( + lower(text) like '%procedure%' + or + lower(text) like '%function%' + ) + order by line_header" + + + + + + + + select distinct + lower(text) as line_header + from + user_source + where + type='PACKAGE' + and + lower(name) = lower(:package_name) + and ( + lower(text) like '%procedure%' + or + lower(text) like '%function%' + ) + order by line_header" -eval { + + + + + + Index: openacs-4/packages/acs-content-repository/tcl/doc-procs-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-content-repository/tcl/doc-procs-postgresql.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/acs-content-repository/tcl/doc-procs-postgresql.xql 27 Apr 2001 02:27:09 -0000 1.1 @@ -0,0 +1,68 @@ + + + postgresql7.1 + + + + + select doc__get_package_header(:package_name) from dual + + + + + + + + select doc__get_proc_header(:proc_name, :package_name) from dual + + + + + + + + select distinct + substr(proname,1,position('__' in proname)-1) as label, + substr(proname,1,position('__' in proname)-1) as value + from + pg_proc + where + proname like '%\\\_\\\_%' + order by + label + + + + + + + + select + proname as line_header + from + pg_proc + where + proname like lower(:package_name) || '\\\_\\\_%' + order by + line_header + + + + + + + + select + proname as line_header + from + pg_proc + where + proname like lower(:package_name) || '\\\_\\\_%' + order by + line_header + + + + + + Index: openacs-4/packages/acs-content-repository/tcl/doc-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-content-repository/tcl/doc-procs.tcl,v diff -u -r1.1 -r1.2 --- openacs-4/packages/acs-content-repository/tcl/doc-procs.tcl 13 Mar 2001 22:59:26 -0000 1.1 +++ openacs-4/packages/acs-content-repository/tcl/doc-procs.tcl 27 Apr 2001 02:27:09 -0000 1.2 @@ -11,7 +11,7 @@ upvar $info_ref info - template::query info_source onevalue " + template::query get_info info_source onevalue " select doc.get_package_header(:package_name) from dual " @@ -44,16 +44,9 @@ upvar $doc_ref doc upvar $code_ref code - if { [template::util::is_nil db] } { - set db [ns_db gethandle] - set free_db 1 - } else { - set free_db 0 - } - - template::query header onevalue " + template::query get_header header onevalue " select doc.get_proc_header(:proc_name, :package_name) from dual - " -db $db + " # Get JavaDoc block, if any if { [regexp {/\*\*(.*)\*/} $header match] } { @@ -65,10 +58,6 @@ set doc "" set code $header } - - if { $free_db } { - ns_db releasehandle $db - } } # Parse the header block and prepare the datasources: @@ -163,14 +152,7 @@ # { {label value} {label value} ... } proc package_list { {db ""} } { - if { [template::util::is_nil db] } { - set db [ns_db gethandle] - set free_db 1 - } else { - set free_db 0 - } - - template::query result multilist " + template::query get_packages result multilist " select distinct lower(name) as label, lower(name) as value @@ -180,11 +162,7 @@ type='PACKAGE' and line=1 - order by label" -db $db - - if { $free_db } { - ns_db releasehandle $db - } + order by label" return $result } @@ -193,14 +171,7 @@ # { value value ... } proc func_list { package_name {db ""} } { - if { [template::util::is_nil db] } { - set db [ns_db gethandle] - set free_db 1 - } else { - set free_db 0 - } - - template::query result multilist " + template::query get_funcs result multilist " select distinct lower(text) as line_header from @@ -214,12 +185,8 @@ or lower(text) like '%function%' ) - order by line_header" -db $db + order by line_header" - if { $free_db } { - ns_db releasehandle $db - } - set line_opts [list] foreach line $result { # Only get lines in form "procedure proc_name..." or "function func_name..." @@ -237,20 +204,13 @@ # { value value ... } proc func_multirow { package_name result_ref {db ""} } { - if { [template::util::is_nil db] } { - set db [ns_db gethandle] - set free_db 1 - } else { - set free_db 0 - } - upvar "${result_ref}:rowcount" result_rowcount set result_rowcount 0 # Get each line that contains "procedure" or "function" in it # Pretty risky... The like query should be improved to return # less false matches - template::query result multirow " + template::query get_functions result multirow " select distinct lower(text) as line_header from @@ -264,7 +224,7 @@ or lower(text) like '%function%' ) - order by line_header" -db $db -eval { + order by line_header" -eval { # Only insert a row into the datasource if it looks like a procedure # or function definition @@ -279,9 +239,5 @@ set result_row(name) [string tolower $name] } } - - if { $free_db } { - ns_db releasehandle $db - } } } Index: openacs-4/packages/acs-content-repository/tcl/filter-procs-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-content-repository/tcl/filter-procs-oracle.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/acs-content-repository/tcl/filter-procs-oracle.xql 27 Apr 2001 02:27:09 -0000 1.1 @@ -0,0 +1,60 @@ + + + oracle8.1.6 + + + + + select + 0 as tree_level, '' as name , 'Home' as title + from + dual + UNION + select + t.tree_level, i.name, content_item.get_title(t.context_id) as title + from ( + select + context_id, level as tree_level + from + acs_objects + where + context_id <> content_item.get_root_folder + connect by + prior context_id = object_id + start with + object_id = :item_id + ) t, cr_items i + where + i.item_id = t.context_id + order by + tree_level + + + + + + + + select + item_id, content_type + from + cr_items + where + item_id = content_item.get_id(:url, :content_root) + + + + + + + + select + content_template.get_path( + content_item.get_template(:item_id, :context),:template_root) as template_url + from + dual + + + + + Index: openacs-4/packages/acs-content-repository/tcl/filter-procs-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-content-repository/tcl/filter-procs-postgresql.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/acs-content-repository/tcl/filter-procs-postgresql.xql 27 Apr 2001 02:27:09 -0000 1.1 @@ -0,0 +1,61 @@ + + + postgresql7.1 + + + + + select + 0 as tree_level, '' as name , 'Home' as title + from + dual + UNION + select + t.tree_level, i.name, content_item.get_title(t.context_id) as title + from ( + select + o2.context_id, tree_level(o2.tree_sortkey) as tree_level + from + (select * from acs_objects where object_id = :item_id) o1, + acs_objects o2 + where + context_id <> content_item__get_root_folder() + and + o2.tree_sortkey <= o1.tree_sortkey + and + o1.tree_sortkey like (o2.tree_sortkey || '%') + ) t, cr_items i + where + i.item_id = t.context_id + order by + tree_level + + + + + + + + select + item_id, content_type + from + cr_items + where + item_id = content_item__get_id(:url, :content_root) + + + + + + + + select + content_template__get_path( + content_item__get_template(:item_id, :context),:template_root) as template_url + from + dual + + + + + Index: openacs-4/packages/acs-content-repository/tcl/filter-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-content-repository/tcl/filter-procs.tcl,v diff -u -r1.1 -r1.2 --- openacs-4/packages/acs-content-repository/tcl/filter-procs.tcl 13 Mar 2001 22:59:26 -0000 1.1 +++ openacs-4/packages/acs-content-repository/tcl/filter-procs.tcl 27 Apr 2001 02:27:09 -0000 1.2 @@ -73,7 +73,7 @@ } # Get the live revision - template::query revision_id onevalue " + template::query get_revision revision_id onevalue " select live_revision from cr_items where item_id = :item_id " -cache "item_live_revision $item_id" @@ -83,7 +83,7 @@ } # Get the mime type, decide if we want the text - template::query mime_type onevalue " + template::query get_mime_type mime_type onevalue " select mime_type from cr_revisions where revision_id = :revision_id " -cache "revision_mime_type $revision_id" -persistent \ @@ -101,14 +101,14 @@ } # Get the content type - template::query content_type onevalue " + template::query get_content_type content_type onevalue " select content_type from cr_items where item_id = :item_id " -cache "item_content_type $item_id" -persistent \ -timeout 3600 # Get the table name - template::query table_name onevalue " + template::query get_table_name table_name onevalue " select table_name from acs_object_types where object_type = :content_type " -cache "type_table_name $content_type" -persistent \ @@ -117,7 +117,7 @@ upvar content content # Get (all) the content (note this is really dependent on file type) - template::query content onerow "select + template::query get_content content onerow "select x.*, :item_id as item_id $text_sql, :content_type as content_type @@ -183,7 +183,7 @@ set url "" # build the folder URL out as we iterate over the query - template::query $varname multirow $query -uplevel -eval { + template::query get_url $varname multirow $query -uplevel -eval { append url "$row(name)/" set row(url) ${url}index.acs } @@ -211,7 +211,7 @@ item_id = content_item.get_id(:url, :content_root)" # cache this query persistently for 1 hour - template::query item_info onerow $query \ + template::query get_item_info item_info onerow $query \ -cache "get_id_filter $url $content_root" \ -persistent -timeout 216000 @@ -228,7 +228,7 @@ set content_type $item_info(content_type) # Make sure that a live revision exists - template::query live_revision onevalue " + template::query get_live_revision live_revision onevalue " select live_revision from cr_items where item_id = :item_id " -cache "item_live_revision $item_id" @@ -256,7 +256,7 @@ dual" - template::query template_url onevalue $query + template::query get_template_url template_url onevalue $query if { [string equal $template_url {}] } { ns_log Notice "No template found to render content item $item_id in context '$context'" @@ -284,4 +284,4 @@ # end of content namespace -} \ No newline at end of file +} Index: openacs-4/packages/acs-content-repository/tcl/filter-procs.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-content-repository/tcl/filter-procs.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/acs-content-repository/tcl/filter-procs.xql 27 Apr 2001 02:27:09 -0000 1.1 @@ -0,0 +1,64 @@ + + + + + + + select live_revision from cr_items where item_id = :item_id + + + + + + + + select mime_type from cr_revisions + where revision_id = :revision_id + + + + + + + + select content_type from cr_items + where item_id = :item_id + + + + + + + + select table_name from acs_object_types + where object_type = :content_type + + + + + + + + select + x.*, + :item_id as item_id $text_sql, + :content_type as content_type + from + cr_revisions r, ${table_name}x x + where + r.revision_id = :revision_id + and + x.revision_id = r.revision_id + + + + + + + + select live_revision from cr_items where item_id = :item_id + + + + + Index: openacs-4/packages/acs-content-repository/tcl/revision-procs-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-content-repository/tcl/revision-procs-oracle.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/acs-content-repository/tcl/revision-procs-oracle.xql 27 Apr 2001 02:27:09 -0000 1.1 @@ -0,0 +1,31 @@ + + + oracle8.1.6 + + + + + begin + :1 := content_revision.new(title => :title, + item_id => :item_id, + v_content => null); + end; + + + + + + + + update + cr_revisions + set + content = empty_blob() + where + revision_id = :revision_id + returning content into :1 + + + + + Index: openacs-4/packages/acs-content-repository/tcl/revision-procs-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-content-repository/tcl/revision-procs-postgresql.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/acs-content-repository/tcl/revision-procs-postgresql.xql 27 Apr 2001 02:27:09 -0000 1.1 @@ -0,0 +1,34 @@ + + + postgresql7.1 + + + + + select content_revision__new(:title, + null, + now(), + 'text/plain', + ' ', + :item_id + ) + + + + + + + + FIXME: need to handle this blob + update + cr_revisions + set + content = empty_lob() + where + revision_id = :revision_id + returning content into :1 + + + + + Index: openacs-4/packages/acs-content-repository/tcl/revision-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-content-repository/tcl/revision-procs.tcl,v diff -u -r1.1 -r1.2 --- openacs-4/packages/acs-content-repository/tcl/revision-procs.tcl 13 Mar 2001 22:59:26 -0000 1.1 +++ openacs-4/packages/acs-content-repository/tcl/revision-procs.tcl 27 Apr 2001 02:27:09 -0000 1.2 @@ -2,21 +2,19 @@ proc cr_revision_upload { title item_id path } { - set db [ns_db gethandle] + set revision_id [db_exec_plsql get_revision_id "begin + :1 := content_revision.new(title => :title, + item_id => :item_id, + v_content => null); + end;"] - ns_ora exec_plsql_bind $db "begin - :revision_id := content_revision.new(title => :title, - item_id => :item_id, - v_content => null); - end;" revision_id + dml_file dml_revision_from_file "update + cr_revisions + set + content = empty_blob() + where + revision_id = :revision_id + returning content into :1" -blob_files [list $path] - ns_ora blob_dml_file_bind $db "update cr_revisions set - content = empty_blob() - where - revision_id = :revision_id - returning content into :1" [list 1] $path - - ns_db releasehandle $db - return $revision_id -} \ No newline at end of file +} Index: openacs-4/packages/acs-templating/acs-templating.info =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-templating/acs-templating.info,v diff -u -r1.2 -r1.3 --- openacs-4/packages/acs-templating/acs-templating.info 5 Apr 2001 18:23:38 -0000 1.2 +++ openacs-4/packages/acs-templating/acs-templating.info 27 Apr 2001 02:27:09 -0000 1.3 @@ -42,13 +42,14 @@ + + + + - - - Index: openacs-4/packages/acs-templating/sql/postgresql/acs-templating-create.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-templating/sql/postgresql/acs-templating-create.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/acs-templating/sql/postgresql/acs-templating-create.sql 27 Apr 2001 02:27:09 -0000 1.1 @@ -0,0 +1,12 @@ +-- Data model to support content ACS Templating System + +-- Copyright (C) 1999-2000 ArsDigita Corporation +-- Author: Karl Goldstein (karlg@arsdigita.com) + +-- $Id: acs-templating-create.sql,v 1.1 2001/04/27 02:27:09 danw Exp $ + +-- This is free software distributed under the terms of the GNU Public +-- License. Full text of the license is available from the GNU Project: +-- http://www.fsf.org/copyleft/gpl.html + +\i demo-create.sql Index: openacs-4/packages/acs-templating/sql/postgresql/acs-templating-drop.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-templating/sql/postgresql/acs-templating-drop.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/acs-templating/sql/postgresql/acs-templating-drop.sql 27 Apr 2001 02:27:09 -0000 1.1 @@ -0,0 +1,9 @@ +-- Uninstall file for the data model created by 'acs-templating-create.sql' +-- (This file created automatically by create-sql-uninst.pl.) +-- +-- brech (Mon Aug 28 11:04:55 2000) +-- +-- $Id: acs-templating-drop.sql,v 1.1 2001/04/27 02:27:09 danw Exp $ +-- + +\i demo-drop.sql Index: openacs-4/packages/acs-templating/sql/postgresql/demo-create.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-templating/sql/postgresql/demo-create.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/acs-templating/sql/postgresql/demo-create.sql 27 Apr 2001 02:27:09 -0000 1.1 @@ -0,0 +1,26 @@ +create sequence ad_template_sample_users_seq start 5 increment 1; + +create table ad_template_sample_users ( + user_id integer primary key, + first_name varchar(20), + last_name varchar(20), + address1 varchar(40), + address2 varchar(40), + city varchar(40), + state varchar(2) +); + + +insert into ad_template_sample_users values + (1, 'Fred', 'Jones', '101 Main St.', NULL, 'Orange', 'CA'); + +insert into ad_template_sample_users values + (2, 'Frieda', 'Mae', 'Lexington Hospital', '102 Central St.', + 'Orange', 'CA'); + +insert into ad_template_sample_users values + (3, 'Sally', 'Saxberg', 'Board of Supervisors', '1933 Fruitvale St.', + 'Woodstock', 'CA'); + +insert into ad_template_sample_users values + (4, 'Yoruba', 'Diaz', '12 Magic Ave.', NULL, 'Lariot', 'WY'); Index: openacs-4/packages/acs-templating/sql/postgresql/demo-drop.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-templating/sql/postgresql/demo-drop.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/acs-templating/sql/postgresql/demo-drop.sql 27 Apr 2001 02:27:09 -0000 1.1 @@ -0,0 +1,10 @@ +-- Uninstall file for the data model created by 'demo-create.sql' +-- (This file created automatically by create-sql-uninst.pl.) +-- +-- brech (Mon Aug 28 11:06:33 2000) +-- +-- $Id: demo-drop.sql,v 1.1 2001/04/27 02:27:09 danw Exp $ +-- + +drop table ad_template_sample_users; +drop sequence ad_template_sample_users_seq; 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.1 -r1.2 --- openacs-4/packages/acs-templating/tcl/paginator-procs.tcl 13 Mar 2001 22:59:27 -0000 1.1 +++ openacs-4/packages/acs-templating/tcl/paginator-procs.tcl 27 Apr 2001 02:27:09 -0000 1.2 @@ -35,7 +35,7 @@ # page number,, such as the first few # letters of a title or date. -proc template::paginator::create { name query args } { +proc template::paginator::create { statement_name name query args } { set level [template::adp_level] variable parse_level @@ -52,7 +52,7 @@ set row_ids [cache get $cache_key:row_ids] if { [string equal $row_ids {}] } { - init $name $query + init $statement_name $name $query } else { set opts(row_ids) $row_ids set opts(context_ids) [cache get $cache_key:context_ids] @@ -67,7 +67,7 @@ # Initialize a paginated query. Only called by create. -proc template::paginator::init { name query } { +proc template::paginator::init { statement_name result_name query } { get_reference @@ -79,7 +79,7 @@ if { [info exists properties(contextual)] } { # query contains two columns, one for ID and one for context cue - uplevel 3 "template::query __paginator_ids multilist \"$query\"" + uplevel 3 "template::query $statement_name __paginator_ids multilist \"$query\"" set i 0 set page_size $properties(pagesize) @@ -96,24 +96,24 @@ } set properties(context_ids) $context_ids - cache set $name:$query:context_ids $context_ids $properties(timeout) + cache set $result_name:$query:context_ids $context_ids $properties(timeout) if { [template::util::is_nil row_ids] } { set row_ids "" } set properties(row_ids) $row_ids - cache set $name:$query:row_ids $row_ids $properties(timeout) + cache set $result_name:$query:row_ids $row_ids $properties(timeout) } else { # no extra column specified for paging by contextual cues - uplevel 3 "template::query __paginator_ids onelist \"$query\"" + uplevel 3 "template::query $statement_name __paginator_ids onelist \"$query\"" set properties(row_ids) $ids - cache set $name:$query:row_ids $ids $properties(timeout) + cache set $result_name:$query:row_ids $ids $properties(timeout) } } @@ -423,7 +423,7 @@ # @param id_column The name of the ID column in the display query (required # to order rows properly). -proc template::paginator::get_data { name datasource query id_column page } { +proc template::paginator::get_data { statement_name name datasource query id_column page } { set ids [get_row_ids $name $page] @@ -456,7 +456,7 @@ uplevel 2 " - template::query __page_data multirow \"$query\" -eval { + template::query $statement_name __page_data multirow \"$query\" -eval { set i \$__page_order(\$row($id_column)) upvar 0 $datasource:\$i __page_sorted_row array set __page_sorted_row \[array get row\] Index: openacs-4/packages/acs-templating/tcl/query-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-templating/tcl/query-procs.tcl,v diff -u -r1.1 -r1.2 --- openacs-4/packages/acs-templating/tcl/query-procs.tcl 13 Mar 2001 22:59:27 -0000 1.1 +++ openacs-4/packages/acs-templating/tcl/query-procs.tcl 27 Apr 2001 02:27:09 -0000 1.2 @@ -10,13 +10,497 @@ # http://www.fsf.org/copyleft/gpl.html -# Supplied options are "oracle" and "generic" +# (DCW - Openacs) converted template db api to use standard api and hooked it +# into the query-dispatcher. This ties into the standard db api's +# transaction control and handle allocation into the templating query interface +# allowing the two db api's to be mixed together. -set path "ns/server/[ns_info server]/ats" -set db [ns_config $path DatabaseInterface oracle] +# Todo - convert caching to use ns_cache. -source "[file dirname [info script]]/database-procs/$db.tcl" +nsv_set __template_query_persistent_cache . . +nsv_set __template_query_persistent_timeout . . + +# @public query + +# Perform a database query + +# @option maxrows Limits the query results of a multirow query +# to a fixed number of rows. +# @option cache Cache the query results keyed on an identifier +# that is unique for both the query and the bind variables +# used in the query. The cached result reflects +# any initial specification of maxrows and startrows. +# @option refresh Force a query to be performed even if it is cached, +# and refresh the cache. +# Only applicable if the cache option is specified as well. +# Does not affect a previously specified timeout period. +# @option timeout The maximum period of time for which the cached results +# are valid in seconds. Only applicable for +# persistently cached results. +# @option persistent Cache the query results persistently, so that +# all subsequent requests use the results. + +proc template::query { statement_name result_name type sql args } { + + #set beginTime [clock clicks] + + template::util::get_opts $args + + if { ! [info exists opts(uplevel)] } { + set opts(uplevel) 2 + } else { + set opts(uplevel) [expr 2 + $opts(uplevel)] + } + + # check the cache for a valid cached query result and return if so + # otherwise continue to perform the query and cache the results afterwards + + if { [info exists opts(cache)] && [get_cached_result $result_name $type] } { + return $opts(result) + } + + if { ! [info exists opts(maxrows)] } { + set opts(maxrows) 10000 + } + + db_with_handle db { + set ret_code [template::query::$type $statement_name $db $result_name \ + $sql] + } + + if { [info exists opts(cache)] } { + + # cache the query result + set_cached_result + } + + #set timeElapsed [expr ([clock clicks] - $beginTime) / 1000] + #ns_log Notice "Query performed in: $timeElapsed ms" + + return $ret_code +} + +# @private onevalue + +# Process a onevalue query. Use a single array to store the results. + +proc template::query::onevalue { statement_name db result_name sql } { + + set full_statement_name [db_qd_get_fullname $statement_name] + + upvar opts opts + + upvar $opts(uplevel) $result_name result + set result "" + + uplevel "set __row \[db_exec 0or1row $db $full_statement_name $sql\]" + upvar __row row + + if { $row != "" } { + + # Set the result in the calling frame. + set result [ns_set value $row 0] + + if { [info exists opts(cache)] } { + set opts(result) $result + } + } +} + +# @private onerow + +# Process a onerow query. Use a single array to store the results. + +proc template::query::onerow { statement_name db result_name sql } { + + set full_statement_name [db_qd_get_fullname $statement_name] + + upvar opts opts + + uplevel "set __row \[db_exec 0or1row $db $full_statement_name $sql\]" + upvar __row row + + if { $row != "" } { + + # Set the results in the calling frame. + upvar $opts(uplevel) $result_name result + + set size [ns_set size $row] + + for { set i 0 } { $i < $size } { incr i } { + + set column [ns_set key $row $i] + set result($column) [ns_set value $row $i] + } + + if { [info exists opts(cache)] } { + set opts(result) [array get result] + } + + return 1 + + } else { + + return 0 + } +} + +# @private multirow + +# Process a multirow query. Use an array for each row row in the +# result. Arrays are named name0, name1, name2 etc. The variable +# name.rowcount is also defined for checking and iteration. + +proc template::query::multirow { statement_name db result_name sql } { + + set full_statement_name [db_qd_get_fullname $statement_name] + + upvar opts opts + + uplevel "set __row \[db_exec select $db $full_statement_name $sql\]" + upvar __row row + + upvar $opts(uplevel) $result_name:rowcount rowcount \ + $result_name:columns column_list + + # set a local variable as to whether we are cacheing or not + if { [info exists opts(cache)] } { + set is_cached 1 + set cached_result [list] + } else { + set is_cached 0 + } + + set rowcount 0 + + if { [info exists opts(eval)] } { + # figure out the level at which to reference the row + set ref_level [expr $opts(uplevel) - 2] + } + + while { [ns_db getrow $db $row] } { + + incr rowcount + + # break if maxrows has been reached + if { $rowcount > $opts(maxrows) } { + ns_db flush $db + upvar $opts(uplevel) $name:has_more_rows has_more_rows + set has_more_rows 1 + incr rowcount -1 + break + } + + # set the results in the calling frame + upvar $opts(uplevel) ${name}:$rowcount result + + set result(rownum) $rowcount + + set size [ns_set size $row] + + for { set i 0 } { $i < $size } { incr i } { + + set column [ns_set key $row $i] + set result($column) [ns_set value $row $i] + + if {$rowcount == 1 } { + lappend column_list $column + } + } + + # Execute custom code for each row + if { [info exists opts(eval)] } { + uplevel $opts(uplevel) " + upvar 0 ${name}:$rowcount row; $opts(eval) + " + } + + if { $is_cached } { + lappend cached_result [array get result] + } + } + + if { $is_cached } { + set opts(result) $cached_result + } +} + +proc template::query::multilist { statement_name db result_name sql } { + + set full_statement_name [db_qd_get_fullname $statement_name] + + upvar opts opts + + uplevel "set __row \[db_exec select $db $full_statement_name $sql\]" + upvar __row row + + upvar $opts(uplevel) $result_name rows + + set rows [list] + + while { [ns_db getrow $db $row] } { + + set values [list] + set size [ns_set size $row] + + for { set i 0 } { $i < $size } { incr i } { + + lappend values [ns_set value $row $i] + } + + lappend rows $values + } + + if { [info exists opts(cache)] } { + set opts(result) $rows + } + + return $rows +} + +# Creates a data source where the values for each row +# are returned as a list. Rows are grouped according +# to the column values specified in the -groupby option +# See template::util::lnest for more details. + +proc template::query::nestedlist { statement_name db result_name sql } { + + set full_statement_name [db_qd_get_fullname $statement_name] + + upvar opts opts + + uplevel "set __row \[db_exec select $db $full_statement_name $sql\]" + upvar __row row + + upvar $opts(uplevel) $result_name rows + + set groups $opts(groupby) + + set rows [list] + + while { [ns_db getrow $db $row] } { + + set values [list] + set size [ns_set size $row] + + for { set i 0 } { $i < $size } { incr i } { + + lappend values [ns_set value $row $i] + } + + # build the values on which to group + set group_values [list] + foreach group $groups { + lappend group_values [ns_set get $row $group] + } + + eval template::util::lnest rows [list $values] $group_values + } + + if { [info exists opts(cache)] } { + set opts(result) $rows + } + + return $rows +} + +proc template::query::onelist { statement_name db result_name sql } { + + set full_statement_name [db_qd_get_fullname $statement_name] + + upvar opts opts + + uplevel "set __row \[db_exec select $db $full_statement_name $sql\]" + upvar __row row + + upvar $opts(uplevel) $result_name rows + + set rows [list] + + while { [ns_db getrow $db $row] } { + + set values [list] + lappend rows [ns_set value $row 0] + } + + if { [info exists opts(cache)] } { + set opts(result) $rows + } +} + +proc template::query::dml { statement_name db name sql } { + + set full_statement_name [db_qd_get_fullname $statement_name] + + upvar opts opts + + uplevel "db_exec dml $db $full_statement_name \"$sql\"" +} + +# @private get_cached_result + +# Looks in the appropriate cache for the named query result +# If a valid result is found, then sets the result in the returning +# stack frame. + +# @return 1 if result was successfully retrieved, 0 if failed + +proc get_cached_result { name type } { + + upvar opts opts + set cache_key $opts(cache) + set success 0 + + if { [info exists opts(persistent)] } { + + if { [nsv_exists __template_query_persistent_cache $cache_key] } { + + # check the timeout + + set timeout [nsv_get __template_query_persistent_timeout $cache_key] + if { $timeout > [ns_time] } { + set cached_result \ + [nsv_get __template_query_persistent_cache $cache_key] + set success 1 + } + } + + } else { + + global __template_query_request_cache + + if { [info exists __template_query_request_cache($cache_key)] } { + + set cached_result $__template_query_request_cache($cache_key) + set success 1 + } + } + + if { $success } { + + switch $type { + + multirow { + + upvar $opts(uplevel) $name:rowcount rowcount + set rowcount [llength $cached_result] + set rownum 1 + + foreach cached_row $cached_result { + upvar $opts(uplevel) $name:$rownum row + array set row $cached_row + incr rownum + } + set opts(result) "" + } + onerow { + + upvar $opts(uplevel) $name result + array set result $cached_result + set opts(result) "" + } + default { + + upvar $opts(uplevel) $name result + set result $cached_result + set opts(result) $cached_result + } + } + } + + return $success +} + +# @private set_cached_result + +# Places a query result in the appropriate cache. + +proc set_cached_result {} { + + upvar opts opts + + if { ! [info exists opts(result)] } { return } + + set cache_key $opts(cache) + + if { [info exists opts(persistent)] } { + + # set the result in the persistent cache + + nsv_set __template_query_persistent_cache $cache_key $opts(result) + + if { [info exists opts(timeout)] } { + set timeout [expr [ns_time] + $opts(timeout)] + } else { + set timeout [expr [ns_time] + 60 * 60 * 24 * 7] + } + + nsv_set __template_query_persistent_timeout $cache_key $timeout + + } else { + + global __template_query_request_cache + set __template_query_request_cache($cache_key) $opts(result) + } +} + +# Deprecated! + +proc template::query::iterate { statement_name db sql body } { + + set full_statement_name [db_qd_get_fullname $statement_name] + + uplevel "set __result \[db_exec select $db $full_statement_name $sql\]" + upvar __result result + + set rowcount 0 + + while { [ns_db getrow $db $result] } { + + upvar __query_iterate_row row + + set row(rownum) [incr rowcount] + + set size [ns_set size $result] + + for { set i 0 } { $i < $size } { incr i } { + + set column [ns_set key $result $i] + set row($column) [ns_set value $result $i] + } + + # Execute custom code for each row + uplevel "upvar 0 __query_iterate_row row; $body" + } +} + +# Flush the cached queries where the query name matches the +# specified string match + +proc template::query::flush_cache { cache_match } { + + # Flush persistent cache + set names [nsv_array names __template_query_persistent_cache] + foreach name $names { + if { [string match $cache_match $name] } { + ns_log notice "FLUSHING QUERY (persistent): $name" + nsv_unset __template_query_persistent_cache $name + } + } + + # Flush temporary cache + global __template_query_request_cache + set names [array names __template_query_persistent_cache] + foreach name $names { + if { [string match $cache_match $name] } { + ns_log notice "FLUSHING QUERY (request): $name" + unset __template_query_persistent_cache($name) + } + } + +} + # Perform get/set operations on a multirow datasource proc template::multirow { op name args } { Index: openacs-4/packages/acs-templating/tcl/table-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-templating/tcl/table-procs.tcl,v diff -u -r1.1 -r1.2 --- openacs-4/packages/acs-templating/tcl/table-procs.tcl 13 Mar 2001 22:59:27 -0000 1.1 +++ openacs-4/packages/acs-templating/tcl/table-procs.tcl 27 Apr 2001 02:27:09 -0000 1.2 @@ -45,23 +45,14 @@ # Create the widget data structure -proc template::widget::table::create { name args } { +proc template::widget::table::create { statement_name name args } { upvar "tablewidget:${name}" widget set widget(name) $name - - upvar 0 widget opts - template::util::get_opts $args - - if { [info exists opts(db)] } { - set db $opts(db) - } else { - set db "" - } template::widget::table::get_params $name 2 - template::widget::table::prepare $name $db 2 + template::widget::table::prepare $statment_name $name 2 } # Get the order by clause for the widget, other parameters (?) @@ -93,9 +84,8 @@ } # Compose the query, if neccessary, and define the datasources -proc template::widget::table::prepare { name { db ""} {level 1} } { +proc template::widget::table::prepare { statement_name name {level 1} } { - set free_db 0 upvar $level "tablewidget:${name}" widget # Get the rows @@ -104,6 +94,7 @@ error "No row datasource available for tablewidget $name" } + # fixme - need to get a statement name here set sql_query $widget(query) # Append the order by clause, if any @@ -114,12 +105,6 @@ append sql_query " $widget(orderby)" } - # Get database handle - if { [template::util::is_nil db] } { - set db [ns_db gethandle] - set free_db 1 - } - if { ![template::util::is_nil widget(column_def)] } { # Convert the column def list to an array for extra speed upvar $level "tablewidget:${name}_column_def" column_arr @@ -160,7 +145,7 @@ } uplevel $level " - template::query tw_${name}_rows multirow \{$sql_query\} -db \{$db\} \\ + template::query $statement_name tw_${name}_rows multirow \{$sql_query\} \\ -eval \{$eval_code\} " @@ -225,7 +210,6 @@ uplevel $level "uplevel 0 tw_${name}_columns $template(columns_data)" } - if { $free_db } { ns_db releasehandle $db } } # Register the tag that actually renders the widget @@ -253,4 +237,4 @@ - \ No newline at end of file + Index: openacs-4/packages/acs-templating/tcl/util-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-templating/tcl/util-procs.tcl,v diff -u -r1.1 -r1.2 --- openacs-4/packages/acs-templating/tcl/util-procs.tcl 13 Mar 2001 22:59:27 -0000 1.1 +++ openacs-4/packages/acs-templating/tcl/util-procs.tcl 27 Apr 2001 02:27:09 -0000 1.2 @@ -128,7 +128,7 @@ append query [join $conditions " and "] - template::query count onevalue $query + template::query get_count count onevalue $query return [expr $count == 0] } Index: openacs-4/packages/acs-templating/tcl/widget-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-templating/tcl/widget-procs.tcl,v diff -u -r1.1 -r1.2 --- openacs-4/packages/acs-templating/tcl/widget-procs.tcl 13 Mar 2001 22:59:27 -0000 1.1 +++ openacs-4/packages/acs-templating/tcl/widget-procs.tcl 27 Apr 2001 02:27:09 -0000 1.2 @@ -365,9 +365,10 @@ error "No search query specified for search widget" } + # FIXME: need to get a statement name here set query $element(search_query) - template::query options multilist $query + template::query get_options options multilist $query set option_count [llength $options] Index: openacs-4/packages/acs-templating/www/doc/demo/form.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-templating/www/doc/demo/form.tcl,v diff -u -r1.1 -r1.2 --- openacs-4/packages/acs-templating/www/doc/demo/form.tcl 13 Mar 2001 22:59:27 -0000 1.1 +++ openacs-4/packages/acs-templating/www/doc/demo/form.tcl 27 Apr 2001 02:27:09 -0000 1.2 @@ -16,28 +16,21 @@ if { [form is_request add_user] } { - set db [ns_db gethandle] - set query "select ad_template_sample_users_seq.nextval from dual" - template::query user_id onevalue $query -db $db + template::query get_user_id user_id onevalue $query - ns_db releasehandle $db - element set_properties add_user user_id -value $user_id } if { [form is_valid add_user] } { - set db [ns_db gethandle] - ns_ora dml $db -bind [ns_getform] " + db_dml insert_sample -bind [ns_getform] " insert into ad_template_sample_users values ( :user_id, :first_name, :last_name, :address1, :address2, :city, :state )" - ns_db releasehandle $db - template::forward index.html } Index: openacs-4/packages/acs-templating/www/doc/demo/multiaccess.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-templating/www/doc/demo/multiaccess.tcl,v diff -u -r1.1 -r1.2 --- openacs-4/packages/acs-templating/www/doc/demo/multiaccess.tcl 13 Mar 2001 22:59:27 -0000 1.1 +++ openacs-4/packages/acs-templating/www/doc/demo/multiaccess.tcl 27 Apr 2001 02:27:09 -0000 1.2 @@ -8,13 +8,9 @@ from ad_template_sample_users" -set db [ns_db gethandle] - -template::query users multirow $query -db $db \ +template::query get_users users multirow $query \ -eval { set row(full_name) "$row(last_name), $row(first_name)" } -ns_db releasehandle $db - # Manually access the datasource # Get the size Index: openacs-4/packages/acs-templating/www/doc/demo/user-edit.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-templating/www/doc/demo/user-edit.tcl,v diff -u -r1.1 -r1.2 --- openacs-4/packages/acs-templating/www/doc/demo/user-edit.tcl 13 Mar 2001 22:59:27 -0000 1.1 +++ openacs-4/packages/acs-templating/www/doc/demo/user-edit.tcl 27 Apr 2001 02:27:09 -0000 1.2 @@ -121,15 +121,11 @@ form get_values user_edit first_name last_name address1 address2 city state - set db [ns_db gethandle] - - ns_ora dml $db "update ad_template_sample_users + db_dml update_sample_users "update ad_template_sample_users set first_name = :first_name, last_name = :last_name, address1 = :address1, address2 = :address2, city = :city, state = :state where user_id = :user_id" - ns_db releasehandle $db - template::forward multiple -} \ No newline at end of file +} Index: openacs-4/packages/acs-templating/www/doc/exercise/form-sample-revised.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-templating/www/doc/exercise/form-sample-revised.tcl,v diff -u -r1.1 -r1.2 --- openacs-4/packages/acs-templating/www/doc/exercise/form-sample-revised.tcl 13 Mar 2001 22:59:27 -0000 1.1 +++ openacs-4/packages/acs-templating/www/doc/exercise/form-sample-revised.tcl 27 Apr 2001 02:27:09 -0000 1.2 @@ -30,19 +30,15 @@ if { [form is_valid add_entry] } { ns_log error "now we've gotten past the if statement" - set db [ns_db gethandle] - ns_ora dml $db -bind [ns_getform] " + db_dml insert_address -bind [ns_getform] " insert into address_book values ( :first_names, :last_name, :title, null, :gender, :address, :city, :state, :zip, :country, :email, :relationship, :primary_phone, :home, :work, :cell, :pager, :fax )" - - ns_db releasehandle $db template::forward index.html - } Index: openacs-4/packages/acs-templating/www/doc/exercise/form-sample.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-templating/www/doc/exercise/form-sample.tcl,v diff -u -r1.1 -r1.2 --- openacs-4/packages/acs-templating/www/doc/exercise/form-sample.tcl 13 Mar 2001 22:59:27 -0000 1.1 +++ openacs-4/packages/acs-templating/www/doc/exercise/form-sample.tcl 27 Apr 2001 02:27:09 -0000 1.2 @@ -97,9 +97,7 @@ [template::form get_values add_entry birthday] - set db [ns_db gethandle] - - ns_ora dml $db -bind [ns_getform] " + db_dml insert_form -bind [ns_getform] " insert into address_book values ( @@ -111,13 +109,11 @@ # can't seem to get orable to bind array variables birthday.day, birthday.month and birthday.year # okay, turns out oracle doesn't support arrays, will have to do this in tcl first - - ns_db releasehandle $db - template::forward form-sample.acs + template::forward form-sample.acs } -template::query address multirow "select * from address_book order by last_name" +template::query get_address address multirow "select * from address_book order by last_name" set rowcount [set address:rowcount] Index: openacs-4/packages/acs-templating/www/doc/exercise/list-and-var-sample.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-templating/www/doc/exercise/list-and-var-sample.tcl,v diff -u -r1.1 -r1.2 --- openacs-4/packages/acs-templating/www/doc/exercise/list-and-var-sample.tcl 13 Mar 2001 22:59:27 -0000 1.1 +++ openacs-4/packages/acs-templating/www/doc/exercise/list-and-var-sample.tcl 27 Apr 2001 02:27:09 -0000 1.2 @@ -68,7 +68,7 @@ "hanging out with my best buds" \ "telling jokes -- my friends say I've got a great sense of humor!"] -template::query friends multirow "select first_names, last_name, age, gender, address, likes_chocolate_p from best_friends" +template::query get_friends friends multirow "select first_names, last_name, age, gender, address, likes_chocolate_p from best_friends" #template::multirow create foo_multirow columns1 columns2 columns3 template::multirow extend friends extra_column