Logo Search packages:      
Sourcecode: kaya version File versions  Download package

pg_inter.cc

#include "pg_inter.h"
#include <VMState.h>
#include <KayaAPI.h>

void* pg_connect(wchar_t* rawconninfo)
{
  char* conninfo = wctostr(rawconninfo);
    PGconn* pc = PQconnectdb(conninfo);
    PGCon * pgc = new PGCon();
    pgc->con = pc;
    pgc->ok = 1;
    
//    cout << pc << "," << pgc << endl;
//    cout << PQstatus(pc) << endl;

    if (pc==NULL || PQstatus(pc) == CONNECTION_BAD)
    {
      pgc->ok = 0;
    }
    return (void*)pgc;
}

bool pg_ok(void* conn)
{
    PGCon* pgc = (PGCon*)conn;
//    cout << pgc->ok << endl;
    return pgc->ok;
}

wchar_t* pg_getError(void* conn)
{
    PGconn* pgc = ((PGCon*)conn)->con;
    return strtowc(PQerrorMessage(pgc));
}

DBtype getDBtype(wchar_t* rawval)
{
  char* val = wctostr(rawval);
    if (strncmp(val,"int",3)==0 && val[3]!='8') { // limit to 32 bit
      return DBINT;
    }
    else if (strncmp(val,"float",5)==0) {
      return DBFLOAT;
    }
    else if (strcmp(val,"bool")==0) {
      return DBBOOL;
    }
    else {
      return DBTEXT;
    }
}

// Work out what OIDs mean what types, so we can build the right structure
// kaya-side.
void pg_getTypeIDs(VMState* vm, PGCon* pgc)
{
    if (pgc->typids.size()!=0) {
      return; // Already done it
    }

    PGresult *res = PQexec(pgc->con,"SELECT oid,* FROM pg_type");
    int numrows = PQntuples(res);

    for(int i = 0; i<numrows; i++) {
      char* val = PQgetvalue(res,i,1); // Get type name
      int oid = atoi(PQgetvalue(res,i,0)); // Get oid
      pgc->typids[oid] = getDBtype(strtowc(val));
//    printf("%d: %s\n", oid, val);
    }
}

void* pg_exec(void* vmptr,void* conn,wchar_t* rawquery)
{
  char* query = wctostr(rawquery);
    VMState* vm = (VMState*)vmptr;
    PGCon* pgc = (PGCon*)conn;

    pg_getTypeIDs(vm,pgc);

    PGresult *res = PQexec(pgc->con,query);
    if (res==NULL) {
      vm->kaya_throw(PQerrorMessage(pgc->con),1);
    }
    if ((PQresultStatus(res)!=PGRES_COMMAND_OK)
      && (PQresultStatus(res) != PGRES_TUPLES_OK)) {
      vm->kaya_throw(PQresultErrorMessage(res),1);
    }
    
    int numrows = PQntuples(res);
    int numflds = PQnfields(res);
    
    KayaArray resarray = newKayaArray(numrows);

    for(int i = 0; i<numrows; i++) {
      KayaArray row = newKayaArray(numflds);
      for(int j = 0; j<numflds; j++) {
          char* val = PQgetvalue(res,i,j);
          KayaValue pv,fld;

            Oid ty = PQftype(res,j);

          switch(pgc->typids[ty]) {
          case DBINT:
          /// If it's an int, make a DBInt(val)
            pv = KayaInt(atoi(val));
            fld = KayaUnion(1,1);
            KayaUnionSetArg(fld,0,pv);
            KayaArrayPush(row,fld);
            break;
          case DBFLOAT:
          /// If it's a float, make a DBFloat(val)
            pv = KayaFloat(atof(val));
            fld = KayaUnion(2,1);
            KayaUnionSetArg(fld,0,pv);
            KayaArrayPush(row,fld);
            break;
          case DBBOOL:
            /// If it's a bool, make a DBBool(val)
            if (val[0]=='t') {
                pv = KayaInt(1);
            } else {
                pv = KayaInt(0);
            }
            fld = KayaUnion(4,1);
            KayaUnionSetArg(fld,0,pv);
            KayaArrayPush(row,fld);
            break;
          case DBTIME:
            /// TODO: If it's a date, parse it and make a timestamp
          default:
            /// Default is to make a DBText
            pv = KayaString(strtowc(val));
            fld = KayaUnion(0,1);
            KayaUnionSetArg(fld,0,pv);
            KayaArrayPush(row,fld);
          }
      }
      KayaArrayPush(resarray,KayaArrayVal(row));
    }

    PGRes* pgr = new PGRes();
    pgr -> res_table = resarray;
    pgr -> rows = numrows;
    pgr -> cols = numflds;
    pgr -> pgres = res;
    PQclear(res);
    return pgr;
}

wchar_t* pg_columnname(void* vmptr,void* res, int col)
{
    VMState* vm = (VMState*)vmptr;
    PGresult *r = ((PGRes*)res)->pgres;
    if (col>=((PGRes*)res)->cols) {
      vm->kaya_throw("Column number out of range",1);
    }
    return strtowc(PQfname(r,col));
}

Array* pg_getstrs(void* res)
{
    return ((PGRes*)res)->res_table;
}

int pg_numrows(void* res)
{
    return ((PGRes*)res)->rows;
}

int pg_numcols(void* res)
{
    return ((PGRes*)res)->cols;
}

void pg_close(void* conn)
{
    PQfinish(((PGCon*)conn)->con);
}

Generated by  Doxygen 1.6.0   Back to index