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

dbdimp.c

/* $Id: dbdimp.c,v 2.6 2002/10/27 14:01:38 flatline Exp $
 * 
 * portions Copyright (c) 1994,1995,1996,1997  Tim Bunce
 * portions Copyright (c) 1997 Thomas K. Wenrich
 * portions Copyright (c) 1997 Jeff Urlwin
 * portions Copyright (c) 2000 Cristian Giussani
 *
 * You may distribute under the terms of either the GNU General Public
 * License or the Artistic License, as specified in the Perl README file.
 *
 */

#include "dbftp.h"

/* for sanity/ease of use with potentially null strings */
#define XXSAFECHAR(p) ((p) ? (p) : "(null)")

DBISTATE_DECLARE;

void
   dbd_init(dbistate)
   dbistate_t *dbistate;
{
    DBIS = dbistate;
}

void 
   do_error ( h, rc, what ) 
   SV* h;
   int rc;
   char *what;
{
   D_imp_xxh(h);
   SV *errstr = DBIc_ERRSTR(imp_xxh);

   dTHR;

   sv_setiv(DBIc_ERR(imp_xxh),(IV)rc);
   sv_setpv( errstr, what );
   DBIh_EVENT2 ( h, ERROR_event, DBIc_ERR(imp_xxh), errstr );

   if ( dbis->debug >= 2 )
       PerlIO_printf ( DBILOGFP, "%s error %d recorded: %s\n", what, rc, SvPV(errstr,na) );

}

int 
   dbd_db_login ( dbh, imp_dbh, dbname, user, auth )
SV* dbh;
imp_dbh_t* imp_dbh;
char* dbname;
char* user;
char* auth;
{
   SV* imp_data = DBIc_IMP_DATA(imp_dbh);
   HV* hv;
   SV** svp;
   char* db;
   char* hostname;
   int port;
   MY_STRING strbuf;

   if ( !SvTRUE(imp_data) || !SvROK(imp_data) ||
        SvTYPE( hv=(HV*) SvRV(imp_data)) != SVt_PVHV )
   {
      croak ("Implemetation dependent data invalid: Not hash ref.\n");
   }

   if ( (svp=hv_fetch(hv, "hostname", strlen("hostname"), FALSE )) &&
        SvTRUE(*svp) )
   {
      hostname = SvPV( *svp, na );
   }
   else
   {
      hostname = "localhost";
   }

   if ( (svp=hv_fetch(hv, "DSN", strlen("DSN"), FALSE )) &&
        SvTRUE(*svp) )
   {
      db = SvPV( *svp, na );
   }
   else
   {
      db = dbname;
   }

   string_init ( &strbuf, 128, 256, db );

   /* Append 'UID=user' in connect string */
   if ( user != NULL )
    if ( strlen ( user ) != 0 )
    {
       string_append ( &strbuf, ";UID=", 5 );
       string_append ( &strbuf, user, 0 );
    }

   /* Append 'PWD=password' in connect string */
   if ( auth != NULL )
    if ( strlen ( auth ) != 0 )
    {
       string_append ( &strbuf, ";PWD=", 5 );
       string_append ( &strbuf, auth, 0 );
    }

   if ( (svp=hv_fetch(hv, "port", strlen("port"), FALSE )) &&
        SvTRUE(*svp) )
   {
      port=atoi(SvPV( *svp, na ));
   }
   else
      port=3000;

   imp_dbh->results=init_dbftp_result();
   if ( imp_dbh->results != NULL )
   {
      if (DBIS->debug >= 2)
            PerlIO_printf(DBILOGFP, "dbd_db_login host %s - port %d - db %s\n", hostname, port, strbuf.string );

      /* Have allocated some resources */
      DBIc_IMPSET_on(imp_dbh); 
      if ( dbftp_connect ( imp_dbh->results, hostname, port, strbuf.string ) == 0 )
      {
         string_free ( &strbuf );
         return ( TRUE );
      }
      else
         do_error ( dbh, -1, dbftp_error_string ( imp_dbh->results ) );
   }
   else
      do_error ( dbh, -1, "db_login/init_dbftp_result" );

   string_free ( &strbuf );
   return ( FALSE );
}

/*
  Free result structure
*/
void dbd_db_destroy ( dbh, imp_dbh )
SV* dbh;
imp_dbh_t* imp_dbh;
{
   free_dbftp_result ( imp_dbh->results );
   DBIc_IMPSET_off(imp_dbh);
}

/*
   No discon_all
*/
int
   dbd_discon_all(drh, imp_drh)
   SV *drh;
imp_drh_t *imp_drh;
{
   do_error ( drh, -1, "db_discon_all/not implemented" );
   return ( FALSE );
}

/*
   No commit
*/
int 
   dbd_db_commit ( dbh, imp_dbh )
SV* dbh;
imp_dbh_t* imp_dbh;
{
   do_error ( dbh, -1, "db_commit/not implemented" );
   return ( FALSE );
}

/*
   No rollback
*/
int
   dbd_db_rollback ( dbh, imp_dbh )
SV* dbh;
imp_dbh_t* imp_dbh;
{
   do_error ( dbh, -1, "db_rollback/not implemented" );
   return ( FALSE );
}

/*
   Do not store anything ATTRIB
*/
int 
   dbd_db_STORE_attrib ( dbh, imp_dbh, keysv, valuesv )
SV* dbh;
imp_dbh_t* imp_dbh;
SV* keysv;
SV* valuesv;
{
   return ( TRUE );
}

/*
   Do not fetch anything ATTRIB
*/
SV*
   dbd_db_FETCH_attrib ( dbh, imp_dbh, keysv )
SV* dbh;
imp_dbh_t* imp_dbh;
SV* keysv;
{
   return ( &sv_undef );
}

/* STATEMENT ******************************************************************/
/*
   prepare: do nothing
*/
int dbd_st_prepare ( sth, imp_sth, statement, attribs )
SV* sth;
imp_sth_t* imp_sth;
char *statement;
SV *attribs;
{
   if ( imp_sth->query == NULL )
   {
      imp_sth->query=(char *)safemalloc(strlen(statement)+2);
      if ( imp_sth->query != NULL )
      {
         memcpy ( imp_sth->query, statement, strlen(statement)+1 );
         imp_sth->rows=-1;

         DBIc_IMPSET_on(imp_sth);
         return ( TRUE );
      }
      else
      {
         do_error ( sth, -1, "dbd_st_prepare/malloc" );
         return ( FALSE );
      }
   }
   return ( TRUE );
}

/*
   execute

   Return value:
   <= -2 ERROR
   >= 0  OK, row count
   -1    OK, unknown count
*/
int dbd_st_execute ( sth, imp_sth )
SV* sth;
imp_sth_t* imp_sth;
{
   char *statement;
   D_imp_dbh_from_sth;

   if ( dbftp_sql ( imp_dbh->results, imp_sth->query ) == 0 )
   {
      /* if query=="SELECT" */
      if ( dbftp_num_field(imp_dbh->results) > 0 )
      {
         DBIc_NUM_FIELDS(imp_sth)=dbftp_num_field(imp_dbh->results);
         if (DBIS->debug >= 2)
            PerlIO_printf(DBILOGFP, "dbd_st_execute num_fields %d\n", dbftp_num_field(imp_dbh->results) );

         DBIc_ACTIVE_on(imp_sth);
      }

      return ( -1 ); /* Always unknown rows count */

   }

   do_error ( sth, -1, dbftp_error_string ( imp_dbh->results ) );
   return ( -2 ); /* ERROR */
}

int
   dbd_st_STORE_attrib(sth, imp_sth, keysv, valuesv)
   SV *sth;
imp_sth_t *imp_sth;
SV *keysv;
SV *valuesv;
{
    STRLEN kl;
    SV *cachesv = NULL;
    char *key = SvPV(keysv,kl);

    if (cachesv) /* cache value for later DBI 'quick' fetch? */
        hv_store((HV*)SvRV(sth), key, kl, cachesv, 0);
    return TRUE;

}

int dbftp_type2sql_type ( char type )
{
   switch ( type )
   {
      case 'N':
         return SQL_DECIMAL;

      case 'D':
         return SQL_DATE;

      case 'd':
         return SQL_DATE;

      case 'C':
      default:
         return SQL_VARCHAR;
   }
}

SV *
   dbd_st_FETCH_attrib(sth, imp_sth, keysv)
   SV *sth;
