static char * sqlite3GetError( sqlite3 * pDb, HB_ERRCODE * pErrCode ) { char * szRet; int iNativeErr = 9999; if( pDb ) { PHB_ITEM pRet = S_HB_ITEMPUTSTR( NULL, sqlite3_errmsg( pDb ) ); szRet = hb_strdup( hb_itemGetCPtr( pRet ) ); hb_itemRelease( pRet ); iNativeErr = sqlite3_errcode( pDb ); } else szRet = hb_strdup( "Unable to get error message" ); if( pErrCode ) *pErrCode = ( HB_ERRCODE ) iNativeErr; return szRet; }
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 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, pName = NULL; 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( &pArea->area, uiFields ); errCode = 0; bError = HB_FALSE; pItemEof = hb_itemArrayNew( uiFields ); for( uiIndex = 0; uiIndex < uiFields; ++uiIndex ) { DBFIELDINFO dbFieldInfo; memset( &dbFieldInfo, 0, sizeof( dbFieldInfo ) ); pName = S_HB_ITEMPUTSTR( pName, sqlite3_column_name( st, uiIndex ) ); dbFieldInfo.atomName = hb_itemGetCPtr( pName ); dbFieldInfo.uiType = sqlite3DeclType( st, uiIndex ); pItem = hb_arrayGetItemPtr( pItemEof, uiIndex + 1 ); switch( dbFieldInfo.uiType ) { case HB_FT_STRING: { int iSize = sqlite3_column_bytes( st, uiIndex ); char * pStr; dbFieldInfo.uiLen = ( HB_USHORT ) HB_MAX( iSize, 10 ); pStr = ( char * ) hb_xgrab( ( HB_SIZE ) dbFieldInfo.uiLen + 1 ); memset( pStr, ' ', dbFieldInfo.uiLen ); hb_itemPutCLPtr( pItem, pStr, dbFieldInfo.uiLen ); break; } case HB_FT_BLOB: dbFieldInfo.uiLen = 4; hb_itemPutC( pItem, NULL ); break; case HB_FT_INTEGER: dbFieldInfo.uiLen = 8; hb_itemPutNInt( pItem, 0 ); break; case HB_FT_LONG: dbFieldInfo.uiLen = 20; dbFieldInfo.uiDec = ( HB_USHORT ) hb_setGetDecimals(); hb_itemPutNDDec( pItem, 0.0, dbFieldInfo.uiDec ); break; case HB_FT_ANY: dbFieldInfo.uiLen = 6; break; default: bError = HB_TRUE; } if( ! bError ) bError = ( SELF_ADDFIELD( &pArea->area, &dbFieldInfo ) == HB_FAILURE ); if( bError ) break; } hb_itemRelease( pName ); 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 * ) ); pArea->pRowFlags = ( HB_BYTE * ) hb_xgrab( 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 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; }