diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 4d23025656..0505568946 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -17,6 +17,26 @@ past entries belonging to author(s): Viktor Szakats. */ +2010-02-28 18:34 UTC+0100 Viktor Szakats (harbour.01 syenar.hu) + * contrib/hbsqlit3/hbsqlit3.c + + Added TOFIX: utf8 conversion is missing from the interface. + + * contrib/rddsql/Makefile + + contrib/rddsql/sddsq3 + + contrib/rddsql/sddsq3/Makefile + + contrib/rddsql/sddsq3/sddsq3.c + + contrib/rddsql/sddsq3/sddsq3.hbc + + contrib/rddsql/sddsq3/tests + + contrib/rddsql/sddsq3/tests/hbmk.hbm + + contrib/rddsql/sddsq3/tests/test1.prg + + contrib/rddsql/sddsq3/tests/test.sq3 + + Added SDD to access SQLITE3 databases. + ; Please test it with real data, especially blobs. + + * contrib/rddsql/sddoci/sddoci.c + * Formatting. + ! Fixed leak. + 2010-02-28 12:59 UTC+0100 Viktor Szakats (harbour.01 syenar.hu) * contrib/rddsql/sddoci/sddoci.c ! Fixed handling of numeric types widths and decimals. diff --git a/harbour/contrib/hbsqlit3/hbsqlit3.c b/harbour/contrib/hbsqlit3/hbsqlit3.c index c32e3e1551..b8455312ff 100644 --- a/harbour/contrib/hbsqlit3/hbsqlit3.c +++ b/harbour/contrib/hbsqlit3/hbsqlit3.c @@ -60,6 +60,8 @@ #include "hbapifs.h" #include "hbstack.h" +/* TOFIX: Convert strings to/from UTF8 in SQLITE3 interface. */ + /* TOFIX: verify the exact SQLITE3 version */ #if SQLITE_VERSION_NUMBER <= 3004001 #define sqlite3_int64 HB_LONGLONG diff --git a/harbour/contrib/rddsql/Makefile b/harbour/contrib/rddsql/Makefile index ba6f3fcc11..4a67d25fba 100644 --- a/harbour/contrib/rddsql/Makefile +++ b/harbour/contrib/rddsql/Makefile @@ -19,6 +19,7 @@ DIRS := \ sddfb \ sddoci \ sddodbc \ + sddsq3 \ include $(TOP)$(ROOT)config/header.mk include $(TOP)$(ROOT)config/lib.mk diff --git a/harbour/contrib/rddsql/sddoci/sddoci.c b/harbour/contrib/rddsql/sddoci/sddoci.c index be2f257bb6..00ae993cf5 100644 --- a/harbour/contrib/rddsql/sddoci/sddoci.c +++ b/harbour/contrib/rddsql/sddoci/sddoci.c @@ -354,6 +354,7 @@ static HB_ERRCODE ocilibOpen( SQLBASEAREAP pArea ) HB_SYMBOL_UNUSED( bNullable ); szOurName = hb_strdup( hb_itemGetCPtr( pName ) ); + hb_itemRelease( pName ); pFieldInfo.atomName = hb_strUpper( szOurName, ( HB_SIZE ) strlen( szOurName ) ); pFieldInfo.uiLen = ( HB_USHORT ) uiSize; @@ -364,36 +365,36 @@ static HB_ERRCODE ocilibOpen( SQLBASEAREAP pArea ) switch( uiDataType ) { case OCI_CDT_TEXT: - pFieldInfo.uiType = HB_FT_STRING; - break; + pFieldInfo.uiType = HB_FT_STRING; + break; case OCI_CDT_NUMERIC: - pFieldInfo.uiType = HB_FT_LONG; - pFieldInfo.uiLen = ( HB_USHORT ) OCI_ColumnGetPrecision( col ); - pFieldInfo.uiDec = ( HB_USHORT ) OCI_ColumnGetScale( col ); - break; + pFieldInfo.uiType = HB_FT_LONG; + pFieldInfo.uiLen = ( HB_USHORT ) OCI_ColumnGetPrecision( col ); + pFieldInfo.uiDec = ( HB_USHORT ) OCI_ColumnGetScale( col ); + break; case OCI_CDT_LONG: - pFieldInfo.uiType = HB_FT_VARLENGTH; - break; + pFieldInfo.uiType = HB_FT_VARLENGTH; + break; case OCI_CDT_RAW: - pFieldInfo.uiType = HB_FT_BLOB; - break; + pFieldInfo.uiType = HB_FT_BLOB; + break; case OCI_CDT_DATETIME: case OCI_CDT_TIMESTAMP: case OCI_CDT_INTERVAL: - pFieldInfo.uiType = HB_FT_TIME; - break; + pFieldInfo.uiType = HB_FT_TIME; + break; default: - /* HB_TRACE( HB_TR_ALWAYS, ("new sql type=%d", uiDataType) ); */ - bError = HB_TRUE; - errCode = ( HB_ERRCODE ) uiDataType; - pFieldInfo.uiType = 0; - pFieldInfo.uiType = HB_FT_STRING; - break; + /* HB_TRACE( HB_TR_ALWAYS, ("new sql type=%d", uiDataType) ); */ + bError = HB_TRUE; + errCode = ( HB_ERRCODE ) uiDataType; + pFieldInfo.uiType = 0; + pFieldInfo.uiType = HB_FT_STRING; + break; } if( ! bError ) @@ -498,12 +499,12 @@ static HB_ERRCODE ocilibGoTo( SQLBASEAREAP pArea, HB_ULONG ulRecNo ) { OCI_Statement * st = ( OCI_Statement * ) pArea->pStmt; OCI_Resultset * rs = OCI_GetResultset( st ); - PHB_ITEM pArray, pItem; - LPFIELD pField; - HB_USHORT ui; while( ulRecNo > pArea->ulRecCount && ! pArea->fFetched ) { + PHB_ITEM pArray; + HB_USHORT ui; + if( ! OCI_FetchNext( rs ) ) { pArea->fFetched = HB_TRUE; @@ -514,9 +515,10 @@ static HB_ERRCODE ocilibGoTo( SQLBASEAREAP pArea, HB_ULONG ulRecNo ) for( ui = 1; ui <= pArea->area.uiFieldCount; ++ui ) { - pItem = NULL; + PHB_ITEM pItem = NULL; + LPFIELD pField = pArea->area.lpFields + ui - 1; - pField = pArea->area.lpFields + ui - 1; + pItem = NULL; switch( pField->uiType ) { diff --git a/harbour/contrib/rddsql/sddsq3/Makefile b/harbour/contrib/rddsql/sddsq3/Makefile new file mode 100644 index 0000000000..b996a7489b --- /dev/null +++ b/harbour/contrib/rddsql/sddsq3/Makefile @@ -0,0 +1,33 @@ +# +# $Id$ +# + +ROOT := ../../../ + +include $(TOP)$(ROOT)config/global.mk + +LIBNAME := sddsq3 + +C_SOURCES := \ + sddsq3.c \ + +_DET_DSP_NAME := sqlite3 +_DET_VAR_INC_ := HB_INC_SQLITE3 +_DET_VAR_HAS_ := HB_HAS_SQLITE3 +_DET_FLT_PLAT := +_DET_FLT_COMP := +_DET_INC_DEFP := /usr/include /boot/common/include +_DET_INC_LOCL := $(realpath $(TOP)$(ROOT)external/sqlite3) +_DET_INC_HEAD := /sqlite3.h +include $(TOP)$(ROOT)config/detfun.mk + +ifneq ($(HB_HAS_SQLITE3),) + + HB_CFLAGS += $(foreach d,$(HB_HAS_SQLITE3),-I$(d)) + + include $(TOP)$(ROOT)config/header.mk + include $(TOP)$(ROOT)config/lib.mk +else + HB_SKIP_REASON := $(_DET_RES_TEXT) + include $(TOP)$(ROOT)config/none.mk +endif diff --git a/harbour/contrib/rddsql/sddsq3/sddsq3.c b/harbour/contrib/rddsql/sddsq3/sddsq3.c new file mode 100644 index 0000000000..a38db8e8fd --- /dev/null +++ b/harbour/contrib/rddsql/sddsq3/sddsq3.c @@ -0,0 +1,477 @@ +/* + * $Id$ + */ + +/* + * SQLite3 Database Driver + * + * Copyright 2010 Viktor Szakats (harbour.01 syenar.hu) + * www - http://www.harbour-project.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307 USA (or visit the web site http://www.gnu.org/). + * + * As a special exception, the Harbour Project gives permission for + * additional uses of the text contained in its release of Harbour. + * + * The exception is that, if you link the Harbour libraries with other + * files to produce an executable, this does not by itself cause the + * resulting executable to be covered by the GNU General Public License. + * Your use of that executable is in no way restricted on account of + * linking the Harbour library code into it. + * + * This exception does not however invalidate any other reasons why + * the executable file might be covered by the GNU General Public License. + * + * This exception applies only to the code released by the Harbour + * Project under the name Harbour. If you copy code from other + * Harbour Project or Free Software Foundation releases into a copy of + * Harbour, as the General Public License permits, the exception does + * not apply to the code that you add in this way. To avoid misleading + * anyone as to the status of such modified files, you must delete + * this exception notice from them. + * + * If you write modifications of your own for Harbour, it is your choice + * whether to permit this exception to apply to your modifications. + * If you do not wish that, delete this exception notice. + * + */ + +#include "hbapi.h" +#include "hbapiitm.h" +#include "hbapistr.h" +#include "hbdate.h" +#include "hbvm.h" + +#if defined( __XCC__ ) || defined( __LCC__ ) +# include "hbrddsql.h" +#else +# include "../hbrddsql.h" +#endif + +#include + +#define S_HB_ARRAYGETSTR( arr, n, phstr, plen ) hb_arrayGetStrUTF8( arr, n, phstr, plen ) +#define S_HB_ITEMCOPYSTR( itm, str, len ) hb_itemCopyStrUTF8( itm, str, len ) +#define S_HB_ITEMGETSTR( itm, phstr, plen ) hb_itemGetStrUTF8( itm, phstr, plen ) +#define S_HB_ITEMPUTSTR( itm, str ) hb_itemPutStrUTF8( itm, str ) +#define S_HB_ITEMPUTSTRLEN( itm, str, len ) hb_itemPutStrLenUTF8( itm, str, len ) + +static HB_ERRCODE sqlite3Connect( SQLDDCONNECTION * pConnection, PHB_ITEM pItem ); +static HB_ERRCODE sqlite3Disconnect( SQLDDCONNECTION * pConnection ); +static HB_ERRCODE sqlite3Execute( SQLDDCONNECTION * pConnection, PHB_ITEM pItem ); +static HB_ERRCODE sqlite3Open( SQLBASEAREAP pArea ); +static HB_ERRCODE sqlite3Close( SQLBASEAREAP pArea ); +static HB_ERRCODE sqlite3GoTo( SQLBASEAREAP pArea, HB_ULONG ulRecNo ); + + +static SDDNODE sq3dd = +{ + NULL, + "SQLITE3", + ( SDDFUNC_CONNECT ) sqlite3Connect, + ( SDDFUNC_DISCONNECT ) sqlite3Disconnect, + ( SDDFUNC_EXECUTE ) sqlite3Execute, + ( SDDFUNC_OPEN ) sqlite3Open, + ( SDDFUNC_CLOSE ) sqlite3Close, + ( SDDFUNC_GOTO ) sqlite3GoTo, + ( SDDFUNC_GETVALUE ) NULL, + ( SDDFUNC_GETVARLEN ) NULL +}; + + +HB_FUNC_EXTERN( SQLBASE ); + +static void hb_sq3dd_init( void * cargo ) +{ + HB_SYMBOL_UNUSED( cargo ); + +#if SQLITE_VERSION_NUMBER >= 3006000 + sqlite3_initialize(); +#endif + + if( ! hb_sddRegister( &sq3dd ) ) + { + hb_errInternal( HB_EI_RDDINVALID, NULL, NULL, NULL ); + HB_FUNC_EXEC( SQLBASE ); /* force SQLBASE linking */ + } +} + +static void hb_sq3dd_exit( void * cargo ) +{ + HB_SYMBOL_UNUSED( cargo ); + +#if SQLITE_VERSION_NUMBER >= 3006000 + sqlite3_shutdown(); +#endif +} + +HB_FUNC( SDDSQLITE3 ) {;} + +HB_INIT_SYMBOLS_BEGIN( sq3dd__InitSymbols ) +{ "SDDSQLITE3", {HB_FS_PUBLIC}, {HB_FUNCNAME( SDDSQLITE3 )}, NULL }, +HB_INIT_SYMBOLS_END( sq3dd__InitSymbols ) + +HB_CALL_ON_STARTUP_BEGIN( _hb_sq3dd_init_ ) + hb_vmAtInit( hb_sq3dd_init, NULL ); + hb_vmAtExit( hb_sq3dd_exit, NULL ); +HB_CALL_ON_STARTUP_END( _hb_sq3dd_init_ ) + +#if defined( HB_PRAGMA_STARTUP ) + #pragma startup sq3dd__InitSymbols + #pragma startup _hb_sq3dd_init_ +#elif defined( HB_DATASEG_STARTUP ) + #define HB_DATASEG_BODY HB_DATASEG_FUNC( sq3dd__InitSymbols ) \ + HB_DATASEG_FUNC( _hb_sq3dd_init_ ) + #include "hbiniseg.h" +#endif + + +/*=====================================================================================*/ +static HB_USHORT hb_errRT_SQ3DD( HB_ERRCODE errGenCode, HB_ERRCODE errSubCode, const char * szDescription, const char * szOperation, HB_ERRCODE errOsCode ) +{ + HB_USHORT uiAction; + PHB_ITEM pError; + + pError = hb_errRT_New( ES_ERROR, "SDDSQLITE3", errGenCode, errSubCode, szDescription, szOperation, errOsCode, EF_NONE ); + uiAction = hb_errLaunch( pError ); + hb_itemRelease( pError ); + return uiAction; +} + + +static char * sqlite3GetError( SQLDDCONNECTION * pConnection, HB_ERRCODE * pErrCode ) +{ + char * szRet; + + int iNativeErr = 9999; + + if( pConnection && pConnection->hConnection ) + { + PHB_ITEM pRet = S_HB_ITEMPUTSTR( NULL, sqlite3_errmsg( ( sqlite3 * ) pConnection->hConnection ) ); + szRet = hb_strdup( hb_itemGetCPtr( pRet ) ); + hb_itemRelease( pRet ); + + iNativeErr = sqlite3_errcode( ( sqlite3 * ) pConnection->hConnection ); + } + else + szRet = hb_strdup( "HY000 Unable to get error message" ); + + if( pErrCode ) + *pErrCode = ( HB_ERRCODE ) iNativeErr; + + return szRet; +} + + +/*============= SDD METHODS =============================================================*/ + +static HB_ERRCODE sqlite3Connect( SQLDDCONNECTION * pConnection, PHB_ITEM pItem ) +{ + sqlite3 * db; + void * hConn; + + if( sqlite3_open( S_HB_ARRAYGETSTR( pItem, 2, &hConn, NULL ), &db ) == SQLITE_OK ) + pConnection->hConnection = db; + else + { + pConnection->hConnection = NULL; + sqlite3_close( db ); + } + + hb_strfree( hConn ); + + return pConnection->hConnection ? HB_SUCCESS : HB_FAILURE; +} + + +static HB_ERRCODE sqlite3Disconnect( SQLDDCONNECTION * pConnection ) +{ + return sqlite3_close( ( sqlite3 * ) pConnection->hConnection ) ? HB_SUCCESS : HB_FAILURE; +} + +static HB_ERRCODE sqlite3Execute( SQLDDCONNECTION * pConnection, PHB_ITEM pItem ) +{ + HB_ERRCODE errCode; + int iRow, iCol; + void * hStatement; + char ** pResult = NULL; + char * pszErrMsg = NULL; + + if( sqlite3_get_table( ( sqlite3 * ) pConnection->hConnection, S_HB_ITEMGETSTR( pItem, &hStatement, NULL ), &pResult, &iRow, &iCol, &pszErrMsg ) != SQLITE_OK ) + { + hb_strfree( hStatement ); + sqlite3GetError( pConnection, &errCode ); + hb_errRT_SQ3DD( EG_OPEN, ESQLDD_STMTALLOC, pszErrMsg, hb_itemGetCPtr( pItem ), errCode ); + hb_xfree( pszErrMsg ); + return HB_FAILURE; + } + else + hb_strfree( hStatement ); + + sqlite3_free_table( pResult ); + + /* TODO: new id */ + hb_rddsqlSetError( 0, NULL, hb_itemGetCPtr( pItem ), NULL, ( unsigned long ) iRow ); + return HB_SUCCESS; +} + +static HB_ERRCODE sqlite3Open( SQLBASEAREAP pArea ) +{ + sqlite3_stmt * st = NULL; + const char * pszQuery; + HB_SIZE nQueryLen; + void * hQuery; + HB_USHORT uiFields, uiIndex; + PHB_ITEM pItemEof, pItem; + HB_ERRCODE errCode; + char * szError; + HB_BOOL bError; + + pItem = hb_itemPutC( NULL, pArea->szQuery ); + pszQuery = S_HB_ITEMGETSTR( pItem, &hQuery, &nQueryLen ); + + if( sqlite3_prepare_v2( ( sqlite3 * ) pArea->pConnection->hConnection, pszQuery, ( int ) nQueryLen, &st, NULL ) != SQLITE_OK ) + { + hb_strfree( hQuery ); + hb_itemRelease( pItem ); + szError = sqlite3GetError( pArea->pConnection, &errCode ); + hb_errRT_SQ3DD( 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 ) + { + sqlite3_finalize( st ); + hb_errRT_SQ3DD( EG_OPEN, ESQLDD_INVALIDQUERY, "No rows", pArea->szQuery, errCode ); + 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 ) + { + PHB_ITEM pName; + int iDataType; + int iSize; + int iDec; + char * szOurName; + DBFIELDINFO pFieldInfo; + + pName = S_HB_ITEMPUTSTR( NULL, sqlite3_column_name( st, uiIndex ) ); + szOurName = hb_strdup( hb_itemGetCPtr( pName ) ); + hb_itemRelease( pName ); + pFieldInfo.atomName = hb_strUpper( szOurName, ( HB_SIZE ) strlen( szOurName ) ); + + 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 ); + } + + if( bError ) + break; + } + + if( bError ) + { + hb_itemRelease( pItemEof ); + sqlite3_finalize( st ); + hb_errRT_SQ3DD( 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; + + pArea->pStmt = ( void * ) st; + return HB_SUCCESS; +} + + +static HB_ERRCODE sqlite3Close( SQLBASEAREAP pArea ) +{ + if( pArea->pStmt ) + { + sqlite3_finalize( ( sqlite3_stmt * ) pArea->pStmt ); + pArea->pStmt = NULL; + } + return HB_SUCCESS; +} + + +static HB_ERRCODE sqlite3GoTo( SQLBASEAREAP pArea, HB_ULONG ulRecNo ) +{ + sqlite3_stmt * st = ( sqlite3_stmt * ) pArea->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_LONG_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, ( 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( 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; +} diff --git a/harbour/contrib/rddsql/sddsq3/sddsq3.hbc b/harbour/contrib/rddsql/sddsq3/sddsq3.hbc new file mode 100644 index 0000000000..452648e724 --- /dev/null +++ b/harbour/contrib/rddsql/sddsq3/sddsq3.hbc @@ -0,0 +1,8 @@ +# +# $Id$ +# + +libs=sddsq3 +libs=sqlite3 + +libs=../rddsql.hbc diff --git a/harbour/contrib/rddsql/sddsq3/tests/hbmk.hbm b/harbour/contrib/rddsql/sddsq3/tests/hbmk.hbm new file mode 100644 index 0000000000..49355927b7 --- /dev/null +++ b/harbour/contrib/rddsql/sddsq3/tests/hbmk.hbm @@ -0,0 +1,5 @@ +# +# $Id$ +# + +../sddsq3.hbc diff --git a/harbour/contrib/rddsql/sddsq3/tests/test.sq3 b/harbour/contrib/rddsql/sddsq3/tests/test.sq3 new file mode 100644 index 0000000000..3e92304b76 Binary files /dev/null and b/harbour/contrib/rddsql/sddsq3/tests/test.sq3 differ diff --git a/harbour/contrib/rddsql/sddsq3/tests/test1.prg b/harbour/contrib/rddsql/sddsq3/tests/test1.prg new file mode 100644 index 0000000000..12a1197171 --- /dev/null +++ b/harbour/contrib/rddsql/sddsq3/tests/test1.prg @@ -0,0 +1,42 @@ +/* + * $Id$ + */ + +#include "simpleio.ch" +#include "hbrddsql.ch" + +REQUEST SDDSQLITE3, SQLMIX + +PROCEDURE Main() + LOCAL tmp + + RDDSETDEFAULT( "SQLMIX" ) + SET( _SET_DATEFORMAT, "yyyy-mm-dd" ) + + AEVAL( rddList(), {| X | QOut( X ) } ) + + ? "-1-" + ? "Connect:", tmp := RDDINFO( RDDI_CONNECT, { "SQLITE3", hb_dirBase() + "test.sq3" } ) + IF tmp == 0 + ? "Unable connect to the server" + ENDIF + ? "-2-" + ? "Use:", DBUSEAREA( .T.,, "select * from t1", "t1" ) + ? "-3-" + ? "Alias:", ALIAS() + ? "-4-" + ? "DB struct:", HB_VALTOEXP( DBSTRUCT() ) + ? "-5-" + FOR tmp := 1 TO FCount() + ? FIELDNAME( tmp ), HB_FIELDTYPE( tmp ) + NEXT + ? "-6-" + INKEY( 0 ) + BROWSE() + + INDEX ON FIELD->AGE TO age + DBGOTOP() + BROWSE() + DBCLOSEAREA() + + RETURN