Merge from trunk
[plcapi.git] / trunk / psycopg2 / doc / async.txt
diff --git a/trunk/psycopg2/doc/async.txt b/trunk/psycopg2/doc/async.txt
new file mode 100644 (file)
index 0000000..518d5fe
--- /dev/null
@@ -0,0 +1,67 @@
+psycopg asynchronous API
+************************
+
+** Important: async quaeries are not enabled for 2.0 **
+
+Program code can initiate an asynchronous query by passing an 'async=1' flag
+to the .execute() method. A very simple example, from the connection to the
+query:
+
+    conn = psycopg.connect(database='test')
+    curs = conn.cursor()
+    curs.execute("SEECT * from test WHERE fielda > %s", (1971,), async=1)
+    
+From then on any query on other cursors derived from the same connection is
+doomed to fail (and raise an exception) until the original cursor (the one
+executing the query) complete the asynchronous operation. This can happen in
+a number of different ways:
+
+    1) one of the .fetchXXX() methods is called, effectively blocking untill
+       data has been sent from the backend to the client, terminating the
+       query.
+       
+    2) .cancel() is called. This method tries to abort the current query and
+       will block until the query is aborted or fully executed. The return
+       value is True if the query was successfully aborted or False if it
+       was executed. Query result are discarded in both cases.
+       
+    3) .execute() is called again on the same cursor (.execute() on a
+       different cursor will simply raise an exception.) This waits for the
+       complete execution of the current query, discard any data and execute
+       the new one.
+
+Note that calling .execute() two times in a row will not abort the former
+query and will temporarily go to synchronous mode until the first of the two
+queries is executed.
+
+Cursors now have some extra methods that make them usefull during
+asynchronous queries:
+
+    .fileno()
+      Returns the file descriptor associated with the current connection and
+      make possible to use a cursor in a context where a file object would be
+      expected (like in a select() call.)
+
+    .isbusy()
+      Returns True if the backend is still processing the query or false if
+      data is ready to be fetched (by one of the .fetchXXX() methods.)
+      
+A code snippet that shows how to use the cursor object in a select() call:
+
+    import psycopg
+    import select
+        
+    conn = psycopg.connect(database='test')
+    curs = conn.cursor()
+    curs.execute("SEECT * from test WHERE fielda > %s", (1971,), async=1)
+
+    # wait for input with a maximum timeout of 5 seconds
+    query_ended = False
+    while not query_ended:
+        rread, rwrite, rspec = select([cursor, another_file], [], [], 5)
+       if not cursor.isbusy():
+          query_ended = True
+       # manage input from other sources like other_file, etc.
+    print "Query Results:"
+    for row in cursor:
+        print row