/*
** EXECUTE.C - This is the module containing the code for SQL for
** executing SQL Commands.
**
** (c) 1996 by Dirk Ohme - all rights reserved
*/

#include "cli.h"

/*---------------------------------------------------------------------------*/
/*  Execute a prepared SQL statement                                         */
/*---------------------------------------------------------------------------*/
RETCODE SQL_API SQLExecute(
        LPSTMT  lpstmt)
{                                                /*--------------------------*/
#ifdef mSQL
        int      ci;                             /* index counter            */
        char    *pszInp;                         /* input string pointer     */
        char    *pszOut;                         /* output string pointer    */
#endif
                                                 /*--------------------------*/
        /*
        ** check parameter
        */
        LogEntry( LOG_STATUS, "[SQLExecute] lpstmt = $%08lX", lpstmt );
        if( NULL == lpstmt || NULL == lpstmt->pSqlDbc ||
            NULL == lpstmt->pSqlDbc->pSqlEnv )
        {
                LogEntry( LOG_ERROR,      "[SQLExecute] NULL == lpstmt" );
                LogEntry( LOG_RETURNCODE, "[SQLExecute] SQL_INVALID_HANDLE" );
                return SQL_INVALID_HANDLE;
        }

        /*
        ** start execution
        */
#ifdef mSQL
        if( NULL == lpstmt->pSqlDbc || 0 > lpstmt->pSqlDbc->hDbSocket )
#endif
#ifdef ORACLE
        if( NULL == lpstmt->pSqlDbc )
#endif
        {
                strcpy( lpstmt->szSqlState, "40003" );
                lpstmt->pszSqlMsg = "[SQLExecute] no connection to database";
                LogEntry( LOG_ERROR, lpstmt->pszSqlMsg );
                LogEntry( LOG_RETURNCODE, "[SQLExecute] SQL_ERROR (%s)",
                          lpstmt->szSqlState );
                return SQL_ERROR;
        }
        if( NULL == lpstmt->pszQuery )
        {
                strcpy( lpstmt->szSqlState, "S1010" );
                lpstmt->pszSqlMsg = "[SQLExecute] no prepared statement";
                LogEntry( LOG_ERROR, lpstmt->pszSqlMsg );
                LogEntry( LOG_RETURNCODE, "[SQLExecute] SQL_ERROR (%s)",
                          lpstmt->szSqlState );
                return SQL_ERROR;
        }

        /*
        ** execute query (mSQL)
        */
#ifdef mSQL
        ci     = 0;
        pszInp = lpstmt->pszQuery;
        pszOut = lpstmt->pSqlDbc->pSqlEnv->szEnvBuffer;

        /*---| parse query string |---*/
        while( '\0' != *pszInp )
        {
                /*---| check for escape sequence |---*/
                if( '%' == *pszInp )
                {
                        pszInp++;
                        switch( *pszInp )
                        {
                                case '%':                  /* character % */
                                       *pszOut = *pszInp;
                                        pszOut++;
                                        break;
                                case 'c':                  /* data entries */
                                        sprintf( pszOut, "%c",
                                                 *((char *)lpstmt->pParamVar[ci++]) );
                                        pszOut = strchr( pszOut, '\0' );
                                        break;
                                case 'd':
                                        sprintf( pszOut, "%d",
                                                 *((int *)lpstmt->pParamVar[ci++]) );
                                        pszOut = strchr( pszOut, '\0' );
                                        break;
                                case 'e':
                                        sprintf( pszOut, "%e",
                                                 *((float *)lpstmt->pParamVar[ci++]) );
                                        pszOut = strchr( pszOut, '\0' );
                                        break;
                                case 'E':
                                        sprintf( pszOut, "%E",
                                                 *((float *)lpstmt->pParamVar[ci++]) );
                                        pszOut = strchr( pszOut, '\0' );
                                        break;
                                case 'g':
                                        sprintf( pszOut, "%g",
                                                 *((float *)lpstmt->pParamVar[ci++]) );
                                        pszOut = strchr( pszOut, '\0' );
                                        break;
                                case 'G':
                                        sprintf( pszOut, "%G",
                                                 *((float *)lpstmt->pParamVar[ci++]) );
                                        pszOut = strchr( pszOut, '\0' );
                                        break;
                                case 'f':
                                        sprintf( pszOut, "%f",
                                                 *((float *)lpstmt->pParamVar[ci++]) );
                                        pszOut = strchr( pszOut, '\0' );
                                        break;
                                case 'i':
                                        sprintf( pszOut, "%i",
                                                 *((int *)lpstmt->pParamVar[ci++]) );
                                        pszOut = strchr( pszOut, '\0' );
                                        break;
                                case 'o':
                                        sprintf( pszOut, "%o",
                                                 *((int *)lpstmt->pParamVar[ci++]) );
                                        pszOut = strchr( pszOut, '\0' );
                                        break;
                                case 'u':
                                        sprintf( pszOut, "%u",
                                                 *((int *)lpstmt->pParamVar[ci++]) );
                                        pszOut = strchr( pszOut, '\0' );
                                        break;
                                case 'x':
                                        sprintf( pszOut, "%x",
                                                 *((int *)lpstmt->pParamVar[ci++]) );
                                        pszOut = strchr( pszOut, '\0' );
                                        break;
                                case 'X':
                                        sprintf( pszOut, "%X",
                                                 *((int *)lpstmt->pParamVar[ci++]) );
                                        pszOut = strchr( pszOut, '\0' );
                                        ci++;
                                        break;
                                case 's':                  /* strings */
                                        strcpy( pszOut, lpstmt->pParamVar[ci++] );
                                        pszOut = strchr( pszOut, '\0' );
                                        break;
                                case '?':                  /* free parameter */
                                default:
                                       *pszOut = *pszInp;
                                        pszOut++;
                        }
                }
                else
                {
                        *pszOut = *pszInp;
                         pszOut++;
                }

                /*---| next character |---*/
                pszInp++;
        }

        /*---| set delimiter |---*/
        *pszOut = '\0';

        /*---| process query |---*/
        if( 0 != msqlQuery( lpstmt->pSqlDbc->hDbSocket,
                            lpstmt->pSqlDbc->pSqlEnv->szEnvBuffer ) )
        {
                /*---| get mSQL error message |---*/
                msqlGetErrMsg( lpstmt->szMsqlErrorMsg );

#endif
#ifdef ORACLE
        if( oexec(&lpstmt->cda) )
        {
#endif
                /*---| error processing |---*/
                strcpy( lpstmt->szSqlState, "08001" );
                lpstmt->pszSqlMsg = "[SQLExecute] cannot execute";
#ifdef mSQL
                LogEntry( LOG_ERROR, "[SQLExecute] cannot execute (%s)",
                          lpstmt->szMsqlErrorMsg );
#endif
#ifdef ORACLE
                LogEntry( LOG_ERROR, "[SQLExecute] cannot execute" );
#endif
                LogEntry( LOG_RETURNCODE, "[SQLExecute] SQL_ERROR (%s)",
                          lpstmt->szSqlState );
                return SQL_ERROR;
        }

#ifdef mSQL
        /*
        ** get results (mSQL)
        */
        lpstmt->pMsqlResult = msqlStoreResult();

        /*
        ** set transfered bytes (mSQL)
        */
        for( ci = 0; ci < SQL_MAX_PARAM; ci++ )
        {
                if( NULL != lpstmt->pcbParam[ci] )
                {
                        *(lpstmt->pcbParam[ci]) = lpstmt->cbParamLen[ci];
                }
        }

        /*
        ** reset binding parameters (mSQL)
        */
        memset( lpstmt->fSqlType,   0, sizeof(int)      * SQL_MAX_COLUMN );
        memset( lpstmt->fCType,     0, sizeof(int)      * SQL_MAX_COLUMN );
        memset( lpstmt->pResultVar, 0, sizeof(void   *) * SQL_MAX_COLUMN );
        memset( lpstmt->pResultLen, 0, sizeof(SDWORD *) * SQL_MAX_COLUMN );
        memset( lpstmt->cbMaxLen,   0, sizeof(int)      * SQL_MAX_COLUMN );
#endif

        /*
        ** return success
        */
        LogEntry( LOG_RETURNCODE, "[SQLExecute] SQL_SUCCESS" );
        return SQL_SUCCESS;
}


/*---------------------------------------------------------------------------*/
/*  Performs the equivalent of SQLPrepare, followed by SQLExecute.           */
/*---------------------------------------------------------------------------*/
RETCODE SQL_API SQLExecDirect(
        LPSTMT  lpstmt,
        UCHAR FAR *szSqlStr,
        SDWORD  cbSqlStr)
{                                                /*--------------------------*/
        RETCODE         rc;                      /* return code              */
                                                 /*--------------------------*/
        /*
        ** check parameter
        */
        LogEntry( LOG_STATUS, "[SQLExecDirect] lpstmt   = $%08lX", lpstmt );
        LogEntry( LOG_STATUS, "                szSqlStr = $%08lX", szSqlStr );
        LogEntry( LOG_STATUS, "                cbSqlStr =  %5d",   cbSqlStr );

        /*
        ** prepare command
        */
        rc = SQLPrepare( lpstmt, szSqlStr, cbSqlStr );
        if( SQL_SUCCESS != rc )
        {
                LogEntry( LOG_RETURNCODE, "[SQLExecDirect] SQL_??? (%d)", rc );
                return rc;
        }

        /*
        ** execute command
        */
        rc = SQLExecute( lpstmt );
        if( SQL_SUCCESS != rc )
        {
                LogEntry( LOG_RETURNCODE, "[SQLExecDirect] SQL_??? (%d)", rc );
                return rc;
        }

        /*
        ** return success
        */
        LogEntry( LOG_RETURNCODE, "[SQLExecute] SQL_SUCCESS" );
        return SQL_SUCCESS;
}


/*---------------------------------------------------------------------------*/
/*  Returns the SQL string as modified by the driver.                        */
/*---------------------------------------------------------------------------*/
RETCODE SQL_API SQLNativeSql(
        LPSTMT  lpstmt,
        UCHAR FAR *szSqlStrIn,
        SDWORD  cbSqlStrIn,
        UCHAR FAR *szSqlStr,
        SDWORD  cbSqlStrMax,
        SDWORD FAR *pcbSqlStr)
{
        return SQL_SUCCESS;
}


/*---------------------------------------------------------------------------*/
/*  Supplies parameter data at execution time.  Used in conjuction with      */
/*  SQLPutData.                                                              */
/*---------------------------------------------------------------------------*/
RETCODE SQL_API SQLParamData(
        LPSTMT  lpstmt,
    PTR FAR *prbgValue)
{
        return SQL_SUCCESS;
}


/*---------------------------------------------------------------------------*/
/*  Supplies parameter data at execution time.  Used in conjunction with     */
/*  SQLParamData.                                                            */
/*---------------------------------------------------------------------------*/
RETCODE SQL_API SQLPutData(
        LPSTMT  lpstmt,
        PTR     rgbValue,
        SDWORD  cbValue)
{
        return SQL_SUCCESS;
}


/*---------------------------------------------------------------------------*/
/*      Cancel Action                                                        */
/*---------------------------------------------------------------------------*/
RETCODE SQL_API SQLCancel(
        LPSTMT  lpstmt)                /* Statement to cancel.               */
{
        /*
        ** check parameter
        */
        LogEntry( LOG_STATUS, "[SQLCancel] lpstmt = $%08lX", lpstmt );
        if( NULL == lpstmt )
        {
                LogEntry( LOG_ERROR,      "[SQLCancel] NULL == lpstmt" );
                LogEntry( LOG_RETURNCODE, "[SQLCancel] SQL_INVALID_HANDLE" );
                return SQL_INVALID_HANDLE;
        }

        /*
        ** return success
        */
        LogEntry( LOG_RETURNCODE, "[SQLCancel] SQL_SUCCESS" );
        return SQL_SUCCESS;
}

/*===| end of file |=========================================================*/
