Home Explore Blog CI



postgresql

70th chunk of `doc/src/sgml/ecpg.sgml`
de9b8a73ab1653fe29c60e7af35365644a9c75f9858fc80f0000000100000fa6
 linkend="ecpg-lo-example"/> shows an example program that
   illustrates how to create, write, and read a large object in an
   ECPG application.
  </para>

  <example id="ecpg-lo-example">
   <title>ECPG Program Accessing Large Objects</title>
<programlisting><![CDATA[
#include <stdio.h>
#include <stdlib.h>
#include <libpq-fe.h>
#include <libpq/libpq-fs.h>

EXEC SQL WHENEVER SQLERROR STOP;

int
main(void)
{
    PGconn     *conn;
    Oid         loid;
    int         fd;
    char        buf[256];
    int         buflen = 256;
    char        buf2[256];
    int         rc;

    memset(buf, 1, buflen);

    EXEC SQL CONNECT TO testdb AS con1;
    EXEC SQL SELECT pg_catalog.set_config('search_path', '', false); EXEC SQL COMMIT;

    conn = ECPGget_PGconn("con1");
    printf("conn = %p\n", conn);

    /* create */
    loid = lo_create(conn, 0);
    if (loid &lt; 0)
        printf("lo_create() failed: %s", PQerrorMessage(conn));

    printf("loid = %d\n", loid);

    /* write test */
    fd = lo_open(conn, loid, INV_READ|INV_WRITE);
    if (fd &lt; 0)
        printf("lo_open() failed: %s", PQerrorMessage(conn));

    printf("fd = %d\n", fd);

    rc = lo_write(conn, fd, buf, buflen);
    if (rc &lt; 0)
        printf("lo_write() failed\n");

    rc = lo_close(conn, fd);
    if (rc &lt; 0)
        printf("lo_close() failed: %s", PQerrorMessage(conn));

    /* read test */
    fd = lo_open(conn, loid, INV_READ);
    if (fd &lt; 0)
        printf("lo_open() failed: %s", PQerrorMessage(conn));

    printf("fd = %d\n", fd);

    rc = lo_read(conn, fd, buf2, buflen);
    if (rc &lt; 0)
        printf("lo_read() failed\n");

    rc = lo_close(conn, fd);
    if (rc &lt; 0)
        printf("lo_close() failed: %s", PQerrorMessage(conn));

    /* check */
    rc = memcmp(buf, buf2, buflen);
    printf("memcmp() = %d\n", rc);

    /* cleanup */
    rc = lo_unlink(conn, loid);
    if (rc &lt; 0)
        printf("lo_unlink() failed: %s", PQerrorMessage(conn));

    EXEC SQL COMMIT;
    EXEC SQL DISCONNECT ALL;
    return 0;
}
]]></programlisting>
  </example>
 </sect1>

 <sect1 id="ecpg-cpp">
  <title><acronym>C++</acronym> Applications</title>

  <para>
   ECPG has some limited support for C++ applications.  This section
   describes some caveats.
  </para>

  <para>
   The <command>ecpg</command> preprocessor takes an input file
   written in C (or something like C) and embedded SQL commands,
   converts the embedded SQL commands into C language chunks, and
   finally generates a <filename>.c</filename> file.  The header file
   declarations of the library functions used by the C language chunks
   that <command>ecpg</command> generates are wrapped
   in <literal>extern "C" { ... }</literal> blocks when used under
   C++, so they should work seamlessly in C++.
  </para>

  <para>
   In general, however, the <command>ecpg</command> preprocessor only
   understands C; it does not handle the special syntax and reserved
   words of the C++ language.  So, some embedded SQL code written in
   C++ application code that uses complicated features specific to C++
   might fail to be preprocessed correctly or might not work as
   expected.
  </para>

  <para>
   A safe way to use the embedded SQL code in a C++ application is
   hiding the ECPG calls in a C module, which the C++ application code
   calls into to access the database, and linking that together with
   the rest of the C++ code.  See <xref linkend="ecpg-cpp-and-c"/>
   about that.
  </para>

  <sect2 id="ecpg-cpp-scope">
   <title>Scope for Host Variables</title>

   <para>
    The <command>ecpg</command> preprocessor understands the scope of
    variables in C.  In the C language, this is rather simple because
    the scopes of variables is based on their code blocks.  In C++,
    however, the class member variables are referenced in a different
    code block from the declared position, so
    the <command>ecpg</command> preprocessor will not understand the
    scope of the class member variables.

Title: ECPG Large Object Example and C++ Support
Summary
This section presents a complete ECPG program example that demonstrates how to create, write to, read from, and delete a large object. It uses `libpq` functions such as `lo_create`, `lo_open`, `lo_write`, `lo_read`, `lo_close`, and `lo_unlink` to perform these operations. The example also shows the necessary SQL commands for connecting to the database and managing transactions. The section then discusses limited support for C++ applications. While the `ecpg` preprocessor generates C code compatible with C++, it primarily understands C syntax. Complicated C++ features within embedded SQL code may cause issues. It suggests encapsulating ECPG calls within a C module for safer integration with C++ code. Finally, it mentions scoping issues with host variables when using C++.