PAB3-DB-Driver-Mysql
view release on metacpan or search on metacpan
#/******************************************************************************
# * num_rows( resid )
# ******************************************************************************/
void
num_rows( resid )
void * resid;
PREINIT:
dMY_CXT;
#ifndef HAS_UV64
char tmp[21], *p1;
#endif
CODE:
switch( my_mysql_stmt_or_res( &MY_CXT, resid ) ) {
case MY_TYPE_RES:
#ifdef HAS_UV64
ST(0) = sv_2mortal( newSVuv( ( (MY_RES *) resid )->numrows ) );
#else
if( ( (MY_RES *) resid )->numrows <= 0xffffffff ) {
ST(0) = sv_2mortal( newSVuv( ( (MY_RES *) resid )->numrows ) );
}
else {
p1 = my_ltoa( tmp, ( (MY_RES *) resid )->numrows, 10 );
ST(0) = sv_2mortal( newSVpvn( tmp, p1 - tmp ) );
}
#endif
break;
case MY_TYPE_STMT:
#ifdef HAS_UV64
ST(0) = sv_2mortal( newSVuv( ( (MY_STMT *) resid )->numrows ) );
#else
if( ( (MY_STMT *) resid )->numrows <= 0xffffffff ) {
ST(0) = sv_2mortal( newSVuv( ( (MY_STMT *) resid )->numrows ) );
}
else {
p1 = my_ltoa( tmp, ( (MY_STMT *) resid )->numrows, 10 );
ST(0) = sv_2mortal( newSVpvn( tmp, p1 - tmp ) );
}
#endif
break;
default:
ST(0) = &PL_sv_undef;
break;
}
#/******************************************************************************
# * fetch_names( resid )
# ******************************************************************************/
void
fetch_names( resid )
void * resid;
PREINIT:
dMY_CXT;
MYSQL_RES *res = NULL;
MYSQL_FIELD *fields;
int num_fields, i;
PPCODE:
switch( my_mysql_stmt_or_res( &MY_CXT, resid ) ) {
case MY_TYPE_RES:
res = ( (MY_RES *) resid )->res;
break;
case MY_TYPE_STMT:
res = ( (MY_STMT *) resid )->meta;
break;
default:
goto exit;
}
fields = mysql_fetch_fields( res );
num_fields = mysql_num_fields( res );
for( i = 0; i < num_fields; i ++ ) {
XPUSHs( sv_2mortal(
newSVpvn( fields[i].name, fields[i].name_length )
) );
}
exit:
{}
#/******************************************************************************
# * fetch_field( resid [, offset] )
# ******************************************************************************/
void
fetch_field( resid, offset = -1 )
void * resid;
long offset;
PREINIT:
dMY_CXT;
MYSQL_RES *res;
MYSQL_FIELD *field;
unsigned int flags;
PPCODE:
switch( my_mysql_stmt_or_res( &MY_CXT, resid ) ) {
case MY_TYPE_RES:
res = ( (MY_RES *) resid )->res;
break;
case MY_TYPE_STMT:
res = ( (MY_STMT *) resid )->meta;
break;
default:
goto exit;
}
if( offset >= 0 )
mysql_field_seek( res, offset );
field = mysql_fetch_field( res );
if( field == NULL ) goto exit;
XPUSHs( sv_2mortal( newSVpvn( "name", 4 ) ) );
XPUSHs( sv_2mortal( newSVpvn( field->name, field->name_length ) ) );
XPUSHs( sv_2mortal( newSVpvn( "table", 5 ) ) );
XPUSHs( sv_2mortal( newSVpvn( field->table, field->table_length ) ) );
XPUSHs( sv_2mortal( newSVpvn( "catalog", 7 ) ) );
XPUSHs( sv_2mortal( newSVpvn( field->catalog, field->catalog_length ) ) );
XPUSHs( sv_2mortal( newSVpvn( "length", 6 ) ) );
XPUSHs( sv_2mortal( newSVuv( field->length ) ) );
XPUSHs( sv_2mortal( newSVpvn( "default", 7 ) ) );
XPUSHs( sv_2mortal( newSVpvn( field->def, field->def_length ) ) );
flags = field->flags;
XPUSHs( sv_2mortal( newSVpvn( "nullable", 8 ) ) );
XPUSHs( sv_2mortal( newSViv( ( flags & NOT_NULL_FLAG ) == 0 ) ) );
XPUSHs( sv_2mortal( newSVpvn( "primary", 6 ) ) );
XPUSHs( sv_2mortal( newSViv( ( flags & PRI_KEY_FLAG ) != 0 ) ) );
XPUSHs( sv_2mortal( newSVpvn( "unique", 6 ) ) );
XPUSHs( sv_2mortal( newSViv( ( flags & UNIQUE_KEY_FLAG ) != 0 ) ) );
XPUSHs( sv_2mortal( newSVpvn( "index", 5 ) ) );
XPUSHs( sv_2mortal( newSViv( ( flags & MULTIPLE_KEY_FLAG ) != 0 ) ) );
XPUSHs( sv_2mortal( newSVpvn( "identity", 8 ) ) );
XPUSHs( sv_2mortal( newSViv( ( flags & AUTO_INCREMENT_FLAG ) != 0 ) ) );
XPUSHs( sv_2mortal( newSVpvn( "numeric", 7 ) ) );
XPUSHs( sv_2mortal( newSViv( ( flags & NUM_FLAG ) != 0 ) ) );
XPUSHs( sv_2mortal( newSVpvn( "binary", 6 ) ) );
XPUSHs( sv_2mortal( newSViv( ( flags & BINARY_FLAG ) != 0 ) ) );
XPUSHs( sv_2mortal( newSVpvn( "zerofill", 8 ) ) );
XPUSHs( sv_2mortal( newSViv( ( flags & ZEROFILL_FLAG ) != 0 ) ) );
XPUSHs( sv_2mortal( newSVpvn( "unsigned", 8 ) ) );
XPUSHs( sv_2mortal( newSViv( ( flags & UNSIGNED_FLAG ) != 0 ) ) );
exit:
{}
#/******************************************************************************
# * field_seek( resid [, offset] )
# ******************************************************************************/
U32
field_seek( resid, offset = 0 )
void * resid;
U32 offset;
PREINIT:
dMY_CXT;
CODE:
switch( my_mysql_stmt_or_res( &MY_CXT, resid ) ) {
case MY_TYPE_RES:
RETVAL = mysql_field_seek( ( (MY_RES *) resid )->res, offset );
break;
case MY_TYPE_STMT:
RETVAL = mysql_field_seek( ( (MY_STMT *) resid )->meta, offset );
break;
default:
RETVAL = 0;
break;
}
OUTPUT:
RETVAL
#/******************************************************************************
# * field_tell( resid )
# ******************************************************************************/
U32
field_tell( resid )
void * resid;
PREINIT:
dMY_CXT;
CODE:
switch( my_mysql_stmt_or_res( &MY_CXT, resid ) ) {
case MY_TYPE_RES:
RETVAL = mysql_field_tell( ( (MY_RES *) resid )->res );
break;
case MY_TYPE_STMT:
RETVAL = mysql_field_tell( ( (MY_STMT *) resid )->meta );
break;
default:
RETVAL = 0;
break;
}
OUTPUT:
RETVAL
#/******************************************************************************
# * fetch_row( resid )
# ******************************************************************************/
void
fetch_row( resid )
void * resid;
PREINIT:
dMY_CXT;
MY_RES *res;
MYSQL_ROW row;
DWORD *lengths;
MY_STMT *stmt;
MYSQL_BIND *result;
DWORD num_fields, i;
PPCODE:
switch( my_mysql_stmt_or_res( &MY_CXT, resid ) ) {
case MY_TYPE_RES:
res = (MY_RES *) resid;
row = mysql_fetch_row( res->res );
if( ! row ) goto error;
num_fields = mysql_num_fields( res->res );
lengths = mysql_fetch_lengths( res->res );
EXTEND( SP, num_fields );
for( i = 0; i < num_fields; i ++ ) {
if( row[i] )
XPUSHs( sv_2mortal( newSVpvn( row[i], lengths[i] ) ) );
else
XPUSHs( &PL_sv_undef );
}
res->rowpos ++;
break;
case MY_TYPE_STMT:
stmt = (MY_STMT *) resid;
if( mysql_stmt_fetch( stmt->stmt ) != 0 ) goto error;
EXTEND( SP, stmt->field_count );
for( i = 0; i < stmt->field_count; i ++ ) {
result = &stmt->result[i];
if( *(result->is_null) )
XPUSHs( &PL_sv_undef );
else
switch( result->buffer_type ) {
case MYSQL_TYPE_TINY:
if( result->is_unsigned )
XPUSHs( sv_2mortal( newSVuv( *((char *) result->buffer) ) ) );
else
XPUSHs( sv_2mortal( newSViv( *((char *) result->buffer) ) ) );
break;
case MYSQL_TYPE_SHORT:
if( result->is_unsigned )
XPUSHs( sv_2mortal( newSVuv( *((short *) result->buffer) ) ) );
else
XPUSHs( sv_2mortal( newSViv( *((short *) result->buffer) ) ) );
break;
case MYSQL_TYPE_LONG:
if( result->is_unsigned )
XPUSHs( sv_2mortal( newSVuv( *((long *) result->buffer) ) ) );
else
XPUSHs( sv_2mortal( newSViv( *((long *) result->buffer) ) ) );
break;
case MYSQL_TYPE_DOUBLE:
XPUSHs( sv_2mortal( newSVnv( *((double *) result->buffer) ) ) );
break;
default:
XPUSHs( sv_2mortal( newSVpvn( result->buffer, *(result->length) ) ) );
break;
}
}
stmt->rowpos ++;
break;
}
error:
{}
#/******************************************************************************
# * fetch_col( resid )
# ******************************************************************************/
void
fetch_col( resid )
void * resid;
PREINIT:
dMY_CXT;
MY_RES *res;
MYSQL_ROW row;
DWORD *lengths;
MY_STMT *stmt;
MYSQL_BIND *result;
PPCODE:
switch( my_mysql_stmt_or_res( &MY_CXT, resid ) ) {
case MY_TYPE_RES:
res = (MY_RES *) resid;
EXTEND( SP, res->numrows );
while( ( row = mysql_fetch_row( res->res ) ) ) {
lengths = mysql_fetch_lengths( res->res );
if( lengths[0] > 0 )
XPUSHs( sv_2mortal( newSVpvn( row[0], lengths[0] ) ) );
else
XPUSHs( &PL_sv_undef );
}
res->rowpos = res->numrows;
break;
case MY_TYPE_STMT:
stmt = (MY_STMT *) resid;
EXTEND( SP, stmt->numrows );
while( mysql_stmt_fetch( stmt->stmt ) == 0 ) {
result = &stmt->result[0];
if( *(result->is_null) )
XPUSHs( &PL_sv_undef );
else
switch( result->buffer_type ) {
case MYSQL_TYPE_TINY:
if( result->is_unsigned )
XPUSHs( sv_2mortal( newSVuv( *((char *) result->buffer) ) ) );
else
XPUSHs( sv_2mortal( newSViv( *((char *) result->buffer) ) ) );
break;
case MYSQL_TYPE_SHORT:
if( result->is_unsigned )
XPUSHs( sv_2mortal( newSVuv( *((short *) result->buffer) ) ) );
else
XPUSHs( sv_2mortal( newSViv( *((short *) result->buffer) ) ) );
break;
case MYSQL_TYPE_LONG:
if( result->is_unsigned )
XPUSHs( sv_2mortal( newSVuv( *((long *) result->buffer) ) ) );
else
XPUSHs( sv_2mortal( newSViv( *((long *) result->buffer) ) ) );
break;
case MYSQL_TYPE_DOUBLE:
XPUSHs( sv_2mortal( newSVnv( *((double *) result->buffer) ) ) );
break;
default:
XPUSHs( sv_2mortal( newSVpvn( result->buffer, *(result->length) ) ) );
break;
}
}
stmt->rowpos = stmt->numrows;
break;
}
#/******************************************************************************
# * fetch_hash( resid )
# ******************************************************************************/
void
fetch_hash( resid )
void * resid;
PREINIT:
dMY_CXT;
MY_RES *res;
MYSQL_ROW row;
MYSQL_FIELD *fields;
MY_STMT *stmt;
MYSQL_BIND *result;
DWORD *lengths;
DWORD num_fields, i;
PPCODE:
switch( my_mysql_stmt_or_res( &MY_CXT, resid ) ) {
case MY_TYPE_RES:
res = (MY_RES *) resid;
row = mysql_fetch_row( res->res );
if( ! row ) goto error;
num_fields = mysql_num_fields( res->res );
lengths = mysql_fetch_lengths( res->res );
fields = mysql_fetch_fields( res->res );
EXTEND( SP, num_fields * 2 );
for( i = 0; i < num_fields; i ++ ) {
XPUSHs( sv_2mortal(
newSVpvn( fields[i].name, fields[i].name_length )
) );
if( row[i] )
XPUSHs( sv_2mortal( newSVpvn( row[i], lengths[i] ) ) );
else
XPUSHs( &PL_sv_undef );
}
res->rowpos ++;
break;
case MY_TYPE_STMT:
stmt = (MY_STMT *) resid;
if( mysql_stmt_fetch( stmt->stmt ) != 0 ) goto error;
fields = mysql_fetch_fields( stmt->meta );
EXTEND( SP, stmt->field_count * 2 );
for( i = 0; i < stmt->field_count; i ++ ) {
XPUSHs( sv_2mortal(
newSVpvn( fields[i].name, fields[i].name_length )
) );
result = &stmt->result[i];
if( *(result->is_null) )
XPUSHs( &PL_sv_undef );
else
switch( result->buffer_type ) {
case MYSQL_TYPE_TINY:
if( result->is_unsigned )
XPUSHs( sv_2mortal( newSVuv( *((char *) result->buffer) ) ) );
else
XPUSHs( sv_2mortal( newSViv( *((char *) result->buffer) ) ) );
break;
case MYSQL_TYPE_SHORT:
if( result->is_unsigned )
XPUSHs( sv_2mortal( newSVuv( *((short *) result->buffer) ) ) );
else
XPUSHs( sv_2mortal( newSViv( *((short *) result->buffer) ) ) );
break;
case MYSQL_TYPE_LONG:
if( result->is_unsigned )
XPUSHs( sv_2mortal( newSVuv( *((long *) result->buffer) ) ) );
else
XPUSHs( sv_2mortal( newSViv( *((long *) result->buffer) ) ) );
break;
case MYSQL_TYPE_DOUBLE:
XPUSHs( sv_2mortal( newSVnv( *((double *) result->buffer) ) ) );
break;
default:
XPUSHs( sv_2mortal( newSVpvn( result->buffer, *(result->length) ) ) );
break;
}
}
stmt->rowpos ++;
break;
}
error:
{}
#/******************************************************************************
# * fetch_lengths( resid )
# ******************************************************************************/
void
fetch_lengths( resid )
void * resid;
PREINIT:
dMY_CXT;
DWORD *lengths;
DWORD num_fields, i;
MY_STMT *stmt;
PPCODE:
switch( my_mysql_stmt_or_res( &MY_CXT, resid ) ) {
case MY_TYPE_RES:
lengths = mysql_fetch_lengths( ( (MY_RES *) resid )->res );
if( lengths ) {
num_fields = mysql_num_fields( ( (MY_RES *) resid )->res );
EXTEND( SP, num_fields );
for( i = 0; i < num_fields; i ++ ) {
XPUSHs( sv_2mortal( newSVuv( lengths[i] ) ) );
}
}
break;
case MY_TYPE_STMT:
stmt = (MY_STMT *) resid;
EXTEND( SP, stmt->field_count );
for( i = 0; i < stmt->field_count; i ++ ) {
XPUSHs( sv_2mortal( newSVuv( *(stmt->result[i].length) ) ) );
}
}
#/******************************************************************************
# * row_seek( resid, offset )
# ******************************************************************************/
int
row_seek( resid, offset = 0 )
void * resid;
UV offset;
PREINIT:
dMY_CXT;
MY_RES *res;
MY_STMT *stmt;
CODE:
switch( my_mysql_stmt_or_res( &MY_CXT, resid ) ) {
case MY_TYPE_RES:
res = (MY_RES *) resid;
if( offset >= (UV) res->numrows )
offset = (UV) res->numrows - 1;
mysql_data_seek( res->res, offset );
res->rowpos = offset;
RETVAL = 1;
break;
case MY_TYPE_STMT:
stmt = (MY_STMT *) resid;
if( offset >= (UV) stmt->numrows )
offset = (UV) stmt->numrows - 1;
mysql_stmt_data_seek( stmt->stmt, offset );
stmt->rowpos = offset;
RETVAL = 1;
break;
default:
RETVAL = 0;
}
OUTPUT:
RETVAL
#/******************************************************************************
# * row_tell( resid )
# ******************************************************************************/
if( r != 0 ) goto error;
con->my_flags ^= MYCF_TRANSACTION;
if( ( con->my_flags & MYCF_AUTOCOMMIT ) != 0 ) {
r = mysql_autocommit( con->conid, TRUE );
if( r != 0 ) goto error;
}
}
RETVAL = 1;
goto exit;
error:
RETVAL = 0;
exit:
OUTPUT:
RETVAL
#/******************************************************************************
# * rollback( [linkid] )
# ******************************************************************************/
int
rollback( linkid = 0 )
void * linkid;
PREINIT:
dMY_CXT;
MY_CON *con;
CODE:
if( ! ( linkid = my_verify_linkid( &MY_CXT, linkid ) ) ) goto error;
con = (MY_CON *) linkid;
if( ( con->my_flags & MYCF_TRANSACTION ) != 0 ) {
int r = mysql_rollback( con->conid );
if( r != 0 ) goto error;
con->my_flags ^= MYCF_TRANSACTION;
if( ( con->my_flags & MYCF_AUTOCOMMIT ) != 0 ) {
r = mysql_autocommit( con->conid, TRUE );
if( r != 0 ) goto error;
}
}
RETVAL = 1;
goto exit;
error:
RETVAL = 0;
exit:
OUTPUT:
RETVAL
#/******************************************************************************
# * show_catalogs( [linkid, [wild]] )
# ******************************************************************************/
void
show_catalogs( linkid = 0, wild = NULL )
void * linkid;
const char *wild;
PREINIT:
dMY_CXT;
MY_CON *con;
MYSQL_RES *res;
MYSQL_ROW row;
PPCODE:
if( ! ( linkid = my_verify_linkid( &MY_CXT, linkid ) ) ) goto error;
con = (MY_CON *) linkid;
res = mysql_list_dbs( con->conid, wild );
if( res ) {
while( ( row = mysql_fetch_row( res ) ) ) {
if( row[0] != 0 ) {
XPUSHs( sv_2mortal( newSVpvn( row[0], strlen( row[0] ) ) ) );
}
}
mysql_free_result( res );
}
error:
{}
#/******************************************************************************
# * show_tables( [linkid [, schema [, db [, wild]]]] )
# ******************************************************************************/
void
show_tables( linkid = 0, schema = NULL, db = NULL, wild = NULL )
void * linkid;
const char *db;
const char *schema;
const char *wild;
PREINIT:
dMY_CXT;
MY_CON *con;
MYSQL_RES *res;
MYSQL_ROW row;
char sql[512], *p1;
AV *av;
PPCODE:
if( ! ( linkid = my_verify_linkid( &MY_CXT, linkid ) ) ) goto error;
con = (MY_CON *) linkid;
if( db && db[0] != '\0' ) {
p1 = my_strcpy( sql, "SHOW TABLES FROM `" );
p1 = my_strcpy( p1, db );
p1 = my_strcpy( p1, "`" );
if( wild && wild[0] != '\0' ) {
p1 = my_strcpy( p1, " LIKE " );
p1 = my_strcpy( p1, wild );
}
if( mysql_real_query( con->conid, sql, (DWORD) (p1 - sql) ) == 0 ) {
res = mysql_store_result( con->conid );
}
else {
res = 0;
}
}
else {
res = mysql_list_tables( con->conid, wild );
}
if( res ) {
while( ( row = mysql_fetch_row( res ) ) ) {
if( row[0] != 0 ) {
// TABLE, SCHEMA, DB, TYPE
av = (AV *) sv_2mortal( (SV *) newAV() );
av_push( av, newSVpvn( row[0], strlen( row[0] ) ) );
av_push( av, &PL_sv_undef );
av_push( av, newSVpv( db, 0 ) );
// todo: add, detect "views"
av_push( av, newSVpvn( "table", 5 ) );
XPUSHs( sv_2mortal( newRV( (SV *) av ) ) );
}
}
mysql_free_result( res );
}
error:
{}
#/******************************************************************************
# * show_fields( [linkid, ] table [, schema [, db, [wild]]]] )
# ******************************************************************************/
void
show_fields( ... )
PREINIT:
dMY_CXT;
void * linkid = 0;
const char *table = NULL;
const char *schema = NULL;
const char *db = NULL;
const char *wild = NULL;
int itemp = 0;
MY_CON *con;
MYSQL_RES *res;
MYSQL_ROW row;
int numfields, numrows, r;
char sql[512], *p1;
AV *av;
PPCODE:
if( items < ( SvIOK( ST(0) ) ? 2 : 1 ) || items > 5 )
Perl_croak( aTHX_ "Usage: " __PACKAGE__ "::show_fields(linkid = 0, table, schema = NULL, db = NULL, wild = NULL)" );
if( SvIOK( ST( itemp ) ) ) {
linkid = INT2PTR( void *, SvIV( ST( itemp ) ) );
itemp ++;
}
table = (const char *) SvPV_nolen( ST( itemp ) );
itemp ++;
if( itemp < items ) {
schema = (const char *) SvPV_nolen( ST( itemp ) );
itemp ++;
}
if( itemp < items ) {
db = (const char *) SvPV_nolen( ST( itemp ) );
itemp ++;
}
if( itemp < items )
wild = (const char *) SvPV_nolen( ST( itemp ) );
con = (MY_CON *) my_verify_linkid( &MY_CXT, linkid );
if( con == NULL ) goto error;
p1 = my_strcpy( sql, "SHOW COLUMNS FROM `" );
p1 = my_strcpy( p1, table );
p1 = my_strcpy( p1, "`" );
if( wild && wild[0] != '\0' ) {
p1 = my_strcpy( p1, " LIKE '" );
p1 = my_strcpy( p1, wild );
p1 = my_strcpy( p1, "'" );
}
r = mysql_real_query( con->conid, sql, (DWORD) (p1 - sql) );
if( r == 0 ) {
res = mysql_store_result( con->conid );
numrows = (DWORD) mysql_num_rows( res );
numfields = mysql_num_fields( res );
EXTEND( SP, numrows );
// COLUMN, NULLABLE, DEFAULT, IS_PRIMARY, IS_UNIQUE, TYPENAME, AUTOINC
while( ( row = mysql_fetch_row( res ) ) ) {
av = (AV *) sv_2mortal( (SV *) newAV() );
av_push( av, newSVpvn( row[0], strlen( row[0] ) ) );
av_push( av, newSViv( strcmp( row[2], "NO" ) == 0 ? 0 : 1 ) );
if( row[4] != 0 )
av_push( av, newSVpvn( row[4], strlen( row[4] ) ) );
else
av_push( av, &PL_sv_undef );
av_push( av, newSViv( strcmp( row[3], "PRI" ) == 0 ? 1 : 0 ) );
av_push( av, newSViv( strcmp( row[3], "UNI" ) == 0 ? 1 : 0 ) );
av_push( av, newSVpvn( row[1], strlen( row[1] ) ) );
av_push( av, newSViv( strstr( row[5], "auto_increment" ) != 0 ? 1 : 0 ) );
XPUSHs( sv_2mortal( newRV( (SV *) av ) ) );
}
mysql_free_result( res );
}
error:
{}
#/******************************************************************************
# * show_index( [linkid, ] table [, schema [, db]] )
# ******************************************************************************/
void
show_index( ... )
PREINIT:
dMY_CXT;
void * linkid = 0;
const char *table = NULL;
const char *schema = NULL;
const char *db = NULL;
MY_CON *con;
MYSQL_RES *res;
MYSQL_ROW row;
char sql[512], *p1;
int step, num_fields, num_rows, itemp = 0;
long r;
AV *av;
PPCODE:
if( items < ( SvIOK( ST(0) ) ? 2 : 1 ) || items > 4 )
Perl_croak( aTHX_ "Usage: " __PACKAGE__ "::show_index(linkid = 0, table, schema = NULL, db = NULL)" );
if( SvIOK( ST( itemp ) ) ) {
linkid = INT2PTR( void *, SvIV( ST( itemp ) ) );
itemp ++;
}
table = (const char *) SvPV_nolen( ST( itemp ) );
itemp ++;
if( itemp < items ) {
schema = (const char *) SvPV_nolen( ST( itemp ) );
itemp ++;
}
if( itemp < items )
db = (const char *) SvPV_nolen( ST( itemp ) );
con = (MY_CON *) my_verify_linkid( &MY_CXT, linkid );
if( con == NULL ) goto error;
// SHOW INDEX FROM table FROM db
p1 = my_strcpy( sql, "SHOW INDEX FROM `" );
p1 = my_strcpy( p1, table );
p1 = my_strcpy( p1, "`" );
if( db != 0 && db[0] != '\0' ) {
p1 = my_strcpy( p1, " FROM `" );
p1 = my_strcpy( p1, db );
p1 = my_strcpy( p1, "`" );
}
step = 0;
retry:
r = mysql_real_query( con->conid, sql, (DWORD) (p1 - sql) );
switch( r ) {
case 0:
break;
case 1:
case CR_SERVER_GONE_ERROR:
case CR_SERVER_LOST:
if( ( con->client_flag & CLIENT_RECONNECT ) != 0 && step == 0 ) {
step ++;
r = my_mysql_reconnect( con );
if( ! r ) goto error;
goto retry;
}
default:
goto error;
}
res = mysql_store_result( con->conid );
num_fields = mysql_num_fields( res );
num_rows = (DWORD) mysql_num_rows( res );
EXTEND( SP, num_rows );
// NAME, COLUMN, TYPE
while( ( row = mysql_fetch_row( res ) ) ) {
av = (AV *) sv_2mortal( (SV *) newAV() );
av_push( av, newSVpvn( row[2], strlen( row[2] ) ) );
av_push( av, newSVpvn( row[4], strlen( row[4] ) ) );
if( strcmp( row[2], "PRIMARY" ) == 0 )
av_push( av, newSViv( 1 ) );
else if( row[1][0] == '0' )
av_push( av, newSViv( 2 ) );
else
av_push( av, newSViv( 3 ) );
XPUSHs( sv_2mortal( newRV( (SV *) av ) ) );
}
( run in 0.881 second using v1.01-cache-2.11-cpan-5511b514fd6 )