Like the previous example, this example uses the asynchronous query commands described in Section 4.4, “Asynchronous Query Processing Commands”. Unlike that example in Section 5.11, “Example - Asynchronous Queries”, this example uses pg_result_callback to establish an event handler to notify the Tcl interpreter when a result is ready. This feature was added to pgtcl-ng at version 1.6.0. In this example, Tcl waits for either an alarm-clock timeout or a result from the query. The same method can be used to wait for file or socket events, or to respond to user actions in a Tk interface, while also waiting for query results. Note: this is not a complete script.
Example 5.19. Asynchronous Query with Event-Driven Results
# Timeout handler. It sets a global flag to indicate TIMEOUT. proc event_timeout {} { global event_flag if {$event_flag eq "WAITING"} { set event_flag TIMEOUT } } # Query ready handler. It sets a global flag to indicate READY. proc event_result {} { global event_flag if {$event_flag eq "WAITING"} { set event_flag READY } } # Issue a query with timeout. # conn is the database connection handle. # sql is the SQL text to execute. # timeout is the number of seconds to wait for the query. # If the query completes, this just displays the row count. In real life, # you would do something more with the results. proc query_timeout {conn sql {timeout 20}} { global event_flag # Calculate timeout in milliseconds: set timeout_msec [expr {1000 * $timeout}] # Initialize the global flag: set event_flag WAITING # Establish the result callback: pg_result_callback $conn event_result # Set the alarm clock: set after_id [after $timeout_msec event_timeout] # Send the query off, but do not wait: pg_sendquery $conn $sql # Wait for something - timeout or results - to change the global flag: vwait event_flag # Did the query complete? if {$event_flag eq "READY"} { # Cancel the alarm clock: after cancel $after_id puts "Query complete. Fetching result:" set res [pg_getresult $conn] puts "The query returned [pg_result $res -numTuples] row(s)." pg_result $res -clear } elseif {$event_flag eq "TIMEOUT"} { puts "Query did not complete! It timed out in about $timeout seconds." puts "Canceling the request:" # Note pg_cancelrequest also cancels the result callback. pg_cancelrequest $conn # Now we have to block until the backend is ready. pg_result [pg_getresult $conn] -clear puts "Request canceled." } }
Here is an example of using the above function. The pg_sleep PostgreSQL backend function (added at PostgreSQL-8.2.0) is used to simulate a slow query. Because the query time is longer than the specified timeout, this will time out. If the numbers are switched, the query will complete.
query_timeout $conn "select pg_sleep(6)" 4
This version of the manual was produced for the
Pgtcl-ng Sourceforge project web service site, which requires the logo on each
page.
To download a logo-free copy of the manual, see the
Pgtcl-ng project
downloads area.