static HB_ERRCODE sqlbaseGoHot( SQLBASEAREAP pArea ) { PHB_ITEM pArray, pItem; HB_USHORT us; pArray = hb_itemArrayNew( pArea->area.uiFieldCount ); for( us = 1; us <= pArea->area.uiFieldCount; us++ ) { pItem = hb_itemNew( NULL ); if( SELF_GETVALUE( ( AREAP ) pArea, us, pItem ) == HB_SUCCESS ) hb_arraySetForward( pArray, us, pItem ); hb_itemRelease( pItem ); } pArea->pRecord = pArray; pArea->bRecordFlags |= SQLDD_FLAG_CACHED; pArea->fRecordChanged = HB_TRUE; return HB_SUCCESS; }
/* $Doc$ * $FuncName$ AddToArray( <pItem>, <pReturn>, <uiPos> ) * $Description$ Add <pItem> to array <pReturn> at pos <uiPos> * $End$ */ static void AddToArray( PHB_ITEM pItem, PHB_ITEM pReturn, ULONG ulPos ) { HB_ITEM_NEW( Temp ); HB_TRACE(HB_TR_DEBUG, ("AddToArray(%p, %p, %lu)", pItem, pReturn, ulPos)); if( pItem->type == HB_IT_SYMBOL ) { int iLen = strlen( pItem->item.asSymbol.value->szName ) + 2; char *sTemp = (char *) hb_xgrab( iLen + 1 ); hb_snprintf( sTemp, iLen + 1, "[%s]", pItem->item.asSymbol.value->szName ); hb_itemPutCPtr( &Temp, sTemp, iLen ); hb_arraySetForward( pReturn, ulPos, &Temp ); // hb_itemRelease( pTemp ); /* Get rid of temporary str.*/ } else /* Normal types */ { hb_arraySet( pReturn, ulPos, pItem ); } }
static HB_ERRCODE sqlbaseCreate( SQLBASEAREAP pArea, LPDBOPENINFO pOpenInfo ) { PHB_ITEM pItemEof, pItem; HB_USHORT uiCount; HB_BOOL bError; pArea->ulConnection = pOpenInfo->ulConnection ? pOpenInfo->ulConnection : s_ulConnectionCurrent; if( pArea->ulConnection > s_ulConnectionCount || ( pArea->ulConnection && ! s_pConnection[ pArea->ulConnection - 1 ] ) ) { hb_errRT_SQLBASE( EG_OPEN, ESQLDD_NOTCONNECTED, "Not connected", NULL ); return HB_FAILURE; } if( pArea->ulConnection ) { pArea->pConnection = s_pConnection[ pArea->ulConnection - 1 ]; pArea->pConnection->uiAreaCount++; pArea->pSDD = pArea->pConnection->pSDD; } else pArea->pSDD = &sddNull; pItemEof = hb_itemArrayNew( pArea->area.uiFieldCount ); bError = HB_FALSE; for( uiCount = 0; uiCount < pArea->area.uiFieldCount; uiCount++ ) { LPFIELD pField = pArea->area.lpFields + uiCount; switch( pField->uiType ) { case HB_FT_STRING: { char * pStr; pStr = ( char * ) hb_xgrab( pField->uiLen + 1 ); memset( pStr, ' ', pField->uiLen ); pStr[ pField->uiLen ] = '\0'; pItem = hb_itemPutCL( NULL, pStr, pField->uiLen ); hb_xfree( pStr ); break; } case HB_FT_MEMO: pItem = hb_itemPutC( NULL, NULL ); break; case HB_FT_INTEGER: if( pField->uiDec ) pItem = hb_itemPutND( NULL, 0.0 ); else pItem = hb_itemPutNI( NULL, 0 ); break; case HB_FT_LONG: if( pField->uiDec ) pItem = hb_itemPutND( NULL, 0.0 ); else pItem = hb_itemPutNL( NULL, 0 ); break; case HB_FT_FLOAT: pItem = hb_itemPutND( NULL, 0.0 ); break; case HB_FT_DOUBLE: pItem = hb_itemPutND( NULL, 0.0 ); break; case HB_FT_DATE: pItem = hb_itemPutDS( NULL, NULL ); break; case HB_FT_LOGICAL: pItem = hb_itemPutL( NULL, HB_FALSE ); break; default: pItem = hb_itemNew( NULL ); bError = HB_TRUE; break; } hb_arraySetForward( pItemEof, uiCount + 1, pItem ); hb_itemRelease( pItem ); if( bError ) break; } if( bError ) { hb_itemClear( pItemEof ); hb_itemRelease( pItemEof ); hb_errRT_SQLBASE( EG_CORRUPTION, ESQLDD_INVALIDFIELD, "Invalid field type", NULL ); SELF_CLOSE( ( AREAP ) pArea ); return HB_FAILURE; } pArea->ulRecCount = 0; pArea->pRow = ( void ** ) hb_xalloc( SQLDD_ROWSET_RESIZE * sizeof( void * ) ); pArea->pRowFlags = ( HB_BYTE * ) hb_xalloc( SQLDD_ROWSET_RESIZE * sizeof( HB_BYTE ) ); pArea->ulRecMax = SQLDD_ROWSET_RESIZE; *( pArea->pRow ) = pItemEof; pArea->pRowFlags[ 0 ] = SQLDD_FLAG_CACHED; pArea->fFetched = HB_TRUE; if( SUPER_CREATE( ( AREAP ) pArea, pOpenInfo ) != HB_SUCCESS ) { SELF_CLOSE( ( AREAP ) pArea ); return HB_FAILURE; } return SELF_GOTOP( ( AREAP ) pArea ); }
//------------------------------- // Manager of signals for windows // static LONG s_signalHandler( int type, int sig, PEXCEPTION_RECORD exc ) { PHB_ITEM pFunction, pExecArray, pRet; ULONG ulPos; UINT uiSig, uiMask; int iRet; // let's find the right signal handler. HB_CRITICAL_LOCK( s_ServiceMutex ); // avoid working if PRG signal handling has been disabled if ( ! bSignalEnabled ) { HB_CRITICAL_UNLOCK( s_ServiceMutex ); return EXCEPTION_EXECUTE_HANDLER; } bSignalEnabled = FALSE; ulPos = hb_arrayLen( sp_hooks ); // subsig not necessary uiSig = (UINT) s_translateSignal( (UINT)type, (UINT)sig ); while( ulPos > 0 ) { pFunction = hb_arrayGetItemPtr( sp_hooks, ulPos ); uiMask = (UINT) hb_arrayGetNI( pFunction, 1 ); if ( (uiMask & uiSig) == uiSig ) { // we don't unlock the mutex now, even if it is // a little dangerous. But we are in a signal hander... // for now just 2 parameters pExecArray = hb_itemArrayNew( 3 ); hb_arraySetForward( pExecArray, 1, hb_arrayGetItemPtr( pFunction, 2 ) ); hb_arraySetNI( pExecArray, 2, uiSig ); /* the third parameter is an array: * 1: low-level signal * 2: low-level subsignal * 3: low-level system error * 4: address that rised the signal * 5: process id of the signal riser * 6: UID of the riser */ pRet = hb_arrayGetItemPtr( pExecArray, 3); hb_arrayNew( pRet, 6 ); hb_arraySetNI( pRet, HB_SERVICE_OSSIGNAL, type ); hb_arraySetNI( pRet, HB_SERVICE_OSSUBSIG, sig ); //could be meaningless, but does not matter here hb_arraySetNI( pRet, HB_SERVICE_OSERROR, GetLastError() ); if (type == 0 ) //exception { hb_arraySetPtr( pRet, HB_SERVICE_ADDRESS, ( void * ) exc->ExceptionAddress ); } else { hb_arraySetPtr( pRet, HB_SERVICE_ADDRESS, NULL ); } //TODO: hb_arraySetNI( pRet, HB_SERVICE_PROCESS, GetCurrentThreadId() ); //TODO: hb_arraySetNI( pRet, HB_SERVICE_UID, 0 ); pRet = hb_itemDo( pExecArray, 0 ); iRet = hb_itemGetNI( pRet ); hb_itemRelease( pRet ); hb_itemRelease( pExecArray ); switch( iRet ) { case HB_SERVICE_HANDLED: bSignalEnabled = TRUE; HB_CRITICAL_UNLOCK( s_ServiceMutex ); return EXCEPTION_CONTINUE_EXECUTION; case HB_SERVICE_QUIT: bSignalEnabled = FALSE; HB_CRITICAL_UNLOCK( s_ServiceMutex ); hb_vmRequestQuit(); #ifndef HB_THREAD_SUPPORT hb_vmQuit(); exit(0); #else hb_threadCancelInternal(); #endif } } ulPos--; } bSignalEnabled = TRUE; return EXCEPTION_EXECUTE_HANDLER; }
static HB_ERRCODE pgsqlOpen( SQLBASEAREAP pArea ) { PGconn * pConn = ( ( SDDCONN * ) pArea->pConnection->pSDDConn )->pConn; SDDDATA * pSDDData; PGresult * pResult; ExecStatusType status; PHB_ITEM pItemEof, pItem; HB_USHORT uiFields, uiCount; HB_BOOL bError; DBFIELDINFO pFieldInfo; pArea->pSDDData = memset( hb_xgrab( sizeof( SDDDATA ) ), 0, sizeof( SDDDATA ) ); pSDDData = ( SDDDATA * ) pArea->pSDDData; pResult = PQexec( pConn, pArea->szQuery ); if( ! pResult ) { hb_errRT_PostgreSQLDD( EG_OPEN, ESQLDD_LOWMEMORY, "Query failed", NULL, 0 ); /* Low memory, etc */ return HB_FAILURE; } status = PQresultStatus( pResult ); if( status != PGRES_TUPLES_OK && status != PGRES_COMMAND_OK ) { hb_errRT_PostgreSQLDD( EG_OPEN, ESQLDD_INVALIDQUERY, PQresultErrorMessage( pResult ), pArea->szQuery, ( HB_ERRCODE ) status ); PQclear( pResult ); return HB_FAILURE; } pSDDData->pResult = pResult; uiFields = ( HB_USHORT ) PQnfields( pResult ); SELF_SETFIELDEXTENT( ( AREAP ) pArea, uiFields ); pItemEof = hb_itemArrayNew( uiFields ); pItem = hb_itemNew( NULL ); bError = HB_FALSE; for( uiCount = 0; uiCount < uiFields; uiCount++ ) { pFieldInfo.atomName = PQfname( pResult, ( int ) uiCount ); pFieldInfo.uiDec = 0; switch( PQftype( pResult, ( int ) uiCount ) ) { case BPCHAROID: case VARCHAROID: pFieldInfo.uiType = HB_FT_STRING; pFieldInfo.uiLen = ( HB_USHORT ) PQfmod( pResult, uiCount ) - 4; break; case TEXTOID: pFieldInfo.uiType = HB_FT_MEMO; pFieldInfo.uiLen = 10; break; case NUMERICOID: pFieldInfo.uiType = HB_FT_DOUBLE; pFieldInfo.uiLen = ( PQfmod( pResult, uiCount ) - 4 ) >> 16; pFieldInfo.uiDec = ( PQfmod( pResult, uiCount ) - 4 ) & 0xFFFF; break; case INT2OID: pFieldInfo.uiType = HB_FT_INTEGER; pFieldInfo.uiLen = 6; break; case INT4OID: pFieldInfo.uiType = HB_FT_INTEGER; pFieldInfo.uiLen = 11; break; case INT8OID: case OIDOID: pFieldInfo.uiType = HB_FT_LONG; pFieldInfo.uiLen = 20; break; case FLOAT4OID: case FLOAT8OID: case CASHOID: /* TODO: ??? */ pFieldInfo.uiType = HB_FT_DOUBLE; pFieldInfo.uiLen = 16; pFieldInfo.uiDec = 2; /* TODO: hb_set.SET_DECIMALS ??? */ break; case BOOLOID: pFieldInfo.uiType = HB_FT_LOGICAL; pFieldInfo.uiLen = 1; break; case DATEOID: pFieldInfo.uiType = HB_FT_DATE; pFieldInfo.uiLen = 8; break; case INETOID: pFieldInfo.uiType = HB_FT_STRING; pFieldInfo.uiLen = 29; break; case CIDROID: pFieldInfo.uiType = HB_FT_STRING; pFieldInfo.uiLen = 32; break; case MACADDROID: pFieldInfo.uiType = HB_FT_STRING; pFieldInfo.uiLen = 17; break; case BITOID: case VARBITOID: pFieldInfo.uiType = HB_FT_STRING; pFieldInfo.uiLen = ( HB_USHORT ) PQfsize( pResult, uiCount ); break; case TIMEOID: pFieldInfo.uiType = HB_FT_STRING; pFieldInfo.uiLen = 12; break; case TIMESTAMPOID: pFieldInfo.uiType = HB_FT_STRING; pFieldInfo.uiLen = 23; break; case TIMETZOID: pFieldInfo.uiType = HB_FT_STRING; pFieldInfo.uiLen = 15; break; case TIMESTAMPTZOID: pFieldInfo.uiType = HB_FT_STRING; pFieldInfo.uiLen = 26; break; case NAMEOID: pFieldInfo.uiType = HB_FT_STRING; pFieldInfo.uiLen = 63; break; case BYTEAOID: pFieldInfo.uiType = HB_FT_STRING; pFieldInfo.uiLen = 0; break; default: pFieldInfo.uiType = 0; pFieldInfo.uiLen = 0; bError = HB_TRUE; break; } /* printf( "field:%s \ttype:%d \tsize:%d \tformat:%d \tmod:%d err=%d\n", pFieldInfo.atomName, PQftype( pResult, ( int ) uiCount ), PQfsize( pResult, uiCount ), PQfformat( pResult, uiCount ) , PQfmod( pResult, uiCount ), bError ); */ if( ! bError ) { switch( pFieldInfo.uiType ) { case HB_FT_STRING: { char * pStr; pStr = ( char * ) hb_xgrab( pFieldInfo.uiLen + 1 ); memset( pStr, ' ', pFieldInfo.uiLen ); pStr[ pFieldInfo.uiLen ] = '\0'; hb_itemPutCL( pItem, pStr, pFieldInfo.uiLen ); hb_xfree( pStr ); break; } case HB_FT_MEMO: hb_itemPutC( pItem, NULL ); hb_itemSetCMemo( pItem ); break; case HB_FT_INTEGER: hb_itemPutNI( pItem, 0 ); break; case HB_FT_LONG: hb_itemPutNL( pItem, 0 ); break; case HB_FT_DOUBLE: hb_itemPutND( pItem, 0.0 ); break; case HB_FT_LOGICAL: hb_itemPutL( pItem, HB_FALSE ); break; case HB_FT_DATE: hb_itemPutDS( pItem, NULL ); break; default: hb_itemClear( pItem ); bError = HB_TRUE; break; } hb_arraySetForward( pItemEof, uiCount + 1, pItem ); /* if( pFieldInfo.uiType == HB_IT_DOUBLE || pFieldInfo.uiType == HB_IT_INTEGER ) pFieldInfo.uiType = HB_IT_LONG; */ if( ! bError ) bError = ( SELF_ADDFIELD( ( AREAP ) pArea, &pFieldInfo ) == HB_FAILURE ); } if( bError ) break; } hb_itemRelease( pItem ); if( bError ) { hb_itemClear( pItemEof ); hb_itemRelease( pItemEof ); hb_errRT_PostgreSQLDD( EG_CORRUPTION, ESQLDD_INVALIDFIELD, "Invalid field type", pArea->szQuery, 0 ); return HB_FAILURE; } pArea->ulRecCount = ( HB_ULONG ) PQntuples( pResult ); pArea->pRow = ( void ** ) hb_xgrab( ( pArea->ulRecCount + 1 ) * sizeof( void * ) ); pArea->pRowFlags = ( HB_BYTE * ) hb_xgrab( ( pArea->ulRecCount + 1 ) * sizeof( HB_BYTE ) ); memset( pArea->pRowFlags, 0, ( pArea->ulRecCount + 1 ) * sizeof( HB_BYTE ) ); *pArea->pRow = pItemEof; pArea->pRowFlags[ 0 ] = SQLDD_FLAG_CACHED; pArea->fFetched = HB_TRUE; return HB_SUCCESS; }
static HB_ERRCODE sqlite3GoTo( SQLBASEAREAP pArea, HB_ULONG ulRecNo ) { sqlite3_stmt * st = ( ( SDDDATA * ) pArea->pSDDData )->pStmt; while( ulRecNo > pArea->ulRecCount && ! pArea->fFetched ) { PHB_ITEM pArray; HB_USHORT ui; pArray = hb_itemArrayNew( pArea->area.uiFieldCount ); for( ui = 0; ui < pArea->area.uiFieldCount; ++ui ) { PHB_ITEM pItem = NULL; LPFIELD pField = pArea->area.lpFields + ui; HB_USHORT uiType = pField->uiType; if( uiType == HB_FT_ANY ) { switch( sqlite3_column_type( st, ui ) ) { case SQLITE_TEXT: uiType = HB_FT_STRING; break; case SQLITE_FLOAT: case SQLITE_INTEGER: uiType = HB_FT_LONG; break; case SQLITE_BLOB: uiType = HB_FT_BLOB; break; } } switch( uiType ) { case HB_FT_STRING: pItem = S_HB_ITEMPUTSTR( NULL, ( const char * ) sqlite3_column_text( st, ui ) ); break; case HB_FT_INTEGER: #if HB_VMLONG_MAX > INT32_MAX && ! defined( HB_LONG_LONG_OFF ) pItem = hb_itemPutNInt( NULL, sqlite3_column_int64( st, ui ) ); break; #endif case HB_FT_LONG: pItem = hb_itemPutNDDec( NULL, sqlite3_column_double( st, ui ), pField->uiDec ); break; case HB_FT_BLOB: pItem = hb_itemPutCL( NULL, ( const char * ) sqlite3_column_blob( st, ui ), sqlite3_column_bytes( st, ui ) ); break; } if( pItem ) { hb_arraySetForward( pArray, ui + 1, pItem ); hb_itemRelease( pItem ); } } if( pArea->ulRecCount + 1 >= pArea->ulRecMax ) { pArea->pRow = ( void ** ) hb_xrealloc( pArea->pRow, ( pArea->ulRecMax + SQLDD_ROWSET_RESIZE ) * sizeof( void * ) ); pArea->pRowFlags = ( HB_BYTE * ) hb_xrealloc( pArea->pRowFlags, ( pArea->ulRecMax + SQLDD_ROWSET_RESIZE ) * sizeof( HB_BYTE ) ); pArea->ulRecMax += SQLDD_ROWSET_RESIZE; } pArea->ulRecCount++; pArea->pRow[ pArea->ulRecCount ] = pArray; pArea->pRowFlags[ pArea->ulRecCount ] = SQLDD_FLAG_CACHED; if( sqlite3_step( st ) != SQLITE_ROW ) { pArea->fFetched = HB_TRUE; break; } } if( ulRecNo == 0 || ulRecNo > pArea->ulRecCount ) { pArea->pRecord = pArea->pRow[ 0 ]; pArea->bRecordFlags = pArea->pRowFlags[ 0 ]; pArea->fPositioned = HB_FALSE; } else { pArea->pRecord = pArea->pRow[ ulRecNo ]; pArea->bRecordFlags = pArea->pRowFlags[ ulRecNo ]; pArea->fPositioned = HB_TRUE; } return HB_SUCCESS; }
static HB_ERRCODE sqlite3GoTo( SQLBASEAREAP pArea, HB_ULONG ulRecNo ) { sqlite3_stmt * st = ( ( SDDDATA * ) pArea->pSDDData )->pStmt; while( ulRecNo > pArea->ulRecCount && ! pArea->fFetched ) { PHB_ITEM pArray; HB_USHORT ui; if( sqlite3_step( st ) != SQLITE_ROW ) { pArea->fFetched = HB_TRUE; break; } pArray = hb_itemArrayNew( pArea->area.uiFieldCount ); for( ui = 0; ui < pArea->area.uiFieldCount; ++ui ) { PHB_ITEM pItem = NULL; LPFIELD pField = pArea->area.lpFields + ui; switch( pField->uiType ) { case HB_FT_STRING: pItem = S_HB_ITEMPUTSTR( NULL, ( const char * ) sqlite3_column_text( st, ui ) ); break; case HB_FT_LONG: case HB_FT_INTEGER: if( pField->uiDec == 0 ) #if HB_VMLONG_MAX == INT32_MAX || defined( HB_LONG_LONG_OFF ) pItem = hb_itemPutNIntLen( NULL, sqlite3_column_int( st, ui ), pField->uiLen ); #else pItem = hb_itemPutNIntLen( NULL, sqlite3_column_int64( st, ui ), pField->uiLen ); #endif else pItem = hb_itemPutNDLen( NULL, sqlite3_column_double( st, ui ), pField->uiLen, pField->uiDec ); break; case HB_FT_BLOB: pItem = hb_itemPutCL( NULL, ( const char * ) sqlite3_column_blob( st, ui ), sqlite3_column_bytes( st, ui ) ); break; } if( pItem ) { hb_arraySetForward( pArray, ui + 1, pItem ); hb_itemRelease( pItem ); } } if( pArea->ulRecCount + 1 <= pArea->ulRecMax ) { pArea->pRow = ( void ** ) hb_xrealloc( pArea->pRow, ( pArea->ulRecMax + SQLDD_ROWSET_RESIZE ) * sizeof( void * ) ); pArea->pRowFlags = ( HB_BYTE * ) hb_xrealloc( pArea->pRowFlags, ( pArea->ulRecMax + SQLDD_ROWSET_RESIZE ) * sizeof( HB_BYTE ) ); pArea->ulRecMax += SQLDD_ROWSET_RESIZE; } pArea->ulRecCount++; pArea->pRow[ pArea->ulRecCount ] = pArray; pArea->pRowFlags[ pArea->ulRecCount ] = SQLDD_FLAG_CACHED; }
static HB_ERRCODE sqlite3Open( SQLBASEAREAP pArea ) { sqlite3 * pDb = ( ( SDDCONN * ) pArea->pConnection->pSDDConn )->pDb; sqlite3_stmt * st = NULL; SDDDATA * pSDDData; const char * pszQuery; HB_SIZE nQueryLen; void * hQuery; HB_USHORT uiFields, uiIndex; PHB_ITEM pItemEof, pItem; HB_ERRCODE errCode; char * szError; HB_BOOL bError; pArea->pSDDData = memset( hb_xgrab( sizeof( SDDDATA ) ), 0, sizeof( SDDDATA ) ); pSDDData = ( SDDDATA * ) pArea->pSDDData; pItem = hb_itemPutC( NULL, pArea->szQuery ); pszQuery = S_HB_ITEMGETSTR( pItem, &hQuery, &nQueryLen ); if( sqlite3_prepare_v2( pDb, pszQuery, ( int ) nQueryLen, &st, NULL ) != SQLITE_OK ) { hb_strfree( hQuery ); hb_itemRelease( pItem ); szError = sqlite3GetError( pDb, &errCode ); hb_errRT_SQLT3DD( EG_OPEN, ESQLDD_INVALIDQUERY, szError, pArea->szQuery, errCode ); sqlite3_finalize( st ); hb_xfree( szError ); return HB_FAILURE; } else { hb_strfree( hQuery ); hb_itemRelease( pItem ); } if( sqlite3_step( st ) != SQLITE_ROW ) { szError = sqlite3GetError( pDb, &errCode ); hb_errRT_SQLT3DD( EG_OPEN, ESQLDD_INVALIDQUERY, szError, pArea->szQuery, errCode ); sqlite3_finalize( st ); hb_xfree( szError ); return HB_FAILURE; } uiFields = ( HB_USHORT ) sqlite3_column_count( st ); SELF_SETFIELDEXTENT( ( AREAP ) pArea, uiFields ); pItemEof = hb_itemArrayNew( uiFields ); /* HB_TRACE( HB_TR_ALWAYS, ("fieldcount=%d", iNameLen) ); */ errCode = 0; bError = HB_FALSE; for( uiIndex = 0; uiIndex < uiFields; ++uiIndex ) { DBFIELDINFO pFieldInfo; PHB_ITEM pName; int iDataType; int iSize; int iDec; pName = S_HB_ITEMPUTSTR( NULL, sqlite3_column_name( st, uiIndex ) ); pFieldInfo.atomName = hb_itemGetCPtr( pName ); iDataType = sqlite3_column_type( st, uiIndex ); iSize = sqlite3_column_bytes( st, uiIndex ); iDec = 0; pFieldInfo.uiLen = ( HB_USHORT ) iSize; pFieldInfo.uiDec = ( HB_USHORT ) iDec; /* HB_TRACE( HB_TR_ALWAYS, ("field: name=%s type=%d len=%d dec=%d nullable=%d", pFieldInfo.atomName, iDataType, iSize, iDec ) ); */ switch( iDataType ) { case SQLITE_TEXT: pFieldInfo.uiType = HB_FT_STRING; break; case SQLITE_FLOAT: case SQLITE_INTEGER: pFieldInfo.uiType = HB_FT_LONG; break; case SQLITE_BLOB: pFieldInfo.uiType = HB_FT_BLOB; break; default: /* HB_TRACE( HB_TR_ALWAYS, ("new sql type=%d", iDataType) ); */ bError = HB_TRUE; errCode = ( HB_ERRCODE ) iDataType; pFieldInfo.uiType = 0; pFieldInfo.uiType = HB_FT_STRING; break; } if( ! bError ) { switch( pFieldInfo.uiType ) { case HB_FT_STRING: { char * pStr = ( char * ) hb_xgrab( ( HB_SIZE ) pFieldInfo.uiLen + 1 ); memset( pStr, ' ', pFieldInfo.uiLen ); pStr[ pFieldInfo.uiLen ] = '\0'; pItem = hb_itemPutCLPtr( NULL, pStr, pFieldInfo.uiLen ); break; } case HB_FT_BLOB: pItem = hb_itemPutC( NULL, NULL ); break; case HB_FT_LONG: if( pFieldInfo.uiDec == 0 ) pItem = hb_itemPutNLLen( NULL, 0, pFieldInfo.uiLen ); else pItem = hb_itemPutNDLen( NULL, 0.0, pFieldInfo.uiLen, pFieldInfo.uiDec ); break; default: pItem = hb_itemNew( NULL ); bError = HB_TRUE; } hb_arraySetForward( pItemEof, uiIndex + 1, pItem ); hb_itemRelease( pItem ); if( ! bError ) bError = ( SELF_ADDFIELD( ( AREAP ) pArea, &pFieldInfo ) == HB_FAILURE ); } hb_itemRelease( pName ); if( bError ) break; } if( bError ) { hb_itemRelease( pItemEof ); sqlite3_finalize( st ); hb_errRT_SQLT3DD( EG_CORRUPTION, ESQLDD_INVALIDFIELD, "Invalid field type", pArea->szQuery, errCode ); return HB_FAILURE; } pArea->ulRecCount = 0; pArea->ulRecMax = SQLDD_ROWSET_INIT; pArea->pRow = ( void ** ) hb_xgrab( SQLDD_ROWSET_INIT * sizeof( void * ) ); memset( pArea->pRow, 0, SQLDD_ROWSET_INIT * sizeof( void * ) ); pArea->pRowFlags = ( HB_BYTE * ) hb_xgrab( SQLDD_ROWSET_INIT * sizeof( HB_BYTE ) ); memset( pArea->pRowFlags, 0, SQLDD_ROWSET_INIT * sizeof( HB_BYTE ) ); pArea->pRow[ 0 ] = pItemEof; pArea->pRowFlags[ 0 ] = SQLDD_FLAG_CACHED; pSDDData->pStmt = st; return HB_SUCCESS; }
static HB_ERRCODE sqlite3Open( SQLBASEAREAP pArea ) { sqlite3 * pDb = ( ( SDDCONN * ) pArea->pConnection->pSDDConn )->pDb; sqlite3_stmt * st = NULL; SDDDATA * pSDDData; const char * pszQuery; HB_SIZE nQueryLen; void * hQuery; HB_USHORT uiFields, uiIndex; PHB_ITEM pItemEof, pItem; HB_ERRCODE errCode; char * szError; HB_BOOL bError; pArea->pSDDData = memset( hb_xgrab( sizeof( SDDDATA ) ), 0, sizeof( SDDDATA ) ); pSDDData = ( SDDDATA * ) pArea->pSDDData; pItem = hb_itemPutC( NULL, pArea->szQuery ); pszQuery = S_HB_ITEMGETSTR( pItem, &hQuery, &nQueryLen ); if( sqlite3_prepare_v2( pDb, pszQuery, ( int ) nQueryLen, &st, NULL ) != SQLITE_OK ) { hb_strfree( hQuery ); hb_itemRelease( pItem ); szError = sqlite3GetError( pDb, &errCode ); hb_errRT_SQLT3DD( EG_OPEN, ESQLDD_INVALIDQUERY, szError, pArea->szQuery, errCode ); sqlite3_finalize( st ); hb_xfree( szError ); return HB_FAILURE; } else { hb_strfree( hQuery ); hb_itemRelease( pItem ); } if( sqlite3_step( st ) != SQLITE_ROW ) { szError = sqlite3GetError( pDb, &errCode ); hb_errRT_SQLT3DD( EG_OPEN, ESQLDD_INVALIDQUERY, szError, pArea->szQuery, errCode ); sqlite3_finalize( st ); hb_xfree( szError ); return HB_FAILURE; } uiFields = ( HB_USHORT ) sqlite3_column_count( st ); SELF_SETFIELDEXTENT( ( AREAP ) pArea, uiFields ); pItemEof = hb_itemArrayNew( uiFields ); #if 0 HB_TRACE( HB_TR_ALWAYS, ( "fieldcount=%d", uiFields ) ); #endif errCode = 0; bError = HB_FALSE; for( uiIndex = 0; uiIndex < uiFields; ++uiIndex ) { DBFIELDINFO pFieldInfo; int iDataType = sqlite3_column_type( st, uiIndex ); PHB_ITEM pName = S_HB_ITEMPUTSTR( NULL, sqlite3_column_name( st, uiIndex ) ); HB_USHORT uiNameLen = ( HB_USHORT ) hb_itemGetCLen( pName ); if( ( ( AREAP ) pArea )->uiMaxFieldNameLength < uiNameLen ) ( ( AREAP ) pArea )->uiMaxFieldNameLength = uiNameLen; pFieldInfo.atomName = hb_itemGetCPtr( pName ); #if 0 HB_TRACE( HB_TR_ALWAYS, ( "field: name=%s type=%d len=%d", pFieldInfo.atomName, iDataType, sqlite3_column_bytes( st, uiIndex ) ) ); #endif /* There are no field length limits stored in the SQLite3 database, so we're resorting to setting some arbitrary default values to make apps relying on these (f.e. Browse()/GET) to behave somewhat better. For better results, update apps to untie UI metrics from any database field/value widths. [vszakats] */ pFieldInfo.uiLen = 10; pFieldInfo.uiDec = 0; switch( iDataType ) { case SQLITE3_TEXT: pFieldInfo.uiType = HB_FT_STRING; break; case SQLITE_FLOAT: pFieldInfo.uiType = HB_FT_LONG; pFieldInfo.uiDec = ( HB_USHORT ) hb_setGetDecimals(); pFieldInfo.uiLen += pFieldInfo.uiDec + 1; break; case SQLITE_INTEGER: pFieldInfo.uiType = HB_FT_LONG; break; case SQLITE_BLOB: case SQLITE_NULL: pFieldInfo.uiType = HB_FT_BLOB; break; default: #if 0 HB_TRACE( HB_TR_ALWAYS, ( "new sql type=%d", iDataType ) ); #endif bError = HB_TRUE; errCode = ( HB_ERRCODE ) iDataType; pFieldInfo.uiType = 0; break; } if( ! bError ) { switch( pFieldInfo.uiType ) { case HB_FT_STRING: { char * pStr = ( char * ) hb_xgrab( ( HB_SIZE ) pFieldInfo.uiLen + 1 ); memset( pStr, ' ', pFieldInfo.uiLen ); pStr[ pFieldInfo.uiLen ] = '\0'; pItem = hb_itemPutCLPtr( NULL, pStr, pFieldInfo.uiLen ); break; } case HB_FT_BLOB: pItem = hb_itemPutC( NULL, NULL ); break; case HB_FT_LONG: if( pFieldInfo.uiDec == 0 ) pItem = hb_itemPutNLLen( NULL, 0, pFieldInfo.uiLen ); else pItem = hb_itemPutNDLen( NULL, 0.0, pFieldInfo.uiLen, pFieldInfo.uiDec ); break; default: pItem = hb_itemNew( NULL ); bError = HB_TRUE; } hb_arraySetForward( pItemEof, uiIndex + 1, pItem ); hb_itemRelease( pItem ); if( ! bError ) bError = ( SELF_ADDFIELD( ( AREAP ) pArea, &pFieldInfo ) == HB_FAILURE ); } hb_itemRelease( pName ); if( bError ) break; } if( bError ) { hb_itemRelease( pItemEof ); sqlite3_finalize( st ); hb_errRT_SQLT3DD( EG_CORRUPTION, ESQLDD_INVALIDFIELD, "Invalid field type", pArea->szQuery, errCode ); return HB_FAILURE; } pArea->ulRecCount = 0; pArea->ulRecMax = SQLDD_ROWSET_INIT; pArea->pRow = ( void ** ) hb_xgrabz( SQLDD_ROWSET_INIT * sizeof( void * ) ); pArea->pRowFlags = ( HB_BYTE * ) hb_xgrabz( SQLDD_ROWSET_INIT * sizeof( HB_BYTE ) ); pArea->pRow[ 0 ] = pItemEof; pArea->pRowFlags[ 0 ] = SQLDD_FLAG_CACHED; pSDDData->pStmt = st; return HB_SUCCESS; }
static HB_ERRCODE odbcGoTo( SQLBASEAREAP pArea, HB_ULONG ulRecNo ) { SQLHSTMT hStmt; SQLRETURN res; SQLLEN iLen; PHB_ITEM pArray, pItem; LPFIELD pField; HB_USHORT ui; /* No pArea->pSDDData for DBCreate() area... * though pArea->fFetched == HB_TRUE for them */ hStmt = pArea->pSDDData ? ( ( SDDDATA * ) pArea->pSDDData )->hStmt : NULL; while( ulRecNo > pArea->ulRecCount && ! pArea->fFetched ) { if( ! SQL_SUCCEEDED( SQLFetch( hStmt ) ) ) { pArea->fFetched = HB_TRUE; break; } pArray = hb_itemArrayNew( pArea->area.uiFieldCount ); pItem = NULL; for( ui = 1; ui <= pArea->area.uiFieldCount; ui++ ) { iLen = SQL_NULL_DATA; res = 0; pField = pArea->area.lpFields + ui - 1; switch( pField->uiType ) { case HB_FT_STRING: if( pField->uiType & HB_FF_BINARY ) { char buffer[ 1 ]; iLen = 0; if( SQL_SUCCEEDED( res = SQLGetData( hStmt, ui, SQL_C_BINARY, buffer, 0, &iLen ) ) ) { if( iLen >= 0 ) { char * val = ( char * ) hb_xgrab( iLen + 1 ); if( SQL_SUCCEEDED( res = SQLGetData( hStmt, ui, SQL_C_BINARY, val, iLen + 1, &iLen ) ) ) pItem = hb_itemPutCLPtr( pItem, val, ( HB_SIZE ) iLen ); else hb_xfree( val ); } } } else { O_HB_CHAR buffer[ 1 ]; #if defined( UNICODE ) SQLSMALLINT iTargetType = SQL_C_WCHAR; #else SQLSMALLINT iTargetType = SQL_C_CHAR; #endif iLen = 0; if( SQL_SUCCEEDED( res = SQLGetData( hStmt, ui, iTargetType, buffer, 0, &iLen ) ) ) { if( iLen >= 0 ) { O_HB_CHAR * val = ( O_HB_CHAR * ) hb_xgrab( iLen + sizeof( O_HB_CHAR ) ); if( SQL_SUCCEEDED( res = SQLGetData( hStmt, ui, iTargetType, val, iLen + sizeof( O_HB_CHAR ), &iLen ) ) ) { #if defined( UNICODE ) iLen >>= 1; #endif pItem = O_HB_ITEMPUTSTRLEN( pItem, val, ( HB_SIZE ) iLen ); } hb_xfree( val ); } } } break; case HB_FT_INTEGER: #if ODBCVER >= 0x0300 if( pField->uiTypeExtended == ( HB_USHORT ) SQL_BIGINT ) { HB_I64 val = 0; /* NOTE: SQL_C_SBIGINT not available before ODBC 3.0 */ if( SQL_SUCCEEDED( res = SQLGetData( hStmt, ui, SQL_C_SBIGINT, &val, sizeof( val ), &iLen ) ) ) pItem = hb_itemPutNIntLen( pItem, val, pField->uiLen ); } else #endif { SQLINTEGER val = 0; if( SQL_SUCCEEDED( res = SQLGetData( hStmt, ui, SQL_C_LONG, &val, sizeof( val ), &iLen ) ) ) pItem = hb_itemPutNLLen( pItem, val, pField->uiLen ); } break; case HB_FT_LONG: if( pField->uiDec == 0 && pField->uiLen < 10 ) { SQLINTEGER val = 0; if( SQL_SUCCEEDED( res = SQLGetData( hStmt, ui, SQL_C_LONG, &val, sizeof( val ), &iLen ) ) ) pItem = hb_itemPutNLLen( pItem, val, pField->uiLen ); } else { double val = 0.0; if( SQL_SUCCEEDED( res = SQLGetData( hStmt, ui, SQL_C_DOUBLE, &val, sizeof( val ), &iLen ) ) ) pItem = hb_itemPutNDLen( pItem, val, pField->uiLen, pField->uiDec ); } break; case HB_FT_DOUBLE: { double val = 0.0; if( SQL_SUCCEEDED( res = SQLGetData( hStmt, ui, SQL_C_DOUBLE, &val, sizeof( val ), &iLen ) ) ) pItem = hb_itemPutNDLen( pItem, val, pField->uiLen, pField->uiDec ); break; } case HB_FT_LOGICAL: { unsigned char val = 0; if( SQL_SUCCEEDED( res = SQLGetData( hStmt, ui, SQL_C_BIT, &val, sizeof( val ), &iLen ) ) ) pItem = hb_itemPutL( pItem, val != 0 ); break; } case HB_FT_DATE: { DATE_STRUCT val = { 0, 0, 0 }; if( SQL_SUCCEEDED( res = SQLGetData( hStmt, ui, SQL_C_DATE, &val, sizeof( val ), &iLen ) ) ) pItem = hb_itemPutD( pItem, val.year, val.month, val.day ); break; } case HB_FT_TIME: { TIME_STRUCT val = { 0, 0, 0 }; if( SQL_SUCCEEDED( res = SQLGetData( hStmt, ui, SQL_C_TIME, &val, sizeof( val ), &iLen ) ) ) pItem = hb_itemPutTDT( pItem, 0, hb_timeEncode( val.hour, val.minute, val.second, 0 ) ); break; } case HB_FT_TIMESTAMP: { TIMESTAMP_STRUCT val = { 0, 0, 0, 0, 0, 0, 0 }; if( SQL_SUCCEEDED( res = SQLGetData( hStmt, ui, SQL_C_TIMESTAMP, &val, sizeof( val ), &iLen ) ) ) pItem = hb_itemPutTDT( pItem, hb_dateEncode( val.year, val.month, val.day ), hb_timeEncode( val.hour, val.minute, val.second, val.fraction / 1000000 ) ); break; } } /* TODO: check SQL_SUCCEEDED( res ) */ /* TODO: check for SQL_NO_TOTAL. What does this mean? */ HB_SYMBOL_UNUSED( res ); if( pItem ) { /* NULL -> NIL */ if( iLen == SQL_NULL_DATA ) hb_itemClear( pItem ); else hb_arraySetForward( pArray, ui, pItem ); } } if( pItem ) hb_itemRelease( pItem ); if( pArea->ulRecCount + 1 >= pArea->ulRecMax ) { pArea->pRow = ( void ** ) hb_xrealloc( pArea->pRow, ( pArea->ulRecMax + SQLDD_ROWSET_RESIZE ) * sizeof( void * ) ); pArea->pRowFlags = ( HB_BYTE * ) hb_xrealloc( pArea->pRowFlags, ( pArea->ulRecMax + SQLDD_ROWSET_RESIZE ) * sizeof( HB_BYTE ) ); pArea->ulRecMax += SQLDD_ROWSET_RESIZE; } pArea->ulRecCount++; pArea->pRow[ pArea->ulRecCount ] = pArray; pArea->pRowFlags[ pArea->ulRecCount ] = SQLDD_FLAG_CACHED; }
static HB_ERRCODE odbcOpen( SQLBASEAREAP pArea ) { SDDCONN * pSDDConn = ( SDDCONN * ) pArea->pConnection->pSDDConn; SDDDATA * pSDDData; O_HB_CHAR * pchQuery; SQLHSTMT hStmt; SQLSMALLINT iNameLen; PHB_ITEM pItemEof, pItem; HB_BOOL bError; HB_USHORT uiFields, uiIndex; HB_ERRCODE errCode; char * szError; SQLRETURN result; pArea->pSDDData = memset( hb_xgrab( sizeof( SDDDATA ) ), 0, sizeof( SDDDATA ) ); pSDDData = ( SDDDATA * ) pArea->pSDDData; #if ODBCVER >= 0x0300 if( ! SQL_SUCCEEDED( SQLAllocHandle( SQL_HANDLE_STMT, pSDDConn->hConn, &hStmt ) ) ) #else if( ! SQL_SUCCEEDED( SQLAllocStmt( pSDDConn->hConn, &hStmt ) ) ) #endif { szError = odbcGetError( pSDDConn->hEnv, pSDDConn->hConn, SQL_NULL_HSTMT, &errCode ); hb_errRT_ODBCDD( EG_OPEN, ESQLDD_STMTALLOC, szError, pArea->szQuery, errCode ); hb_xfree( szError ); return HB_FAILURE; } pchQuery = O_HB_CHARDUP( pArea->szQuery ); result = SQLExecDirect( hStmt, ( SQLTCHAR * ) HB_UNCONST( pchQuery ), ( SQLINTEGER ) O_HB_STRLEN( pchQuery ) ); hb_xfree( pchQuery ); if( ! SQL_SUCCEEDED( result ) ) { szError = odbcGetError( pSDDConn->hEnv, pSDDConn->hConn, hStmt, &errCode ); #if ODBCVER >= 0x0300 SQLFreeHandle( SQL_HANDLE_STMT, hStmt ); #else SQLFreeStmt( hStmt, SQL_DROP ); #endif hb_errRT_ODBCDD( EG_OPEN, ESQLDD_INVALIDQUERY, szError, pArea->szQuery, errCode ); hb_xfree( szError ); return HB_FAILURE; } if( ! SQL_SUCCEEDED( SQLNumResultCols( hStmt, &iNameLen ) ) ) { szError = odbcGetError( pSDDConn->hEnv, pSDDConn->hConn, hStmt, &errCode ); #if ODBCVER >= 0x0300 SQLFreeHandle( SQL_HANDLE_STMT, hStmt ); #else SQLFreeStmt( hStmt, SQL_DROP ); #endif hb_errRT_ODBCDD( EG_OPEN, ESQLDD_STMTDESCR + 1000, szError, pArea->szQuery, errCode ); hb_xfree( szError ); return HB_FAILURE; } uiFields = ( HB_USHORT ) iNameLen; SELF_SETFIELDEXTENT( &pArea->area, uiFields ); pItemEof = hb_itemArrayNew( uiFields ); pItem = hb_itemNew( NULL ); #if 0 HB_TRACE( HB_TR_ALWAYS, ( "fieldcount=%d", iNameLen ) ); #endif errCode = 0; bError = HB_FALSE; for( uiIndex = 0; uiIndex < uiFields; uiIndex++ ) { DBFIELDINFO dbFieldInfo; char * pszName; SQLTCHAR cName[ 256 ]; SQLULEN uiSize; SQLSMALLINT iDataType, iDec, iNull; if( ! SQL_SUCCEEDED( SQLDescribeCol( hStmt, ( SQLSMALLINT ) uiIndex + 1, cName, HB_SIZEOFARRAY( cName ), &iNameLen, &iDataType, &uiSize, &iDec, &iNull ) ) ) { hb_itemRelease( pItemEof ); hb_itemRelease( pItem ); szError = odbcGetError( pSDDConn->hEnv, pSDDConn->hConn, hStmt, NULL ); #if ODBCVER >= 0x0300 SQLFreeHandle( SQL_HANDLE_STMT, hStmt ); #else SQLFreeStmt( hStmt, SQL_DROP ); #endif hb_errRT_ODBCDD( EG_OPEN, ESQLDD_STMTDESCR + 1001, szError, pArea->szQuery, 0 ); hb_xfree( szError ); return HB_FAILURE; } memset( &dbFieldInfo, 0, sizeof( dbFieldInfo ) ); dbFieldInfo.atomName = pszName = O_HB_OSSTRDUP( ( O_HB_CHAR * ) cName ); /* We do mapping of many SQL types to one Harbour field type here, so, we need store real SQL type in uiTypeExtended. SQL types are signed, so, HB_USHORT type casting is a little hackish. We need to remember use this casting also in expressions like this: if( pField->uiTypeExtended == ( HB_USHORT ) SQL_BIGINT ) or introduce our own unsigned SQL types. [Mindaugas] */ dbFieldInfo.uiTypeExtended = ( HB_USHORT ) iDataType; dbFieldInfo.uiLen = ( HB_USHORT ) uiSize; dbFieldInfo.uiDec = iDec; if( iNull == SQL_NULLABLE ) dbFieldInfo.uiFlags |= HB_FF_NULLABLE; #if 0 HB_TRACE( HB_TR_ALWAYS, ( "field: name=%s type=%d len=%d dec=%d null=%d", dbFieldInfo.atomName, iDataType, uiSize, iDec, iNull ) ); #endif switch( iDataType ) { case SQL_CHAR: case SQL_VARCHAR: case SQL_LONGVARCHAR: dbFieldInfo.uiType = HB_FT_STRING; break; case SQL_WCHAR: case SQL_WVARCHAR: case SQL_WLONGVARCHAR: dbFieldInfo.uiType = HB_FT_STRING; dbFieldInfo.uiFlags |= HB_FF_UNICODE; break; case SQL_BINARY: case SQL_VARBINARY: case SQL_LONGVARBINARY: dbFieldInfo.uiType = HB_FT_STRING; dbFieldInfo.uiFlags |= HB_FF_BINARY; break; case SQL_TINYINT: case SQL_SMALLINT: case SQL_INTEGER: case SQL_BIGINT: dbFieldInfo.uiType = HB_FT_INTEGER; break; case SQL_DECIMAL: case SQL_NUMERIC: dbFieldInfo.uiType = HB_FT_LONG; break; case SQL_REAL: case SQL_FLOAT: case SQL_DOUBLE: dbFieldInfo.uiType = HB_FT_DOUBLE; break; case SQL_BIT: dbFieldInfo.uiType = HB_FT_LOGICAL; break; case SQL_DATE: #if ODBCVER >= 0x0300 case SQL_TYPE_DATE: #endif dbFieldInfo.uiType = HB_FT_DATE; break; case SQL_TIME: #if ODBCVER >= 0x0300 case SQL_TYPE_TIME: #endif dbFieldInfo.uiType = HB_FT_TIME; break; /* SQL_DATETIME = SQL_DATE = 9 */ case SQL_TIMESTAMP: #if ODBCVER >= 0x0300 case SQL_TYPE_TIMESTAMP: #endif dbFieldInfo.uiType = HB_FT_TIMESTAMP; break; default: #if 0 HB_TRACE( HB_TR_ALWAYS, ( "new sql type=%d", iDataType ) ); #endif bError = HB_TRUE; errCode = ( HB_ERRCODE ) iDataType; break; } if( ! bError ) { switch( dbFieldInfo.uiType ) { case HB_FT_STRING: { char * pStr; pStr = ( char * ) hb_xgrab( ( HB_SIZE ) dbFieldInfo.uiLen + 1 ); memset( pStr, ' ', dbFieldInfo.uiLen ); pStr[ dbFieldInfo.uiLen ] = '\0'; hb_itemPutCL( pItem, pStr, dbFieldInfo.uiLen ); hb_xfree( pStr ); break; } case HB_FT_MEMO: hb_itemPutC( pItem, NULL ); break; case HB_FT_INTEGER: hb_itemPutNI( pItem, 0 ); break; case HB_FT_LONG: if( dbFieldInfo.uiDec == 0 ) hb_itemPutNLLen( pItem, 0, dbFieldInfo.uiLen ); else hb_itemPutNDLen( pItem, 0.0, dbFieldInfo.uiLen, dbFieldInfo.uiDec ); break; case HB_FT_DOUBLE: hb_itemPutNDLen( pItem, 0.0, dbFieldInfo.uiLen, dbFieldInfo.uiDec ); break; case HB_FT_LOGICAL: hb_itemPutL( pItem, HB_FALSE ); break; case HB_FT_DATE: hb_itemPutDL( pItem, 0 ); break; case HB_FT_TIME: hb_itemPutTDT( pItem, 0, 0 ); break; case HB_FT_TIMESTAMP: hb_itemPutTDT( pItem, 0, 0 ); break; default: hb_itemClear( pItem ); bError = HB_TRUE; break; } hb_arraySetForward( pItemEof, uiIndex + 1, pItem ); if( ! bError ) bError = ( SELF_ADDFIELD( &pArea->area, &dbFieldInfo ) == HB_FAILURE ); hb_xfree( pszName ); } if( bError ) break; } hb_itemRelease( pItem ); if( bError ) { hb_itemRelease( pItemEof ); #if ODBCVER >= 0x0300 SQLFreeHandle( SQL_HANDLE_STMT, hStmt ); #else SQLFreeStmt( hStmt, SQL_DROP ); #endif hb_errRT_ODBCDD( EG_CORRUPTION, ESQLDD_INVALIDFIELD, "Invalid field type", pArea->szQuery, errCode ); return HB_FAILURE; } pArea->ulRecCount = 0; pArea->ulRecMax = SQLDD_ROWSET_INIT; pArea->pRow = ( void ** ) hb_xgrab( SQLDD_ROWSET_INIT * sizeof( void * ) ); pArea->pRowFlags = ( HB_BYTE * ) hb_xgrab( SQLDD_ROWSET_INIT * sizeof( HB_BYTE ) ); pArea->pRow[ 0 ] = pItemEof; pArea->pRowFlags[ 0 ] = SQLDD_FLAG_CACHED; pSDDData->hStmt = hStmt; return HB_SUCCESS; }
static HB_ERRCODE mysqlOpen( SQLBASEAREAP pArea ) { MYSQL * pMySql = ( ( SDDCONN * ) pArea->pConnection->pSDDConn )->pMySql; SDDDATA * pSDDData; PHB_ITEM pItemEof, pItem; HB_ULONG ulIndex; HB_USHORT uiFields, uiCount; HB_ERRCODE errCode = 0; HB_BOOL bError; DBFIELDINFO pFieldInfo; MYSQL_FIELD * pMyField; void ** pRow; pArea->pSDDData = memset( hb_xgrab( sizeof( SDDDATA ) ), 0, sizeof( SDDDATA ) ); pSDDData = ( SDDDATA * ) pArea->pSDDData; if( mysql_real_query( pMySql, pArea->szQuery, ( unsigned long ) strlen( pArea->szQuery ) ) ) { hb_errRT_MySQLDD( EG_OPEN, ESQLDD_INVALIDQUERY, ( const char * ) mysql_error( pMySql ), pArea->szQuery, mysql_errno( pMySql ) ); return HB_FAILURE; } if( ( pSDDData->pResult = mysql_store_result( pMySql ) ) == NULL ) { hb_errRT_MySQLDD( EG_MEM, ESQLDD_INVALIDQUERY, ( const char * ) mysql_error( pMySql ), pArea->szQuery, mysql_errno( pMySql ) ); return HB_FAILURE; } uiFields = ( HB_USHORT ) mysql_num_fields( pSDDData->pResult ); SELF_SETFIELDEXTENT( ( AREAP ) pArea, uiFields ); pItemEof = hb_itemArrayNew( uiFields ); bError = HB_FALSE; for( uiCount = 0; uiCount < uiFields; uiCount++ ) { pMyField = mysql_fetch_field_direct( pSDDData->pResult, uiCount ); pFieldInfo.atomName = pMyField->name; pFieldInfo.uiLen = ( HB_USHORT ) pMyField->length; pFieldInfo.uiDec = 0; switch( pMyField->type ) { case MYSQL_TYPE_TINY: case MYSQL_TYPE_SHORT: pFieldInfo.uiType = HB_FT_INTEGER; break; case MYSQL_TYPE_LONG: case MYSQL_TYPE_LONGLONG: case MYSQL_TYPE_INT24: pFieldInfo.uiType = HB_FT_LONG; break; case MYSQL_TYPE_DECIMAL: case MYSQL_TYPE_NEWDECIMAL: case MYSQL_TYPE_FLOAT: case MYSQL_TYPE_DOUBLE: pFieldInfo.uiType = HB_FT_DOUBLE; pFieldInfo.uiDec = ( HB_USHORT ) pMyField->decimals; break; case MYSQL_TYPE_STRING: case MYSQL_TYPE_VAR_STRING: case MYSQL_TYPE_ENUM: pFieldInfo.uiType = HB_FT_STRING; break; case MYSQL_TYPE_DATE: pFieldInfo.uiType = HB_FT_DATE; break; case MYSQL_TYPE_TINY_BLOB: case MYSQL_TYPE_MEDIUM_BLOB: case MYSQL_TYPE_LONG_BLOB: case MYSQL_TYPE_BLOB: pFieldInfo.uiType = HB_FT_MEMO; break; case MYSQL_TYPE_TIMESTAMP: case MYSQL_TYPE_DATETIME: pFieldInfo.uiType = HB_FT_TIMESTAMP; pFieldInfo.uiLen = 8; break; case MYSQL_TYPE_TIME: pFieldInfo.uiType = HB_FT_TIME; pFieldInfo.uiLen = 4; break; case MYSQL_TYPE_NULL: case MYSQL_TYPE_YEAR: case MYSQL_TYPE_NEWDATE: case MYSQL_TYPE_SET: case MYSQL_TYPE_VARCHAR: case MYSQL_TYPE_BIT: case MYSQL_TYPE_GEOMETRY: bError = HB_TRUE; errCode = ( HB_ERRCODE ) pMyField->type; pFieldInfo.uiType = 0; break; } if( ! bError ) { switch( pFieldInfo.uiType ) { case HB_FT_STRING: { char * pStr; pStr = ( char * ) hb_xgrab( pFieldInfo.uiLen + 1 ); memset( pStr, ' ', pFieldInfo.uiLen ); pStr[ pFieldInfo.uiLen ] = '\0'; pItem = hb_itemPutCL( NULL, pStr, pFieldInfo.uiLen ); hb_xfree( pStr ); break; } case HB_FT_MEMO: pItem = hb_itemPutC( NULL, NULL ); break; case HB_FT_INTEGER: pItem = hb_itemPutNI( NULL, 0 ); break; case HB_FT_LONG: pItem = hb_itemPutNL( NULL, 0 ); break; case HB_FT_DOUBLE: pItem = hb_itemPutND( NULL, 0.0 ); break; case HB_FT_DATE: pItem = hb_itemPutDS( NULL, NULL ); break; case HB_FT_TIMESTAMP: case HB_FT_TIME: pItem = hb_itemPutTDT( NULL, 0, 0 ); break; default: pItem = hb_itemNew( NULL ); bError = HB_TRUE; break; } hb_arraySetForward( pItemEof, uiCount + 1, pItem ); hb_itemRelease( pItem ); #if 0 if( pFieldInfo.uiType == HB_IT_DOUBLE || pFieldInfo.uiType == HB_IT_INTEGER ) pFieldInfo.uiType = HB_IT_LONG; #endif if( ! bError ) bError = ( SELF_ADDFIELD( ( AREAP ) pArea, &pFieldInfo ) == HB_FAILURE ); } if( bError ) break; } if( bError ) { hb_itemRelease( pItemEof ); hb_errRT_MySQLDD( EG_CORRUPTION, ESQLDD_INVALIDFIELD, "Invalid field type", pArea->szQuery, errCode ); return HB_FAILURE; } pArea->ulRecCount = ( HB_ULONG ) mysql_num_rows( pSDDData->pResult ); pArea->pRow = ( void ** ) hb_xgrab( ( pArea->ulRecCount + 1 ) * sizeof( void * ) ); pArea->pRowFlags = ( HB_BYTE * ) hb_xgrabz( ( pArea->ulRecCount + 1 ) * sizeof( HB_BYTE ) ); pArea->ulRecMax = pArea->ulRecCount + 1; pRow = pArea->pRow; *pRow = pItemEof; pArea->pRowFlags[ 0 ] = SQLDD_FLAG_CACHED; pRow++; for( ulIndex = 1; ulIndex <= pArea->ulRecCount; ulIndex++ ) { *pRow++ = ( void * ) mysql_row_tell( pSDDData->pResult ); mysql_fetch_row( pSDDData->pResult ); } pArea->fFetched = HB_TRUE; return HB_SUCCESS; }
/* Manager of signals for windows */ static LONG s_signalHandler( int type, int sig, PEXCEPTION_RECORD exc ) { HB_SIZE nPos; HB_UINT uiSig; /* let's find the right signal handler. */ hb_threadEnterCriticalSectionGC( &s_ServiceMutex ); /* avoid working if PRG signal handling has been disabled */ if( ! s_bSignalEnabled ) { hb_threadLeaveCriticalSection( &s_ServiceMutex ); return EXCEPTION_EXECUTE_HANDLER; } s_bSignalEnabled = HB_FALSE; nPos = hb_arrayLen( s_pHooks ); /* subsig not necessary */ uiSig = ( HB_UINT ) s_translateSignal( ( HB_UINT ) type, ( HB_UINT ) sig ); while( nPos > 0 ) { PHB_ITEM pFunction; HB_UINT uiMask; pFunction = hb_arrayGetItemPtr( s_pHooks, nPos ); uiMask = ( HB_UINT ) hb_arrayGetNI( pFunction, 1 ); if( ( uiMask & uiSig ) == uiSig ) { PHB_ITEM pExecArray, pRet; int iRet; /* we don't unlock the mutex now, even if it is a little dangerous. But we are in a signal hander... for now just 2 parameters */ pExecArray = hb_itemArrayNew( 3 ); hb_arraySetForward( pExecArray, 1, hb_arrayGetItemPtr( pFunction, 2 ) ); hb_arraySetNI( pExecArray, 2, uiSig ); /* the third parameter is an array: * 1: low-level signal * 2: low-level subsignal * 3: low-level system error * 4: address that rose the signal * 5: process id of the signal riser * 6: UID of the riser */ pRet = hb_arrayGetItemPtr( pExecArray, 3 ); hb_arrayNew( pRet, 6 ); hb_arraySetNI( pRet, HB_SERVICE_OSSIGNAL, type ); hb_arraySetNI( pRet, HB_SERVICE_OSSUBSIG, sig ); /* could be meaningless, but does not matter here */ hb_arraySetNI( pRet, HB_SERVICE_OSERROR, GetLastError() ); if( type == 0 ) /* exception */ hb_arraySetPtr( pRet, HB_SERVICE_ADDRESS, ( void * ) exc->ExceptionAddress ); else hb_arraySetPtr( pRet, HB_SERVICE_ADDRESS, NULL ); /* TODO: */ hb_arraySetNI( pRet, HB_SERVICE_PROCESS, GetCurrentThreadId() ); /* TODO: */ hb_arraySetNI( pRet, HB_SERVICE_UID, 0 ); pRet = hb_itemDo( pExecArray, 0 ); iRet = hb_itemGetNI( pRet ); hb_itemRelease( pRet ); hb_itemRelease( pExecArray ); switch( iRet ) { case HB_SERVICE_HANDLED: s_bSignalEnabled = HB_TRUE; hb_threadLeaveCriticalSection( &s_ServiceMutex ); return EXCEPTION_CONTINUE_EXECUTION; case HB_SERVICE_QUIT: s_bSignalEnabled = HB_FALSE; hb_threadLeaveCriticalSection( &s_ServiceMutex ); hb_vmRequestQuit(); #ifndef HB_THREAD_SUPPORT hb_vmQuit(); exit( 0 ); #else hb_threadCancelInternal(); #endif } } nPos--; } s_bSignalEnabled = HB_TRUE; return EXCEPTION_EXECUTE_HANDLER; }
static HB_ERRCODE ocilibGoTo( SQLBASEAREAP pArea, HB_ULONG ulRecNo ) { OCI_Statement * st = ( ( SDDDATA * ) pArea->pSDDData )->pStmt; OCI_Resultset * rs = OCI_GetResultset( st ); while( ulRecNo > pArea->ulRecCount && ! pArea->fFetched ) { PHB_ITEM pArray; HB_USHORT ui; if( ! OCI_FetchNext( rs ) ) { pArea->fFetched = HB_TRUE; break; } pArray = hb_itemArrayNew( pArea->area.uiFieldCount ); for( ui = 1; ui <= pArea->area.uiFieldCount; ++ui ) { PHB_ITEM pItem = NULL; LPFIELD pField = pArea->area.lpFields + ui - 1; switch( pField->uiType ) { case HB_FT_STRING: if( OCI_IsNull( rs, ui ) ) { char * pStr = ( char * ) hb_xgrab( ( HB_SIZE ) pField->uiLen + 1 ); memset( pStr, ' ', pField->uiLen ); pStr[ pField->uiLen ] = '\0'; pItem = hb_itemPutCLPtr( NULL, pStr, pField->uiLen ); } else { const dtext * val; if( ( val = OCI_GetString( rs, ui ) ) != NULL ) pItem = D_HB_ITEMPUTSTRLEN( NULL, val, ( HB_SIZE ) dtslen( val ) ); /* TODO: Pad it to pField->uiLen size with spaces? */ } break; case HB_FT_LONG: case HB_FT_INTEGER: if( pField->uiDec == 0 ) #if HB_VMLONG_MAX == INT32_MAX || defined( HB_LONG_LONG_OFF ) pItem = hb_itemPutNIntLen( NULL, OCI_GetInt( rs, ui ), pField->uiLen ); #else pItem = hb_itemPutNIntLen( NULL, OCI_GetBigInt( rs, ui ), pField->uiLen ); #endif else pItem = hb_itemPutNDLen( NULL, OCI_GetDouble( rs, ui ), pField->uiLen, pField->uiDec ); break; case HB_FT_VARLENGTH: case HB_FT_MEMO: { OCI_Long * val = OCI_GetLong( rs, ui ); if( val ) { unsigned int uiSize = OCI_LongGetSize( val ); if( OCI_LongGetType( val ) == OCI_CLONG ) pItem = D_HB_ITEMPUTSTRLEN( NULL, ( D_HB_CHAR * ) OCI_LongGetBuffer( val ), uiSize ); else pItem = hb_itemPutCL( NULL, ( char * ) OCI_LongGetBuffer( val ), uiSize ); } break; } case HB_FT_IMAGE: case HB_FT_BLOB: case HB_FT_OLE: { OCI_Long * val = OCI_GetLong( rs, ui ); if( val ) pItem = hb_itemPutCL( NULL, ( char * ) OCI_LongGetBuffer( val ), OCI_LongGetSize( val ) ); break; } case HB_FT_CURRENCY: case HB_FT_CURDOUBLE: case HB_FT_FLOAT: case HB_FT_DOUBLE: pItem = hb_itemPutNDLen( NULL, OCI_GetDouble( rs, ui ), pField->uiLen, pField->uiDec ); break; case HB_FT_DATE: { OCI_Date * date = OCI_GetDate( rs, ui ); int iYear, iMonth, iDay; if( date && OCI_DateGetDate( date, &iYear, &iMonth, &iDay ) ) pItem = hb_itemPutD( NULL, iYear, iMonth, iDay ); break; } case HB_FT_TIME: { OCI_Date * date = OCI_GetDate( rs, ui ); int iYear, iMonth, iDay, iHour, iMin, iSec; if( date && OCI_DateGetDateTime( date, &iYear, &iMonth, &iDay, &iHour, &iMin, &iSec ) ) pItem = hb_itemPutTDT( NULL, hb_dateEncode( iYear, iMonth, iDay ), hb_timeEncode( iHour, iMin, iSec, 0 ) ); break; } case HB_FT_TIMESTAMP: { OCI_Timestamp * ts = OCI_GetTimestamp( rs, ui ); int iYear, iMonth, iDay, iHour, iMin, iSec, iFSec; if( ts && OCI_TimestampGetDateTime( ts, &iYear, &iMonth, &iDay, &iHour, &iMin, &iSec, &iFSec ) ) pItem = hb_itemPutTDT( NULL, hb_dateEncode( iYear, iMonth, iDay ), hb_timeEncode( iHour, iMin, iSec, iFSec / 1000000 ) ); break; } } if( pItem ) { hb_arraySetForward( pArray, ui, pItem ); hb_itemRelease( pItem ); } } if( pArea->ulRecCount + 1 <= pArea->ulRecMax ) { pArea->pRow = ( void ** ) hb_xrealloc( pArea->pRow, ( pArea->ulRecMax + SQLDD_ROWSET_RESIZE ) * sizeof( void * ) ); pArea->pRowFlags = ( HB_BYTE * ) hb_xrealloc( pArea->pRowFlags, ( pArea->ulRecMax + SQLDD_ROWSET_RESIZE ) * sizeof( HB_BYTE ) ); pArea->ulRecMax += SQLDD_ROWSET_RESIZE; } pArea->ulRecCount++; pArea->pRow[ pArea->ulRecCount ] = pArray; pArea->pRowFlags[ pArea->ulRecCount ] = SQLDD_FLAG_CACHED; }
static HB_ERRCODE ocilibOpen( SQLBASEAREAP pArea ) { OCI_Statement * st = OCI_StatementCreate( ( ( SDDCONN * ) pArea->pConnection->pSDDConn )->pConn ); OCI_Resultset * rs; SDDDATA * pSDDData; void * hQuery; HB_USHORT uiFields, uiIndex; PHB_ITEM pItemEof, pItem; HB_ERRCODE errCode; char * szError; HB_BOOL bError; pArea->pSDDData = memset( hb_xgrab( sizeof( SDDDATA ) ), 0, sizeof( SDDDATA ) ); pSDDData = ( SDDDATA * ) pArea->pSDDData; if( ! st ) { szError = ocilibGetError( &errCode ); hb_errRT_OCIDD( EG_OPEN, ESQLDD_STMTALLOC, szError, pArea->szQuery, errCode ); hb_xfree( szError ); return HB_FAILURE; } pItem = hb_itemPutC( NULL, pArea->szQuery ); if( ! OCI_ExecuteStmt( st, M_HB_ITEMGETSTR( pItem, &hQuery, NULL ) ) ) { hb_strfree( hQuery ); hb_itemRelease( pItem ); szError = ocilibGetError( &errCode ); OCI_StatementFree( st ); hb_errRT_OCIDD( EG_OPEN, ESQLDD_INVALIDQUERY, szError, pArea->szQuery, errCode ); hb_xfree( szError ); return HB_FAILURE; } else { hb_strfree( hQuery ); hb_itemRelease( pItem ); } rs = OCI_GetResultset( st ); uiFields = ( HB_USHORT ) OCI_GetColumnCount( rs ); SELF_SETFIELDEXTENT( ( AREAP ) pArea, uiFields ); pItemEof = hb_itemArrayNew( uiFields ); pItem = hb_itemNew( NULL ); #if 0 HB_TRACE( HB_TR_ALWAYS, ( "fieldcount=%d", iNameLen ) ); #endif errCode = 0; bError = HB_FALSE; for( uiIndex = 0; uiIndex < uiFields; ++uiIndex ) { DBFIELDINFO pFieldInfo; PHB_ITEM pName; OCI_Column * col = OCI_GetColumn( rs, uiIndex + 1 ); unsigned int uiDataType; unsigned int uiSize; int iDec; HB_BOOL bNullable; if( ! col ) { hb_itemRelease( pItemEof ); hb_itemRelease( pItem ); szError = ocilibGetError( NULL ); OCI_StatementFree( st ); hb_errRT_OCIDD( EG_OPEN, ESQLDD_STMTDESCR + 1001, szError, pArea->szQuery, 0 ); hb_xfree( szError ); return HB_FAILURE; } pName = D_HB_ITEMPUTSTR( NULL, OCI_ColumnGetName( col ) ); pFieldInfo.atomName = hb_itemGetCPtr( pName ); uiDataType = OCI_ColumnGetType( col ); uiSize = OCI_ColumnGetSize( col ); iDec = OCI_ColumnGetPrecision( col ); bNullable = ( HB_BOOL ) OCI_ColumnGetNullable( col ); if( bNullable ) pFieldInfo.uiFlags |= HB_FF_NULLABLE; pFieldInfo.uiLen = ( HB_USHORT ) uiSize; pFieldInfo.uiDec = ( HB_USHORT ) iDec; #if 0 HB_TRACE( HB_TR_ALWAYS, ( "field: name=%s type=%d len=%d dec=%d nullable=%d %d %d %d %d", pFieldInfo.atomName, uiDataType, uiSize, iDec, bNullable, OCI_ColumnGetScale( col ), OCI_ColumnGetPrecision( col ), OCI_ColumnGetFractionalPrecision( col ), OCI_ColumnGetLeadingPrecision( col ) ) ); #endif switch( uiDataType ) { case OCI_CDT_TEXT: pFieldInfo.uiType = HB_FT_STRING; break; case OCI_CDT_NUMERIC: pFieldInfo.uiType = HB_FT_LONG; /* For plain 'NUMERIC', precision is zero and scale is -127 */ if( OCI_ColumnGetPrecision( col ) > 0 ) pFieldInfo.uiLen = ( HB_USHORT ) OCI_ColumnGetPrecision( col ); if( OCI_ColumnGetScale( col ) >= 0 ) pFieldInfo.uiDec = ( HB_USHORT ) OCI_ColumnGetScale( col ); else pFieldInfo.uiDec = ( HB_USHORT ) hb_setGetDecimals(); break; case OCI_CDT_LONG: pFieldInfo.uiType = HB_FT_VARLENGTH; break; case OCI_CDT_RAW: pFieldInfo.uiType = HB_FT_BLOB; break; case OCI_CDT_DATETIME: case OCI_CDT_TIMESTAMP: case OCI_CDT_INTERVAL: pFieldInfo.uiType = HB_FT_TIME; break; default: #if 0 HB_TRACE( HB_TR_ALWAYS, ( "new sql type=%d", uiDataType ) ); #endif bError = HB_TRUE; errCode = ( HB_ERRCODE ) uiDataType; pFieldInfo.uiType = 0; pFieldInfo.uiType = HB_FT_STRING; break; } if( ! bError ) { switch( pFieldInfo.uiType ) { case HB_FT_STRING: { char * pStr = ( char * ) hb_xgrab( ( HB_SIZE ) pFieldInfo.uiLen + 1 ); memset( pStr, ' ', pFieldInfo.uiLen ); pStr[ pFieldInfo.uiLen ] = '\0'; hb_itemPutCLPtr( pItem, pStr, pFieldInfo.uiLen ); break; } case HB_FT_MEMO: case HB_FT_VARLENGTH: case HB_FT_BLOB: hb_itemPutC( pItem, NULL ); break; case HB_FT_INTEGER: hb_itemPutNI( pItem, 0 ); break; case HB_FT_LONG: if( pFieldInfo.uiDec == 0 ) hb_itemPutNLLen( pItem, 0, pFieldInfo.uiLen ); else hb_itemPutNDLen( pItem, 0.0, pFieldInfo.uiLen, pFieldInfo.uiDec ); break; case HB_FT_DOUBLE: hb_itemPutNDLen( pItem, 0.0, pFieldInfo.uiLen, pFieldInfo.uiDec ); break; case HB_FT_LOGICAL: hb_itemPutL( pItem, HB_FALSE ); break; case HB_FT_DATE: hb_itemPutDL( pItem, 0 ); break; case HB_FT_TIME: case HB_FT_TIMESTAMP: hb_itemPutTDT( pItem, 0, 0 ); break; default: hb_itemClear( pItem ); bError = HB_TRUE; } hb_arraySetForward( pItemEof, uiIndex + 1, pItem ); if( ! bError ) bError = ( SELF_ADDFIELD( ( AREAP ) pArea, &pFieldInfo ) == HB_FAILURE ); } hb_itemRelease( pName ); if( bError ) break; } hb_itemRelease( pItem ); if( bError ) { hb_itemRelease( pItemEof ); OCI_StatementFree( st ); hb_errRT_OCIDD( EG_CORRUPTION, ESQLDD_INVALIDFIELD, "Invalid field type", pArea->szQuery, errCode ); return HB_FAILURE; } pArea->ulRecCount = 0; pArea->ulRecMax = SQLDD_ROWSET_INIT; pArea->pRow = ( void ** ) hb_xgrab( SQLDD_ROWSET_INIT * sizeof( void * ) ); memset( pArea->pRow, 0, SQLDD_ROWSET_INIT * sizeof( void * ) ); pArea->pRowFlags = ( HB_BYTE * ) hb_xgrab( SQLDD_ROWSET_INIT * sizeof( HB_BYTE ) ); memset( pArea->pRowFlags, 0, SQLDD_ROWSET_INIT * sizeof( HB_BYTE ) ); pArea->pRow[ 0 ] = pItemEof; pArea->pRowFlags[ 0 ] = SQLDD_FLAG_CACHED; pSDDData->pStmt = st; return HB_SUCCESS; }