Re: Writing transactions from pgtksh - Mailing list pgsql-interfaces
From | Andreas Kretzer |
---|---|
Subject | Re: Writing transactions from pgtksh |
Date | |
Msg-id | 3CB2A539.B73785CC@kretzer-berlin.de Whole thread Raw |
In response to | Writing transactions from pgtksh (Denis Chavez <dnchavez@gmx.net>) |
List | pgsql-interfaces |
<tt>Denis Chavez schrieb:</tt><blockquote type="CITE"><tt>Hi!</tt><tt></tt><p><tt>I'm using pgtksh to develop a Postgresclient application. I need to use</tt><br /><tt>transactions, but</tt><br /><tt>the Postgres Programmer's Guide justtells me to use large objects and</tt><br /><tt>doesn't give any</tt><br /><tt>example.</tt><tt></tt><p><tt>Any ideaon how to use this pg_lo* with transactions in pgtksh?</tt></blockquote><tt>I'm using the normal Tcl/Tk together withlibpgtcl.so (or libpgtcl.dll under windoze).</tt><br /><tt>It should effectively be the same thing.</tt><tt></tt><p><tt>Thedocumentation states, that you must enclose your LargeObject operation</tt><br /><tt>in a transaction-- and this is definetly true! So let's take a code fragment</tt><br /><tt>to create a large object from a client-localfile ($db is my connection handle):</tt><tt></tt><p><tt>proc create_lobject {db file} {</tt><br /><tt> # let'sopen the file</tt><br /><tt> if {[catch {set fd [open $file r]}]} {</tt><br /><tt> ... error message 'couldn'topen file' ...</tt><br /><tt> return -1</tt><br /><tt> }</tt><br /><tt> fconfigure $fd -translation binary-encoding binary -eofchar {}</tt><tt></tt><p><tt> # now create the object</tt><br /><tt> set oid [pg_lo_create$db INV_READ|INV_WRITE]</tt><br /><tt> if {[catch {set oid [expr $oid * 1]}]} { # check for numeric value</tt><br/><tt> ... some error message ...</tt><br /><tt> return -1</tt><br /><tt> }</tt><tt></tt><p><tt> # start with a transaction and open the object</tt><br /><tt> set res [pg_exec $db "BEGIN TRANSACTION;"]</tt><br/><tt> pg_result $res -clear; # don't care for result - this should always work</tt><br /><tt> </tt><br/><tt> set lobj_fd [pg_lo_open $db $oid w]</tt><br /><tt> # one should check $lobj_fd for succesfull open- I don't do this for now :-(</tt><br /><tt> </tt><br /><tt> # now sequentially read file and write to the large objectlike</tt><br /><tt> # you would do with a regular file</tt><br /><tt> while {![eof $fd]} {</tt><br /><tt> set buf [read $fd 1024]</tt><br /><tt> set len [string bytelength $buf]</tt><br /><tt> pg_lo_write $db$lobj_fd $buf $len</tt><br /><tt> }</tt><tt></tt><p><tt> # finish everything</tt><br /><tt> pg_lo_close $db $lobj_fd</tt><br/><tt> close $fd</tt><tt></tt><p><tt> set res [pg_exec $db "COMMIT TRANSACTION;"]</tt><br /><tt> pg_result$res -clear</tt><tt></tt><p><tt> return $oid</tt><br /><tt>}</tt><tt></tt><p><tt>Remember to store the returnedOID in some descriptive data set. The</tt><br /><tt>large object can only be recovered by it's OID. Reading worksexactly</tt><br /><tt>like writing - except that you don't create the object before opening</tt><br /><tt>it.</tt><tt></tt><p><tt>ATTENTION:This works under linux :-) but may give you some trouble</tt><br /><tt>under Windows:-(</tt><br /><tt>Under Windows you can't really import binary files as they are recoded</tt><br /><tt>every time.Even the 'fconfigure' command can't do anything against</tt><br /><tt>it (I'm still searching for the reason ...). Onemay be that you even</tt><br /><tt>can't figure out the real length of what you read from the file and</tt><br /><tt>inaddition the 'buf' contains weired chars that won't make up the</tt><br /><tt>real binary representation of the file(mainly because some UTF-8</tt><br /><tt>chars or whatever).</tt><tt></tt><p><tt>There are two other methods to readand write large objects.</tt><br /><tt>pg_lo_import and pg_lo_export that should do all that in one</tt><br /><tt>step.I encountered the same problems with binary files on windows</tt><br /><tt>so I just don't use them anymore.</tt><tt></tt><p><tt>Hopethis helps</tt><tt></tt><p><tt>Andreas</tt>
pgsql-interfaces by date: