driver-pgsql.c revision 9a605d0cd75f4c1431b660ad659cdb9fd05a3f3b
/* Copyright (C) 2004 Timo Sirainen */
#include "lib.h"
#include "ioloop.h"
#include "ioloop-internal.h" /* kind of dirty, but it should be fine.. */
#include "sql-api-private.h"
#ifdef BUILD_PGSQL
#include <stdlib.h>
#include <time.h>
#include <libpq-fe.h>
struct pgsql_db {
const char *connect_string;
enum io_condition io_dir;
struct sql_result *sync_result;
char *error;
unsigned int connecting:1;
unsigned int connected:1;
unsigned int querying:1;
};
struct pgsql_result {
struct sql_result api;
unsigned int fields_count;
const char **fields;
const char **values;
void *context;
};
struct pgsql_queue {
struct pgsql_queue *next;
char *query;
struct pgsql_result *result;
};
struct pgsql_transaction_context {
struct sql_transaction_context ctx;
void *context;
const char *error;
unsigned int opened:1;
unsigned int failed:1;
};
extern struct sql_db driver_pgsql_db;
extern struct sql_result driver_pgsql_result;
{
}
{
const char *msg;
return "(no error set)";
/* Error message should contain trailing \n, we don't want it */
}
{
enum io_condition io_dir = 0;
int ret;
;
switch (ret) {
case PGRES_POLLING_READING:
break;
case PGRES_POLLING_WRITING:
break;
case PGRES_POLLING_OK:
break;
case PGRES_POLLING_FAILED:
i_error("pgsql: Connect failed to %s: %s",
return;
}
}
}
{
/* don't try reconnecting more than once a second */
i_fatal("pgsql: PQconnectStart() failed (out of memory)");
i_error("pgsql: Connect failed to %s: %s",
return -1;
} else {
/* nonblocking connecting begins. */
return 0;
}
}
{
}
{
}
}
static enum sql_db_flags
{
return 0;
}
{
do {
break;
return;
}
{
return;
/* we'll have to read the rest of the results as well */
} else {
}
}
{
bool free_result = TRUE;
t_push();
t_pop();
}
if (free_result)
/* disconnected */
}
}
{
return;
}
get_result, result);
}
return;
}
}
{
int ret;
if (ret > 0)
return;
if (ret < 0) {
} else {
/* all flushed */
}
}
{
int ret;
return;
}
if (ret < 0) {
return;
}
if (ret > 0) {
/* write blocks */
} else {
}
}
{
struct pgsql_queue *queue;
}
{
return;
return;
}
}
static void
{
struct pgsql_queue *queue;
}
{
/* only one query at a time */
return;
}
/* try connecting again */
return;
}
else {
/* there's already queries queued, send them first */
}
}
void *context __attr_unused__)
{
}
static const char *
{
char *to;
#ifdef HAVE_PQESCAPE_STRING_CONN
#else
#endif
return to;
}
{
struct pgsql_result *result;
}
{
struct pgsql_result *result;
}
{
}
static struct sql_result *
{
else {
/* have to move our existing I/O handler to new I/O loop */
}
return db->sync_result;
}
{
/* second time we're here */
}
return -1;
case PGRES_COMMAND_OK:
/* no rows returned */
return 0;
case PGRES_TUPLES_OK:
case PGRES_EMPTY_QUERY:
case PGRES_NONFATAL_ERROR:
/* nonfatal error */
return -1;
default:
/* treat as fatal error */
return -1;
}
}
{
unsigned int i;
return;
/* @UNSAFE */
for (i = 0; i < result->fields_count; i++)
}
static unsigned int
{
return result->fields_count;
}
static const char *
{
}
const char *field_name)
{
unsigned int i;
for (i = 0; i < result->fields_count; i++) {
return i;
}
return -1;
}
static const char *
unsigned int idx)
{
return NULL;
}
static const char *
const char *field_name)
{
int idx;
if (idx < 0)
return NULL;
}
static const char *const *
{
unsigned int i;
}
/* @UNSAFE */
for (i = 0; i < result->fields_count; i++) {
}
}
{
const char *msg;
return "(no error set)";
/* Error message should contain trailing \n, we don't want it */
}
static struct sql_transaction_context *
{
struct pgsql_transaction_context *ctx;
}
static void
{
struct pgsql_transaction_context *ctx =
(struct pgsql_transaction_context *)context;
if (sql_result_next_row(result) < 0)
else
}
static void
{
struct pgsql_transaction_context *ctx =
(struct pgsql_transaction_context *)_ctx;
return;
}
}
static int
const char **error_r)
{
struct pgsql_transaction_context *ctx =
(struct pgsql_transaction_context *)_ctx;
struct sql_result *result;
} else {
if (sql_result_next_row(result) < 0)
else
}
}
static void
{
struct pgsql_transaction_context *ctx =
(struct pgsql_transaction_context *)_ctx;
}
static void
struct pgsql_transaction_context *ctx)
{
if (sql_result_next_row(result) < 0) {
}
}
static void
{
struct pgsql_transaction_context *ctx =
(struct pgsql_transaction_context *)_ctx;
return;
}
}
struct sql_db driver_pgsql_db = {
"pgsql",
};
struct sql_result driver_pgsql_result = {
NULL,
};
void driver_pgsql_init(void);
void driver_pgsql_deinit(void);
void driver_pgsql_init(void)
{
}
void driver_pgsql_deinit(void)
{
}
#endif