DBD-TimesTen

 view release on metacpan or  search on metacpan

dbdimp.c  view on Meta::CPAN

/* $Id: dbdimp.c 572 2006-12-02 04:37:01Z wagnerch $
 * 
 * portions Copyright (c) 1994,1995,1996,1997  Tim Bunce
 * portions Copyright (c) 1997 Thomas K. Wenrich
 * portions Copyright (c) 1997-2001 Jeff Urlwin
 * portions Copyright (c) 2006 Chad Wagner
 *
 * 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 "TimesTen.h"

static const char *cSqlTables = "SQLTables(%s,%s,%s,%s)";
static const char *cSqlPrimaryKeys = "SQLPrimaryKeys(%s,%s,%s)";
static const char *cSqlForeignKeys = "SQLForeignKeys(%s,%s,%s,%s,%s,%s)";
static const char *cSqlColumns = "SQLColumns(%s,%s,%s,%s)";
static const char *cSqlGetTypeInfo = "SQLGetTypeInfo(%d)";
static void dbd_error_flush(SV *h);
static int dbd_describe(SV *h, imp_sth_t *imp_sth);
static int build_results(SV *sth, RETCODE orc);
static void dbd_preparse(imp_sth_t *imp_sth, char *statement);
static int dbd_rebind_ph (SV *sth, imp_sth_t *imp_sth, phs_t *phs);
static int dbd_st_describe_param (SV *sth, phs_t *phs);


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

/* unique value for db attrib that won't conflict with SQL types, just
 * increment by one if you are adding! */
#define TT_IGNORE_NAMED_PLACEHOLDERS   0x8332
#define TT_DEFAULT_BIND_TYPE           0x8333
#define TT_ROWCACHESIZE                0x8334
#define TT_EXEC_DIRECT                 0x8335
#define TT_QUERY_TIMEOUT               0x8336

/*
 * TT_DEFAULT_BIND_TYPE_VALUE is now set to 0, which means that
 * DBD::TimesTen will call SQLDescribeParam to find out what type of
 * binding should be set.  If SQLDescribeParam fails, then the bind type
 * will be set to SQL_VARCHAR as a backup.
 *
 */
#define TT_DEFAULT_BIND_TYPE_VALUE	0

/* BLOB's are not supported in TimesTen, do not enable this. */
#undef TT_BLOB_ENABLED


DBISTATE_DECLARE;


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

static void timesten_handle_outparams(imp_sth_t *imp_sth, int debug)
{
   int i = (imp_sth->out_params_av) ? AvFILL(imp_sth->out_params_av)+1 : 0;
   if (debug >= 3)
      PerlIO_printf(DBIc_LOGPIO(imp_sth),
		    "       handling %d output parameters\n", i);
   while (--i >= 0) {
      phs_t *phs = (phs_t*)(void*)SvPVX(AvARRAY(imp_sth->out_params_av)[i]);
      SV *sv = phs->sv;
      if (debug >= 8) {
	 PerlIO_printf(DBIc_LOGPIO(imp_sth),
		       "       out %s has length of %d\n",
		       phs->name, phs->cbValue);
      }

      /* phs->cbValue has been updated by ODBC to hold the length of the result	*/
      if (phs->cbValue != SQL_NULL_DATA) {	/* is okay	*/
	 /*
	  * When ODBC fills an output parameter buffer, the size of the
	  * data that were available is written into the memory location
	  * provided by cbValue pointer argument during the SQLBindParameter() call.
	  * (In this case, the cbValue pointer has been set to &phs->cbValue).
	  *
	  * If the number of bytes available exceeds the size of the output buffer,
	  * ODBC will truncate the data such that it fits in the available buffer.
	  * However, the cbValue will still reflect the size of the data before it
	  * was truncated.
	  *
	  * This fact provides us a way to detect truncation on this particular
	  * output parameter.  Otherwise, the only way to detect truncation is
	  * through a follow-up to a SQL_SUCCESS_WITH_INFO result.  Such a call
	  * cannot return enough information to state exactly where the truncation
	  * occurred.
	  * -jeremy
	  */

	 if (phs->cbValue > phs->maxlen) {
	    /* a truncation occurred */
	    SvPOK_only(sv);
	    SvCUR_set(sv, phs->maxlen);
	    *SvEND(sv) = '\0';



( run in 1.763 second using v1.01-cache-2.11-cpan-39bf76dae61 )