2 * psql - the PostgreSQL interactive terminal
4 * Copyright 2000-2002 by PostgreSQL Global Development Group
6 * $Header: /cvsroot/pgsql/src/bin/psql/large_obj.c,v 1.24 2003/03/20 06:43:35 momjian Exp $
8 #include "postgres_fe.h"
14 #include "variables.h"
19 #define atooid(x) ((Oid) strtoul((x), NULL, 10))
23 * Since all large object ops must be in a transaction, we must do some magic
24 * here. You can set the variable lo_transaction to one of commit|rollback|
25 * nothing to get your favourite behaviour regarding any transaction in
26 * progress. Rollback is default.
29 static char notice[80];
32 _my_notice_handler(void *arg, const char *message)
35 strncpy(notice, message, 79);
41 handle_transaction(void)
45 PQnoticeProcessor old_notice_hook;
47 switch (SwitchVariable(pset.vars, "LO_TRANSACTION",
59 old_notice_hook = PQsetNoticeProcessor(pset.db, _my_notice_handler, NULL);
61 res = PSQLexec(commit ? "COMMIT" : "ROLLBACK", false);
67 if ((!commit && strcmp(notice, "WARNING: ROLLBACK: no transaction in progress\n") != 0) ||
68 (commit && strcmp(notice, "WARNING: COMMIT: no transaction in progress\n") != 0))
69 fputs(notice, stderr);
74 puts(gettext("Warning: Your transaction in progress has been committed."));
76 puts(gettext("Warning: Your transaction in progress has been rolled back."));
79 PQsetNoticeProcessor(pset.db, old_notice_hook, NULL);
88 * Write a large object to a file
91 do_lo_export(const char *loid_arg, const char *filename_arg)
97 own_transaction = VariableEquals(pset.vars, "LO_TRANSACTION", "nothing");
101 psql_error("\\lo_export: not connected to a database\n");
107 if (!handle_transaction())
110 if (!(res = PSQLexec("BEGIN", false)))
116 status = lo_export(pset.db, atooid(loid_arg), filename_arg);
118 { /* of course this status is documented
120 fputs(PQerrorMessage(pset.db), stderr);
123 res = PQexec(pset.db, "ROLLBACK");
131 if (!(res = PSQLexec("COMMIT", false)))
133 res = PQexec(pset.db, "ROLLBACK");
141 fprintf(pset.queryFout, "lo_export\n");
151 * Copy large object from file to database
154 do_lo_import(const char *filename_arg, const char *comment_arg)
160 bool own_transaction;
162 own_transaction = VariableEquals(pset.vars, "LO_TRANSACTION", "nothing");
166 psql_error("\\lo_import: not connected to a database\n");
172 if (!handle_transaction())
175 if (!(res = PSQLexec("BEGIN", false)))
181 loid = lo_import(pset.db, filename_arg);
182 if (loid == InvalidOid)
184 fputs(PQerrorMessage(pset.db), stderr);
187 res = PQexec(pset.db, "ROLLBACK");
193 /* insert description if given */
194 /* XXX don't try to hack pg_description if not superuser */
195 /* XXX ought to replace this with some kind of COMMENT command */
196 if (comment_arg && pset.issuper)
200 size_t slen = strlen(comment_arg);
202 cmdbuf = malloc(slen * 2 + 256);
207 res = PQexec(pset.db, "ROLLBACK");
213 "INSERT INTO pg_catalog.pg_description VALUES ('%u', "
214 "'pg_catalog.pg_largeobject'::regclass, "
217 bufptr = cmdbuf + strlen(cmdbuf);
218 for (i = 0; i < slen; i++)
220 if (comment_arg[i] == '\'' || comment_arg[i] == '\\')
222 *bufptr++ = comment_arg[i];
224 strcpy(bufptr, "')");
226 if (!(res = PSQLexec(cmdbuf, false)))
230 res = PQexec(pset.db, "ROLLBACK");
243 if (!(res = PSQLexec("COMMIT", false)))
245 res = PQexec(pset.db, "ROLLBACK");
254 fprintf(pset.queryFout, "lo_import %u\n", loid);
255 sprintf(oidbuf, "%u", loid);
256 SetVariable(pset.vars, "LASTOID", oidbuf);
266 * removes a large object out of the database
269 do_lo_unlink(const char *loid_arg)
273 Oid loid = atooid(loid_arg);
276 bool own_transaction;
278 own_transaction = VariableEquals(pset.vars, "LO_TRANSACTION", "nothing");
282 psql_error("\\lo_unlink: not connected to a database\n");
288 if (!handle_transaction())
291 if (!(res = PSQLexec("BEGIN", false)))
297 status = lo_unlink(pset.db, loid);
300 fputs(PQerrorMessage(pset.db), stderr);
303 res = PQexec(pset.db, "ROLLBACK");
309 /* remove the comment as well */
310 /* XXX don't try to hack pg_description if not superuser */
311 /* XXX ought to replace this with some kind of COMMENT command */
314 sprintf(buf, "DELETE FROM pg_catalog.pg_description WHERE objoid = '%u' "
315 "AND classoid = 'pg_catalog.pg_largeobject'::regclass",
317 if (!(res = PSQLexec(buf, false)))
321 res = PQexec(pset.db, "ROLLBACK");
330 if (!(res = PSQLexec("COMMIT", false)))
332 res = PQexec(pset.db, "ROLLBACK");
340 fprintf(pset.queryFout, "lo_unlink %u\n", loid);
350 * Show all large objects in database with comments
357 printQueryOpt myopt = pset.popt;
359 snprintf(buf, sizeof(buf),
360 "SELECT loid as \"ID\", pg_catalog.obj_description(loid, 'pg_largeobject') as \"%s\"\n"
361 "FROM (SELECT DISTINCT loid FROM pg_catalog.pg_largeobject) x\n"
363 gettext("Description"));
365 res = PSQLexec(buf, false);
369 myopt.topt.tuples_only = false;
370 myopt.nullPrint = NULL;
371 myopt.title = gettext("Large objects");
373 printQuery(res, &myopt, pset.queryFout);