DBD-TimesTen
view release on metacpan or search on metacpan
/* $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 )