source: subversion/applications/utils/export/osm2pgsql-intarray/pgsql.c @ 28719

Last change on this file since 28719 was 8886, checked in by martinvoosterhout, 11 years ago

When a prepared statement fails, log the parameters for debugging purposes.

File size: 3.9 KB
Line 
1/* Helper functions for the postgresql connections */
2
3#include <stdio.h>
4#include <stdlib.h>
5#include <stdarg.h>
6#include <string.h>
7#include <libpq-fe.h>
8#include "osmtypes.h" // For exit_nicely()
9#include "pgsql.h"
10
11void escape(char *out, int len, const char *in)
12{ 
13    /* Apply escaping of TEXT COPY data
14    Escape: backslash itself, newline, carriage return, and the current delimiter character (tab)
15    file:///usr/share/doc/postgresql-8.1.8/html/sql-copy.html
16    */
17    int count = 0; 
18    const char *old_in = in, *old_out = out;
19
20    if (!len)
21        return;
22
23    while(*in && count < len-3) { 
24        switch(*in) {
25            case '\\': *out++ = '\\'; *out++ = '\\'; count+= 2; break;
26      //    case    8: *out++ = '\\'; *out++ = '\b'; count+= 2; break;
27      //    case   12: *out++ = '\\'; *out++ = '\f'; count+= 2; break;
28            case '\n': *out++ = '\\'; *out++ = '\n'; count+= 2; break;
29            case '\r': *out++ = '\\'; *out++ = '\r'; count+= 2; break;
30            case '\t': *out++ = '\\'; *out++ = '\t'; count+= 2; break;
31      //    case   11: *out++ = '\\'; *out++ = '\v'; count+= 2; break;
32            default:   *out++ = *in; count++; break;
33        }
34        in++;
35    }
36    *out = '\0';
37
38    if (*in)
39        fprintf(stderr, "%s truncated at %d chars: %s\n%s\n", __FUNCTION__, count, old_in, old_out);
40}
41
42int pgsql_exec(PGconn *sql_conn, ExecStatusType expect, const char *fmt, ...)
43{
44    PGresult   *res;
45    va_list ap;
46    char *sql, *nsql;
47    int n, size = 100;
48
49    /* Based on vprintf manual page */
50    /* Guess we need no more than 100 bytes. */
51
52    if ((sql = malloc(size)) == NULL) {
53        fprintf(stderr, "Memory allocation failed\n");
54        exit_nicely();
55    }
56
57    while (1) {
58        /* Try to print in the allocated space. */
59        va_start(ap, fmt);
60        n = vsnprintf(sql, size, fmt, ap);
61        va_end(ap);
62        /* If that worked, return the string. */
63        if (n > -1 && n < size)
64            break;
65        /* Else try again with more space. */
66        if (n > -1)    /* glibc 2.1 */
67            size = n+1; /* precisely what is needed */
68        else           /* glibc 2.0 */
69            size *= 2;  /* twice the old size */
70        if ((nsql = realloc (sql, size)) == NULL) {
71            free(sql);
72            fprintf(stderr, "Memory re-allocation failed\n");
73            exit_nicely();
74        } else {
75            sql = nsql;
76        }
77    }
78
79#ifdef DEBUG_PGSQL
80    fprintf( stderr, "Executing: %s\n", sql );
81#endif
82    res = PQexec(sql_conn, sql);
83    if (PQresultStatus(res) != expect) {
84        fprintf(stderr, "%s failed: %s\n", sql, PQerrorMessage(sql_conn));
85        free(sql);
86        PQclear(res);
87        exit_nicely();
88    }
89    free(sql);
90    PQclear(res);
91    return 0;
92}
93
94int pgsql_CopyData(const char *context, PGconn *sql_conn, const char *sql)
95{
96#ifdef DEBUG_PGSQL
97    fprintf( stderr, "%s>>> %s\n", context, sql );
98#endif
99    int r = PQputCopyData(sql_conn, sql, strlen(sql));
100    if (r != 1) {
101        fprintf(stderr, "%s - bad result during COPY, data %s\n", context, sql);
102        exit_nicely();
103    }
104    return 0;
105}
106
107PGresult *pgsql_execPrepared( PGconn *sql_conn, const char *stmtName, int nParams, const char *const * paramValues, ExecStatusType expect)
108{
109#ifdef DEBUG_PGSQL
110    fprintf( stderr, "ExecPrepared: %s\n", stmtName );
111#endif
112    PGresult *res = PQexecPrepared(sql_conn, stmtName, nParams, paramValues, NULL, NULL, 0);
113    if (PQresultStatus(res) != expect) {
114        fprintf(stderr, "%s failed: %s(%d)\n", stmtName, PQerrorMessage(sql_conn), PQresultStatus(res));
115        if( nParams )
116        {
117            int i;
118            fprintf( stderr, "Arguments were: " );
119            for( i=0; i<nParams; i++  )
120                fprintf( stderr, "%s, ", paramValues[i] );
121            fprintf( stderr,  "\n");
122        }
123        PQclear(res);
124        exit_nicely();
125    }
126    if( expect != PGRES_TUPLES_OK )
127    {
128        PQclear(res);
129        res = NULL;
130    }
131    return res;
132}
133
Note: See TracBrowser for help on using the repository browser.