dbcapi_isql.cpp

This example shows how to write an ISQL application using dbcapi.

// *********************************************************************
// Copyright 1994-2008 iAnywhere Solutions, Inc.  All rights reserved.
// This sample code is provided AS IS, without warranty or liability
// of any kind.
//
// You may use, reproduce, modify and distribute this sample code
// without limitation, on the condition that you retain the foregoing
// copyright notice and disclaimer as to the original iAnywhere code.
//
// *********************************************************************
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <assert.h>

#include "sacapidll.h"

#define max( x, y) ( x >= y ? x : y )

SQLAnywhereInterface api;
a_sqlany_connection *conn;


void print_blob( char * buffer, size_t length )
/**********************************************/
{
    size_t I;

    if( length == 0 ) {
        return;
    }
    printf( "0x" );
    I = 0;
    while( I < length ) {
        printf( "%.2X", (unsigned char)buffer[i] );
        I++;
    }
}


void execute( char * query )
/***************************/
{
    a_sqlany_stmt * stmt;
    int             err_code;
    char            err_mesg[SACAPI_ERROR_SIZE];
    int             I;
    int             num_rows;
    int             length;

    stmt = api.sqlany_execute_direct( conn, query );
    if( stmt == NULL ) {
        err_code = api.sqlany_error( conn, err_mesg, sizeof(err_mesg) );
        printf( "Failed: [%d] '%s'\n", err_code, err_mesg );
        return;
    }
    if( api.sqlany_error( conn, NULL, 0 ) > 0 ) {
        err_code = api.sqlany_error( conn, err_mesg, sizeof(err_mesg) );
        printf( "Warning: [%d] '%s'\n", err_code, err_mesg );
    }
    if( api.sqlany_num_cols( stmt ) == 0 ) {
        printf( "Executed successfully.\n" );
        if( api.sqlany_affected_rows( stmt ) > 0 ) {
            printf( "%d affected rows.\n", api.sqlany_affected_rows( stmt ) );
        }
        api.sqlany_free_stmt( stmt );
        return;
    }

    // first output column header
    length = 0;
    for( I = 0; I < api.sqlany_num_cols( stmt ); I++ ) {
        a_sqlany_column_info    column_info;

        if( I > 0 ) {
            printf( "," );
            length += 1;
        }
        api.sqlany_get_column_info( stmt, I, &column_info );
        printf( "%s", column_info.name );
        length += (int)strlen( column_info.name );
    }
    printf( "\n" );
    for( I = 0; I < length; I++ ) {
        printf( "-" );
    }
    printf( "\n" );
    num_rows = 0;
    while( api.sqlany_fetch_next( stmt ) ) {
        num_rows++;
        for( I = 0; I < api.sqlany_num_cols( stmt ); I++ ) {
            a_sqlany_data_value dvalue;

            api.sqlany_get_column( stmt, I, &dvalue );
            if( I > 0 ) {
                printf( "," );
            }
            if( *(dvalue.is_null) ) {
                printf( "(NULL)" );
                continue;
            }
            switch( dvalue.type ) {
                case A_BINARY:
                    print_blob( dvalue.buffer, *(dvalue.length) );
                    break;
                case A_STRING:
                    printf( "'%.*s'", *(dvalue.length), (char *)dvalue.buffer, *(dvalue.length) );
                    break;
                case A_VAL64:
                    printf( "%lld", *(long long*)dvalue.buffer);
                    break;
                case A_UVAL64:
                    printf( "%lld", *(unsigned long long*)dvalue.buffer);
                    break;
                case A_VAL32:
                    printf( "%d", *(int*)dvalue.buffer );
                    break;
                case A_UVAL32:
                    printf( "%u", *(unsigned int*)dvalue.buffer );
                    break;
                case A_VAL16:
                    printf( "%d", *(short*)dvalue.buffer );
                    break;
                case A_UVAL16:
                    printf( "%u", *(unsigned short*)dvalue.buffer );
                    break;
                case A_VAL8:
                    printf( "%d", *(char*)dvalue.buffer );
                    break;
                case A_UVAL8:
                    printf( "%d", *(char*)dvalue.buffer );
                    break;
                case A_DOUBLE:
                    printf( "%f", *(double*)dvalue.buffer );
                    break;
            }
        }
        printf( "\n" );
    }
    for( I = 0; I < length; I++ ) {
        printf( "-" );
    }
    printf( "\n" );

    printf( "%d rows returned\n", num_rows );
    if( api.sqlany_error( conn, NULL, 0 ) != 100 ) {
        char buffer[256];
        int  code = api.sqlany_error( conn, buffer, sizeof(buffer) );
        printf( "Failed: [%d] '%s'\n", code, buffer );
    }
    printf( "\n" );

    fflush( stdout );
    api.sqlany_free_stmt( stmt );
}


int main( int argc, char * argv[] )
/**********************************/
{
    unsigned int  max_api_ver;
    char          buffer[256];
    int           len;
    int           ch;

    if( argc < 1 ) {
        printf( "Usage: %s -c <connection_string>\n", argv[0] );
        exit( 0 );
    }
    if( !sqlany_initialize_interface( &api, NULL ) ) {
        printf( "Failed to initialize the interface!\n" );
        exit( 0 );
    }
    if( !api.sqlany_init( "isql", SQLANY_CURRENT_API_VERSION, &max_api_ver )) {
        printf( "Failed to initialize the interface! Supported version = %d\n", max_api_ver );
        sqlany_finalize_interface( &api );
        return -1;
    }
    conn = api.sqlany_new_connection();

    if( !api.sqlany_connect( conn, argv[1] ) ) {
        int code = api.sqlany_error( conn, buffer, sizeof(buffer) );
        printf( "Could not connect: [%d] %s\n", code, buffer );
        goto done;
    }

    printf( "Connected successfully!\n" );
    while( 1 ) {
        printf( "\n%s> ", argv[0] );
        fflush( stdout );

        len = 0;
        while( len < (sizeof(buffer) - 1) ) {
            ch = fgetc( stdin );
            if( ch == '\0' || ch == '\n' || ch == '\r' || ch == -1 ) {
                break;
            }
            buffer[len] = (char)tolower( ch );
            len++;
        }
        buffer[len] = '\0';
        if(buffer[0] == '\0' ) {
            break;
        }
        if( strcmp( buffer, "quit" ) == 0 ) {
            break;
        }
        execute( buffer );
    }

    api.sqlany_disconnect( conn );

done:
    api.sqlany_free_connection( conn );
    api.sqlany_fini();
    sqlany_finalize_interface( &api );
}