* src/rtl/cdpapi.c
* src/rtl/iousr.c
* src/rtl/hbjson.c
* src/rtl/gtcrs/gtcrs.c
* src/rtl/gtsln/gtsln.c
* src/rtl/gttrm/gttrm.c
* src/rtl/gtxwc/gtxwc.c
* src/rdd/workarea.c
* src/rdd/hbsix/sxcompr.c
* contrib/hbct/token2.c
* contrib/hbsqlit3/core.c
* pacified some of -Wshadow warnings
* include/hbapicdp.h
! typo in comment: bytes -> bits
* src/vm/garbage.c
* src/vm/thread.c
* disabled some code with spinlocks when HB_HELGRIND_FRIENDLY macro
is defined. It causes that final MT HVM code is slower using native
platform mutexes but only such ones helgrind can recognize so the
new macro can be useful for people who want to make some tests with
helgrind. In such case they should rebuild Harbour with
HB_USER_CFLAGS=HB_HELGRIND_FRIENDLY
We use spinlocks and atomic integer operations also in few other
places so it's possible that deeper tests can exploit them and
we will have to cover them by HB_HELGRIND_FRIENDLY too just to
easy detect real problems.
2292 lines
59 KiB
C
2292 lines
59 KiB
C
/*
|
|
* Harbour Project source code:
|
|
* SQLite3 library low level (client api) interface code
|
|
*
|
|
* Copyright 2007-2010 P.Chornyj <myorg63@mail.ru>
|
|
*
|
|
* 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.txt. 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.
|
|
*
|
|
* See COPYING.txt for licensing terms.
|
|
*
|
|
*/
|
|
|
|
#include "sqlite3.h"
|
|
|
|
#include "hbvm.h"
|
|
#include "hbapi.h"
|
|
#include "hbapiitm.h"
|
|
#include "hbapierr.h"
|
|
#include "hbapifs.h"
|
|
#include "hbapistr.h"
|
|
#include "hbstack.h"
|
|
|
|
/* TOFIX: 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 ** );
|
|
|
|
typedef struct
|
|
{
|
|
sqlite3 * db;
|
|
PHB_ITEM cbAuthorizer;
|
|
PHB_ITEM cbBusyHandler;
|
|
PHB_ITEM cbProgressHandler;
|
|
PHB_ITEM cbHookCommit;
|
|
PHB_ITEM cbHookRollback;
|
|
PHB_ITEM cbFunc;
|
|
} 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;
|
|
}
|
|
|
|
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 );
|
|
}
|
|
}
|
|
|
|
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 );
|
|
}
|
|
|
|
/**
|
|
Callbacs 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;
|
|
int i;
|
|
|
|
hb_vmPushEvalSym();
|
|
hb_vmPush( pCallback );
|
|
hb_vmPushInteger( argc );
|
|
|
|
if( argc > 0 )
|
|
{
|
|
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, 1, hb_paramError( 1 ) );
|
|
}
|
|
|
|
/**
|
|
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, 1, hb_paramError( 1 ) );
|
|
}
|
|
|
|
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, 1, hb_paramError( 1 ) );
|
|
#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, 1, hb_paramError( 1 ) );
|
|
}
|
|
|
|
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, 1, hb_paramError( 1 ) );
|
|
}
|
|
|
|
/**
|
|
Name Of The Folder 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(): Can't create directory %s", pszDirName ) );
|
|
}
|
|
else
|
|
HB_TRACE( HB_TR_DEBUG,
|
|
( "sqlite_temp_directory(): Directory doesn't 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_xgrab( sizeof( HB_SQLITE3 ) );
|
|
hb_xmemset( hbsqlite3, 0, 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 doesn't 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_xgrab( sizeof( HB_SQLITE3 ) );
|
|
hb_xmemset( hbsqlite3, 0, 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_ISBLOCK( 3 ) || HB_ISSYMBOL( 3 ) )
|
|
rc = sqlite3_exec( pHbSqlite3->db, hb_parstr_utf8( 2, &hSQLText,
|
|
NULL ), callback, ( void * ) hb_param( 3, HB_IT_BLOCK | HB_IT_SYMBOL ),
|
|
&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, 1, hb_paramError( 1 ) );
|
|
}
|
|
|
|
/**
|
|
Compiling An SQL Statement
|
|
|
|
sqlite3_prepare( db, cSQLTEXT )
|
|
-> 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;
|
|
|
|
if( sqlite3_prepare_v2( pHbSqlite3->db, pszSQLText, ( int ) nSQLText, &pStmt, &pszTail ) == 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, 1, hb_paramError( 1 ) );
|
|
}
|
|
|
|
/**
|
|
Determine If An SQL Statement Is Complete
|
|
|
|
sqlite3_complete( sqlText ) -> lResult
|
|
*/
|
|
|
|
HB_FUNC( SQLITE3_COMPLETE )
|
|
{
|
|
void * hSQLText;
|
|
|
|
hb_retl( sqlite3_complete( hb_parstr_utf8( 1, &hSQLText, NULL ) ) );
|
|
|
|
hb_strfree( hSQLText );
|
|
}
|
|
|
|
/**
|
|
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 )
|
|
{
|
|
/* TOFIX: 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, 1, hb_paramError( 1 ) );
|
|
#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, 1, hb_paramError( 1 ) );
|
|
#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, 1, hb_paramError( 1 ) );
|
|
#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, 1, hb_paramError( 1 ) );
|
|
}
|
|
#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, 1, hb_paramError( 1 ) );
|
|
}
|
|
|
|
/**
|
|
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, 1, hb_paramError( 1 ) );
|
|
}
|
|
|
|
/**
|
|
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, 1, hb_paramError( 1 ) );
|
|
}
|
|
|
|
/**
|
|
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, 1, hb_paramError( 1 ) );
|
|
}
|
|
|
|
/*
|
|
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, 1, hb_paramError( 1 ) );
|
|
}
|
|
|
|
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, 1, hb_paramError( 1 ) );
|
|
}
|
|
|
|
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, 1, hb_paramError( 1 ) );
|
|
}
|
|
|
|
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, 1, hb_paramError( 1 ) );
|
|
}
|
|
|
|
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, 1, hb_paramError( 1 ) );
|
|
}
|
|
|
|
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, 1, hb_paramError( 1 ) );
|
|
}
|
|
|
|
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, 1, hb_paramError( 1 ) );
|
|
}
|
|
|
|
/**
|
|
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, 1, hb_paramError( 1 ) );
|
|
}
|
|
|
|
/**
|
|
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, 1, hb_paramError( 1 ) );
|
|
}
|
|
|
|
/**
|
|
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, 1, hb_paramError( 1 ) );
|
|
}
|
|
|
|
/**
|
|
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, 1, hb_paramError( 1 ) );
|
|
}
|
|
|
|
/**
|
|
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, 1, hb_paramError( 1 ) );
|
|
}
|
|
|
|
/**
|
|
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, 1, hb_paramError( 1 ) );
|
|
}
|
|
|
|
/**
|
|
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, 1, hb_paramError( 1 ) );
|
|
}
|
|
|
|
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, 1, hb_paramError( 1 ) );
|
|
}
|
|
|
|
/**
|
|
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, 1, hb_paramError( 1 ) );
|
|
}
|
|
|
|
/**
|
|
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, 1, hb_paramError( 1 ) );
|
|
}
|
|
|
|
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, 1, hb_paramError( 1 ) );
|
|
}
|
|
|
|
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, 1, hb_paramError( 1 ) );
|
|
}
|
|
|
|
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, 1, hb_paramError( 1 ) );
|
|
}
|
|
|
|
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, 1, hb_paramError( 1 ) );
|
|
}
|
|
|
|
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, 1, hb_paramError( 1 ) );
|
|
}
|
|
|
|
/**
|
|
Enable Or Disable Extension Loading
|
|
|
|
sqlite3_enable_load_extension( db, lOnOff ) -> prev.state
|
|
*/
|
|
|
|
HB_FUNC( SQLITE3_ENABLE_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 )
|
|
hb_retni( sqlite3_enable_load_extension( pHbSqlite3->db, hb_parl( 2 ) ) );
|
|
else
|
|
hb_errRT_BASE_SubstR( EG_ARG, 0, NULL, HB_ERR_FUNCNAME, 1, hb_paramError( 1 ) );
|
|
#else
|
|
hb_retni( -1 );
|
|
#endif /* SQLITE_OMIT_LOAD_EXTENSION */
|
|
}
|
|
|
|
/*
|
|
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, 1, hb_paramError( 1 ) );
|
|
}
|
|
|
|
/**
|
|
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, j, k = 0;
|
|
|
|
for( i = 0; i < iRow + 1; i++ )
|
|
{
|
|
PHB_ITEM pArray = hb_itemArrayNew( iCol );
|
|
|
|
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, 1, hb_paramError( 1 ) );
|
|
}
|
|
|
|
/**
|
|
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, 1, hb_paramError( 1 ) );
|
|
#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, 1, hb_paramError( 1 ) );
|
|
#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, 1, hb_paramError( 1 ) );
|
|
#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, 1, hb_paramError( 1 ) );
|
|
#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, 1, hb_paramError( 1 ) );
|
|
#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, 1, hb_paramError( 1 ) );
|
|
}
|
|
|
|
/**
|
|
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, 1, hb_paramError( 1 ) );
|
|
}
|
|
|
|
/**
|
|
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 );
|
|
|
|
/*hb_xmemset( buffer, 0, iLen );*/
|
|
|
|
if( SQLITE_OK == sqlite3_blob_read( pBlob, ( void * ) buffer, iLen, hb_parni( 3 ) ) )
|
|
{
|
|
buffer[ iLen ] = '\0';
|
|
hb_retclen_buffer( buffer, iLen );
|
|
}
|
|
else
|
|
hb_xfree( buffer );
|
|
}
|
|
else
|
|
hb_errRT_BASE_SubstR( EG_ARG, 0, NULL, HB_ERR_FUNCNAME, 1, hb_paramError( 1 ) );
|
|
}
|
|
|
|
/**
|
|
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, 1, hb_paramError( 1 ) );
|
|
}
|
|
|
|
/**
|
|
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, 1, hb_paramError( 1 ) );
|
|
}
|
|
|
|
/**
|
|
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( db, lOnOff )
|
|
sqlite3_profile( db, lOnOff )
|
|
*/
|
|
|
|
static void SQL3ProfileLog( void * sFile, const char * sProfileMsg, sqlite3_uint64 int64 )
|
|
{
|
|
if( sProfileMsg )
|
|
{
|
|
FILE * hFile = hb_fopen( sFile ? ( const char * ) sFile : "hbsq3_pr.log", "a" );
|
|
|
|
if( hFile )
|
|
{
|
|
fprintf( hFile, "%s - %"PFLL "d\n", sProfileMsg, int64 );
|
|
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 );
|
|
}
|
|
}
|
|
}
|
|
|
|
HB_FUNC( SQLITE3_PROFILE )
|
|
{
|
|
HB_SQLITE3 * pHbSqlite3 = ( HB_SQLITE3 * ) hb_sqlite3_param( 1, HB_SQLITE3_DB, HB_TRUE );
|
|
|
|
if( pHbSqlite3 && pHbSqlite3->db )
|
|
sqlite3_profile( pHbSqlite3->db, hb_parl( 2 ) ? SQL3ProfileLog : NULL,
|
|
( void * ) ( HB_ISCHAR( 3 ) ? hb_parcx( 3 ) : NULL ) );
|
|
else
|
|
hb_errRT_BASE_SubstR( EG_ARG, 0, NULL, HB_ERR_FUNCNAME, 1, hb_paramError( 1 ) );
|
|
}
|
|
|
|
HB_FUNC( SQLITE3_TRACE )
|
|
{
|
|
HB_SQLITE3 * pHbSqlite3 = ( HB_SQLITE3 * ) hb_sqlite3_param( 1, HB_SQLITE3_DB, HB_TRUE );
|
|
|
|
if( pHbSqlite3 && pHbSqlite3->db )
|
|
sqlite3_trace( pHbSqlite3->db, hb_parl( 2 ) ? SQL3TraceLog : NULL,
|
|
( void * ) ( HB_ISCHAR( 3 ) ? hb_parcx( 3 ) : NULL ) );
|
|
else
|
|
hb_errRT_BASE_SubstR( EG_ARG, 0, NULL, HB_ERR_FUNCNAME, 1, hb_paramError( 1 ) );
|
|
}
|
|
|
|
/**
|
|
BLOB Import/export
|
|
*/
|
|
|
|
HB_FUNC( SQLITE3_FILE_TO_BUFF )
|
|
{
|
|
HB_FHANDLE handle = hb_fsOpen( hb_parcx( 1 ), FO_READ );
|
|
|
|
if( handle != FS_ERROR )
|
|
{
|
|
char * buffer;
|
|
HB_SIZE nSize;
|
|
|
|
nSize = hb_fsSeek( handle, 0, FS_END );
|
|
hb_fsSeek( handle, 0, FS_SET );
|
|
buffer = ( char * ) hb_xgrab( nSize + 1 );
|
|
nSize = hb_fsReadLarge( handle, buffer, nSize );
|
|
buffer[ nSize ] = '\0';
|
|
hb_fsClose( handle );
|
|
|
|
hb_retclen_buffer( buffer, nSize );
|
|
}
|
|
else
|
|
hb_retc_null();
|
|
}
|
|
|
|
HB_FUNC( SQLITE3_BUFF_TO_FILE )
|
|
{
|
|
HB_FHANDLE handle = hb_fsCreate( hb_parcx( 1 ), FC_NORMAL );
|
|
HB_SIZE nSize = hb_parcsiz( 2 ) - 1;
|
|
|
|
if( handle != FS_ERROR && nSize > 0 )
|
|
{
|
|
hb_retni( hb_fsWriteLarge( handle, hb_parcx( 2 ), nSize ) == nSize ? 0 : -1 );
|
|
hb_fsClose( handle );
|
|
}
|
|
else
|
|
hb_retni( 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_ISBLOCK( 2 ) || HB_ISSYMBOL( 2 ) )
|
|
{
|
|
pHbSqlite3->cbBusyHandler = hb_itemNew( hb_param( 2, HB_IT_BLOCK | HB_IT_SYMBOL ) );
|
|
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_ISBLOCK( 3 ) )
|
|
{
|
|
pHbSqlite3->cbProgressHandler = hb_itemNew( hb_param( 3, HB_IT_BLOCK | HB_IT_SYMBOL ) );
|
|
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_ISBLOCK( 2 ) || HB_ISSYMBOL( 2 ) )
|
|
{
|
|
pHbSqlite3->cbHookCommit = hb_itemNew( hb_param( 2, HB_IT_BLOCK | HB_IT_SYMBOL ) );
|
|
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_ISBLOCK( 2 ) || HB_ISSYMBOL( 2 ) )
|
|
{
|
|
pHbSqlite3->cbHookRollback = hb_itemNew( hb_param( 2, HB_IT_BLOCK | HB_IT_SYMBOL ) );
|
|
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_ISBLOCK( 2 ) || HB_ISSYMBOL( 2 ) )
|
|
{
|
|
pHbSqlite3->cbAuthorizer = hb_itemNew( hb_param( 2, HB_IT_BLOCK | HB_IT_SYMBOL ) );
|
|
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 );
|
|
sqlite3_backup * pBackup;
|
|
|
|
if( pHbSqlite3Dest && pHbSqlite3Dest->db && pHbSqlite3Source && pHbSqlite3Source->db &&
|
|
HB_ISCHAR( 2 ) && HB_ISCHAR( 4 ) )
|
|
{
|
|
pBackup = sqlite3_backup_init( pHbSqlite3Dest->db, hb_parcx(
|
|
2 ), pHbSqlite3Source->db, hb_parcx( 4 ) );
|
|
|
|
if( pBackup )
|
|
hb_retptr( pBackup ); /* TOFIX: 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
|
|
/* TOFIX: 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
|
|
/* TOFIX: 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
|
|
/* TOFIX: 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
|
|
/* TOFIX: 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 )
|
|
{
|
|
/* TOFIX: 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 )
|
|
{
|
|
/* TOFIX: 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 Threadsafe
|
|
|
|
sqlite3_threadsafe() -> nResult
|
|
*/
|
|
|
|
HB_FUNC( SQLITE3_THREADSAFE )
|
|
{
|
|
/* TOFIX: 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
|
|
int iCurrent, iHighwater;
|
|
|
|
if( hb_pcount() > 3 && ( HB_ISNUM( 2 ) && HB_ISBYREF( 2 ) ) && ( HB_ISNUM( 3 ) && HB_ISBYREF( 3 ) ) )
|
|
{
|
|
hb_retni( sqlite3_status( hb_parni( 1 ), &iCurrent, &iHighwater, ( int ) hb_parl( 4 ) ) );
|
|
|
|
hb_storni( iCurrent, 2 );
|
|
hb_storni( iHighwater, 3 );
|
|
}
|
|
else
|
|
hb_retni( -1 );
|
|
#else
|
|
hb_retni( -1 );
|
|
#endif
|
|
}
|
|
|
|
/**
|
|
Database Connection Status
|
|
|
|
sqlite3_db_status( pDb, nOp, @nCurrent, @nHighwater, lResetFlag ) -> nResult
|
|
*/
|
|
|
|
HB_FUNC( SQLITE3_DB_STATUS )
|
|
{
|
|
#if SQLITE_VERSION_NUMBER >= 3006001
|
|
int iCurrent, iHighwater;
|
|
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 ) ) )
|
|
{
|
|
hb_retni( sqlite3_db_status( pHbSqlite3->db, hb_parni( 2 ), &iCurrent, &iHighwater,
|
|
( int ) hb_parl( 5 ) ) );
|
|
|
|
hb_storni( iCurrent, 3 );
|
|
hb_storni( iHighwater, 4 );
|
|
}
|
|
else
|
|
hb_retni( -1 );
|
|
#else
|
|
hb_retni( -1 );
|
|
#endif
|
|
}
|
|
|
|
/**
|
|
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_parc( 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] )
|
|
|
|
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_ISBLOCK( 4 ) || HB_ISSYMBOL( 4 ) )
|
|
{
|
|
pHbSqlite3->cbFunc = hb_itemNew( hb_param( 4, HB_IT_BLOCK | HB_IT_SYMBOL ) );
|
|
hb_gcUnlock( pHbSqlite3->cbFunc );
|
|
|
|
hb_retni(
|
|
sqlite3_create_function( pHbSqlite3->db,
|
|
hb_parstr_utf8( 2, &hFuncName, NULL ),
|
|
hb_parnidef( 4, -1 ),
|
|
SQLITE_UTF8,
|
|
pHbSqlite3->cbFunc,
|
|
func, NULL, NULL ) );
|
|
}
|
|
else
|
|
hb_retni(
|
|
sqlite3_create_function( pHbSqlite3->db,
|
|
hb_parstr_utf8( 2, &hFuncName, NULL ),
|
|
-1,
|
|
SQLITE_UTF8,
|
|
NULL,
|
|
NULL, NULL, NULL ) );
|
|
|
|
if( hFuncName )
|
|
hb_strfree( hFuncName );
|
|
}
|
|
else
|
|
hb_retni( SQLITE_ERROR );
|
|
}
|