Files
Przemysław Czerpak 96ca3fe470 2014-01-21 20:41 UTC+0100 Przemyslaw Czerpak (druzus/at/poczta.onet.pl)
* Makefile
  * config/*
  * contrib/*
  * doc/*
  * extras/*
  * include/*
  * lib/*
  * package/*
  * src/*
  * tests/*
  * utils/*
    * removed empty lines left after removed '$' + 'Id' + '$' identifiers
2014-01-21 20:41:05 +01:00

424 lines
11 KiB
C

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <time.h>
#include <ibase.h>
#include <iberror.h>
#ifndef ISC_INT64_FORMAT
#if ( defined( _MSC_VER ) && defined( WIN32 ) ) || ( defined( __BORLANDC__ ) && defined( __WIN32__ ) )
#define ISC_INT64_FORMAT "I64"
#else
#define ISC_INT64_FORMAT "ll"
#endif
#endif
#define USER "sysdba"
#define PASSWORD "masterkey"
#define DATABASE "127.0.0.1:d:\\fontes\\lixo\\test.gdb"
#define ERREXIT( status, rc ) { isc_print_status( status ); return rc; }
#define MAX_BUFFER 1024
int execute( char * exec_str );
int query( char * sel_str );
int fetch( void );
int qclose( void );
char * getdata( int pos );
isc_db_handle db = NULL;
int dialect = 1;
XSQLDA ISC_FAR * sqlda;
isc_stmt_handle stmt = NULL;
isc_tr_handle trans = NULL;
int main()
{
char dpb[ 48 ];
int i = 0, len;
long status[ 20 ];
dpb[ i++ ] = isc_dpb_version1;
dpb[ i++ ] = isc_dpb_user_name;
len = strlen( USER );
dpb[ i++ ] = ( char ) len;
strncpy( &( dpb[ i ] ), USER, len );
i += len;
dpb[ i++ ] = isc_dpb_password;
len = strlen( PASSWORD );
dpb[ i++ ] = len;
strncpy( &( dpb[ i ] ), PASSWORD, len );
i += len;
if( isc_attach_database( status, 0, DATABASE, &db, i, dpb ) )
ERREXIT( status, 1 );
execute( "DROP TABLE TESTE" );
execute( "CREATE TABLE TESTE (code smallint)" );
execute( "INSERT INTO TESTE (code) VALUES (100)" );
query( "SELECT * FROM TESTE" );
while( fetch() == 0 )
printf( "%s\n", getdata( 0 ) );
qclose();
if( isc_detach_database( status, &db ) )
ERREXIT( status, 1 );
return 1;
}
int execute( char * exec_str )
{
isc_tr_handle trans = NULL;
long status[ 20 ];
if( isc_start_transaction( status, &trans, 1, &db, 0, NULL ) )
ERREXIT( status, 1 );
if( isc_dsql_execute_immediate( status, &db, &trans, 0, exec_str, dialect, NULL ) )
ERREXIT( status, 1 );
if( isc_commit_transaction( status, &trans ) )
ERREXIT( status, 1 );
return 1;
}
int query( char * sel_str )
{
ISC_STATUS status[ 20 ];
XSQLVAR * var;
int n, i, dtype;
if( isc_start_transaction( status, &trans, 1, &db, 0, NULL ) )
ERREXIT( status, 1 );
/* Allocate an output SQLDA. Just to check number of columns */
sqlda = ( XSQLDA * ) malloc( XSQLDA_LENGTH( 1 ) );
sqlda->sqln = 1;
sqlda->version = 1;
/* Allocate a statement */
if( isc_dsql_allocate_statement( status, &db, &stmt ) )
ERREXIT( status, 1 );
/* Prepare the statement. */
if( isc_dsql_prepare( status, &trans, &stmt, 0, sel_str, dialect, sqlda ) )
ERREXIT( status, 1 );
/* Describe sql contents */
if( isc_dsql_describe( status, &stmt, dialect, sqlda ) )
ERREXIT( status, 1 );
/* Relocate necessary number of columns */
if( sqlda->sqld > sqlda->sqln )
{
free( sqlda );
n = sqlda->sqld;
sqlda = ( XSQLDA * ) malloc( XSQLDA_LENGTH( n ) );
sqlda->sqln = n;
sqlda->version = 1;
if( isc_dsql_describe( status, &stmt, dialect, sqlda ) )
ERREXIT( status, 1 );
}
for( i = 0, var = sqlda->sqlvar; i < sqlda->sqld; i++, var++ )
{
dtype = ( var->sqltype & ~1 );
switch( dtype )
{
case SQL_VARYING:
var->sqltype = SQL_TEXT;
var->sqldata = ( char * ) malloc( sizeof( char ) * var->sqllen + 2 );
break;
case SQL_TEXT:
var->sqldata = ( char * ) malloc( sizeof( char ) * var->sqllen + 2 );
break;
case SQL_LONG:
var->sqltype = SQL_LONG;
var->sqldata = ( char * ) malloc( sizeof( long ) );
break;
default:
var->sqldata = ( char * ) malloc( sizeof( char ) * var->sqllen );
break;
}
if( var->sqltype & 1 )
{
var->sqlind = ( short * ) malloc( sizeof( short ) );
}
}
if( ! sqlda->sqld )
{
/* Execute and commit non-select querys */
if( isc_dsql_execute( status, &trans, &stmt, dialect, NULL ) )
ERREXIT( status, 1 );
if( isc_commit_transaction( status, &trans ) )
ERREXIT( status, 1 );
trans = NULL;
}
else
{
if( isc_dsql_execute( status, &trans, &stmt, dialect, sqlda ) )
ERREXIT( status, 1 );
}
return 1;
}
int fetch( void )
{
long fetch_stat;
long status[ 20 ];
fetch_stat = isc_dsql_fetch( status, &stmt, dialect, sqlda );
if( fetch_stat != 100L )
ERREXIT( status, 1 );
return fetch_stat;
}
int qclose( void )
{
long status[ 20 ];
if( isc_dsql_free_statement( status, &stmt, DSQL_drop ) )
ERREXIT( status, 1 );
if( trans )
if( isc_commit_transaction( status, &trans ) )
ERREXIT( status, 1 );
if( sqlda )
free( sqlda );
return 1;
}
char * getdata( int pos )
{
short dtype;
char data[ MAX_BUFFER ], * p;
char blob_s[ 20 ], date_s[ 25 ];
short len;
long status[ 20 ];
struct tm times;
ISC_QUAD bid;
XSQLVAR * var;
if( ( pos + 1 ) > sqlda->sqln )
return "error";
var = sqlda->sqlvar;
var += pos;
dtype = var->sqltype & ~1;
p = data;
if( ( var->sqltype & 1 ) && ( *var->sqlind < 0 ) )
{
switch( dtype )
{
case SQL_TEXT:
case SQL_VARYING:
len = var->sqllen;
break;
case SQL_SHORT:
len = 6;
if( var->sqlscale > 0 )
len += var->sqlscale;
break;
case SQL_LONG:
len = 11;
if( var->sqlscale > 0 )
len += var->sqlscale;
break;
case SQL_INT64:
len = 21;
if( var->sqlscale > 0 )
len += var->sqlscale;
break;
case SQL_FLOAT:
len = 15;
break;
case SQL_DOUBLE:
len = 24;
break;
case SQL_TIMESTAMP:
len = 24;
break;
case SQL_TYPE_DATE:
len = 10;
break;
case SQL_TYPE_TIME:
len = 13;
break;
case SQL_BLOB:
case SQL_ARRAY:
default:
len = 17;
break;
}
if( ( dtype == SQL_TEXT ) || ( dtype == SQL_VARYING ) )
sprintf( p, "%-*s ", len, "NULL" );
else
sprintf( p, "%*s ", len, "NULL" );
}
else
{
switch( dtype )
{
case SQL_TEXT:
sprintf( p, "%.*s ", var->sqllen, var->sqldata );
break;
case SQL_VARYING:
sprintf( p, "%.*s ", var->sqllen, var->sqldata );
break;
case SQL_SHORT:
case SQL_LONG:
case SQL_INT64:
{
ISC_INT64 value = 0;
short field_width = 0;
short dscale;
switch( dtype )
{
case SQL_SHORT:
value = ( ISC_INT64 ) *( short ISC_FAR * ) var->sqldata;
field_width = 6;
break;
case SQL_LONG:
value = ( ISC_INT64 ) *( long ISC_FAR * ) var->sqldata;
field_width = 11;
break;
case SQL_INT64:
value = ( ISC_INT64 ) *( ISC_INT64 ISC_FAR * ) var->sqldata;
field_width = 21;
break;
}
dscale = var->sqlscale;
if( dscale < 0 )
{
ISC_INT64 tens;
short i;
tens = 1;
for( i = 0; i > dscale; i-- )
{
tens *= 10;
if( value >= 0 )
{
sprintf( p,
"%*" ISC_INT64_FORMAT "d.%0*"
ISC_INT64_FORMAT "d",
field_width - 1 + dscale,
( ISC_INT64 ) ( value / tens ), -dscale,
( ISC_INT64 ) ( value % tens ) );
}
else if( ( value / tens ) != 0 )
{
sprintf( p,
"%*" ISC_INT64_FORMAT "d.%0*"
ISC_INT64_FORMAT "d",
field_width - 1 + dscale,
( ISC_INT64 ) ( value / tens ), -dscale,
( ISC_INT64 ) -( value % tens ) );
}
else
{
sprintf( p, "%*s.%0*" ISC_INT64_FORMAT "d",
field_width - 1 + dscale,
"-0", -dscale,
( ISC_INT64 ) -( value % tens ) );
}
}
}
else if( dscale )
{
sprintf( p, "%*" ISC_INT64_FORMAT "d%0*d",
field_width, ( ISC_INT64 ) value, dscale, 0 );
}
else
{
sprintf( p, "%*" ISC_INT64_FORMAT "d",
field_width, ( ISC_INT64 ) value );
}
};
break;
case SQL_FLOAT:
sprintf( p, "%15g ", *( float ISC_FAR * ) ( var->sqldata ) );
break;
case SQL_DOUBLE:
sprintf( p, "%24f ", *( double ISC_FAR * ) ( var->sqldata ) );
break;
case SQL_TIMESTAMP:
isc_decode_timestamp( ( ISC_TIMESTAMP ISC_FAR * ) var->sqldata, &times );
sprintf( date_s, "%04d-%02d-%02d %02d:%02d:%02d.%04lui",
times.tm_year + 1900,
times.tm_mon + 1,
times.tm_mday,
times.tm_hour,
times.tm_min,
times.tm_sec,
( ( ISC_TIMESTAMP * ) var->sqldata )->timestamp_time % 10000 );
sprintf( p, "%*s ", 24, date_s );
break;
case SQL_TYPE_DATE:
isc_decode_sql_date( ( ISC_DATE ISC_FAR * ) var->sqldata, &times );
sprintf( date_s, "%04d-%02d-%02d",
times.tm_year + 1900, times.tm_mon + 1, times.tm_mday );
sprintf( p, "%*s ", 10, date_s );
break;
case SQL_TYPE_TIME:
isc_decode_sql_time( ( ISC_TIME ISC_FAR * ) var->sqldata, &times );
sprintf( date_s, "%02d:%02d:%02d.%04lui",
times.tm_hour,
times.tm_min,
times.tm_sec, ( *( ( ISC_TIME * ) var->sqldata ) ) % 10000 );
sprintf( p, "%*s ", 13, date_s );
break;
case SQL_BLOB:
case SQL_ARRAY:
/* Print the blob id on blobs or arrays */
bid = *( ISC_QUAD ISC_FAR * ) var->sqldata;
sprintf( blob_s, "%08x:%08x", ( unsigned int ) bid.gds_quad_high,
( unsigned int ) bid.gds_quad_low );
sprintf( p, "%17s ", blob_s );
break;
default:
break;
}
}
return p;
}