db_with_handle (public)

 db_with_handle [ -dbn dbn ] db code_block

Defined in packages/acs-tcl/tcl/01-database-procs.tcl

Place a usable database handle in db and executes code_block.

Switches:
-dbn
(optional)
Database name to use. If empty_string, use the default database
Parameters:
db - Name of the handle variable used in the code block
code_block - code block to be executed with handle

Partial Call Graph (max 5 caller/called nodes):
%3 test_db__0or1row db__0or1row (test acs-tcl) db_with_handle db_with_handle test_db__0or1row->db_with_handle test_db__1row db__1row (test acs-tcl) test_db__1row->db_with_handle test_xowiki_test_cases xowiki_test_cases (test xowiki) test_xowiki_test_cases->db_with_handle ad_log ad_log (public) db_with_handle->ad_log db_available_pools db_available_pools (public) db_with_handle->db_available_pools ds_collect_db_call ds_collect_db_call (public) db_with_handle->ds_collect_db_call

Testcases:
db__0or1row, db__1row, xowiki_test_cases
Source code:
        #
        # Let the caller decide, how the handle variable is called in
        # the code block.
        #
        upvar 1 $db dbh

        #
        # Get the pools and the current allocated handles for this thread.
        #
        set pools [db_available_pools $dbn]
        set currentHandles [ns_db currenthandles]
        #ns_log notice "### pools <$pools> currentHandles <$currentHandles>"

        set db ""
        set n 0
        foreach pool $pools {
            #
            # Do we have already handles allocated from this pool?
            #
            if {[dict exists $currentHandles $pool]} {
                #
                # Are there handles, which are not active (i.e. not in
                # a currently open "ns_db select" and "ns_db getrow"
                # context.
                #
                foreach {handle active} [dict get $currentHandles $pool] {
                    #ns_log notice "### FOUND pool $pool handle $handle active $active"
                    if {$active eq "0"} {
                        #
                        # We can use this handle
                        #
                        set db $handle
                        break
                    }
                }
            } else {
                break
            }
            incr n
        }
        #
        # In case, we got no handle above, we have to allocate a
        # handle from the next pool, from which we have not got a
        # handle before.
        #
        if {$db eq ""} {
            #
            # We were not successful above
            #
            set pool [lindex $pools $n]
            if {$pool eq ""} {
                ad_log error "handles from all pools <$pools> are exhausted"
                error "could not obtain handle, all pools are exhausted"
            }
            set start_time [expr {[clock clicks -microseconds]/1000.0}]
            #ns_log notice "### BEFORE gethandle $pool ($n)"
            set errno [catch {
                set db [ns_db gethandle $pool]
            } error]
            #ad_log notice "### AFTER gethandle $pool errno $errno handle <$db> currentHandles [ns_db currenthandles]"
            ds_collect_db_call $db gethandle "" $pool $start_time $errno $error
            if { $errno } {
                ns_log notice "### RETURNING error $error"
                return -code $errno -errorcode $::errorCode -errorinfo $::errorInfo $error
            }
        }
        #ns_log notice "### db_with_handle has handle <$db>"

        set dbh $db
        set errno [catch { uplevel 1 $code_block } error]

        # Unset dbh, so any subsequence use of this variable will bomb.
        unset -nocomplain dbh

        # If errno is 1, it's an error, so return errorCode and errorInfo;
        # if errno = 2, it's a return, so don't try to return errorCode/errorInfo
        # errno = 3 or 4 give undefined results

        if { $errno == 1 } {
            # A real error occurred
            ns_log notice "### db_with_handle returned error <$error> for statement $code_block"
            return -code $errno -errorcode $::errorCode -errorinfo $::errorInfo $error
        }

        if { $errno == 2 } {

            # The code block called a "return", so pass the message through but don't try
            # to return errorCode or errorInfo since they may not exist

            return -code $errno $error
        }
XQL Not present:
Generic, PostgreSQL, Oracle
[ hide source ] | [ make this the default ]
Show another procedure: