-
Notifications
You must be signed in to change notification settings - Fork 10
/
README.async
143 lines (92 loc) · 5.26 KB
/
README.async
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
$Id$
Experimental Tcl interface to PostgreSQL asynchronous query processing
by Karl Lehenbauer ([email protected]) 10/2002 (revised 6/2004)
RATIONALE
From the C-interface docs:
The PQexec function is adequate for submitting commands in simple
synchronous applications. It has a couple of major deficiencies however:
* PQexec waits for the command to be completed. The application may
have other work to do (such as maintaining a user interface), in which
case it won't want to block waiting for the response.
* Since control is buried inside PQexec, it is hard for the frontend
to decide it would like to try to cancel the ongoing command. (It
can be done from a signal handler, but not otherwise.)
* PQexec can return only one PGresult structure. If the submitted
command string contains multiple SQL commands, all but the last
PGresult are discarded by PQexec.
WHAT THIS IS
A handful of new pg_* commands have been added to support asynchronous
operation, including cancelling requests that are currently being
processed and obtaining results from each SQL command when a
query contains multiple commands.
SOMEWHAT EXPERIMENTAL IN NATURE
This is a new Tcl interface to asynchronous query processing capabilities that
have been made available through the Postgres C interface.
We're calling it experimental because we think we'll want to evolve and change
the interface, perhaps simplifying it, as we gain experience with it. So
if you use it, understand that we are not promising to provide the same
interface or backwards compatibility to this interface in future releases.
ASYNCHRONOUS QUERY PROCESSING COMMANDS
pg_sendquery connection query
This works like pg_exec, except that the query is issued asynchronously
and pg_sendquery returns immediately without providing a result handle.
With Postgres 7.4 and above, you can also do variable substitution.
pg_sendquery connection query var1 var2 ...
...for example...
pg_sendquery $conn {insert into people values ($1, $2, $3, $4, $5);} \
$name $address $city $state $zip
You can also execute prepared statements:
pg_exec $conn {prepare insert_people (varchar, varchar, varchar, varchar, varchar) as insert into people values ($1, $2, $3, $4, $5);}
pg_sendquery_prepared $conn insert_people $name $address $city $state $zip
To get result handles resulting from the execution of pg_sendqery (and there
may be more than one if there are multiple SQL commands in the query), you
need to repeatedly call
pg_getresult connection
This will return the same sort of result handle that pg_exec returns.
If there is no query currently being processed or all of the results have
been obtained, pg_getresult returns nothing.
pg_isbusy connection
pg_getresult can block if results aren't yet available. To avoid this,
you can use pg_isbusy to check to see if the connection is busy processing
a query.
If this returns 1, pg_getresult will block if called. If it's 0, you can
safely call pg_getresult and it won't block.
pg_blocking
This sets whether a connection is set for blocking or nonblocking, and
allows that state to be changed.
syntax:
pg_blocking connection - returns the current state, 1 = blocking, 0 = non
pg_blocking connection 1 - sets the connection to blocking
pg_blocking connection 0 - sets the connection to nonblocking
Note - I'm not sure about all of the ramifications of setting a connection
nonblocking. Even with a connection in the (default) blocking state,
pg_isbusy seems to work OK and can be used in conjunction with pg_getresult
to keep from blocking while processing query results.
pg_cancelrequest connection
This request that postgresql abandon processing of the current command
issued via pg_sendquery.
There is no guarantee that the request will be cancelled. If it is and
you were in the middle of a transaction, the entire transaction is cancelled.
You still need to call pg_getresult repeatedly until it doesn't return
anything, and handle (and discard) all of the returned result handles.
HOW TO USE IT
We really need some example code. Probably we need some Tcl code that will
be part of the libary, pulled in with "package require Pgtcl", that will
issue a pg_sendrequest and iteratively call pg_isbusy on a timer, then
looping through passed-in Tcl code for each result until none are found.
You'll want to write something that issues the request via pg_sendquery.
Then you'll want a proc that does a pg_isbusy and if it is busy, calls
itself to run again after, oh, a tenth of a second or so, via "after".
If pg_isbusy returns 0, you can safely call pg_getresult to get a result.
(Use pg_result to examine the result, as in the past.) If pg_getresult
returns an empty string, there is no more work to be done.
If you want to cancel a request that is currently in progress, use
pg_cancelrequest. Note that you still need to do the pg_getresult
thing repeatedly until it returns nothing. For more information, read
the C interface docs in the PostgreSQL documentation.
I know you'd like some example code. We don't have any yet. That's why we
call it an alpha release.
LICENSE
Berkeley License. Freely redistributable for any use including resale,
without royalty or other sucky GPL restrictions. Don't sue us if it
kills your dog.