DBD-DB2
view release on metacpan or search on metacpan
croak( "Error: Modification of a read-only value attempted" );
if( !SvOK( bufsv) )
sv_setpv( bufsv, "" ); /* initialize undefined variable */
SvGROW( bufsv, (STRLEN)(destoffset + len + cbNullSize) );
rtval = SQLGetData( imp_sth->phstmt,
(SQLUSMALLINT) field,
fbh->ftype,
SvPVX(bufsv) + destoffset,
len + cbNullSize,
&retl );
if (rtval == SQL_SUCCESS_WITH_INFO) /* XXX should check for 01004 */
retl = len;
if (retl == SQL_NULL_DATA) /* field is null */
{
(void)SvOK_off(bufsv);
return TRUE;
}
CHECK_ERROR(sth, SQL_HANDLE_STMT, imp_sth->phstmt, rtval, "GetData Failed To Read LOB");
EOI(rtval);
SvCUR_set(bufsv, destoffset+retl );
*SvEND(bufsv) = '\0'; /* consistent with perl sv_setpvn etc */
return TRUE;
}
int dbd_st_rows( SV *sth,
imp_sth_t *imp_sth ) {
return imp_sth->RowCount;
}
int dbd_st_cancel( SV *sth,
imp_sth_t *imp_sth ) {
D_imp_dbh_from_sth;
SQLRETURN ret;
if (DBIc_ACTIVE(imp_sth) ) {
ret = SQLCancel(imp_sth->phstmt);
CHECK_ERROR(sth, SQL_HANDLE_STMT, imp_sth->phstmt, ret, "SQLCancel Failed");
EOI(ret);
ret = SQLFreeStmt(imp_sth->phstmt,SQL_CLOSE);
CHECK_ERROR(sth, SQL_HANDLE_STMT, imp_sth->phstmt, ret, "SQLCancel Failed");
EOI(ret);
}
DBIc_ACTIVE_off(imp_sth);
return TRUE;
}
int dbd_st_finish( SV *sth,
imp_sth_t *imp_sth ) {
D_imp_dbh_from_sth;
SQLRETURN ret;
/* Cancel further fetches from this cursor. We don't */
/* close the cursor (SQLFreeHandle) 'til DESTROY (dbd_st_destroy).*/
/* The application may call execute(...) again on the same */
/* statement handle. */
if (DBIc_ACTIVE(imp_sth) ) {
ret = SQLFreeStmt(imp_sth->phstmt,SQL_CLOSE);
CHECK_ERROR(sth, SQL_HANDLE_STMT, imp_sth->phstmt, ret, "SQLFreeStmt Failed");
EOI(ret);
}
DBIc_ACTIVE_off(imp_sth);
return TRUE;
}
void dbd_st_destroy( SV *sth,
imp_sth_t *imp_sth ) {
D_imp_dbh_from_sth;
SQLINTEGER i;
SQLRETURN ret;
/* Free off contents of imp_sth */
for( i = 0; i < imp_sth->numFieldsAllocated; ++i) {
imp_fbh_t *fbh = &imp_sth->fbh[i];
Safefree( fbh->buffer );
}
Safefree(imp_sth->fbh);
Safefree(imp_sth->fbh_cbuf);
Safefree(imp_sth->statement);
if (imp_sth->bind_names) {
HV *hv = imp_sth->bind_names;
SV *sv;
char *key;
I32 retlen;
phs_t *phs;
hv_iterinit(hv);
while( (sv = hv_iternextsv(hv, &key, &retlen)) != NULL ) {
if (sv != &PL_sv_undef) {
phs = (phs_t*)SvPVX(sv);
SvREFCNT_dec( phs->sv );
if( phs->buffer != NULL && phs->bufferSize > 0 )
Safefree( phs->buffer );
}
}
sv_free((SV*)imp_sth->bind_names);
}
if( DBIc_ACTIVE( imp_dbh ) &&
!DBIc_IADESTROY( imp_sth ) &&
SQL_NULL_HSTMT != imp_sth->phstmt ) {
ret = SQLFreeHandle( SQL_HANDLE_STMT, imp_sth->phstmt );
CHECK_ERROR(sth, SQL_HANDLE_STMT, imp_sth->phstmt, ret, "Statement Destruction Error");
imp_sth->phstmt = SQL_NULL_HSTMT;
}
DBIc_IMPSET_off( imp_sth ); /* let DBI know we've done it */
}
static SQLINTEGER getStatementAttr( char *key,
STRLEN keylen ) {
/* For better performance, the keys are sorted by length */
switch( keylen )
{
#ifndef AS400
case 10:
if( strEQ( key, "db2_noscan" ) )
return SQL_ATTR_NOSCAN;
return SQL_ERROR;
case 12:
if( strEQ( key, "db2_max_rows" ) )
return SQL_ATTR_MAX_ROWS;
else if( strEQ( key, "db2_prefetch" ) )
return SQL_ATTR_PREFETCH;
return SQL_ERROR;
case 14:
if( strEQ( key, "db2_earlyclose" ) )
return SQL_ATTR_EARLYCLOSE;
else if( strEQ( key, "db2_max_length" ) )
return SQL_ATTR_MAX_LENGTH;
else if( strEQ( key, "db2_row_number" ) )
return SQL_ATTR_ROW_NUMBER;
return SQL_ERROR;
#endif
case 15:
if( strEQ( key, "db2_call_return" ) )
return SQL_ATTR_CALL_RETURN;
else if( strEQ( key, "db2_concurrency" ) )
return SQL_ATTR_CONCURRENCY;
else if( strEQ( key, "db2_cursor_hold" ) )
return SQL_ATTR_CURSOR_HOLD;
return SQL_ERROR;
#ifndef AS400
case 17:
if( strEQ( key, "db2_query_timeout" ) )
return SQL_ATTR_QUERY_TIMEOUT;
else if( strEQ( key, "db2_retrieve_data" ) )
return SQL_ATTR_RETRIEVE_DATA;
else if( strEQ( key, "db2_txn_isolation" ) )
return SQL_ATTR_TXN_ISOLATION;
return SQL_ERROR;
case 20:
if( strEQ( key, "db2_deferred_prepare" ) )
return SQL_ATTR_DEFERRED_PREPARE;
return SQL_ERROR;
#endif
case 21:
if( strEQ( key, "db2_rowcount_prefetch") )
return SQL_ATTR_ROWCOUNT_PREFETCH;
return SQL_ERROR;
case 22:
if( strEQ( key, "db2_optimize_for_nrows" ) )
return SQL_ATTR_OPTIMIZE_FOR_NROWS;
return SQL_ERROR;
case 28:
if( strEQ( key, "db2_query_optimization_level" ) )
return SQL_ATTR_QUERY_OPTIMIZATION_LEVEL;
return SQL_ERROR;
default:
return SQL_ERROR;
}
}
int dbd_st_STORE_attrib( SV *sth,
imp_sth_t *imp_sth,
SV *keysv,
SV *valuesv ) {
STRLEN kl;
char *key = SvPV( keysv, kl );
SQLINTEGER Attribute = getStatementAttr( key, kl );
SQLRETURN ret;
SQLPOINTER ValuePtr = 0;
SQLINTEGER StringLength = 0;
char msg[128]; /* buffer for error messages */
#ifdef AS400
SQLPOINTER param;
#endif
if( Attribute < 0 ) /* Don't know what this attribute is */
return FALSE;
switch( Attribute ) {
/* Booleans */
#ifndef AS400
CHECK_ERROR(sth, SQL_HANDLE_STMT, imp_sth->phstmt, ret, msg);
return FALSE;
}
return TRUE;
}
SV *dbd_st_FETCH_attrib( SV *sth,
imp_sth_t *imp_sth,
SV *keysv ) {
STRLEN kl;
char *key = SvPV( keysv, kl );
int i;
SV *retsv = NULL;
AV *av;
int cacheit = 1;
SQLINTEGER Attribute;
SQLRETURN ret = 0;
if (!imp_sth->done_desc && !dbd_describe(sth, imp_sth)) {
/* dbd_describe has already called check_error() */
/* We can't return Nullsv here because the xs code will */
/* then just pass the attribute name to DBI for FETCH. */
croak("Describe failed during %s->FETCH(%s)",
SvPV(sth,PL_na), key);
}
i = DBIc_NUM_FIELDS(imp_sth);
if( kl == 7 && strEQ( key, "lengths" ) ) {
av = newAV();
retsv = sv_2mortal( newRV_inc( (SV*)av ) );
while(--i >= 0)
av_store(av, i, newSViv((IV)imp_sth->fbh[i].dsize));
}
else if( kl == 5 && strEQ( key, "types" ) ) {
av = newAV();
retsv = sv_2mortal( newRV_inc( (SV*)av ) );
while(--i >= 0)
av_store(av, i, newSViv(imp_sth->fbh[i].dbtype));
}
else if( kl == 13 && strEQ( key, "NUM_OF_PARAMS" ) ) {
HV *bn = imp_sth->bind_names;
retsv = sv_2mortal( newSViv( (bn) ? HvKEYS(bn) : 0 ) );
}
else if( kl == 4 && strEQ( key, "NAME" ) ) {
av = newAV();
retsv = sv_2mortal( newRV_inc( sv_2mortal((SV*)av) ) );
while(--i >= 0)
av_store(av, i, newSVpv((char *)imp_sth->fbh[i].cbuf,0));
}
else if( kl == 8 && strEQ( key, "NULLABLE" ) ) {
av = newAV();
retsv = sv_2mortal( newRV_inc( sv_2mortal((SV*)av) ) );
while(--i >= 0)
av_store(av, i,
(imp_sth->fbh[i].nullok == 1) ? &PL_sv_yes : &PL_sv_no);
}
else if( kl == 10 && strEQ( key, "CursorName" ) ) {
char cursor_name[256];
SQLSMALLINT cursor_name_len;
ret = SQLGetCursorName(imp_sth->phstmt, (SQLCHAR *)cursor_name,
sizeof(cursor_name), &cursor_name_len);
CHECK_ERROR(sth, SQL_HANDLE_STMT, imp_sth->phstmt, ret, "SQLNGetCursorName Failed");
if (ret < 0)
return Nullsv;
else
retsv = sv_2mortal( newSVpv(cursor_name, cursor_name_len) );
}
else if( kl == 4 && strEQ( key, "TYPE" ) ) {
av = newAV();
retsv = sv_2mortal( newRV_inc( sv_2mortal( (SV*)av ) ) );
while(--i >= 0)
av_store(av, i, newSViv(imp_sth->fbh[i].dbtype));
}
else if( kl == 9 && strEQ( key, "PRECISION" ) ) {
av = newAV();
retsv = sv_2mortal( newRV_inc( sv_2mortal( (SV*)av ) ) );
while(--i >= 0)
av_store(av, i, newSViv(imp_sth->fbh[i].prec));
}
else if( kl == 5 && strEQ( key, "SCALE" ) ) {
av = newAV();
retsv = sv_2mortal( newRV_inc( sv_2mortal( (SV*)av ) ) );
while(--i >= 0)
av_store(av, i, newSViv(imp_sth->fbh[i].scale));
}
else if( 16 == kl && strEQ( key, "db2_more_results" ) ) {
if( !DBIc_ACTIVE(imp_sth) ) {
/* Statement has been finished, no more results available */
retsv = &PL_sv_no;
}
else if( imp_sth->bMoreResults ) {
/* Already know that there are more result sets */
retsv = &PL_sv_yes;
}
else {
ret = SQLMoreResults( imp_sth->phstmt );
CHECK_ERROR(sth, SQL_HANDLE_STMT, imp_sth->phstmt, ret, "Error Getting More Results");
if( SQL_SUCCESS == ret ) {
retsv = &PL_sv_yes;
}
else {
/* No more results, finish statement */
dbd_st_finish(sth, imp_sth);
retsv = &PL_sv_no;
}
}
if( &PL_sv_yes == retsv ) {
/* describe and allocate storage for results */
imp_sth->done_desc = FALSE;
/* Remove statement attribs in cache */
if (hv_exists((HV*) SvRV(sth), "NAME", 4) )
hv_delete((HV *) SvRV(sth), "NAME", 4, G_DISCARD);
if (hv_exists((HV*) SvRV(sth), "NAME_uc", 7))
hv_delete((HV *) SvRV(sth), "NAME_uc", 7, G_DISCARD);
if (hv_exists((HV*) SvRV(sth), "NAME_lc", 7) )
hv_delete((HV *) SvRV(sth), "NAME_lc", 7, G_DISCARD);
if (hv_exists((HV*) SvRV(sth), "TYPE", 4) )
hv_delete((HV *) SvRV(sth), "TYPE", 4, G_DISCARD);
if (hv_exists((HV*) SvRV(sth), "PRECISION", 9) )
hv_delete((HV *) SvRV(sth), "PRECISION", 9, G_DISCARD);
( run in 0.816 second using v1.01-cache-2.11-cpan-39bf76dae61 )