imp_sth_t *imp_sth;
SV *keysv;
{
   STRLEN kl;
    char *key = SvPV(keysv,kl);
    int i;
    SV *retsv = NULL;
    /* Default to caching results for DBI dispatch quick_FETCH  */
    int cacheit = TRUE;
    D_imp_dbh_from_sth;

    if (kl==13 && strEQ(key, "NUM_OF_PARAMS"))  /* handled by DBI */
        return Nullsv;

    i = DBIc_NUM_FIELDS(imp_sth);

    if (kl==4 && strEQ(key, "TYPE")) {
        AV *av = newAV();
        retsv = newRV(sv_2mortal((SV*)av));
        while(--i >= 0)
            av_store(av, i, newSViv(dbftp_type2sql_type(dbftp_field_type(imp_dbh->results,i)))); /* ??? */

    } else if (kl==5 && strEQ(key, "SCALE")) {
        AV *av = newAV();
        retsv = newRV(sv_2mortal((SV*)av));
        while(--i >= 0)
            av_store(av, i, newSViv(0)); /* ??? */

    } else if (kl==9 && strEQ(key, "PRECISION")) {
        AV *av = newAV();
        retsv = newRV(sv_2mortal((SV*)av));
        while(--i >= 0)
            av_store(av, i, newSViv(dbftp_field_len(imp_dbh->results,i))); /* Length */

    } else if (kl==4 && strEQ(key, "NAME")) {
        AV *av = newAV();
        retsv = newRV(sv_2mortal((SV*)av));
        while(--i >= 0)
            av_store(av, i, newSVpv((char*)dbftp_field_name(imp_dbh->results,i),0));

    } else if (kl==8 && strEQ(key, "NULLABLE")) {
        AV *av = newAV();
        retsv = newRV(sv_2mortal((SV*)av));
        while(--i >= 0)
            av_store(av, i, boolSV(TRUE));

    } else {
        return Nullsv;
    }
    if (cacheit) { /* cache for next time (via DBI quick_FETCH) */
        SV **svp = hv_fetch((HV*)SvRV(sth), key, kl, 1);
        sv_free(*svp);
        *svp = retsv;
        (void)SvREFCNT_inc(retsv);      /* so sv_2mortal won't free it  */
    }
    return sv_2mortal(retsv);
}

void
   dbd_st_destroy(sth, imp_sth)
   SV *sth;
imp_sth_t *imp_sth;
{

   if ( imp_sth->query != NULL )
      Safefree ( imp_sth->query );

   DBIc_IMPSET_off(imp_sth);
}

int 
   dbd_st_finish( sth, imp_sth )
   SV *sth;
imp_sth_t *imp_sth;
{
   DBIc_ACTIVE_off(imp_sth);
   return TRUE;
}

AV *
   dbd_st_fetch(sth, imp_sth)
SV * sth;
imp_sth_t *imp_sth;
{
   AV *av;
   char *strdmy;
   int fields=DBIc_NUM_FIELDS(imp_sth);
   int idmy;
   D_imp_dbh_from_sth;

   /* Check that execute() was executed sucessfully. This also implies */
   /* that dbd_describe() executed sucessfuly so the memory buffers    */
   /* are allocated and bound.                                         */
   if ( !DBIc_ACTIVE(imp_sth) ) {
               do_error(sth, -1, "no select statement currently executing");
               return Nullav;
   }

   if ( dbftp_fetch_row ( imp_dbh->results ) != 0 )
   {
      DBIc_ACTIVE_off(imp_sth);
      return Nullav;
   }

   /* Have a row */
   av=DBIS->get_fbav(imp_sth);

   if ( imp_sth->rows==-1 )
      imp_sth->rows=0;

   imp_sth->rows++;

   for ( idmy=0; idmy<fields; idmy++ )
   {
      strdmy=dbftp_fetch_value ( imp_dbh->results, idmy );
      if (DBIS->debug >= 2)
            PerlIO_printf(DBILOGFP, "dbd_st_fetch field %d - '%s'\n", idmy, strdmy ); 

      if ( strdmy != NULL )
      {
         /* ??? No 'chopBlanks' handled */
         sv_setpvn(AvARRAY(av)[idmy], strdmy, strlen(strdmy) );
      }
      else
         svOK_off(AvARRAY(av)[idmy] );
   } 

   return av; 
}

int
   dbd_st_rows(sth, imp_sth)
   SV *sth;
imp_sth_t *imp_sth;
{
    return imp_sth->rows;
}


Generated by  Doxygen 1.6.0   Back to index