2 * psql - the PostgreSQL interactive terminal
4 * Copyright 2000 by PostgreSQL Global Development Group
6 * $Header: /cvsroot/pgsql/src/bin/psql/large_obj.c,v 1.14 2001/03/22 04:00:20 momjian Exp $
8 #include "postgres_fe.h"
14 #include "variables.h"
20 * Since all large object ops must be in a transaction, we must do some magic
21 * here. You can set the variable lo_transaction to one of commit|rollback|
22 * nothing to get your favourite behaviour regarding any transaction in
23 * progress. Rollback is default.
26 static char notice[80];
29 _my_notice_handler(void *arg, const char *message)
32 strncpy(notice, message, 79);
38 handle_transaction(void)
40 const char *var = GetVariable(pset.vars, "LO_TRANSACTION");
43 PQnoticeProcessor old_notice_hook;
45 if (var && strcmp(var, "nothing") == 0)
48 commit = (var && strcmp(var, "commit") == 0);
51 old_notice_hook = PQsetNoticeProcessor(pset.db, _my_notice_handler, NULL);
53 res = PSQLexec(commit ? "COMMIT" : "ROLLBACK");
59 if ((!commit && strcmp(notice, "NOTICE: ROLLBACK: no transaction in progress\n") != 0) ||
60 (commit && strcmp(notice, "NOTICE: COMMIT: no transaction in progress\n") != 0))
61 fputs(notice, stderr);
66 puts("Warning: Your transaction in progress has been committed.");
68 puts("Warning: Your transaction in progress has been rolled back.");
71 PQsetNoticeProcessor(pset.db, old_notice_hook, NULL);
80 * Write a large object to a file
83 do_lo_export(const char *loid_arg, const char *filename_arg)
87 bool own_transaction = true;
88 const char *var = GetVariable(pset.vars, "LO_TRANSACTION");
90 if (var && strcmp(var, "nothing") == 0)
91 own_transaction = false;
95 if (!pset.cur_cmd_interactive)
96 fprintf(stderr, "%s: ", pset.progname);
97 fputs("\\lo_export: not connected to a database\n", stderr);
103 if (!handle_transaction())
106 if (!(res = PSQLexec("BEGIN")))
112 status = lo_export(pset.db, atol(loid_arg), filename_arg);
114 { /* of course this status is documented
116 fputs(PQerrorMessage(pset.db), stderr);
119 res = PQexec(pset.db, "ROLLBACK");
127 if (!(res = PSQLexec("COMMIT")))
129 res = PQexec(pset.db, "ROLLBACK");
137 fprintf(pset.queryFout, "lo_export\n");
147 * Copy large object from file to database
150 do_lo_import(const char *filename_arg, const char *comment_arg)
156 bool own_transaction = true;
157 const char *var = GetVariable(pset.vars, "LO_TRANSACTION");
159 if (var && strcmp(var, "nothing") == 0)
160 own_transaction = false;
164 if (!pset.cur_cmd_interactive)
165 fprintf(stderr, "%s: ", pset.progname);
166 fputs("\\lo_import: not connected to a database\n", stderr);
172 if (!handle_transaction())
175 if (!(res = PSQLexec("BEGIN")))
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 */
196 sprintf(buf, "INSERT INTO pg_description VALUES (%u, '", loid);
197 for (i = 0; i < strlen(comment_arg); i++)
198 if (comment_arg[i] == '\'')
201 strncat(buf, &comment_arg[i], 1);
204 if (!(res = PSQLexec(buf)))
208 res = PQexec(pset.db, "ROLLBACK");
217 if (!(res = PSQLexec("COMMIT")))
219 res = PQexec(pset.db, "ROLLBACK");
228 fprintf(pset.queryFout, "lo_import %d\n", loid);
229 sprintf(buf, "%u", (unsigned int) loid);
230 SetVariable(pset.vars, "LASTOID", buf);
240 * removes a large object out of the database
243 do_lo_unlink(const char *loid_arg)
247 Oid loid = (Oid) atol(loid_arg);
249 bool own_transaction = true;
250 const char *var = GetVariable(pset.vars, "LO_TRANSACTION");
252 if (var && strcmp(var, "nothing") == 0)
253 own_transaction = false;
257 if (!pset.cur_cmd_interactive)
258 fprintf(stderr, "%s: ", pset.progname);
259 fputs("\\lo_unlink: not connected to a database\n", stderr);
265 if (!handle_transaction())
268 if (!(res = PSQLexec("BEGIN")))
274 status = lo_unlink(pset.db, loid);
277 fputs(PQerrorMessage(pset.db), stderr);
280 res = PQexec(pset.db, "ROLLBACK");
286 /* remove the comment as well */
287 sprintf(buf, "DELETE FROM pg_description WHERE objoid = %u", loid);
288 if (!(res = PSQLexec(buf)))
292 res = PQexec(pset.db, "ROLLBACK");
301 if (!(res = PSQLexec("COMMIT")))
303 res = PQexec(pset.db, "ROLLBACK");
311 fprintf(pset.queryFout, "lo_unlink %d\n", loid);
321 * Show all large objects in database with comments
328 printQueryOpt myopt = pset.popt;
331 "SELECT loid as \"ID\", obj_description(loid) as \"Description\"\n"
332 "FROM (SELECT DISTINCT loid FROM pg_largeobject) x\n"
339 myopt.topt.tuples_only = false;
340 myopt.nullPrint = NULL;
341 myopt.title = "Large objects";
343 printQuery(res, &myopt, pset.queryFout);