/*-------------------------------------------------------------------------
 *
 * tdb.h--
 *    header for tdb.c
 *
 * Copyright (c) 1994, Regents of the University of California
 *
 * tdb.h,v 1.3 1995/04/29 07:54:49 jolly Exp
 *
 * NOTES
 *    libtdb is a generic database interface for Tioga to support
 *    access to both Postgres(pglite) and Illustra
 *
 *    to use, 
 *      #define TDB_MI to use the illustra libmi interface
 *      #define TDB_PQ to use the postgres(pglite) libpq interface
 *
 *    default is TDB_PQ
 *
 *-------------------------------------------------------------------------
 */
#ifndef _TDB_H_
#define _TDB_H_

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define TG_DB_ERR_MSG_LEN 2024

/*typedef struct varlena *TgAttValue;*/
typedef void *TgAttValue;

typedef TgAttValue *TgTuple;

typedef struct _tgtypeblock {
    char *name;			/* type name */
    int  adtid;			/* type id */
    int  adtsize;		/* type size */
} TgTypeBlock;

typedef struct _tgtuplegroup {
  int         type;		/* binary or ascii */
  int         numTuples;	/* number of tuples */
  int         numAttributes;	/* number of attributes */
  TgTypeBlock *attribute;	/* info. about the attributes */
  TgTuple     *tuple;		/* array of tuples, each tuple is an
				 * array of TgAttValue */
} TgTupleGroup;

/* error status are returned in this string */
extern char tgDbErrMsg[];

/* queries for being, end, and abort transactions */
extern char beginXact[], endXact[], abortXact[];

#define BEGIN_XACT(db) TgDoQuery(db, beginXact, 0)
#define END_XACT(db)   TgDoQuery(db, endXact, 0)
#define ABORT_XACT(db) TgDoQuery(db, abortXact, 0)

#include "libpq-fe.h"
typedef struct _tgdb {
  char *name;			/* name of the database */
  char *host;			/* hostname of the backend */
  char *port;			/* port number */
  char *pgtty;			/* tty (for postgres) */
  char *pgoption;		/* option (for postgres) */
  int  status;      /* connection status, 0 means disconnected */
  PortalBuffer *portal;     /* last portal buffer for query results*/
} TgDb;

extern TgDb *TgNewDB(char *name, char *host, char *port,
		     char *pgtty, char *pgoption);

  
/* -- function and macros that can be used -- */

#define TG_FREE(FREE, M) if (M) FREE(M) ; (M) = NULL

#define TG_FREEDB(db) TG_FREE(TgFreeDb, db)

#define GET_ATTR(TG, TI, ATTNAME) \
  (TG)->tuple[TI][TgAttNameToNum(TG, ATTNAME)]

/* #define DUP_ATTR(TG, TI, ATTNAME) dupstr(GET_ATTR(TG, TI, ATTNAME)) */

/* dup_attr ---
     returns a copy of the ascii value of the attribute value if it is non-null
     otherwise, returns ""
*/
extern TgAttValue dup_attr(TgTupleGroup* tg, int tuple_index, char* attname);

/*
 * TgFreeDb -- free the db structure.  If a connection is still present when
 *             this routine is called, the connection will be closed.
 *             It would be better for the user to call the macro TG_FREEDB
 *             instead of calling this function directly.
 */
extern void TgFreeDb(TgDb *db);

/*
 * TgConnectDB -- establish a connection with the database backend.
 *
 *                Returns:
 *                          0  -- connection to server failed
 *                          1  -- connection to server succeed, no error.
 */
extern int TgConnectDB(TgDb *db);

/*
 * TgCloseDB -- close the connection with the database server.
 */
extern void TgCloseDB(TgDb *db);

/*
 * TgRetrieve -- Do a retrieve query to the database and returns the result
 *               in a TgTupleGroup.  The result can be in either binary or
 *               ASCII form.
 *
 *               Returns NULL if an error has occured with the error message
 *               stored in 'tgDbErrMsg'
 */
extern TgTupleGroup *TgRetrieve(TgDb *db, char *query, int binary);

/*
 * TgDoQuery -- issue an arbituary query to the database back end.
 *              If a NULL is passed in as the query, this function checks
 *              to make sure that all processing that needs to be done are
 *              done.
 *
 *              Returns:
 *                      0 -- error occurred, error mesg is stored in tgDbErrMsg
 *                      1 -- query successful, no more processing needed
 *                      2 -- query returns tuples, more processing is needed
 */

extern int TgDoQuery(TgDb *db, char *query, int binary);

/*
 * TgGetData -- get data from a retrieve query.  Call this function only
 *              immediately after TgDoQuery() returns 2.
 */
extern TgTupleGroup *TgGetData(TgDb *db, int binary);

/*
 * TgAttNameToNum -- given a tuple group and an attName, returns the attribute
 *                   index.  Returns -1 if attName doesn't exist, or other
 *                   error has occured that prevents the function from
 *                   determine the attribute number.
 */
extern int TgAttNameToNum(TgTupleGroup *, char *);

#define TG_FREETUPLEGROUP(g) TG_FREE(TgFreeTuplegroup, g)

/*
 * TgFreeTuplegroup -- free memory associated with a tuple group.  It is
 *                     recommended that you use TG_FREETUPLEGROUP macro
 *                     instead of calling this function directly.
 */
extern void TgFreeTuplegroup(TgTupleGroup *);

/* extern char *DuplicateString(char *); */

#endif /* _TDB_H_ */
