Header And Logo

PostgreSQL
| The world's most advanced open source database.

Functions

large_obj.c File Reference

#include "postgres_fe.h"
#include "large_obj.h"
#include "settings.h"
#include "common.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,...) __attribute__((format(PG_PRINTF_ATTRIBUTE
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

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

Definition at line 143 of file large_obj.c.

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

Referenced by exec_command().

{
    int         status;
    bool        own_transaction;

    if (!start_lo_xact("\\lo_export", &own_transaction))
        return false;

    SetCancelConn();
    status = lo_export(pset.db, atooid(loid_arg), filename_arg);
    ResetCancelConn();

    /* of course this status is documented nowhere :( */
    if (status != 1)
    {
        psql_error("%s", PQerrorMessage(pset.db));
        return fail_lo_xact("\\lo_export", own_transaction);
    }

    if (!finish_lo_xact("\\lo_export", own_transaction))
        return false;

    print_lo_result("lo_export");

    return true;
}

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

Definition at line 177 of file large_obj.c.

References _psqlSettings::db, fail_lo_xact(), finish_lo_xact(), free, InvalidOid, lo_import(), malloc, NULL, PQclear(), PQerrorMessage(), PQescapeStringConn(), print_lo_result(), pset, psql_error(), PSQLexec(), ResetCancelConn(), SetCancelConn(), SetVariable(), start_lo_xact(), and _psqlSettings::vars.

Referenced by exec_command().

{
    PGresult   *res;
    Oid         loid;
    char        oidbuf[32];
    bool        own_transaction;

    if (!start_lo_xact("\\lo_import", &own_transaction))
        return false;

    SetCancelConn();
    loid = lo_import(pset.db, filename_arg);
    ResetCancelConn();

    if (loid == InvalidOid)
    {
        psql_error("%s", PQerrorMessage(pset.db));
        return fail_lo_xact("\\lo_import", own_transaction);
    }

    /* insert description if given */
    if (comment_arg)
    {
        char       *cmdbuf;
        char       *bufptr;
        size_t      slen = strlen(comment_arg);

        cmdbuf = malloc(slen * 2 + 256);
        if (!cmdbuf)
            return fail_lo_xact("\\lo_import", own_transaction);
        sprintf(cmdbuf, "COMMENT ON LARGE OBJECT %u IS '", loid);
        bufptr = cmdbuf + strlen(cmdbuf);
        bufptr += PQescapeStringConn(pset.db, bufptr, comment_arg, slen, NULL);
        strcpy(bufptr, "'");

        if (!(res = PSQLexec(cmdbuf, false)))
        {
            free(cmdbuf);
            return fail_lo_xact("\\lo_import", own_transaction);
        }

        PQclear(res);
        free(cmdbuf);
    }

    if (!finish_lo_xact("\\lo_import", own_transaction))
        return false;

    print_lo_result("lo_import %u", loid);

    sprintf(oidbuf, "%u", loid);
    SetVariable(pset.vars, "LASTOID", oidbuf);

    return true;
}

bool do_lo_list ( void   ) 

Definition at line 275 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().

{
    PGresult   *res;
    char        buf[1024];
    printQueryOpt myopt = pset.popt;

    if (pset.sversion >= 90000)
    {
        snprintf(buf, sizeof(buf),
                 "SELECT oid as \"%s\",\n"
                 "  pg_catalog.pg_get_userbyid(lomowner) as \"%s\",\n"
            "  pg_catalog.obj_description(oid, 'pg_largeobject') as \"%s\"\n"
                 "  FROM pg_catalog.pg_largeobject_metadata "
                 "  ORDER BY oid",
                 gettext_noop("ID"),
                 gettext_noop("Owner"),
                 gettext_noop("Description"));
    }
    else
    {
        snprintf(buf, sizeof(buf),
                 "SELECT loid as \"%s\",\n"
           "  pg_catalog.obj_description(loid, 'pg_largeobject') as \"%s\"\n"
             "FROM (SELECT DISTINCT loid FROM pg_catalog.pg_largeobject) x\n"
                 "ORDER BY 1",
                 gettext_noop("ID"),
                 gettext_noop("Description"));
    }

    res = PSQLexec(buf, false);
    if (!res)
        return false;

    myopt.topt.tuples_only = false;
    myopt.nullPrint = NULL;
    myopt.title = _("Large objects");
    myopt.translate_header = true;

    printQuery(res, &myopt, pset.queryFout, pset.logfile);

    PQclear(res);
    return true;
}

bool do_lo_unlink ( const char *  loid_arg  ) 

Definition at line 240 of file large_obj.c.

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

Referenced by exec_command().

{
    int         status;
    Oid         loid = atooid(loid_arg);
    bool        own_transaction;

    if (!start_lo_xact("\\lo_unlink", &own_transaction))
        return false;

    SetCancelConn();
    status = lo_unlink(pset.db, loid);
    ResetCancelConn();

    if (status == -1)
    {
        psql_error("%s", PQerrorMessage(pset.db));
        return fail_lo_xact("\\lo_unlink", own_transaction);
    }

    if (!finish_lo_xact("\\lo_unlink", own_transaction))
        return false;

    print_lo_result("lo_unlink %u", loid);

    return true;
}

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

Definition at line 122 of file large_obj.c.

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

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

{
    PGresult   *res;

    if (own_transaction && pset.autocommit)
    {
        /* close out our own xact */
        res = PSQLexec("ROLLBACK", false);
        PQclear(res);
    }

    return false;               /* always */
}

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

Definition at line 99 of file large_obj.c.

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

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

{
    PGresult   *res;

    if (own_transaction && pset.autocommit)
    {
        /* close out our own xact */
        if (!(res = PSQLexec("COMMIT", false)))
        {
            res = PSQLexec("ROLLBACK", false);
            PQclear(res);
            return false;
        }
        PQclear(res);
    }

    return true;
}

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

Definition at line 20 of file large_obj.c.

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

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

{
    va_list     ap;

    if (!pset.quiet)
    {
        if (pset.popt.topt.format == PRINT_HTML)
            fputs("<p>", pset.queryFout);

        va_start(ap, fmt);
        vfprintf(pset.queryFout, fmt, ap);
        va_end(ap);

        if (pset.popt.topt.format == PRINT_HTML)
            fputs("</p>\n", pset.queryFout);
        else
            fputs("\n", pset.queryFout);
    }

    if (pset.logfile)
    {
        va_start(ap, fmt);
        vfprintf(pset.logfile, fmt, ap);
        va_end(ap);
        fputs("\n", pset.logfile);
    }
}

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

Definition at line 57 of file large_obj.c.

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

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

{
    PGTransactionStatusType tstatus;
    PGresult   *res;

    *own_transaction = false;

    if (!pset.db)
    {
        psql_error("%s: not connected to a database\n", operation);
        return false;
    }

    tstatus = PQtransactionStatus(pset.db);

    switch (tstatus)
    {
        case PQTRANS_IDLE:
            /* need to start our own xact */
            if (!(res = PSQLexec("BEGIN", false)))
                return false;
            PQclear(res);
            *own_transaction = true;
            break;
        case PQTRANS_INTRANS:
            /* use the existing xact */
            break;
        case PQTRANS_INERROR:
            psql_error("%s: current transaction is aborted\n", operation);
            return false;
        default:
            psql_error("%s: unknown transaction status\n", operation);
            return false;
    }

    return true;
}