Index: openacs-4/packages/acs-tcl/tcl/00-acs-tcl-init.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-tcl/tcl/Attic/00-acs-tcl-init.tcl,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/acs-tcl/tcl/00-acs-tcl-init.tcl 21 Feb 2022 20:27:00 -0000 1.1.2.1 @@ -0,0 +1,9 @@ +# +# This file is intended to be the first *-init.tcl file to be called +# after loading the *-proc.tcl files. +# + +set ::acs::kernel_id [ad_acs_kernel_id] + +::acs::dc create_db_function_interface ;# -verbose ;# -match test.* + Index: openacs-4/packages/acs-tcl/tcl/20-memoize-init.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-tcl/tcl/20-memoize-init.tcl,v diff -u -N -r1.7.2.5 -r1.7.2.6 --- openacs-4/packages/acs-tcl/tcl/20-memoize-init.tcl 10 Feb 2022 21:33:44 -0000 1.7.2.5 +++ openacs-4/packages/acs-tcl/tcl/20-memoize-init.tcl 21 Feb 2022 20:27:00 -0000 1.7.2.6 @@ -4,7 +4,6 @@ # # Create the cache used by util_memoize. # -set ::acs::kernel_id [ad_acs_kernel_id] ns_cache create util_memoize -size \ [parameter::get -package_id $::acs::kernel_id -parameter MaxSize -default 200000] Index: openacs-4/packages/acs-tcl/tcl/acs-db-00-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-tcl/tcl/Attic/acs-db-00-procs.tcl,v diff -u -N -r1.1.2.1 -r1.1.2.2 --- openacs-4/packages/acs-tcl/tcl/acs-db-00-procs.tcl 20 Feb 2022 19:45:20 -0000 1.1.2.1 +++ openacs-4/packages/acs-tcl/tcl/acs-db-00-procs.tcl 21 Feb 2022 20:27:00 -0000 1.1.2.2 @@ -42,6 +42,7 @@ ::nx::Class create ::acs::db::Driver { :property backend + :property driver # # Define the "abstract" API (here via protected methods) # @@ -87,8 +88,9 @@ ::nx::Class create ::acs::db::nsdbi -superclasses ::acs::db::Driver ::nx::Class create ::acs::db::nsdbi-postgresql -superclasses {::acs::db::nsdbi ::acs::db::postgresql} - - + # + # Preliminary list of functions (to be extened/refined) + # ::acs::db::nsdb public method list_of_lists {{-dbn ""} {-bind ""} -prepare qn sql} { set bindOpt [expr {$bind ne "" ? [list -bind $bind] : ""}] if {$sql eq ""} { @@ -97,6 +99,14 @@ return [:uplevel [list ::db_list_of_lists -dbn $dbn $qn $sql {*}$bindOpt]] } + ::acs::db::nsdb public method list {{-dbn ""} {-bind ""} -prepare qn sql} { + set bindOpt [expr {$bind ne "" ? [list -bind $bind] : ""}] + if {$sql eq ""} { + set qn [uplevel [list [self] qn $qn]] + } + uplevel [list ::db_list -dbn $dbn $qn $sql {*}$bindOpt] + } + ::acs::db::nsdbi public method list_of_lists {{-dbn ""} {-bind ""} -prepare qn sql} { if {$sql eq ""} { set sql [:get_sql $qn] @@ -107,6 +117,19 @@ -result lists -max 1000000 -- $sql]] } + ::acs::db::nsdbi public method list {{-dbn ""} {-bind ""} -prepare qn sql} { + if {$sql eq ""} { + set sql [:get_sql $qn] + } + set flat [:uplevel [list ::dbi_rows -columns __columns \ + {*}[expr {$dbn ne "" ? [list -db $dbn] : ""}] \ + {*}[expr {$bind ne "" ? [list -bind $bind] : ""}] \ + -- $sql]] + if {[:uplevel {llength $__columns}] > 1} { + error "query is returning more than one column" + } + return $flat + } ########################################################################## # @@ -147,7 +170,10 @@ set driver nsdbi } } - return [::acs::db::$driver-$backend create $name -backend $backend] + + return [::acs::db::$driver-$backend create $name \ + -backend $backend \ + -driver $driver] } # Index: openacs-4/packages/acs-tcl/tcl/acs-db-12-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-tcl/tcl/Attic/acs-db-12-procs.tcl,v diff -u -N -r1.1.2.2 -r1.1.2.3 --- openacs-4/packages/acs-tcl/tcl/acs-db-12-procs.tcl 21 Feb 2022 08:49:15 -0000 1.1.2.2 +++ openacs-4/packages/acs-tcl/tcl/acs-db-12-procs.tcl 21 Feb 2022 20:27:00 -0000 1.1.2.3 @@ -44,20 +44,34 @@ return {CHAR NUMBER VARCHAR2 DATE TABLE} } - # # Mapping of SQL "package" name and "object" name to the names as # stored in the database. # - ::acs::db::oracle method sql_function_name {package_name object_name} { + ::acs::db::postgresql method sql_function_name {package_name object_name} { return ${package_name}__${object_name} } ::acs::db::oracle method sql_function_name {package_name object_name} { return ${package_name}.${object_name} } - # + # Helper for replacing different SQL notations for calling + # database functions. + # + ::acs::db::postgresql public method map_function_name {sql} { + # Replace calls to function names in provided SQL + # (dummy function for PostgreSQL) + return $sql + } + + ::acs::db::oracle public method map_function_name {sql} { + # Replace calls to function names in provided SQL + # (replace "package__object" by "package.object"). + return [string map [list "__" .] $sql] + } + + # # Generator function # ::acs::db::SQL public method create_db_function_interface { @@ -77,19 +91,44 @@ # # ::acs::dc call /package_name/ /object_name/ ?/args/? # + + ns_log notice "Creating DB function interface" \ + "(driver '[::acs::dc cget -driver]', backend '[::acs::dc cget -backend]')" + set db_definitions "" foreach item [:get_all_package_functions -dbn $dbn] { lassign $item package_name object_name sql_info + if {[string match "*TRG" [string toupper $object_name]]} { # no need to provide interface to trigger functions continue } + set package_name [string tolower $package_name] set object_name [string tolower $object_name] - set key ${package_name}.${object_name} + set key ${package_name}.${object_name} if {$match ne "*" && ![string match $match $key]} { continue } + + set nr_args [llength [dict get $sql_info argument_names]] + if { + [llength [dict get $sql_info types]] != $nr_args + || [llength [dict get $sql_info defaulted]] != $nr_args + || [llength [dict get $sql_info defaults]] != $nr_args + } { + ns_log warning "Inconsistent definition skipped: $key" \ + "argument_names $nr_args" \ + "types [llength [dict get $sql_info types]]" \ + "defaulted [llength [dict get $sql_info defaulted]]" \ + "defaults [llength [dict get $sql_info defaults]]\n" \ + "names [dict get $sql_info argument_names]\n" \ + "types [dict get $sql_info types]\n" \ + "defaulted [dict get $sql_info defaulted]\n" \ + "defaults [dict get $sql_info defaults]" + continue + } + ns_log notice "generate stub for '$key'" if {![dict exists $db_definitions $key]} { dict set db_definitions $key package_name $package_name @@ -202,7 +241,11 @@ # # Currently, "defaults" are only available for PostgreSQL # - + if {![db_table_exists acs_function_args]} { + ns_log notice "acs_function_args is not (yet) defined, don't create stub functions now" + return {} + } + set definitions [::acs::dc list_of_lists -dbn $dbn get_all_package_functions { select function, arg_name, arg_default from acs_function_args @@ -232,7 +275,7 @@ # argument types, return type) from PostgreSQL system # catalogs. # - set pg_data [::xo::dc list_of_lists -dbn $dbn [current method] { + set pg_data [::acs::dc list_of_lists -dbn $dbn [current method] { select distinct af.function, substring(af.function from 0 for position('__' in af.function)) as package_name, @@ -552,7 +595,7 @@ } -::acs::dc create_db_function_interface ;# -verbose ;# -match test.* +#::acs::dc create_db_function_interface -verbose ;# -match test.* # Local variables: # mode: tcl