PostgreSQL Source Code  git master
large_obj.c File Reference
#include "postgres_fe.h"
#include "common.h"
#include "common/logging.h"
#include "fe_utils/cancel.h"
#include "large_obj.h"
#include "settings.h"
Include dependency graph for large_obj.c:

Go to the source code of this file.

Functions

static void print_lo_result (const char *fmt,...) pg_attribute_printf(1
 
static bool start_lo_xact (const char *operation, bool *own_transaction)
 
static bool finish_lo_xact (const char *operation, bool own_transaction)
 
static bool fail_lo_xact (const char *operation, bool own_transaction)
 
bool do_lo_export (const char *loid_arg, const char *filename_arg)
 
bool do_lo_import (const char *filename_arg, const char *comment_arg)
 
bool do_lo_unlink (const char *loid_arg)
 
bool do_lo_list (void)
 

Function Documentation

◆ do_lo_export()

bool do_lo_export ( const char *  loid_arg,
const char *  filename_arg 
)

Definition at line 142 of file large_obj.c.

References atooid, _psqlSettings::db, fail_lo_xact(), finish_lo_xact(), lo_export(), pg_log_info, PQerrorMessage(), print_lo_result(), pset, ResetCancelConn(), SetCancelConn(), start_lo_xact(), and status().

Referenced by exec_command_lo().

143 {
144  int status;
145  bool own_transaction;
146 
147  if (!start_lo_xact("\\lo_export", &own_transaction))
148  return false;
149 
150  SetCancelConn(NULL);
151  status = lo_export(pset.db, atooid(loid_arg), filename_arg);
152  ResetCancelConn();
153 
154  /* of course this status is documented nowhere :( */
155  if (status != 1)
156  {
158  return fail_lo_xact("\\lo_export", own_transaction);
159  }
160 
161  if (!finish_lo_xact("\\lo_export", own_transaction))
162  return false;
163 
164  print_lo_result("lo_export");
165 
166  return true;
167 }
PGconn * db
Definition: settings.h:82
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6623
PsqlSettings pset
Definition: startup.c:31
void ResetCancelConn(void)
Definition: cancel.c:89
static bool finish_lo_xact(const char *operation, bool own_transaction)
Definition: large_obj.c:98
int lo_export(PGconn *conn, Oid lobjId, const char *filename)
Definition: fe-lobj.c:784
static bool fail_lo_xact(const char *operation, bool own_transaction)
Definition: large_obj.c:121
void SetCancelConn(PGconn *conn)
Definition: cancel.c:59
#define atooid(x)
Definition: postgres_ext.h:42
static void print_lo_result(const char *fmt,...) pg_attribute_printf(1
Definition: large_obj.c:19
static bool start_lo_xact(const char *operation, bool *own_transaction)
Definition: large_obj.c:56
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:226
#define pg_log_info(...)
Definition: logging.h:87

◆ do_lo_import()

bool do_lo_import ( const char *  filename_arg,
const char *  comment_arg 
)

Definition at line 176 of file large_obj.c.

References _psqlSettings::db, fail_lo_xact(), finish_lo_xact(), free, InvalidOid, lo_import(), MCXT_ALLOC_NO_OOM, pg_log_info, pg_malloc_extended(), PQclear(), PQerrorMessage(), PQescapeStringConn(), print_lo_result(), pset, PSQLexec(), ResetCancelConn(), SetCancelConn(), SetVariable(), sprintf, start_lo_xact(), and _psqlSettings::vars.

Referenced by exec_command_lo().

177 {
178  PGresult *res;
179  Oid loid;
180  char oidbuf[32];
181  bool own_transaction;
182 
183  if (!start_lo_xact("\\lo_import", &own_transaction))
184  return false;
185 
186  SetCancelConn(NULL);
187  loid = lo_import(pset.db, filename_arg);
188  ResetCancelConn();
189 
190  if (loid == InvalidOid)
191  {
193  return fail_lo_xact("\\lo_import", own_transaction);
194  }
195 
196  /* insert description if given */
197  if (comment_arg)
198  {
199  char *cmdbuf;
200  char *bufptr;
201  size_t slen = strlen(comment_arg);
202 
203  cmdbuf = pg_malloc_extended(slen * 2 + 256, MCXT_ALLOC_NO_OOM);
204  if (!cmdbuf)
205  return fail_lo_xact("\\lo_import", own_transaction);
206  sprintf(cmdbuf, "COMMENT ON LARGE OBJECT %u IS '", loid);
207  bufptr = cmdbuf + strlen(cmdbuf);
208  bufptr += PQescapeStringConn(pset.db, bufptr, comment_arg, slen, NULL);
209  strcpy(bufptr, "'");
210 
211  if (!(res = PSQLexec(cmdbuf)))
212  {
213  free(cmdbuf);
214  return fail_lo_xact("\\lo_import", own_transaction);
215  }
216 
217  PQclear(res);
218  free(cmdbuf);
219  }
220 
221  if (!finish_lo_xact("\\lo_import", own_transaction))
222  return false;
223 
224  print_lo_result("lo_import %u", loid);
225 
226  sprintf(oidbuf, "%u", loid);
227  SetVariable(pset.vars, "LASTOID", oidbuf);
228 
229  return true;
230 }
PGconn * db
Definition: settings.h:82
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6623
PsqlSettings pset
Definition: startup.c:31
void ResetCancelConn(void)
Definition: cancel.c:89
static bool finish_lo_xact(const char *operation, bool own_transaction)
Definition: large_obj.c:98
#define MCXT_ALLOC_NO_OOM
Definition: fe_memutils.h:18
unsigned int Oid
Definition: postgres_ext.h:31
#define sprintf
Definition: port.h:194
static bool fail_lo_xact(const char *operation, bool own_transaction)
Definition: large_obj.c:121
size_t PQescapeStringConn(PGconn *conn, char *to, const char *from, size_t length, int *error)
Definition: fe-exec.c:3410
void SetCancelConn(PGconn *conn)
Definition: cancel.c:59
void * pg_malloc_extended(size_t size, int flags)
Definition: fe_memutils.c:59
static void print_lo_result(const char *fmt,...) pg_attribute_printf(1
Definition: large_obj.c:19
#define InvalidOid
Definition: postgres_ext.h:36
void PQclear(PGresult *res)
Definition: fe-exec.c:694
#define free(a)
Definition: header.h:65
bool SetVariable(VariableSpace space, const char *name, const char *value)
Definition: variables.c:211
static bool start_lo_xact(const char *operation, bool *own_transaction)
Definition: large_obj.c:56
Oid lo_import(PGconn *conn, const char *filename)
Definition: fe-lobj.c:668
#define pg_log_info(...)
Definition: logging.h:87
PGresult * PSQLexec(const char *query)
Definition: common.c:546
VariableSpace vars
Definition: settings.h:117

◆ do_lo_list()

bool do_lo_list ( void  )

Definition at line 274 of file large_obj.c.

References _, buf, gettext_noop, _psqlSettings::logfile, printQueryOpt::nullPrint, _psqlSettings::popt, PQclear(), printQuery(), pset, PSQLexec(), _psqlSettings::queryFout, snprintf, _psqlSettings::sversion, printQueryOpt::title, printQueryOpt::topt, printQueryOpt::translate_header, and printTableOpt::tuples_only.

Referenced by exec_command_d(), and exec_command_lo().

275 {
276  PGresult *res;
277  char buf[1024];
278  printQueryOpt myopt = pset.popt;
279 
280  if (pset.sversion >= 90000)
281  {
282  snprintf(buf, sizeof(buf),
283  "SELECT oid as \"%s\",\n"
284  " pg_catalog.pg_get_userbyid(lomowner) as \"%s\",\n"
285  " pg_catalog.obj_description(oid, 'pg_largeobject') as \"%s\"\n"
286  " FROM pg_catalog.pg_largeobject_metadata "
287  " ORDER BY oid",
288  gettext_noop("ID"),
289  gettext_noop("Owner"),
290  gettext_noop("Description"));
291  }
292  else
293  {
294  snprintf(buf, sizeof(buf),
295  "SELECT loid as \"%s\",\n"
296  " pg_catalog.obj_description(loid, 'pg_largeobject') as \"%s\"\n"
297  "FROM (SELECT DISTINCT loid FROM pg_catalog.pg_largeobject) x\n"
298  "ORDER BY 1",
299  gettext_noop("ID"),
300  gettext_noop("Description"));
301  }
302 
303  res = PSQLexec(buf);
304  if (!res)
305  return false;
306 
307  myopt.topt.tuples_only = false;
308  myopt.nullPrint = NULL;
309  myopt.title = _("Large objects");
310  myopt.translate_header = true;
311 
312  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
313 
314  PQclear(res);
315  return true;
316 }
char * nullPrint
Definition: print.h:168
PsqlSettings pset
Definition: startup.c:31
printTableOpt topt
Definition: print.h:167
#define gettext_noop(x)
Definition: c.h:1148
FILE * queryFout
Definition: settings.h:84
bool tuples_only
Definition: print.h:108
static char * buf
Definition: pg_test_fsync.c:67
bool translate_header
Definition: print.h:171
FILE * logfile
Definition: settings.h:115
void PQclear(PGresult *res)
Definition: fe-exec.c:694
char * title
Definition: print.h:169
printQueryOpt popt
Definition: settings.h:91
void printQuery(const PGresult *result, const printQueryOpt *opt, FILE *fout, bool is_pager, FILE *flog)
Definition: print.c:3434
#define snprintf
Definition: port.h:192
#define _(x)
Definition: elog.c:87
PGresult * PSQLexec(const char *query)
Definition: common.c:546

◆ do_lo_unlink()

bool do_lo_unlink ( const char *  loid_arg)

Definition at line 239 of file large_obj.c.

References atooid, _psqlSettings::db, fail_lo_xact(), finish_lo_xact(), lo_unlink(), pg_log_info, PQerrorMessage(), print_lo_result(), pset, ResetCancelConn(), SetCancelConn(), start_lo_xact(), and status().

Referenced by exec_command_lo().

240 {
241  int status;
242  Oid loid = atooid(loid_arg);
243  bool own_transaction;
244 
245  if (!start_lo_xact("\\lo_unlink", &own_transaction))
246  return false;
247 
248  SetCancelConn(NULL);
249  status = lo_unlink(pset.db, loid);
250  ResetCancelConn();
251 
252  if (status == -1)
253  {
255  return fail_lo_xact("\\lo_unlink", own_transaction);
256  }
257 
258  if (!finish_lo_xact("\\lo_unlink", own_transaction))
259  return false;
260 
261  print_lo_result("lo_unlink %u", loid);
262 
263  return true;
264 }
PGconn * db
Definition: settings.h:82
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6623
PsqlSettings pset
Definition: startup.c:31
void ResetCancelConn(void)
Definition: cancel.c:89
int lo_unlink(PGconn *conn, Oid lobjId)
Definition: fe-lobj.c:628
static bool finish_lo_xact(const char *operation, bool own_transaction)
Definition: large_obj.c:98
unsigned int Oid
Definition: postgres_ext.h:31
static bool fail_lo_xact(const char *operation, bool own_transaction)
Definition: large_obj.c:121
void SetCancelConn(PGconn *conn)
Definition: cancel.c:59
#define atooid(x)
Definition: postgres_ext.h:42
static void print_lo_result(const char *fmt,...) pg_attribute_printf(1
Definition: large_obj.c:19
static bool start_lo_xact(const char *operation, bool *own_transaction)
Definition: large_obj.c:56
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:226
#define pg_log_info(...)
Definition: logging.h:87

◆ fail_lo_xact()

static bool fail_lo_xact ( const char *  operation,
bool  own_transaction 
)
static

Definition at line 121 of file large_obj.c.

References _psqlSettings::autocommit, PQclear(), pset, and PSQLexec().

Referenced by do_lo_export(), do_lo_import(), and do_lo_unlink().

122 {
123  PGresult *res;
124 
125  if (own_transaction && pset.autocommit)
126  {
127  /* close out our own xact */
128  res = PSQLexec("ROLLBACK");
129  PQclear(res);
130  }
131 
132  return false; /* always */
133 }
PsqlSettings pset
Definition: startup.c:31
bool autocommit
Definition: settings.h:124
void PQclear(PGresult *res)
Definition: fe-exec.c:694
PGresult * PSQLexec(const char *query)
Definition: common.c:546

◆ finish_lo_xact()

static bool finish_lo_xact ( const char *  operation,
bool  own_transaction 
)
static

Definition at line 98 of file large_obj.c.

References _psqlSettings::autocommit, PQclear(), pset, and PSQLexec().

Referenced by do_lo_export(), do_lo_import(), and do_lo_unlink().

99 {
100  PGresult *res;
101 
102  if (own_transaction && pset.autocommit)
103  {
104  /* close out our own xact */
105  if (!(res = PSQLexec("COMMIT")))
106  {
107  res = PSQLexec("ROLLBACK");
108  PQclear(res);
109  return false;
110  }
111  PQclear(res);
112  }
113 
114  return true;
115 }
PsqlSettings pset
Definition: startup.c:31
bool autocommit
Definition: settings.h:124
void PQclear(PGresult *res)
Definition: fe-exec.c:694
PGresult * PSQLexec(const char *query)
Definition: common.c:546

◆ print_lo_result()

static void static void print_lo_result ( const char *  fmt,
  ... 
)
static

Definition at line 19 of file large_obj.c.

References printTableOpt::format, _psqlSettings::logfile, _psqlSettings::popt, PRINT_HTML, pset, _psqlSettings::queryFout, _psqlSettings::quiet, printQueryOpt::topt, and vfprintf.

Referenced by do_lo_export(), do_lo_import(), and do_lo_unlink().

20 {
21  va_list ap;
22 
23  if (!pset.quiet)
24  {
26  fputs("<p>", pset.queryFout);
27 
28  va_start(ap, fmt);
29  vfprintf(pset.queryFout, fmt, ap);
30  va_end(ap);
31 
33  fputs("</p>\n", pset.queryFout);
34  else
35  fputs("\n", pset.queryFout);
36  }
37 
38  if (pset.logfile)
39  {
40  va_start(ap, fmt);
41  vfprintf(pset.logfile, fmt, ap);
42  va_end(ap);
43  fputs("\n", pset.logfile);
44  }
45 }
PsqlSettings pset
Definition: startup.c:31
enum printFormat format
Definition: print.h:99
printTableOpt topt
Definition: print.h:167
FILE * queryFout
Definition: settings.h:84
FILE * logfile
Definition: settings.h:115
printQueryOpt popt
Definition: settings.h:91
#define vfprintf
Definition: port.h:195

◆ start_lo_xact()

static bool start_lo_xact ( const char *  operation,
bool own_transaction 
)
static

Definition at line 56 of file large_obj.c.

References _psqlSettings::db, pg_log_error, PQclear(), PQTRANS_IDLE, PQTRANS_INERROR, PQTRANS_INTRANS, PQtransactionStatus(), pset, and PSQLexec().

Referenced by do_lo_export(), do_lo_import(), and do_lo_unlink().

57 {
59  PGresult *res;
60 
61  *own_transaction = false;
62 
63  if (!pset.db)
64  {
65  pg_log_error("%s: not connected to a database", operation);
66  return false;
67  }
68 
69  tstatus = PQtransactionStatus(pset.db);
70 
71  switch (tstatus)
72  {
73  case PQTRANS_IDLE:
74  /* need to start our own xact */
75  if (!(res = PSQLexec("BEGIN")))
76  return false;
77  PQclear(res);
78  *own_transaction = true;
79  break;
80  case PQTRANS_INTRANS:
81  /* use the existing xact */
82  break;
83  case PQTRANS_INERROR:
84  pg_log_error("%s: current transaction is aborted", operation);
85  return false;
86  default:
87  pg_log_error("%s: unknown transaction status", operation);
88  return false;
89  }
90 
91  return true;
92 }
PGconn * db
Definition: settings.h:82
PsqlSettings pset
Definition: startup.c:31
#define pg_log_error(...)
Definition: logging.h:79
PGTransactionStatusType PQtransactionStatus(const PGconn *conn)
Definition: fe-connect.c:6578
void PQclear(PGresult *res)
Definition: fe-exec.c:694
PGTransactionStatusType
Definition: libpq-fe.h:103
PGresult * PSQLexec(const char *query)
Definition: common.c:546