2 * psql - the PostgreSQL interactive terminal
4 * Copyright (c) 2000-2008, PostgreSQL Global Development Group
8 #include "postgres_fe.h"
16 print_lo_result(const char *fmt
,...)
17 __attribute__((format(printf
, 1, 2)));
20 print_lo_result(const char *fmt
,...)
26 if (pset
.popt
.topt
.format
== PRINT_HTML
)
27 fputs("<p>", pset
.queryFout
);
30 vfprintf(pset
.queryFout
, fmt
, ap
);
33 if (pset
.popt
.topt
.format
== PRINT_HTML
)
34 fputs("</p>\n", pset
.queryFout
);
36 fputs("\n", pset
.queryFout
);
42 vfprintf(pset
.logfile
, fmt
, ap
);
44 fputs("\n", pset
.logfile
);
50 * Prepare to do a large-object operation. We *must* be inside a transaction
51 * block for all these operations, so start one if needed.
53 * Returns TRUE if okay, FALSE if failed. *own_transaction is set to indicate
54 * if we started our own transaction or not.
57 start_lo_xact(const char *operation
, bool *own_transaction
)
59 PGTransactionStatusType tstatus
;
62 *own_transaction
= false;
66 psql_error("%s: not connected to a database\n", operation
);
70 tstatus
= PQtransactionStatus(pset
.db
);
75 /* need to start our own xact */
76 if (!(res
= PSQLexec("BEGIN", false)))
79 *own_transaction
= true;
82 /* use the existing xact */
85 psql_error("%s: current transaction is aborted\n", operation
);
88 psql_error("%s: unknown transaction status\n", operation
);
96 * Clean up after a successful LO operation
99 finish_lo_xact(const char *operation
, bool own_transaction
)
103 if (own_transaction
&& pset
.autocommit
)
105 /* close out our own xact */
106 if (!(res
= PSQLexec("COMMIT", false)))
108 res
= PSQLexec("ROLLBACK", false);
119 * Clean up after a failed LO operation
122 fail_lo_xact(const char *operation
, bool own_transaction
)
126 if (own_transaction
&& pset
.autocommit
)
128 /* close out our own xact */
129 res
= PSQLexec("ROLLBACK", false);
133 return false; /* always */
140 * Write a large object to a file
143 do_lo_export(const char *loid_arg
, const char *filename_arg
)
146 bool own_transaction
;
148 if (!start_lo_xact("\\lo_export", &own_transaction
))
152 status
= lo_export(pset
.db
, atooid(loid_arg
), filename_arg
);
155 /* of course this status is documented nowhere :( */
158 fputs(PQerrorMessage(pset
.db
), stderr
);
159 return fail_lo_xact("\\lo_export", own_transaction
);
162 if (!finish_lo_xact("\\lo_export", own_transaction
))
165 print_lo_result("lo_export");
174 * Copy large object from file to database
177 do_lo_import(const char *filename_arg
, const char *comment_arg
)
182 bool own_transaction
;
184 if (!start_lo_xact("\\lo_import", &own_transaction
))
188 loid
= lo_import(pset
.db
, filename_arg
);
191 if (loid
== InvalidOid
)
193 fputs(PQerrorMessage(pset
.db
), stderr
);
194 return fail_lo_xact("\\lo_import", own_transaction
);
197 /* insert description if given */
202 size_t slen
= strlen(comment_arg
);
204 cmdbuf
= malloc(slen
* 2 + 256);
206 return fail_lo_xact("\\lo_import", own_transaction
);
207 sprintf(cmdbuf
, "COMMENT ON LARGE OBJECT %u IS '", loid
);
208 bufptr
= cmdbuf
+ strlen(cmdbuf
);
209 bufptr
+= PQescapeStringConn(pset
.db
, bufptr
, comment_arg
, slen
, NULL
);
212 if (!(res
= PSQLexec(cmdbuf
, false)))
215 return fail_lo_xact("\\lo_import", own_transaction
);
222 if (!finish_lo_xact("\\lo_import", own_transaction
))
225 print_lo_result("lo_import %u", loid
);
227 sprintf(oidbuf
, "%u", loid
);
228 SetVariable(pset
.vars
, "LASTOID", oidbuf
);
237 * removes a large object out of the database
240 do_lo_unlink(const char *loid_arg
)
243 Oid loid
= atooid(loid_arg
);
244 bool own_transaction
;
246 if (!start_lo_xact("\\lo_unlink", &own_transaction
))
250 status
= lo_unlink(pset
.db
, loid
);
255 fputs(PQerrorMessage(pset
.db
), stderr
);
256 return fail_lo_xact("\\lo_unlink", own_transaction
);
259 if (!finish_lo_xact("\\lo_unlink", own_transaction
))
262 print_lo_result("lo_unlink %u", loid
);
272 * Show all large objects in database with comments
279 printQueryOpt myopt
= pset
.popt
;
281 snprintf(buf
, sizeof(buf
),
282 "SELECT loid as \"%s\",\n"
283 " pg_catalog.obj_description(loid, 'pg_largeobject') as \"%s\"\n"
284 "FROM (SELECT DISTINCT loid FROM pg_catalog.pg_largeobject) x\n"
287 gettext_noop("Description"));
289 res
= PSQLexec(buf
, false);
293 myopt
.topt
.tuples_only
= false;
294 myopt
.nullPrint
= NULL
;
295 myopt
.title
= _("Large objects");
296 myopt
.translate_header
= true;
298 printQuery(res
, &myopt
, pset
.queryFout
, pset
.logfile
);