/* * SQLite3 library low-level (client API) interface code * * Copyright 2007-2010 P.Chornyj * * 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 program; see the file LICENSE.txt. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA (or visit https://www.gnu.org/licenses/). * * 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 "sqlite3.h" #include "hbapi.h" #include "hbvm.h" #include "hbapiitm.h" #include "hbapierr.h" #include "hbapifs.h" #include "hbapistr.h" #include "hbstack.h" /* FIXME: verify the exact SQLITE3 version */ #if SQLITE_VERSION_NUMBER <= 3004001 #define sqlite3_int64 HB_LONGLONG #define sqlite3_uint64 HB_ULONGLONG #endif #define HB_SQLITE3_DB 6000001 #define HB_ERR_MEMSTRU_NOT_MEM_BLOCK 4001 #define HB_ERR_MEMSTRU_WRONG_MEMSTRU_BLOCK 4002 #define HB_ERR_MEMSTRU_DESTROYED 4003 #ifdef SQLITE3_DYNLIB extern char * sqlite3_temp_directory; #endif /* SQLITE3_DYNLIB */ static PHB_ITEM hb_sqlite3_itemPut( PHB_ITEM pItem, void * pMemAddr, int iType ); static void * hb_sqlite3_itemGet( PHB_ITEM pItem, int iType, HB_BOOL fError ); static void hb_sqlite3_ret( void * pMemAddr, int iType ); static void * hb_sqlite3_param( int iParam, int iType, HB_BOOL fError ); static int callback( void *, int, char **, char ** ); static int authorizer( void *, int, const char *, const char *, const char *, const char * ); static int busy_handler( void *, int ); static int progress_handler( void * ); static int hook_commit( void * ); static void hook_rollback( void * ); static void func( sqlite3_context *, int, sqlite3_value ** ); #if SQLITE_VERSION_NUMBER >= 3014000 static int trace_handler( unsigned, void *, void *, void * ); #endif typedef struct { sqlite3 * db; PHB_ITEM cbAuthorizer; PHB_ITEM cbBusyHandler; PHB_ITEM cbProgressHandler; PHB_ITEM cbHookCommit; PHB_ITEM cbHookRollback; PHB_ITEM cbFunc; #if SQLITE_VERSION_NUMBER >= 3014000 PHB_ITEM cbTraceHandler; #else PHB_ITEM sProfileFileName; PHB_ITEM sTraceFileName; #endif } HB_SQLITE3, * PHB_SQLITE3; typedef struct { int type; HB_SQLITE3 * hbsqlite3; } HB_SQLITE3_HOLDER, * PHB_SQLITE3_HOLDER; typedef sqlite3_stmt * psqlite3_stmt; /** destructor, it's executed automatically */ static HB_GARBAGE_FUNC( hb_sqlite3_destructor ) { PHB_SQLITE3_HOLDER pStructHolder = ( PHB_SQLITE3_HOLDER ) Cargo; if( pStructHolder && pStructHolder->hbsqlite3 ) { if( pStructHolder->hbsqlite3->db ) { sqlite3_close( pStructHolder->hbsqlite3->db ); pStructHolder->hbsqlite3->db = NULL; } if( pStructHolder->hbsqlite3->cbAuthorizer ) { hb_itemRelease( pStructHolder->hbsqlite3->cbAuthorizer ); pStructHolder->hbsqlite3->cbAuthorizer = NULL; } if( pStructHolder->hbsqlite3->cbBusyHandler ) { hb_itemRelease( pStructHolder->hbsqlite3->cbBusyHandler ); pStructHolder->hbsqlite3->cbBusyHandler = NULL; } if( pStructHolder->hbsqlite3->cbProgressHandler ) { hb_itemRelease( pStructHolder->hbsqlite3->cbProgressHandler ); pStructHolder->hbsqlite3->cbProgressHandler = NULL; } if( pStructHolder->hbsqlite3->cbHookCommit ) { hb_itemRelease( pStructHolder->hbsqlite3->cbHookCommit ); pStructHolder->hbsqlite3->cbHookCommit = NULL; } if( pStructHolder->hbsqlite3->cbHookRollback ) { hb_itemRelease( pStructHolder->hbsqlite3->cbHookRollback ); pStructHolder->hbsqlite3->cbHookRollback = NULL; } if( pStructHolder->hbsqlite3->cbFunc ) { hb_itemRelease( pStructHolder->hbsqlite3->cbFunc ); pStructHolder->hbsqlite3->cbFunc = NULL; } #if SQLITE_VERSION_NUMBER >= 3014000 if( pStructHolder->hbsqlite3->cbTraceHandler ) { hb_itemRelease( pStructHolder->hbsqlite3->cbTraceHandler ); pStructHolder->hbsqlite3->cbTraceHandler = NULL; } #else if( pStructHolder->hbsqlite3->sProfileFileName ) { hb_itemRelease( pStructHolder->hbsqlite3->sProfileFileName ); pStructHolder->hbsqlite3->sProfileFileName = NULL; } if( pStructHolder->hbsqlite3->sTraceFileName ) { hb_itemRelease( pStructHolder->hbsqlite3->sTraceFileName ); pStructHolder->hbsqlite3->sTraceFileName = NULL; } #endif hb_xfree( pStructHolder->hbsqlite3 ); pStructHolder->hbsqlite3 = NULL; } } static HB_GARBAGE_FUNC( hb_sqlite3_mark ) { PHB_SQLITE3_HOLDER pStructHolder = ( PHB_SQLITE3_HOLDER ) Cargo; if( pStructHolder && pStructHolder->hbsqlite3 ) { if( pStructHolder->hbsqlite3->cbAuthorizer ) hb_gcMark( pStructHolder->hbsqlite3->cbAuthorizer ); if( pStructHolder->hbsqlite3->cbBusyHandler ) hb_gcMark( pStructHolder->hbsqlite3->cbBusyHandler ); if( pStructHolder->hbsqlite3->cbProgressHandler ) hb_gcMark( pStructHolder->hbsqlite3->cbProgressHandler ); if( pStructHolder->hbsqlite3->cbHookCommit ) hb_gcMark( pStructHolder->hbsqlite3->cbHookCommit ); if( pStructHolder->hbsqlite3->cbHookRollback ) hb_gcMark( pStructHolder->hbsqlite3->cbHookRollback ); if( pStructHolder->hbsqlite3->cbFunc ) hb_gcMark( pStructHolder->hbsqlite3->cbFunc ); #if SQLITE_VERSION_NUMBER >= 3014000 if( pStructHolder->hbsqlite3->cbTraceHandler ) { hb_gcMark( pStructHolder->hbsqlite3->cbTraceHandler ); } #else if( pStructHolder->hbsqlite3->sProfileFileName ) { hb_gcMark( pStructHolder->hbsqlite3->sProfileFileName ); } if( pStructHolder->hbsqlite3->sTraceFileName ) { hb_gcMark( pStructHolder->hbsqlite3->sTraceFileName ); } #endif } } static const HB_GC_FUNCS s_gcSqlite3Funcs = { hb_sqlite3_destructor, hb_sqlite3_mark }; static PHB_ITEM hb_sqlite3_itemPut( PHB_ITEM pItem, void * pMemAddr, int iType ) { PHB_SQLITE3_HOLDER pStructHolder; if( pItem ) { if( HB_IS_COMPLEX( pItem ) ) hb_itemClear( pItem ); } else pItem = hb_itemNew( pItem ); pStructHolder = ( PHB_SQLITE3_HOLDER ) hb_gcAllocate( sizeof( HB_SQLITE3_HOLDER ), &s_gcSqlite3Funcs ); pStructHolder->hbsqlite3 = ( HB_SQLITE3 * ) pMemAddr; pStructHolder->type = iType; return hb_itemPutPtrGC( pItem, pStructHolder ); } static void * hb_sqlite3_itemGet( PHB_ITEM pItem, int iType, HB_BOOL fError ) { PHB_SQLITE3_HOLDER pStructHolder = ( PHB_SQLITE3_HOLDER ) hb_itemGetPtrGC( pItem, &s_gcSqlite3Funcs ); int iError = 0; HB_SYMBOL_UNUSED( iError ); if( ! pStructHolder ) iError = HB_ERR_MEMSTRU_NOT_MEM_BLOCK; else if( pStructHolder->type != iType ) iError = HB_ERR_MEMSTRU_WRONG_MEMSTRU_BLOCK; else if( ! pStructHolder->hbsqlite3 ) iError = HB_ERR_MEMSTRU_DESTROYED; else return pStructHolder->hbsqlite3; if( fError ) hb_errRT_BASE_SubstR( EG_ARG, iError, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); return NULL; } static void hb_sqlite3_ret( void * pMemAddr, int iType ) { hb_sqlite3_itemPut( hb_stackReturnItem(), pMemAddr, iType ); } static void * hb_sqlite3_param( int iParam, int iType, HB_BOOL fError ) { return hb_sqlite3_itemGet( hb_param( iParam, HB_IT_POINTER ), iType, fError ); } /** Callback helpers: Compile-Time Authorization Callback A Callback To Handle SQLITE_BUSY Errors Query Progress Callbacks Commit And Rollback Notification Callback */ static int callback( void * Cargo, int argc, char ** argv, char ** azColName ) { PHB_ITEM pCallback = ( PHB_ITEM ) Cargo; if( pCallback && hb_vmRequestReenter() ) { PHB_ITEM pArrayValue = hb_itemArrayNew( argc ); PHB_ITEM pArrayColName = hb_itemArrayNew( argc ); int iRes, i; for( i = 0; i < argc; i++ ) { hb_arraySetStrUTF8( pArrayValue, i + 1, ( const char * ) ( argv[ i ] ? argv[ i ] : "NULL" ) ); hb_arraySetStrUTF8( pArrayColName, i + 1, ( const char * ) azColName[ i ] ); } hb_vmPushEvalSym(); hb_vmPush( pCallback ); hb_vmPushInteger( argc ); hb_vmPush( pArrayValue ); hb_vmPush( pArrayColName ); hb_vmSend( 3 ); iRes = hb_parni( -1 ); hb_itemRelease( pArrayValue ); hb_itemRelease( pArrayColName ); hb_vmRequestRestore(); return iRes; } return 0; } static int authorizer( void * Cargo, int iAction, const char * sName1, const char * sName2, const char * sName3, const char * sName4 ) { PHB_ITEM pCallback = ( PHB_ITEM ) Cargo; if( pCallback && hb_vmRequestReenter() ) { int iRes; PHB_ITEM pItem1 = hb_itemPutStrUTF8( NULL, sName1 ); PHB_ITEM pItem2 = hb_itemPutStrUTF8( NULL, sName2 ); PHB_ITEM pItem3 = hb_itemPutStrUTF8( NULL, sName3 ); PHB_ITEM pItem4 = hb_itemPutStrUTF8( NULL, sName4 ); hb_vmPushEvalSym(); hb_vmPush( pCallback ); hb_vmPushInteger( iAction ); hb_vmPush( pItem1 ); hb_vmPush( pItem2 ); hb_vmPush( pItem3 ); hb_vmPush( pItem4 ); hb_vmSend( 5 ); iRes = hb_parni( -1 ); hb_itemRelease( pItem1 ); hb_itemRelease( pItem2 ); hb_itemRelease( pItem3 ); hb_itemRelease( pItem4 ); hb_vmRequestRestore(); return iRes; } return 0; } static int busy_handler( void * Cargo, int iNumberOfTimes ) { PHB_ITEM pCallback = ( PHB_ITEM ) Cargo; if( pCallback && hb_vmRequestReenter() ) { int iRes; hb_vmPushEvalSym(); hb_vmPush( pCallback ); hb_vmPushInteger( iNumberOfTimes ); hb_vmSend( 1 ); iRes = hb_parni( -1 ); hb_vmRequestRestore(); return iRes; } return 0; } static int progress_handler( void * Cargo ) { PHB_ITEM pCallback = ( PHB_ITEM ) Cargo; if( pCallback && hb_vmRequestReenter() ) { int iRes; hb_vmPushEvalSym(); hb_vmPush( pCallback ); hb_vmSend( 0 ); iRes = hb_parni( -1 ); hb_vmRequestRestore(); return iRes; } return 0; } static int hook_commit( void * Cargo ) { PHB_ITEM pCallback = ( PHB_ITEM ) Cargo; if( pCallback && hb_vmRequestReenter() ) { int iRes; hb_vmPushEvalSym(); hb_vmPush( pCallback ); hb_vmSend( 0 ); iRes = hb_parni( -1 ); hb_vmRequestRestore(); return iRes; } return 0; } static void hook_rollback( void * Cargo ) { PHB_ITEM pCallback = ( PHB_ITEM ) Cargo; if( pCallback && hb_vmRequestReenter() ) { hb_vmPushEvalSym(); hb_vmPush( pCallback ); hb_vmSend( 0 ); hb_vmRequestRestore(); } } static void func( sqlite3_context * ctx, int argc, sqlite3_value ** argv ) { PHB_ITEM pCallback = ( PHB_ITEM ) sqlite3_user_data( ctx ); if( pCallback && hb_vmRequestReenter() ) { PHB_ITEM pResult; hb_vmPushEvalSym(); hb_vmPush( pCallback ); hb_vmPushInteger( argc ); if( argc > 0 ) { int i; for( i = 0; i < argc; i++ ) { switch( sqlite3_value_type( argv[ i ] ) ) { case SQLITE_NULL: hb_vmPushNil(); break; case SQLITE_TEXT: hb_itemPutStrUTF8( hb_stackAllocItem(), ( const char * ) sqlite3_value_text( argv[ i ] ) ); break; case SQLITE_FLOAT: hb_vmPushDouble( sqlite3_value_double( argv[ i ] ), HB_DEFAULT_DECIMALS ); break; case SQLITE_INTEGER: #if HB_VMLONG_MAX == INT32_MAX || defined( HB_LONG_LONG_OFF ) hb_vmPushInteger( sqlite3_value_int( argv[ i ] ) ); #else hb_vmPushNumInt( sqlite3_value_int64( argv[ i ] ) ); #endif break; case SQLITE_BLOB: hb_vmPushString( ( const char * ) sqlite3_value_blob( argv[ i ] ), sqlite3_value_bytes( argv[ i ] ) ); break; default: hb_itemPutCConst( hb_stackAllocItem(), ":default:" ); break; } } } hb_vmSend( ( HB_USHORT ) argc + 1 ); pResult = hb_param( -1, HB_IT_ANY ); switch( hb_itemType( pResult ) ) { case HB_IT_NIL: sqlite3_result_null( ctx ); break; case HB_IT_INTEGER: case HB_IT_LONG: #if HB_VMLONG_MAX == INT32_MAX || defined( HB_LONG_LONG_OFF ) sqlite3_result_int( ctx, hb_itemGetNI( pResult ) ); #else sqlite3_result_int64( ctx, hb_itemGetNInt( pResult ) ); #endif break; case HB_IT_DOUBLE: sqlite3_result_double( ctx, hb_itemGetND( pResult ) ); break; case HB_IT_STRING: { void * hText; HB_SIZE nText; const char * pszText = hb_itemGetStrUTF8( pResult, &hText, &nText ); sqlite3_result_text( ctx, pszText, ( int ) nText, SQLITE_TRANSIENT ); hb_strfree( hText ); break; } default: sqlite3_result_error_code( ctx, -1 ); break; } hb_vmRequestRestore(); } } /** sqlite3_libversion() --> cVersion sqlite3_libversion_number() --> nVersionNumber sqlite3_sourceid() --> cSourceID Returns values equivalent to the header constants SQLITE_VERSION, SQLITE_VERSION_NUMBER, SQLITE_SOURCE_ID. */ HB_FUNC( SQLITE3_LIBVERSION ) { hb_retc( sqlite3_libversion() ); } HB_FUNC( SQLITE3_LIBVERSION_NUMBER ) { hb_retni( sqlite3_libversion_number() ); } HB_FUNC( SQLITE3_SOURCEID ) { #if SQLITE_VERSION_NUMBER >= 3006018 hb_retc( sqlite3_sourceid() ); #else hb_retc_null(); #endif } /** sqlite3_initialize() --> nResult sqlite3_shutdown() --> nResult The sqlite3_initialize() routine initializes the SQLite library. The sqlite3_shutdown() routine deallocates any resources that were allocated by sqlite3_initialize() */ HB_FUNC( SQLITE3_INITIALIZE ) { #if SQLITE_VERSION_NUMBER >= 3006000 hb_retni( sqlite3_initialize() ); #else hb_retni( -1 ); #endif } HB_FUNC( SQLITE3_SHUTDOWN ) { #if SQLITE_VERSION_NUMBER >= 3006000 hb_retni( sqlite3_shutdown() ); #else hb_retni( -1 ); #endif } /** Enable Or Disable Extended Result Codes sqlite3_extended_result_codes( db, lOnOff ) --> nResultCode */ HB_FUNC( SQLITE3_EXTENDED_RESULT_CODES ) { HB_SQLITE3 * pHbSqlite3 = ( HB_SQLITE3 * ) hb_sqlite3_param( 1, HB_SQLITE3_DB, HB_TRUE ); if( pHbSqlite3 && pHbSqlite3->db ) hb_retni( sqlite3_extended_result_codes( pHbSqlite3->db, hb_parl( 2 ) ) ); else hb_errRT_BASE_SubstR( EG_ARG, 0, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); } /** Error Codes And Messages sqlite3_errcode( db ) --> returns the numeric result code or extended result code sqlite3_errmsg( db ) --> return English-language text that describes the error */ HB_FUNC( SQLITE3_ERRCODE ) { HB_SQLITE3 * pHbSqlite3 = ( HB_SQLITE3 * ) hb_sqlite3_param( 1, HB_SQLITE3_DB, HB_TRUE ); if( pHbSqlite3 && pHbSqlite3->db ) hb_retni( sqlite3_errcode( pHbSqlite3->db ) ); else hb_errRT_BASE_SubstR( EG_ARG, 0, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); } HB_FUNC( SQLITE3_EXTENDED_ERRCODE ) { #if SQLITE_VERSION_NUMBER >= 3006005 HB_SQLITE3 * pHbSqlite3 = ( HB_SQLITE3 * ) hb_sqlite3_param( 1, HB_SQLITE3_DB, HB_TRUE ); if( pHbSqlite3 && pHbSqlite3->db ) hb_retni( sqlite3_extended_errcode( pHbSqlite3->db ) ); else hb_errRT_BASE_SubstR( EG_ARG, 0, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); #else hb_retni( -1 ); #endif } HB_FUNC( SQLITE3_ERRMSG ) { HB_SQLITE3 * pHbSqlite3 = ( HB_SQLITE3 * ) hb_sqlite3_param( 1, HB_SQLITE3_DB, HB_TRUE ); if( pHbSqlite3 && pHbSqlite3->db ) hb_retstr_utf8( sqlite3_errmsg( pHbSqlite3->db ) ); else hb_errRT_BASE_SubstR( EG_ARG, 0, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); } HB_FUNC( SQLITE3_ERRSTR ) { #if SQLITE_VERSION_NUMBER >= 3007015 hb_retstr_utf8( sqlite3_errstr( hb_parni( 1 ) ) ); #else hb_retc_null(); #endif } /** Suspend Execution For A Short Time sqlite3_sleep( ms ) */ HB_FUNC( SQLITE3_SLEEP ) { hb_retni( sqlite3_sleep( hb_parni( 1 ) ) ); } /** Last Insert Rowid sqlite3_last_insert_rowid( db ) --> nROWID */ HB_FUNC( SQLITE3_LAST_INSERT_ROWID ) { HB_SQLITE3 * pHbSqlite3 = ( HB_SQLITE3 * ) hb_sqlite3_param( 1, HB_SQLITE3_DB, HB_TRUE ); if( pHbSqlite3 && pHbSqlite3->db ) hb_retnint( sqlite3_last_insert_rowid( pHbSqlite3->db ) ); else hb_errRT_BASE_SubstR( EG_ARG, 0, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); } /** Name Of The Directory Holding Temporary Files sqlite3_temp_directory( cDirName ) --> lResult */ HB_FUNC( SQLITE3_TEMP_DIRECTORY ) { HB_BOOL bResult = HB_FALSE; #ifdef SQLITE3_DYNLIB { char * pszFree; const char * pszDirName = hb_fsNameConv( hb_parcx( 1 ), &pszFree ); if( hb_fsIsDirectory( pszDirName ) ) bResult = HB_TRUE; else { if( hb_parl( 2 ) ) /* create temp directory if not exist */ { if( hb_fsMkDir( pszDirName ) ) bResult = HB_TRUE; else HB_TRACE( HB_TR_DEBUG, ( "sqlite_temp_directory(): Could not create directory %s", pszDirName ) ); } else HB_TRACE( HB_TR_DEBUG, ( "sqlite_temp_directory(): Directory does not exist %s", pszDirName ) ); } if( bResult ) sqlite3_temp_directory = hb_strdup( pszDirName ); if( pszFree ) hb_xfree( pszFree ); } #endif /* SQLITE3_DYNLIB */ hb_retl( bResult ); } /** Opening( creating ) A New Database Connection sqlite3_open( cDatabace, lCreateIfNotExist ) --> return pointer to Db or NIL if error occurs sqlite3_open_v2( cDatabace, nOpenMode ) --> return pHbSqlite3 or NIL */ HB_FUNC( SQLITE3_OPEN ) { sqlite3 * db; char * pszFree; const char * pszdbName = hb_fsNameConv( hb_parcx( 1 ), &pszFree ); if( hb_fsFileExists( pszdbName ) || hb_parl( 2 ) ) { if( sqlite3_open( pszdbName, &db ) == SQLITE_OK ) { HB_SQLITE3 * hbsqlite3; hbsqlite3 = ( HB_SQLITE3 * ) hb_xgrabz( sizeof( HB_SQLITE3 ) ); hbsqlite3->db = db; hb_sqlite3_ret( hbsqlite3, HB_SQLITE3_DB ); } else { sqlite3_close( db ); hb_retptr( NULL ); } } else { HB_TRACE( HB_TR_DEBUG, ( "sqlite3_open(): Database does not exist %s", pszdbName ) ); hb_retptr( NULL ); } if( pszFree ) hb_xfree( pszFree ); } HB_FUNC( SQLITE3_OPEN_V2 ) { #if SQLITE_VERSION_NUMBER >= 3005000 sqlite3 * db; char * pszFree; const char * pszdbName = hb_fsNameConv( hb_parcx( 1 ), &pszFree ); if( sqlite3_open_v2( pszdbName, &db, hb_parni( 2 ), NULL ) == SQLITE_OK ) { HB_SQLITE3 * hbsqlite3; hbsqlite3 = ( HB_SQLITE3 * ) hb_xgrabz( sizeof( HB_SQLITE3 ) ); hbsqlite3->db = db; hb_sqlite3_ret( hbsqlite3, HB_SQLITE3_DB ); } else { sqlite3_close( db ); hb_retptr( NULL ); } if( pszFree ) hb_xfree( pszFree ); #else hb_retptr( NULL ); #endif } /** One-Step Query Execution Interface sqlite3_exec( db, cSQLTEXT, [pCallbackFunc | cCallbackFunc] ) --> nResultCode */ HB_FUNC( SQLITE3_EXEC ) { HB_SQLITE3 * pHbSqlite3 = ( HB_SQLITE3 * ) hb_sqlite3_param( 1, HB_SQLITE3_DB, HB_TRUE ); if( pHbSqlite3 && pHbSqlite3->db ) { void * hSQLText; char * pszErrMsg = NULL; int rc; if( HB_ISEVALITEM( 3 ) ) rc = sqlite3_exec( pHbSqlite3->db, hb_parstr_utf8( 2, &hSQLText, NULL ), callback, ( void * ) hb_param( 3, HB_IT_EVALITEM ), &pszErrMsg ); else rc = sqlite3_exec( pHbSqlite3->db, hb_parstr_utf8( 2, &hSQLText, NULL ), NULL, 0, &pszErrMsg ); if( rc != SQLITE_OK ) { HB_TRACE( HB_TR_DEBUG, ( "sqlite3_exec(): Returned error: %s", pszErrMsg ) ); sqlite3_free( pszErrMsg ); } hb_strfree( hSQLText ); hb_retni( rc ); } else hb_errRT_BASE_SubstR( EG_ARG, 0, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); } /** Compiling An SQL Statement sqlite3_prepare( db, cSQLTEXT, [nPrepFlags] ) --> return pointer to compiled statement or NIL if error occurs TODO: pszTail? */ HB_FUNC( SQLITE3_PREPARE ) { HB_SQLITE3 * pHbSqlite3 = ( HB_SQLITE3 * ) hb_sqlite3_param( 1, HB_SQLITE3_DB, HB_TRUE ); if( pHbSqlite3 && pHbSqlite3->db ) { void * hSQLText; HB_SIZE nSQLText; const char * pszSQLText = hb_parstr_utf8( 2, &hSQLText, &nSQLText ); psqlite3_stmt pStmt; const char * pszTail; int result; #if SQLITE_VERSION_NUMBER >= 3020000 result = sqlite3_prepare_v3( pHbSqlite3->db, pszSQLText, ( int ) nSQLText, ( unsigned int ) hb_parnl( 3 ), &pStmt, &pszTail ); #else result = sqlite3_prepare_v2( pHbSqlite3->db, pszSQLText, ( int ) nSQLText, &pStmt, &pszTail ); #endif if( result == SQLITE_OK ) hb_retptr( pStmt ); else { sqlite3_finalize( pStmt ); hb_retptr( NULL ); } hb_strfree( hSQLText ); } else hb_errRT_BASE_SubstR( EG_ARG, 0, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); } /** Determine If An SQL Statement Is Complete sqlite3_complete( sqlText ) --> lResult */ HB_FUNC( SQLITE3_COMPLETE ) { if( HB_ISCHAR( 1 ) ) { void * hSQLText; hb_retl( sqlite3_complete( hb_parstr_utf8( 1, &hSQLText, NULL ) ) ); hb_strfree( hSQLText ); } else hb_errRT_BASE_SubstR( EG_ARG, 0, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); } /** This interface can be used to retrieve a saved copy of the original SQL text used to create a prepared statement if that statement was compiled using either sqlite3_prepare() sqlite3_sql( pStmt ) --> cSQLTEXT */ HB_FUNC( SQLITE3_SQL ) { /* FIXME: verify the exact SQLITE3 version */ #if SQLITE_VERSION_NUMBER > 3004001 psqlite3_stmt pStmt = ( psqlite3_stmt ) hb_parptr( 1 ); if( pStmt ) hb_retstr_utf8( sqlite3_sql( pStmt ) ); else hb_errRT_BASE_SubstR( EG_ARG, 0, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); #else hb_retc_null(); #endif } /** Prepared Statement Status. sqlite3_stmt_status( pStmt, nOp, lResetFlag ) --> nStatus */ HB_FUNC( SQLITE3_STMT_STATUS ) { #if SQLITE_VERSION_NUMBER >= 3006004 psqlite3_stmt pStmt = ( psqlite3_stmt ) hb_parptr( 1 ); if( pStmt ) hb_retni( sqlite3_stmt_status( pStmt, hb_parni( 2 ), ( int ) hb_parl( 3 ) ) ); else hb_errRT_BASE_SubstR( EG_ARG, 0, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); #else hb_retni( -1 ); #endif } /** sqlite3_stmt_readonly( pStmt ) --> lResult Determine If An SQL Statement Writes The Database */ HB_FUNC( SQLITE3_STMT_READONLY ) { #if SQLITE_VERSION_NUMBER >= 3007004 psqlite3_stmt pStmt = ( psqlite3_stmt ) hb_parptr( 1 ); if( pStmt ) hb_retl( ( HB_BOOL ) sqlite3_stmt_readonly( pStmt ) ); else hb_errRT_BASE_SubstR( EG_ARG, 0, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); #else hb_retni( -1 ); #endif } /** Find The Database Handle Associated With A Prepared Statement sqlite3_db_handle( pStmt ) --> pHbSqlite3 */ #if 0 HB_FUNC( SQLITE3_DB_HANDLE ) { psqlite3_stmt pStmt = ( psqlite3_stmt ) hb_parptr( 1 ); if( pStmt ) { /* ... */ } else hb_errRT_BASE_SubstR( EG_ARG, 0, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); } #endif /** Evaluate An Prepared SQL Statement sqlite3_step( pStmt ) --> nResultCode */ HB_FUNC( SQLITE3_STEP ) { psqlite3_stmt pStmt = ( psqlite3_stmt ) hb_parptr( 1 ); if( pStmt ) hb_retni( sqlite3_step( pStmt ) ); else hb_errRT_BASE_SubstR( EG_ARG, 0, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); } /** Reset All Bindings On A Prepared Statement sqlite3_clear_bindings( pStmt ) --> nResultCode Contrary to the intuition of many, sqlite3_reset() does not reset the bindings on a prepared statement. Use this routine to reset all host parameters to NULL. */ HB_FUNC( SQLITE3_CLEAR_BINDINGS ) { psqlite3_stmt pStmt = ( psqlite3_stmt ) hb_parptr( 1 ); if( pStmt ) hb_retni( sqlite3_clear_bindings( pStmt ) ); else hb_errRT_BASE_SubstR( EG_ARG, 0, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); } /** Reset A Prepared Statement Object sqlite3_reset( pStmt ) --> nResultCode */ HB_FUNC( SQLITE3_RESET ) { psqlite3_stmt pStmt = ( psqlite3_stmt ) hb_parptr( 1 ); if( pStmt ) hb_retni( sqlite3_reset( pStmt ) ); else hb_errRT_BASE_SubstR( EG_ARG, 0, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); } /** Finalize A Prepared Statement Object sqlite3_finalize( pStmt ) --> nResultCode */ HB_FUNC( SQLITE3_FINALIZE ) { psqlite3_stmt pStmt = ( psqlite3_stmt ) hb_parptr( 1 ); if( pStmt ) hb_retni( sqlite3_finalize( pStmt ) ); else hb_errRT_BASE_SubstR( EG_ARG, 0, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); } /* int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*)); int sqlite3_bind_double(sqlite3_stmt*, int, double); int sqlite3_bind_int(sqlite3_stmt*, int, int); int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64); int sqlite3_bind_null(sqlite3_stmt*, int); int sqlite3_bind_text(sqlite3_stmt*, int, const char*, int n, void(*)(void*)); int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*); int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n) */ /** Binding Values To Prepared Statements These routines return SQLITE_OK on success or an error code if anything goes wrong. SQLITE_RANGE is returned if the parameter index is out of range. SQLITE_NOMEM is returned if malloc fails. SQLITE_MISUSE is returned if these routines are called on a virtual machine that is the wrong state or which has already been finalized. */ HB_FUNC( SQLITE3_BIND_BLOB ) { psqlite3_stmt pStmt = ( psqlite3_stmt ) hb_parptr( 1 ); if( pStmt ) hb_retni( sqlite3_bind_blob( pStmt, hb_parni( 2 ), hb_parcx( 3 ), ( int ) hb_parcsiz( 3 ) - 1, SQLITE_TRANSIENT ) ); else hb_errRT_BASE_SubstR( EG_ARG, 0, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); } HB_FUNC( SQLITE3_BIND_DOUBLE ) { psqlite3_stmt pStmt = ( psqlite3_stmt ) hb_parptr( 1 ); if( pStmt ) hb_retni( sqlite3_bind_double( pStmt, hb_parni( 2 ), hb_parnd( 3 ) ) ); else hb_errRT_BASE_SubstR( EG_ARG, 0, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); } HB_FUNC( SQLITE3_BIND_INT ) { psqlite3_stmt pStmt = ( psqlite3_stmt ) hb_parptr( 1 ); if( pStmt ) hb_retni( sqlite3_bind_int( pStmt, hb_parni( 2 ), hb_parni( 3 ) ) ); else hb_errRT_BASE_SubstR( EG_ARG, 0, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); } HB_FUNC( SQLITE3_BIND_INT64 ) { psqlite3_stmt pStmt = ( psqlite3_stmt ) hb_parptr( 1 ); sqlite3_int64 int64 = hb_parnint( 3 ); if( pStmt ) hb_retni( sqlite3_bind_int64( pStmt, hb_parni( 2 ), int64 ) ); else hb_errRT_BASE_SubstR( EG_ARG, 0, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); } HB_FUNC( SQLITE3_BIND_NULL ) { psqlite3_stmt pStmt = ( psqlite3_stmt ) hb_parptr( 1 ); if( pStmt ) hb_retni( sqlite3_bind_null( pStmt, hb_parni( 2 ) ) ); else hb_errRT_BASE_SubstR( EG_ARG, 0, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); } HB_FUNC( SQLITE3_BIND_TEXT ) { psqlite3_stmt pStmt = ( psqlite3_stmt ) hb_parptr( 1 ); if( pStmt ) { void * hSQLText; HB_SIZE nSQLText; const char * pszSQLText = hb_parstr_utf8( 3, &hSQLText, &nSQLText ); hb_retni( sqlite3_bind_text( pStmt, hb_parni( 2 ), pszSQLText, ( int ) nSQLText, SQLITE_TRANSIENT ) ); hb_strfree( hSQLText ); } else hb_errRT_BASE_SubstR( EG_ARG, 0, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); } HB_FUNC( SQLITE3_BIND_ZEROBLOB ) { psqlite3_stmt pStmt = ( psqlite3_stmt ) hb_parptr( 1 ); if( pStmt ) hb_retni( sqlite3_bind_zeroblob( pStmt, hb_parni( 2 ), hb_parni( 3 ) ) ); else hb_errRT_BASE_SubstR( EG_ARG, 0, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); } /** Number Of Host Parameters sqlite3_bind_parameter_count( pStmt ) --> nResult */ HB_FUNC( SQLITE3_BIND_PARAMETER_COUNT ) { psqlite3_stmt pStmt = ( psqlite3_stmt ) hb_parptr( 1 ); if( pStmt ) hb_retni( sqlite3_bind_parameter_count( pStmt ) ); else hb_errRT_BASE_SubstR( EG_ARG, 0, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); } /** Index Of A Parameter With A Given Name sqlite3_bind_parameter_index( pStmt, cParameterName ) --> nResult */ HB_FUNC( SQLITE3_BIND_PARAMETER_INDEX ) { psqlite3_stmt pStmt = ( psqlite3_stmt ) hb_parptr( 1 ); if( pStmt ) { void * hParameterName; hb_retni( sqlite3_bind_parameter_index( pStmt, hb_parstr_utf8( 2, &hParameterName, NULL ) ) ); hb_strfree( hParameterName ); } else hb_errRT_BASE_SubstR( EG_ARG, 0, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); } /** Name Of A Host Parameter sqlite3_bind_parameter_name( pStmt, nParameterIndex ) --> cParameterName */ HB_FUNC( SQLITE3_BIND_PARAMETER_NAME ) { psqlite3_stmt pStmt = ( psqlite3_stmt ) hb_parptr( 1 ); if( pStmt ) hb_retstr_utf8( sqlite3_bind_parameter_name( pStmt, hb_parni( 2 ) ) ); else hb_errRT_BASE_SubstR( EG_ARG, 0, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); } /** Count The Number Of Rows Modified sqlite3_changes( db ) --> nRowCount */ HB_FUNC( SQLITE3_CHANGES ) { HB_SQLITE3 * pHbSqlite3 = ( HB_SQLITE3 * ) hb_sqlite3_param( 1, HB_SQLITE3_DB, HB_TRUE ); if( pHbSqlite3 && pHbSqlite3->db ) hb_retni( sqlite3_changes( pHbSqlite3->db ) ); else hb_errRT_BASE_SubstR( EG_ARG, 0, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); } /** Total Number Of Rows Modified sqlite3_total_changes( db ) --> nRowCount */ HB_FUNC( SQLITE3_TOTAL_CHANGES ) { HB_SQLITE3 * pHbSqlite3 = ( HB_SQLITE3 * ) hb_sqlite3_param( 1, HB_SQLITE3_DB, HB_TRUE ); if( pHbSqlite3 && pHbSqlite3->db ) hb_retni( sqlite3_total_changes( pHbSqlite3->db ) ); else hb_errRT_BASE_SubstR( EG_ARG, 0, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); } /** Number Of Columns In A Result Set sqlite3_column_count( pStmt ) --> nColumnCount */ HB_FUNC( SQLITE3_COLUMN_COUNT ) { psqlite3_stmt pStmt = ( psqlite3_stmt ) hb_parptr( 1 ); if( pStmt ) hb_retni( sqlite3_column_count( pStmt ) ); else hb_errRT_BASE_SubstR( EG_ARG, 0, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); } /** sqlite3_column_type( pStmt, nIndex ) --> nColumnType nColumnType is Datatype code for the initial data type of the result column SQLITE_INTEGER 1 SQLITE_FLOAT 2 SQLITE_TEXT 3 SQLITE3_TEXT 3 SQLITE_BLOB 4 SQLITE_NULL 5 Declared Datatype Of A Query Result (see doc) sqlite3_column_decltype( pStmt, nIndex ) --> nColumnDeclType */ HB_FUNC( SQLITE3_COLUMN_TYPE ) { psqlite3_stmt pStmt = ( psqlite3_stmt ) hb_parptr( 1 ); if( pStmt ) hb_retni( sqlite3_column_type( pStmt, hb_parni( 2 ) - 1 ) ); else hb_errRT_BASE_SubstR( EG_ARG, 0, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); } HB_FUNC( SQLITE3_COLUMN_DECLTYPE ) { psqlite3_stmt pStmt = ( psqlite3_stmt ) hb_parptr( 1 ); if( pStmt ) hb_retstr_utf8( sqlite3_column_decltype( pStmt, hb_parni( 2 ) - 1 ) ); else hb_errRT_BASE_SubstR( EG_ARG, 0, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); } /** Column Names In A Result Set sqlite3_column_name( pStmt, columnIndex ) --> columnName */ HB_FUNC( SQLITE3_COLUMN_NAME ) { psqlite3_stmt pStmt = ( psqlite3_stmt ) hb_parptr( 1 ); if( pStmt ) hb_retstr_utf8( sqlite3_column_name( pStmt, hb_parni( 2 ) - 1 ) ); else hb_errRT_BASE_SubstR( EG_ARG, 0, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); } /** sqlite3_column_bytes( pStmt, columnIndex ) --> returns the number of bytes in that BLOB or string Results Values From A Query sqlite3_column_blob( pStmt, columnIndex ) --> value as BLOB sqlite3_column_double( pStmt, columnIndex ) --> value as double sqlite3_column_int( pStmt, columnIndex ) --> value as integer sqlite3_column_int64( pStmt, columnIndex ) --> value as long long sqlite3_column_text( pStmt, columnIndex ) --> value as text */ HB_FUNC( SQLITE3_COLUMN_BYTES ) { psqlite3_stmt pStmt = ( psqlite3_stmt ) hb_parptr( 1 ); if( pStmt ) hb_retni( sqlite3_column_bytes( pStmt, hb_parni( 2 ) - 1 ) ); else hb_errRT_BASE_SubstR( EG_ARG, 0, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); } HB_FUNC( SQLITE3_COLUMN_BLOB ) { psqlite3_stmt pStmt = ( psqlite3_stmt ) hb_parptr( 1 ); if( pStmt ) { int iIndex = hb_parni( 2 ) - 1; hb_retclen( ( const char * ) sqlite3_column_blob( pStmt, iIndex ), sqlite3_column_bytes( pStmt, iIndex ) ); } else hb_errRT_BASE_SubstR( EG_ARG, 0, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); } HB_FUNC( SQLITE3_COLUMN_DOUBLE ) { psqlite3_stmt pStmt = ( psqlite3_stmt ) hb_parptr( 1 ); if( pStmt ) hb_retnd( sqlite3_column_double( pStmt, hb_parni( 2 ) - 1 ) ); else hb_errRT_BASE_SubstR( EG_ARG, 0, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); } HB_FUNC( SQLITE3_COLUMN_INT ) { psqlite3_stmt pStmt = ( psqlite3_stmt ) hb_parptr( 1 ); if( pStmt ) hb_retni( sqlite3_column_int( pStmt, hb_parni( 2 ) - 1 ) ); else hb_errRT_BASE_SubstR( EG_ARG, 0, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); } HB_FUNC( SQLITE3_COLUMN_INT64 ) { psqlite3_stmt pStmt = ( psqlite3_stmt ) hb_parptr( 1 ); if( pStmt ) hb_retnint( sqlite3_column_int64( pStmt, hb_parni( 2 ) - 1 ) ); else hb_errRT_BASE_SubstR( EG_ARG, 0, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); } HB_FUNC( SQLITE3_COLUMN_TEXT ) { psqlite3_stmt pStmt = ( psqlite3_stmt ) hb_parptr( 1 ); if( pStmt ) { int iIndex = hb_parni( 2 ) - 1; hb_retstrlen_utf8( ( const char * ) sqlite3_column_text( pStmt, iIndex ), sqlite3_column_bytes( pStmt, iIndex ) ); } else hb_errRT_BASE_SubstR( EG_ARG, 0, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); } HB_FUNC( SQLITE3_LOAD_EXTENSION ) { #ifndef SQLITE_OMIT_LOAD_EXTENSION HB_SQLITE3 * pHbSqlite3 = ( HB_SQLITE3 * ) hb_sqlite3_param( 1, HB_SQLITE3_DB, HB_TRUE ); if( pHbSqlite3 && pHbSqlite3->db ) { char * zErrMsg = NULL; hb_retni( sqlite3_load_extension( pHbSqlite3->db, hb_parcx( 2 ), hb_parc( 3 ), &zErrMsg ) ); hb_storc( zErrMsg, 4 ); sqlite3_free( zErrMsg ); } else hb_errRT_BASE_SubstR( EG_ARG, 0, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); #else hb_retni( -1 ); #endif /* SQLITE_OMIT_LOAD_EXTENSION */ } /** Enable Or Disable Extension Loading sqlite3_enable_load_extension( db, lOnOff ) --> prev.state */ HB_FUNC( SQLITE3_ENABLE_LOAD_EXTENSION ) { HB_SQLITE3 * pHbSqlite3 = ( HB_SQLITE3 * ) hb_sqlite3_param( 1, HB_SQLITE3_DB, HB_TRUE ); if( pHbSqlite3 && pHbSqlite3->db ) #ifndef SQLITE_OMIT_LOAD_EXTENSION hb_retni( sqlite3_enable_load_extension( pHbSqlite3->db, hb_parl( 2 ) ) ); #else hb_retni( -1 ); #endif /* SQLITE_OMIT_LOAD_EXTENSION */ else hb_errRT_BASE_SubstR( EG_ARG, 0, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); } /** Reset Automatic Extension Loading sqlite3_reset_auto_extension() */ HB_FUNC( SQLITE3_RESET_AUTO_EXTENSION ) { sqlite3_reset_auto_extension(); } /** Set A Busy Timeout sqlite3_busy_timeout( db, ms ) */ HB_FUNC( SQLITE3_BUSY_TIMEOUT ) { HB_SQLITE3 * pHbSqlite3 = ( HB_SQLITE3 * ) hb_sqlite3_param( 1, HB_SQLITE3_DB, HB_TRUE ); if( pHbSqlite3 && pHbSqlite3->db ) hb_retni( sqlite3_busy_timeout( pHbSqlite3->db, hb_parni( 2 ) ) ); else hb_errRT_BASE_SubstR( EG_ARG, 0, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); } /** Convenience Routines For Running Queries sqlite3_get_table( db, sqlText ) --> aResult */ HB_FUNC( SQLITE3_GET_TABLE ) { HB_SQLITE3 * pHbSqlite3 = ( HB_SQLITE3 * ) hb_sqlite3_param( 1, HB_SQLITE3_DB, HB_TRUE ); if( pHbSqlite3 && pHbSqlite3->db ) { void * hSQLText; PHB_ITEM pResultList = hb_itemArrayNew( 0 ); int iRow, iCol; char * pszErrMsg = NULL; char ** pResult; if( sqlite3_get_table( pHbSqlite3->db, hb_parstr_utf8( 2, &hSQLText, NULL ), &pResult, &iRow, &iCol, &pszErrMsg ) == SQLITE_OK ) { int i, k = 0; for( i = 0; i < iRow + 1; i++ ) { PHB_ITEM pArray = hb_itemArrayNew( iCol ); int j; for( j = 1; j <= iCol; j++, k++ ) hb_arraySetStrUTF8( pArray, j, ( const char * ) pResult[ k ] ); hb_arrayAddForward( pResultList, pArray ); hb_itemRelease( pArray ); } } else { HB_TRACE( HB_TR_DEBUG, ( "sqlite3_get_table(): Returned error: %s", pszErrMsg ) ); sqlite3_free( pszErrMsg ); } sqlite3_free_table( pResult ); hb_strfree( hSQLText ); hb_itemReturnRelease( pResultList ); } else hb_errRT_BASE_SubstR( EG_ARG, 0, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); } /** Extract Metadata About A Column Of A Table based on int sqlite3_table_column_metadata( sqlite3 *db, - IN: Connection handle const char *zDbName, - IN: Database name or NULL const char *zTableName, - IN: Table name const char *zColumnName, - IN: Column name char const **pzDataType, - OUT: Declared data type char const **pzCollSeq, - OUT: Collation sequence name int *pNotNull, - OUT: True if NOT NULL constraint exists int *pPrimaryKey, - OUT: True if column part of PK int *pAutoinc - OUT: True if column is auto-increment ); */ HB_FUNC( SQLITE3_TABLE_COLUMN_METADATA ) { #ifdef SQLITE_ENABLE_COLUMN_METADATA HB_SQLITE3 * pHbSqlite3 = ( HB_SQLITE3 * ) hb_sqlite3_param( 1, HB_SQLITE3_DB, HB_TRUE ); if( pHbSqlite3 && pHbSqlite3->db ) { char const * pzDataType = NULL; char const * pzCollSeq = NULL; int iNotNull = 0; int iPrimaryKey = 0; int iAutoinc = 0; void * hDbName; void * hTableName; void * hColumnName; if( sqlite3_table_column_metadata( pHbSqlite3->db, hb_parstr_utf8( 2, &hDbName, NULL ), hb_parstr_utf8( 3, &hTableName, NULL ), hb_parstr_utf8( 4, &hColumnName, NULL ), &pzDataType /* pzDataDtype */, &pzCollSeq /* pzCollSeq */, &iNotNull, &iPrimaryKey, &iAutoinc ) == SQLITE_OK ) { PHB_ITEM pArray = hb_itemArrayNew( 5 ); hb_arraySetStrUTF8( pArray, 1, pzDataType ); hb_arraySetStrUTF8( pArray, 2, pzCollSeq ); hb_arraySetL( pArray, 3, ( HB_BOOL ) ( iNotNull != 0 ) ); hb_arraySetL( pArray, 4, ( HB_BOOL ) ( iPrimaryKey != 0 ) ); hb_arraySetL( pArray, 5, ( HB_BOOL ) ( iAutoinc != 0 ) ); hb_itemReturnRelease( pArray ); } hb_strfree( hDbName ); hb_strfree( hTableName ); hb_strfree( hColumnName ); } else hb_errRT_BASE_SubstR( EG_ARG, 0, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); #else hb_reta( 0 ); #endif /* SQLITE_ENABLE_COLUMN_METADATA */ } /** Source Of Data In A Query Result sqlite3_column_database_name( pStmt, ColumnIndex ) --> cDatabaseName sqlite3_column_table_name( pStmt, ColumnIndex ) --> cTableName sqlite3_column_origin_name( pStmt, ColumnIndex ) --> cColumnName */ HB_FUNC( SQLITE3_COLUMN_DATABASE_NAME ) { #ifdef SQLITE_ENABLE_COLUMN_METADATA psqlite3_stmt pStmt = ( psqlite3_stmt ) hb_parptr( 1 ); if( pStmt ) hb_retstr_utf8( sqlite3_column_database_name( pStmt, hb_parni( 2 ) - 1 ) ); else hb_errRT_BASE_SubstR( EG_ARG, 0, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); #else hb_retc_null(); #endif /* SQLITE_ENABLE_COLUMN_METADATA */ } HB_FUNC( SQLITE3_COLUMN_TABLE_NAME ) { #ifdef SQLITE_ENABLE_COLUMN_METADATA psqlite3_stmt pStmt = ( psqlite3_stmt ) hb_parptr( 1 ); if( pStmt ) hb_retstr_utf8( sqlite3_column_table_name( pStmt, hb_parni( 2 ) - 1 ) ); else hb_errRT_BASE_SubstR( EG_ARG, 0, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); #else hb_retc_null(); #endif /* SQLITE_ENABLE_COLUMN_METADATA */ } HB_FUNC( SQLITE3_COLUMN_ORIGIN_NAME ) { #ifdef SQLITE_ENABLE_COLUMN_METADATA psqlite3_stmt pStmt = ( psqlite3_stmt ) hb_parptr( 1 ); if( pStmt ) hb_retstr_utf8( sqlite3_column_origin_name( pStmt, hb_parni( 2 ) - 1 ) ); else hb_errRT_BASE_SubstR( EG_ARG, 0, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); #else hb_retc_null(); #endif /* SQLITE_ENABLE_COLUMN_METADATA */ } /* BLOB I/O */ /** Open A BLOB For Incremental I/O Open a handle to the blob located in row iRow, column zColumn, table zTable in database zDb. i.e. the same blob that would be selected by: SELECT zColumn FROM zDb.zTable WHERE rowid = iRow; */ HB_FUNC( SQLITE3_BLOB_OPEN ) { HB_SQLITE3 * pHbSqlite3 = ( HB_SQLITE3 * ) hb_sqlite3_param( 1, HB_SQLITE3_DB, HB_TRUE ); if( pHbSqlite3 && pHbSqlite3->db ) { sqlite3_blob * ppBlob = NULL; void * hDbName; void * hTableName; void * hColumnName; if( sqlite3_blob_open( pHbSqlite3->db, hb_parstr_utf8( 2, &hDbName, NULL ), hb_parstr_utf8( 3, &hTableName, NULL ), hb_parstr_utf8( 4, &hColumnName, NULL ), ( sqlite3_int64 ) hb_parnint( 5 ) /* iRow */, hb_parni( 6 ) /* flags */, &ppBlob ) == SQLITE_OK ) hb_retptr( ppBlob ); else hb_retptr( NULL ); hb_strfree( hDbName ); hb_strfree( hTableName ); hb_strfree( hColumnName ); } else hb_retptr( NULL ); } /** Move a BLOB Handle to a New Row */ HB_FUNC( SQLITE3_BLOB_REOPEN ) { #if SQLITE_VERSION_NUMBER >= 3007004 sqlite3_blob * pBlob = ( sqlite3_blob * ) hb_parptr( 1 ); if( pBlob ) hb_retni( sqlite3_blob_reopen( pBlob, hb_parnint( 2 ) ) ); else hb_errRT_BASE_SubstR( EG_ARG, 0, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); #else hb_retni( -1 ); #endif } /** Close A BLOB Handle */ HB_FUNC( SQLITE3_BLOB_CLOSE ) { sqlite3_blob * pBlob = ( sqlite3_blob * ) hb_parptr( 1 ); if( pBlob ) hb_retni( sqlite3_blob_close( pBlob ) ); else hb_errRT_BASE_SubstR( EG_ARG, 0, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); } /** Return The Size Of An Open BLOB */ HB_FUNC( SQLITE3_BLOB_BYTES ) { sqlite3_blob * pBlob = ( sqlite3_blob * ) hb_parptr( 1 ); if( pBlob ) hb_retni( sqlite3_blob_bytes( pBlob ) ); else hb_errRT_BASE_SubstR( EG_ARG, 0, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); } /** Read Data From A BLOB Incrementally */ HB_FUNC( SQLITE3_BLOB_READ ) { sqlite3_blob * pBlob = ( sqlite3_blob * ) hb_parptr( 1 ); if( pBlob ) { int iLen = hb_parni( 2 ); char * buffer; if( iLen == 0 ) iLen = sqlite3_blob_bytes( pBlob ); buffer = ( char * ) hb_xgrab( iLen + 1 ); if( SQLITE_OK == sqlite3_blob_read( pBlob, ( void * ) buffer, iLen, hb_parni( 3 ) ) ) hb_retclen_buffer( buffer, iLen ); else hb_xfree( buffer ); } else hb_errRT_BASE_SubstR( EG_ARG, 0, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); } /** Write Data Into A BLOB Incrementally */ HB_FUNC( SQLITE3_BLOB_WRITE ) { sqlite3_blob * pBlob = ( sqlite3_blob * ) hb_parptr( 1 ); if( pBlob ) { int iLen = hb_parni( 3 ); if( iLen == 0 ) iLen = ( int ) hb_parcsiz( 2 ) - 1; hb_retni( sqlite3_blob_write( pBlob, hb_parcx( 2 ), iLen, hb_parni( 4 ) ) ); } else hb_errRT_BASE_SubstR( EG_ARG, 0, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); } /** Test To See If The Database Is In Auto-Commit Mode sqlite3_get_autocommit( db ) --> lResult */ HB_FUNC( SQLITE3_GET_AUTOCOMMIT ) { HB_SQLITE3 * pHbSqlite3 = ( HB_SQLITE3 * ) hb_sqlite3_param( 1, HB_SQLITE3_DB, HB_TRUE ); if( pHbSqlite3 && pHbSqlite3->db ) hb_retl( sqlite3_get_autocommit( pHbSqlite3->db ) ); else hb_errRT_BASE_SubstR( EG_ARG, 0, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); } /** Enable Or Disable Shared Pager Cache sqlite3_enable_shared_cache( lOnOff ) --> nResultCode */ HB_FUNC( SQLITE3_ENABLE_SHARED_CACHE ) { hb_retni( sqlite3_enable_shared_cache( hb_parl( 1 ) ) ); } /** Tracing And Profiling Functions sqlite3_trace_v2( db, nMask, [ bCallback ] ) // Starting with 3.14.0 sqlite3_trace( db, lOnOff, [ filename ] ) // Deprecated in 3.14.0 sqlite3_profile( db, lOnOff, [ filename ] ) // Deprecated in 3.14.0 */ #if SQLITE_VERSION_NUMBER >= 3014000 static int trace_handler( unsigned uType, void *cbTraceHandler, void * p, void * x ) { PHB_ITEM pCallback = ( PHB_ITEM ) cbTraceHandler; int iRes = 0; if( pCallback && hb_vmRequestReenter() ) { hb_vmPushEvalSym(); hb_vmPush( pCallback ); hb_vmPushNumInt( uType ); switch( uType ) { case SQLITE_TRACE_STMT: hb_vmPushPointer( p ); hb_vmPushString( ( const char * ) x, strlen( ( char * ) x ) ); hb_vmSend( 3 ); break; case SQLITE_TRACE_PROFILE: hb_vmPushPointer( p ); hb_vmPushNumInt( *( sqlite3_uint64 * ) x ); hb_vmSend( 3 ); break; case SQLITE_TRACE_ROW: HB_SYMBOL_UNUSED( x ); hb_vmPushPointer( p ); hb_vmSend( 2 ); break; case SQLITE_TRACE_CLOSE: { PHB_ITEM pItem = hb_itemNew( NULL ); HB_SQLITE3 * hbsqlite3 = ( HB_SQLITE3 * ) hb_xgrabz( sizeof( HB_SQLITE3 ) ); HB_SYMBOL_UNUSED( x ); hbsqlite3->db = ( sqlite3 * ) p; hb_sqlite3_itemPut( pItem, hbsqlite3, HB_SQLITE3_DB ); hb_vmPush( pItem ); hb_vmSend( 2 ); /* We don't want sqlite3_close() called recursively * and don't want to implement a weak reference engine yet * so we just clear the pointer before hb_itemRelease(). */ hbsqlite3->db = NULL; hb_itemRelease( pItem ); break; } } iRes = hb_parni( -1 ); hb_vmRequestRestore(); } return iRes; } #endif HB_FUNC( SQLITE3_TRACE_V2 ) { #if SQLITE_VERSION_NUMBER >= 3014000 HB_SQLITE3 * pHbSqlite3 = ( HB_SQLITE3 * ) hb_sqlite3_param( 1, HB_SQLITE3_DB, HB_TRUE ); if( pHbSqlite3 && pHbSqlite3->db ) { unsigned uMask = ( unsigned int ) hb_parnint( 2 ); int iRes; if( pHbSqlite3->cbTraceHandler ) { hb_itemRelease( pHbSqlite3->cbTraceHandler ); pHbSqlite3->cbTraceHandler = NULL; } if( HB_ISEVALITEM( 3 ) ) { pHbSqlite3->cbTraceHandler = hb_itemNew( hb_param( 3, HB_IT_EVALITEM ) ); hb_gcUnlock( pHbSqlite3->cbTraceHandler ); iRes = sqlite3_trace_v2( pHbSqlite3->db, uMask, uMask ? trace_handler : NULL, uMask ? ( void * ) pHbSqlite3->cbTraceHandler : NULL ); } else iRes = sqlite3_trace_v2( pHbSqlite3->db, 0, NULL, NULL ); hb_retni( iRes ); } else hb_errRT_BASE_SubstR( EG_ARG, 0, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); #else hb_errRT_BASE_SubstR( EG_UNSUPPORTED, 0, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); #endif } #if SQLITE_VERSION_NUMBER < 3014000 static void SQL3ProfileLog( void * sFile, const char * sProfileMsg, sqlite3_uint64 uint64 ) { if( sProfileMsg ) { FILE * hFile = hb_fopen( sFile ? ( const char * ) sFile : "hbsq3_pr.log", "a" ); if( hFile ) { fprintf( hFile, "%s - %" PFLL "u\n", sProfileMsg, uint64 ); fclose( hFile ); } } } static void SQL3TraceLog( void * sFile, const char * sTraceMsg ) { if( sTraceMsg ) { FILE * hFile = hb_fopen( sFile ? ( const char * ) sFile : "hbsq3_tr.log", "a" ); if( hFile ) { fprintf( hFile, "%s\n", sTraceMsg ); fclose( hFile ); } } } #endif HB_FUNC( SQLITE3_PROFILE ) { #if SQLITE_VERSION_NUMBER < 3014000 HB_SQLITE3 * pHbSqlite3 = ( HB_SQLITE3 * ) hb_sqlite3_param( 1, HB_SQLITE3_DB, HB_TRUE ); if( pHbSqlite3 && pHbSqlite3->db ) { HB_BOOL bFlag = hb_parl( 2 ); if( pHbSqlite3->sProfileFileName ) { hb_itemRelease( pHbSqlite3->sProfileFileName ); pHbSqlite3->sProfileFileName = NULL; } if( bFlag && HB_ISCHAR( 3 ) ) { pHbSqlite3->sProfileFileName = hb_itemNew( hb_param( 3, HB_IT_STRING ) ); hb_gcUnlock( pHbSqlite3->sProfileFileName ); } sqlite3_profile( pHbSqlite3->db, bFlag ? SQL3ProfileLog : NULL, pHbSqlite3->sProfileFileName ? HB_UNCONST( hb_itemGetCPtr( pHbSqlite3->sProfileFileName ) ) : NULL ); } else hb_errRT_BASE_SubstR( EG_ARG, 0, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); #else hb_errRT_BASE_SubstR( EG_UNSUPPORTED, 0, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); #endif } HB_FUNC( SQLITE3_TRACE ) { #if SQLITE_VERSION_NUMBER < 3014000 HB_SQLITE3 * pHbSqlite3 = ( HB_SQLITE3 * ) hb_sqlite3_param( 1, HB_SQLITE3_DB, HB_TRUE ); if( pHbSqlite3 && pHbSqlite3->db ) { HB_BOOL bFlag = hb_parl( 2 ); if( pHbSqlite3->sTraceFileName ) { hb_itemRelease( pHbSqlite3->sTraceFileName ); pHbSqlite3->sTraceFileName = NULL; } if( bFlag && HB_ISCHAR( 3 ) ) { pHbSqlite3->sTraceFileName = hb_itemNew( hb_param( 3, HB_IT_STRING ) ); hb_gcUnlock( pHbSqlite3->sTraceFileName ); } sqlite3_trace( pHbSqlite3->db, bFlag ? SQL3TraceLog : NULL, pHbSqlite3->sTraceFileName ? HB_UNCONST( hb_itemGetCPtr( pHbSqlite3->sTraceFileName ) ) : NULL ); } else hb_errRT_BASE_SubstR( EG_ARG, 0, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); #else hb_errRT_BASE_SubstR( EG_UNSUPPORTED, 0, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); #endif } /** BLOB Import/export */ HB_FUNC( SQLITE3_FILE_TO_BUFF ) { HB_SIZE nSize; char * pBuffer = ( char * ) hb_fileLoad( hb_parcx( 1 ), 0, &nSize ); if( pBuffer ) hb_retclen_buffer( pBuffer, nSize ); else hb_retc_null(); } HB_FUNC( SQLITE3_BUFF_TO_FILE ) { if( HB_ISCHAR( 1 ) ) { PHB_FILE handle = hb_fileExtOpen( hb_parc( 1 ), NULL, FO_WRITE | FO_EXCLUSIVE | FO_PRIVATE | FXO_TRUNCATE | FXO_SHARELOCK | FXO_NOSEEKPOS, NULL, NULL ); if( handle ) { HB_SIZE nSize = hb_parclen( 2 ); hb_retns( hb_fileWrite( handle, hb_parcx( 2 ), nSize, -1 ) == nSize ? 0 : -1 ); hb_fileClose( handle ); return; } } hb_retns( -1 ); } /** Causes any pending database operation to abort and return at its earliest opportunity. sqlite3_interrupt( db ) --> NIL */ HB_FUNC( SQLITE3_INTERRUPT ) { HB_SQLITE3 * pHbSqlite3 = ( HB_SQLITE3 * ) hb_sqlite3_param( 1, HB_SQLITE3_DB, HB_TRUE ); if( pHbSqlite3 && pHbSqlite3->db ) sqlite3_interrupt( pHbSqlite3->db ); } /** A Callback To Handle SQLITE_BUSY Errors sqlite3_busy_handler( db, nNumOfOpCodes, [cFunc|sFunc] ) */ HB_FUNC( SQLITE3_BUSY_HANDLER ) { HB_SQLITE3 * pHbSqlite3 = ( HB_SQLITE3 * ) hb_sqlite3_param( 1, HB_SQLITE3_DB, HB_TRUE ); if( pHbSqlite3 && pHbSqlite3->db ) { if( pHbSqlite3->cbBusyHandler ) { hb_itemRelease( pHbSqlite3->cbBusyHandler ); pHbSqlite3->cbBusyHandler = NULL; } if( HB_ISEVALITEM( 2 ) ) { pHbSqlite3->cbBusyHandler = hb_itemNew( hb_param( 2, HB_IT_EVALITEM ) ); hb_gcUnlock( pHbSqlite3->cbBusyHandler ); sqlite3_busy_handler( pHbSqlite3->db, busy_handler, ( void * ) pHbSqlite3->cbBusyHandler ); } else sqlite3_busy_handler( pHbSqlite3->db, NULL, NULL ); } } /** Query Progress Callbacks sqlite3_progress_handler( db, nNumOfOpCodes, [cFunc|sFunc] ) */ HB_FUNC( SQLITE3_PROGRESS_HANDLER ) { HB_SQLITE3 * pHbSqlite3 = ( HB_SQLITE3 * ) hb_sqlite3_param( 1, HB_SQLITE3_DB, HB_TRUE ); if( pHbSqlite3 && pHbSqlite3->db ) { if( pHbSqlite3->cbProgressHandler ) { hb_itemRelease( pHbSqlite3->cbProgressHandler ); pHbSqlite3->cbProgressHandler = NULL; } if( HB_ISNUM( 2 ) && HB_ISEVALITEM( 3 ) ) { pHbSqlite3->cbProgressHandler = hb_itemNew( hb_param( 3, HB_IT_EVALITEM ) ); hb_gcUnlock( pHbSqlite3->cbProgressHandler ); sqlite3_progress_handler( pHbSqlite3->db, hb_parni( 2 ), progress_handler, ( void * ) pHbSqlite3->cbProgressHandler ); } else sqlite3_progress_handler( pHbSqlite3->db, 0, NULL, NULL ); } } /** Commit And Rollback Notification Callbacks sqlite3_commit_hook( db, [cFunc|sFunc] ) sqlite3_rollback_hook( db, [cFunc|sFunc] ) */ HB_FUNC( SQLITE3_COMMIT_HOOK ) { HB_SQLITE3 * pHbSqlite3 = ( HB_SQLITE3 * ) hb_sqlite3_param( 1, HB_SQLITE3_DB, HB_TRUE ); if( pHbSqlite3 && pHbSqlite3->db ) { if( pHbSqlite3->cbHookCommit ) { hb_itemRelease( pHbSqlite3->cbHookCommit ); pHbSqlite3->cbHookCommit = NULL; } if( HB_ISEVALITEM( 2 ) ) { pHbSqlite3->cbHookCommit = hb_itemNew( hb_param( 2, HB_IT_EVALITEM ) ); hb_gcUnlock( pHbSqlite3->cbHookCommit ); sqlite3_commit_hook( pHbSqlite3->db, hook_commit, ( void * ) pHbSqlite3->cbHookCommit ); } else sqlite3_commit_hook( pHbSqlite3->db, NULL, NULL ); } } HB_FUNC( SQLITE3_ROLLBACK_HOOK ) { HB_SQLITE3 * pHbSqlite3 = ( HB_SQLITE3 * ) hb_sqlite3_param( 1, HB_SQLITE3_DB, HB_TRUE ); if( pHbSqlite3 && pHbSqlite3->db ) { if( pHbSqlite3->cbHookRollback ) { hb_itemRelease( pHbSqlite3->cbHookRollback ); pHbSqlite3->cbHookRollback = NULL; } if( HB_ISEVALITEM( 2 ) ) { pHbSqlite3->cbHookRollback = hb_itemNew( hb_param( 2, HB_IT_EVALITEM ) ); hb_gcUnlock( pHbSqlite3->cbHookRollback ); sqlite3_rollback_hook( pHbSqlite3->db, hook_rollback, ( void * ) pHbSqlite3->cbHookRollback ); } else sqlite3_rollback_hook( pHbSqlite3->db, NULL, NULL ); } } /** Compile-Time Authorization Callbacks sqlite3_set_authorizer( pDb, [cFunc|sFunc] ) */ HB_FUNC( SQLITE3_SET_AUTHORIZER ) { HB_SQLITE3 * pHbSqlite3 = ( HB_SQLITE3 * ) hb_sqlite3_param( 1, HB_SQLITE3_DB, HB_TRUE ); if( pHbSqlite3 && pHbSqlite3->db ) { if( pHbSqlite3->cbAuthorizer ) { hb_itemRelease( pHbSqlite3->cbAuthorizer ); pHbSqlite3->cbAuthorizer = NULL; } if( HB_ISEVALITEM( 2 ) ) { pHbSqlite3->cbAuthorizer = hb_itemNew( hb_param( 2, HB_IT_EVALITEM ) ); hb_gcUnlock( pHbSqlite3->cbAuthorizer ); hb_retni( sqlite3_set_authorizer( pHbSqlite3->db, authorizer, ( void * ) pHbSqlite3->cbAuthorizer ) ); } else hb_retni( sqlite3_set_authorizer( pHbSqlite3->db, NULL, NULL ) ); } } /** This API is used to overwrite the contents of one database with that of another. It is useful either for creating backups of databases or for copying in-memory databases to or from persistent files. ! Experimental ! sqlite3_backup_init( DbDest, cDestName, DbSource, cSourceName ) -> return pointer to Backup or NIL if error occurs sqlite3_backup_step( pBackup, nPage ) --> nResult sqlite3_backup_finish( pBackup ) --> nResult sqlite3_backup_remaining( pBackup ) --> nResult sqlite3_backup_pagecount( pBackup ) --> nResult */ HB_FUNC( SQLITE3_BACKUP_INIT ) { #if SQLITE_VERSION_NUMBER >= 3006011 HB_SQLITE3 * pHbSqlite3Dest = ( HB_SQLITE3 * ) hb_sqlite3_param( 1, HB_SQLITE3_DB, HB_TRUE ); HB_SQLITE3 * pHbSqlite3Source = ( HB_SQLITE3 * ) hb_sqlite3_param( 3, HB_SQLITE3_DB, HB_TRUE ); if( pHbSqlite3Dest && pHbSqlite3Dest->db && pHbSqlite3Source && pHbSqlite3Source->db && HB_ISCHAR( 2 ) && HB_ISCHAR( 4 ) ) { sqlite3_backup * pBackup = sqlite3_backup_init( pHbSqlite3Dest->db, hb_parcx( 2 ), pHbSqlite3Source->db, hb_parcx( 4 ) ); if( pBackup ) hb_retptr( pBackup ); /* FIXME: Create GC collected pointer */ else hb_retptr( NULL ); } else hb_retptr( NULL ); #else hb_retptr( NULL ); #endif } HB_FUNC( SQLITE3_BACKUP_STEP ) { #if SQLITE_VERSION_NUMBER >= 3006011 /* FIXME: Use GC collected pointer */ sqlite3_backup * pBackup = ( sqlite3_backup * ) hb_parptr( 1 ); if( pBackup ) hb_retni( sqlite3_backup_step( pBackup, hb_parni( 2 ) ) ); else hb_retni( -1 ); #else hb_retni( -1 ); #endif } HB_FUNC( SQLITE3_BACKUP_FINISH ) { #if SQLITE_VERSION_NUMBER >= 3006011 /* FIXME: Use and free GC collected pointer */ sqlite3_backup * pBackup = ( sqlite3_backup * ) hb_parptr( 1 ); if( pBackup ) hb_retni( sqlite3_backup_finish( pBackup ) ); else hb_retni( -1 ); #else hb_retni( -1 ); #endif } HB_FUNC( SQLITE3_BACKUP_REMAINING ) { #if SQLITE_VERSION_NUMBER >= 3006011 /* FIXME: Use GC collected pointer */ sqlite3_backup * pBackup = ( sqlite3_backup * ) hb_parptr( 1 ); if( pBackup ) hb_retni( sqlite3_backup_remaining( pBackup ) ); else hb_retni( -1 ); #else hb_retni( -1 ); #endif } HB_FUNC( SQLITE3_BACKUP_PAGECOUNT ) { #if SQLITE_VERSION_NUMBER >= 3006011 /* FIXME: Use GC collected pointer */ sqlite3_backup * pBackup = ( sqlite3_backup * ) hb_parptr( 1 ); if( pBackup ) hb_retni( sqlite3_backup_pagecount( pBackup ) ); else hb_retni( -1 ); #else hb_retni( -1 ); #endif } /** Memory Allocator Statistics sqlite3_memory_used() --> nResult sqlite3_memory_highwater( lResetFlag ) --> nResult */ HB_FUNC( SQLITE3_MEMORY_USED ) { /* FIXME: verify the exact SQLITE3 version */ #if SQLITE_VERSION_NUMBER > 3004001 hb_retnint( sqlite3_memory_used() ); #else hb_retnint( -1 ); #endif } HB_FUNC( SQLITE3_MEMORY_HIGHWATER ) { /* FIXME: verify the exact SQLITE3 version */ #if SQLITE_VERSION_NUMBER > 3004001 hb_retnint( sqlite3_memory_highwater( ( int ) hb_parl( 1 ) ) ); #else hb_retnint( -1 ); #endif } /** Test to see if the library is thread-safe sqlite3_threadsafe() --> nResult */ HB_FUNC( SQLITE3_THREADSAFE ) { /* FIXME: verify the exact SQLITE3 version */ #if SQLITE_VERSION_NUMBER > 3004001 hb_retni( sqlite3_threadsafe() ); #else hb_retni( -1 ); #endif } /** SQLite Runtime Status sqlite3_status( nOp, @nCurrent, @nHighwater, lResetFlag ) --> nResult */ HB_FUNC( SQLITE3_STATUS ) { #if SQLITE_VERSION_NUMBER >= 3006000 if( hb_pcount() > 3 && ( HB_ISNUM( 2 ) && HB_ISBYREF( 2 ) ) && ( HB_ISNUM( 3 ) && HB_ISBYREF( 3 ) ) ) { int iCurrent, iHighwater; hb_retni( sqlite3_status( hb_parni( 1 ), &iCurrent, &iHighwater, ( int ) hb_parl( 4 ) ) ); hb_storni( iCurrent, 2 ); hb_storni( iHighwater, 3 ); return; } #endif hb_storni( 0, 3 ); hb_storni( 0, 4 ); hb_retni( -1 ); } HB_FUNC( SQLITE3_STATUS64 ) { #if SQLITE_VERSION_NUMBER >= 3080900 && ! defined( HB_LONG_LONG_OFF ) if( hb_pcount() > 3 && ( HB_ISNUM( 2 ) && HB_ISBYREF( 2 ) ) && ( HB_ISNUM( 3 ) && HB_ISBYREF( 3 ) ) ) { sqlite3_int64 iCurrent, iHighwater; hb_retni( sqlite3_status( hb_parni( 1 ), &iCurrent, &iHighwater, ( int ) hb_parl( 4 ) ) ); hb_stornint( iCurrent, 2 ); hb_stornint( iHighwater, 3 ); return; } #endif hb_stornint( 0, 2 ); hb_stornint( 0, 3 ); hb_retni( -1 ); } /** Database Connection Status sqlite3_db_status( pDb, nOp, @nCurrent, @nHighwater, lResetFlag ) --> nResult */ HB_FUNC( SQLITE3_DB_STATUS ) { #if SQLITE_VERSION_NUMBER >= 3006001 HB_SQLITE3 * pHbSqlite3 = ( HB_SQLITE3 * ) hb_sqlite3_param( 1, HB_SQLITE3_DB, HB_TRUE ); if( pHbSqlite3 && pHbSqlite3->db && ( hb_pcount() > 4 ) && ( HB_ISNUM( 3 ) && HB_ISBYREF( 3 ) ) && ( HB_ISNUM( 4 ) && HB_ISBYREF( 4 ) ) ) { int iCurrent, iHighwater; hb_retni( sqlite3_db_status( pHbSqlite3->db, hb_parni( 2 ), &iCurrent, &iHighwater, ( int ) hb_parl( 5 ) ) ); hb_storni( iCurrent, 3 ); hb_storni( iHighwater, 4 ); return; } #endif hb_storni( 0, 3 ); hb_storni( 0, 4 ); hb_retni( -1 ); } /** Run-time Limits sqlite3_limit( pDb, nId, nNewVal ) --> nOldVal */ HB_FUNC( SQLITE3_LIMIT ) { #if SQLITE_VERSION_NUMBER >= 3005008 HB_SQLITE3 * pHbSqlite3 = ( HB_SQLITE3 * ) hb_sqlite3_param( 1, HB_SQLITE3_DB, HB_TRUE ); if( pHbSqlite3 && pHbSqlite3->db && ( hb_pcount() > 2 ) && HB_ISNUM( 2 ) && HB_ISNUM( 3 ) ) hb_retni( sqlite3_limit( pHbSqlite3->db, hb_parni( 2 ), hb_parni( 3 ) ) ); else hb_retni( -1 ); #else hb_retni( -1 ); #endif } /** Run-Time Library Compilation Options Diagnostics sqlite3_compileoption_used( cOptName ) --> nResult sqlite3_compileoption_get( nOptNum ) --> cResult */ HB_FUNC( SQLITE3_COMPILEOPTION_USED ) { #if SQLITE_VERSION_NUMBER >= 3006023 hb_retl( ( HB_BOOL ) sqlite3_compileoption_used( hb_parcx( 1 ) ) ); #else hb_retl( HB_FALSE ); #endif } HB_FUNC( SQLITE3_COMPILEOPTION_GET ) { #if SQLITE_VERSION_NUMBER >= 3006023 hb_retc( sqlite3_compileoption_get( hb_parni( 1 ) ) ); #else hb_retc_null(); #endif } /** Create Or Redefine SQL Functions sqlite3_create_function( db, cFuncName, nArg, [cFunc|sFunc], [nFunctionFlags] ) Only scalar function creation now supported. */ HB_FUNC( SQLITE3_CREATE_FUNCTION ) { HB_SQLITE3 * pHbSqlite3 = ( HB_SQLITE3 * ) hb_sqlite3_param( 1, HB_SQLITE3_DB, HB_TRUE ); if( pHbSqlite3 && pHbSqlite3->db && HB_ISCHAR( 2 ) ) { void * hFuncName = NULL; if( pHbSqlite3->cbFunc ) { hb_itemRelease( pHbSqlite3->cbFunc ); pHbSqlite3->cbFunc = NULL; } if( HB_ISEVALITEM( 4 ) ) { pHbSqlite3->cbFunc = hb_itemNew( hb_param( 4, HB_IT_EVALITEM ) ); hb_gcUnlock( pHbSqlite3->cbFunc ); hb_retni( sqlite3_create_function( pHbSqlite3->db, hb_parstr_utf8( 2, &hFuncName, NULL ), hb_parnidef( 4, -1 ), SQLITE_UTF8 | hb_parnidef( 5, 0 ), pHbSqlite3->cbFunc, func, NULL, NULL ) ); } else hb_retni( sqlite3_create_function( pHbSqlite3->db, hb_parstr_utf8( 2, &hFuncName, NULL ), -1, SQLITE_UTF8 | hb_parnidef( 5, 0 ), NULL, NULL, NULL, NULL ) ); if( hFuncName ) hb_strfree( hFuncName ); } else hb_retni( SQLITE_ERROR ); } /** Get database filename for given connection and database name sqlite3_db_filename( pDb, sDbName ) */ HB_FUNC( SQLITE3_DB_FILENAME ) { #if SQLITE_VERSION_NUMBER >= 3007010 HB_SQLITE3 * pHbSqlite3 = ( HB_SQLITE3 * ) hb_sqlite3_param( 1, HB_SQLITE3_DB, HB_TRUE ); if( pHbSqlite3 && pHbSqlite3->db && HB_ISCHAR( 2 ) ) hb_retc( ( const char * ) sqlite3_db_filename( pHbSqlite3->db, hb_parc( 2 ) ) ); else hb_errRT_BASE_SubstR( EG_ARG, 0, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); #else hb_errRT_BASE_SubstR( EG_UNSUPPORTED, 0, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); #endif } /** Get expanded SQL for a prepared statement sqlite3_expanded_sql( pPreparedStatement ) */ HB_FUNC( SQLITE3_EXPANDED_SQL ) { #if SQLITE_VERSION_NUMBER >= 3014000 psqlite3_stmt pStmt = ( psqlite3_stmt ) hb_parptr( 1 ); if( pStmt ) { char *sql = sqlite3_expanded_sql( pStmt ); hb_retstr_utf8( sql ); sqlite3_free( sql ); } else hb_errRT_BASE_SubstR( EG_ARG, 0, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); #else hb_errRT_BASE_SubstR( EG_UNSUPPORTED, 0, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); #endif }