#include "PGConnection.h"
#include "libpq-fe.h"
#include "stdio.h"

#define thisPGconn ((PGconn *) \
    ((unhand(this))->PGconnRep))
#define COPYBUFLEN 1024

void PGConnection_finish(struct \
     HPGConnection *this)
{
  PQfinish(thisPGconn);
}


void PGConnection_connectDB \
           (struct HPGConnection *this,
       struct Hjava_lang_String *host,
       struct Hjava_lang_String *port,
       struct Hjava_lang_String *options,
       struct Hjava_lang_String *tty,
       struct Hjava_lang_String *dbName)
{
      /* First, we get C versions of the */
      /* strings passed into the */
      /* constructor.  Java will free these */
      /* when they have no pointers */
      /* left. (at the end of this function)*/
  char *PGhost = makeCString(host);
  char *PGtty  = makeCString(tty);
  char *PGport = makeCString(port);
  char *PGoptions = makeCString(options);
  char *PGdbName = makeCString(dbName);


      /* Make the PQ call to create the */
      /* connection.  This will allocate a */
      /* new PGconn. */
  PGconn *tmpConn = PQsetdb(PGhost, PGport, \
       PGoptions, PGtty, PGdbName);
      /* Store this as a long in Java */
  unhand(this)->PGconnRep = (long)tmpConn;
  return;
}

struct Hjava_lang_String *PGConnection_db(struct\
      HPGConnection *this)
{
  /* We could use the macro thisPGconn
  /* (defined above) here like so:*/
  /* char *tmp = PQdb(thisPGconn); */
  char *tmp = PQdb(((PGconn *)((unhand(this))->PGconnRep)));
  return makeJavaString(tmp, strlen(tmp));
}
struct Hjava_lang_String *PGConnection_host(struct\
      HPGConnection *this)
{
  char *tmp = PQhost(thisPGconn);
  return makeJavaString(tmp, strlen(tmp));
}
struct Hjava_lang_String *PGConnection_options(struct\
      HPGConnection *this)
{
  char *tmp = PQoptions(thisPGconn);
  return makeJavaString(tmp, strlen(tmp));
}
struct Hjava_lang_String *PGConnection_port(struct \
      HPGConnection *this)
{
  char *tmp = PQport(thisPGconn);
  return makeJavaString(tmp, strlen(tmp));
}
struct Hjava_lang_String *PGConnection_tty(struct\
      HPGConnection *this)
{
  char *tmp = PQtty(thisPGconn);
  return makeJavaString(tmp, strlen(tmp));
}
struct Hjava_lang_String *
PGConnection_errorMessage(struct HPGConnection *this)
{
  char *tmp = PQerrorMessage(thisPGconn);
  return makeJavaString(tmp, strlen(tmp));
}

void PGConnection_reset(struct HPGConnection *this)
{
      /* Simply call the PQ lib function */
  PQreset(thisPGconn);
  unhand(this)->copyDone = 0;\
      /* false on reset */
  unhand(this)->getlineResult = 0; \
      /* also reset here */
  return;
}

long PGConnection_status(struct \
     HPGConnection *this)
{
      /* Simply call the PQ lib */
      /* function--in this case,*/
      /* cast the enum to a */
      /* long*/
  return (long)PQstatus(thisPGconn);
}

      /* Unfortunately, we can't */
      /* pass a File into native */
      /* code, so we use a filename */
      /* instead*/
void PGConnection_trace(struct HPGConnection *this,
         struct Hjava_lang_String *filename)
{
  char *tmpFilename = makeCString(filename);
  FILE *tmpFile;
  if (strcmp(tmpFilename, "stdout") == 0) \
      /* Check for stdout */
    tmpFile = stdout;
  else if (strcmp(tmpFilename, "stderr") == 0) \
      /* and stderr */
    tmpFile = stderr;
  else
    tmpFile = fopen(tmpFilename, "a");
  PQtrace(thisPGconn, tmpFile);
  return;
}

void PGConnection_untrace(struct \
     HPGConnection *this)
{
  PQuntrace(thisPGconn);
  return;
}

long PGConnection_nativeExec\
     (struct HPGConnection *this,
      struct Hjava_lang_String *query)
{
  char *tmpQuery = makeCString(query);

  PGresult *tmpResult = PQexec(thisPGconn, \
     tmpQuery);

  return (long)tmpResult;
}
extern struct Hjava_lang_String *
PGConnection_nativeGetline(struct \
      HPGConnection *this)
{
  char buffer[COPYBUFLEN];

  int res = PQgetline(thisPGconn, buffer, 1024);
  unhand(this)->getlineResult = res;
  return makeJavaString(buffer, strlen(buffer));
}

long PGConnection_endcopy(struct \
     HPGConnection *this)
{
  unhand(this)->copyDone = 0;
  return (long)PQendcopy(thisPGconn);
}


void PGConnection_putline \
           (struct HPGConnection *this,
            struct Hjava_lang_String *data)
{
  char *tmp = makeCString(data);
  PQputline(thisPGconn, tmp);
  return;
}