2007-09-13 16:40 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl)
* harbour/include/Makefile
+ harbour/include/hbsxdef.ch
* harbour/include/dbinfo.ch
* harbour/include/hbrdddbf.h
* harbour/include/hbrddcdx.h
* harbour/include/hbrddntx.h
* harbour/contrib/bmdbfcdx/hbrddbmcdx.h
* harbour/source/rdd/dbf1.c
* harbour/source/rdd/workarea.c
+ added SIx3 compatible triggers support
They should work like in SIx3 with some intentional excpetions:
1) if 4-th parameter exists (PREUSE/GET/PUT) then it's passed by
reference otherwise is not passed at all and PCOUNT() in trigger
functions returns 3
SIx3 do not pass 4-th parameter by reference and if it not
exist then passes 0
2) EVENT_POSTCLOSE is executed after SUPER_CLOSE()
SIx3 executes EVENT_POSTCLOSE just before SUPER_CLOSE()
3) EVENT_UPDATE is executed _ALWAYS_ when DBF is updated also
when WA does not have open indexes
SIx3 executes EVENT_UPDATE only when at least one index is
open without checking if it's updated or not
4) EVENT_POSTUSE is executed from OPEN() method in "DBF" RDD not
from index RDDs so before the indexes are open
SIx3 executes EVENT_POSTUSE after opening indexes
It's possible that I'll change this condition in the future
This commit is contained in:
@@ -8,6 +8,34 @@
|
||||
2002-12-01 13:30 UTC+0100 Foo Bar <foo.bar@foobar.org>
|
||||
*/
|
||||
|
||||
2007-09-13 16:40 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl)
|
||||
* harbour/include/Makefile
|
||||
+ harbour/include/hbsxdef.ch
|
||||
* harbour/include/dbinfo.ch
|
||||
* harbour/include/hbrdddbf.h
|
||||
* harbour/include/hbrddcdx.h
|
||||
* harbour/include/hbrddntx.h
|
||||
* harbour/contrib/bmdbfcdx/hbrddbmcdx.h
|
||||
* harbour/source/rdd/dbf1.c
|
||||
* harbour/source/rdd/workarea.c
|
||||
+ added SIx3 compatible triggers support
|
||||
They should work like in SIx3 with some intentional excpetions:
|
||||
1) if 4-th parameter exists (PREUSE/GET/PUT) then it's passed by
|
||||
reference otherwise is not passed at all and PCOUNT() in trigger
|
||||
functions returns 3
|
||||
SIx3 do not pass 4-th parameter by reference and if it not
|
||||
exist then passes 0
|
||||
2) EVENT_POSTCLOSE is executed after SUPER_CLOSE()
|
||||
SIx3 executes EVENT_POSTCLOSE just before SUPER_CLOSE()
|
||||
3) EVENT_UPDATE is executed _ALWAYS_ when DBF is updated also
|
||||
when WA does not have open indexes
|
||||
SIx3 executes EVENT_UPDATE only when at least one index is
|
||||
open without checking if it's updated or not
|
||||
4) EVENT_POSTUSE is executed from OPEN() method in "DBF" RDD not
|
||||
from index RDDs so before the indexes are open
|
||||
SIx3 executes EVENT_POSTUSE after opening indexes
|
||||
It's possible that I'll change this condition in the future
|
||||
|
||||
2007-09-13 13:30 UTC+0100 Viktor Szakats (harbour.01 syenar.hu)
|
||||
* makefile.vc
|
||||
* makefile.gc
|
||||
|
||||
@@ -515,6 +515,7 @@ typedef struct _CDXAREA
|
||||
BOOL fFLocked; /* TRUE if file is locked */
|
||||
BOOL fHeaderLocked; /* TRUE if DBF header is locked */
|
||||
BOOL fTrigger; /* Execute trigger function */
|
||||
LPDBOPENINFO lpdbOpenInfo; /* Pointer to current dbOpenInfo structure in OPEN/CREATE methods */
|
||||
LPDBRELINFO lpdbPendingRel; /* Pointer to parent rel struct */
|
||||
ULONG * pLocksPos; /* List of records locked */
|
||||
ULONG ulNumLocksPos; /* Number of records locked */
|
||||
|
||||
@@ -100,7 +100,8 @@ PRG_HEADERS=\
|
||||
setcurs.ch \
|
||||
simpleio.ch \
|
||||
std.ch \
|
||||
tbrowse.ch
|
||||
hbsxdef.ch \
|
||||
tbrowse.ch \
|
||||
|
||||
API_HEADERS=\
|
||||
error.api \
|
||||
|
||||
@@ -104,6 +104,7 @@
|
||||
/* misc */
|
||||
#define RDDI_PENDINGTRIGGER 40 /* set pending trigger for next open operation */
|
||||
#define RDDI_PENDINGPASSWORD 41 /* set pending password for next open operation */
|
||||
#define RDDI_PASSWORD 42 /* Get/Set default password */
|
||||
|
||||
/*
|
||||
Constants for SELF_ORDINFO ()
|
||||
|
||||
@@ -515,6 +515,7 @@ typedef struct _CDXAREA
|
||||
BOOL fFLocked; /* TRUE if file is locked */
|
||||
BOOL fHeaderLocked; /* TRUE if DBF header is locked */
|
||||
BOOL fTrigger; /* Execute trigger function */
|
||||
LPDBOPENINFO lpdbOpenInfo; /* Pointer to current dbOpenInfo structure in OPEN/CREATE methods */
|
||||
LPDBRELINFO lpdbPendingRel; /* Pointer to parent rel struct */
|
||||
ULONG * pLocksPos; /* List of records locked */
|
||||
ULONG ulNumLocksPos; /* Number of records locked */
|
||||
|
||||
@@ -113,6 +113,11 @@ typedef struct _DBFDATA
|
||||
char szIndexExt[ HB_MAX_FILE_EXT + 1 ];
|
||||
char szMemoExt[ HB_MAX_FILE_EXT + 1 ];
|
||||
|
||||
char * szPasswd;
|
||||
char * szPendingPasswd;
|
||||
char * szTrigger;
|
||||
char * szPendingTrigger;
|
||||
|
||||
BYTE bLockType; /* 0 */
|
||||
BYTE bTableType; /* DB_DBF_STD */
|
||||
BYTE bCryptType; /* DB_CRYPT_NONE */
|
||||
@@ -208,6 +213,7 @@ typedef struct _DBFAREA
|
||||
BOOL fFLocked; /* TRUE if file is locked */
|
||||
BOOL fHeaderLocked; /* TRUE if DBF header is locked */
|
||||
BOOL fTrigger; /* Execute trigger function */
|
||||
LPDBOPENINFO lpdbOpenInfo; /* Pointer to current dbOpenInfo structure in OPEN/CREATE methods */
|
||||
LPDBRELINFO lpdbPendingRel; /* Pointer to parent rel struct */
|
||||
ULONG * pLocksPos; /* List of records locked */
|
||||
ULONG ulNumLocksPos; /* Number of records locked */
|
||||
|
||||
@@ -408,6 +408,7 @@ typedef struct _NTXAREA
|
||||
BOOL fFLocked; /* TRUE if file is locked */
|
||||
BOOL fHeaderLocked; /* TRUE if DBF header is locked */
|
||||
BOOL fTrigger; /* Execute trigger function */
|
||||
LPDBOPENINFO lpdbOpenInfo; /* Pointer to current dbOpenInfo structure in OPEN/CREATE methods */
|
||||
LPDBRELINFO lpdbPendingRel; /* Pointer to parent rel struct */
|
||||
ULONG * pLocksPos; /* List of records locked */
|
||||
ULONG ulNumLocksPos; /* Number of records locked */
|
||||
|
||||
91
harbour/include/hbsxdef.ch
Normal file
91
harbour/include/hbsxdef.ch
Normal file
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Harbour Project source code:
|
||||
* SIx3 compatible constants
|
||||
*
|
||||
* Copyright 2007 Przemyslaw Czerpak <druzus / at / priv.onet.pl>
|
||||
* www - http://www.harbour-project.org
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this software; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA (or visit the web site http://www.gnu.org/).
|
||||
*
|
||||
* As a special exception, the Harbour Project gives permission for
|
||||
* additional uses of the text contained in its release of Harbour.
|
||||
*
|
||||
* The exception is that, if you link the Harbour libraries with other
|
||||
* files to produce an executable, this does not by itself cause the
|
||||
* resulting executable to be covered by the GNU General Public License.
|
||||
* Your use of that executable is in no way restricted on account of
|
||||
* linking the Harbour library code into it.
|
||||
*
|
||||
* This exception does not however invalidate any other reasons why
|
||||
* the executable file might be covered by the GNU General Public License.
|
||||
*
|
||||
* This exception applies only to the code released by the Harbour
|
||||
* Project under the name Harbour. If you copy code from other
|
||||
* Harbour Project or Free Software Foundation releases into a copy of
|
||||
* Harbour, as the General Public License permits, the exception does
|
||||
* not apply to the code that you add in this way. To avoid misleading
|
||||
* anyone as to the status of such modified files, you must delete
|
||||
* this exception notice from them.
|
||||
*
|
||||
* If you write modifications of your own for Harbour, it is your choice
|
||||
* whether to permit this exception to apply to your modifications.
|
||||
* If you do not wish that, delete this exception notice.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HB_SIX_DEF_CH_
|
||||
#define HB_SIX_DEF_CH_
|
||||
|
||||
/*
|
||||
* Event Constants for Trigger System
|
||||
*/
|
||||
#define EVENT_PREUSE 1
|
||||
#define EVENT_POSTUSE 2
|
||||
#define EVENT_UPDATE 3
|
||||
#define EVENT_APPEND 4
|
||||
#define EVENT_DELETE 5
|
||||
#define EVENT_RECALL 6
|
||||
#define EVENT_PACK 7
|
||||
#define EVENT_ZAP 8
|
||||
#define EVENT_PUT 9
|
||||
#define EVENT_GET 10
|
||||
#define EVENT_PRECLOSE 11
|
||||
#define EVENT_POSTCLOSE 12
|
||||
#define EVENT_PREMEMOPACK 13
|
||||
#define EVENT_POSTMEMOPACK 14
|
||||
|
||||
/*
|
||||
* Trigger Toggle Values
|
||||
*/
|
||||
#define TRIGGER_ENABLE 1
|
||||
#define TRIGGER_DISABLE 2
|
||||
#define TRIGGER_REMOVE 3
|
||||
#define TRIGGER_INSTALL 4
|
||||
#define TRIGGER_PENDING 5 /* Internal Use Only */
|
||||
|
||||
|
||||
/*
|
||||
* Sx_File2BLOB() actions
|
||||
*/
|
||||
#define BLOB_FILECOMPRESS 1
|
||||
#define BLOB_FILEENCRYPT 2
|
||||
|
||||
|
||||
#endif /* HB_SIX_DEF_CH_ */
|
||||
@@ -50,6 +50,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#define HB_TRIGVAR_BYREF
|
||||
|
||||
#include "hbapi.h"
|
||||
#include "hbinit.h"
|
||||
#include "hbvm.h"
|
||||
@@ -65,11 +67,17 @@
|
||||
#include "hbsxfunc.h"
|
||||
#include "error.ch"
|
||||
#include "rddsys.ch"
|
||||
#include "hbsxdef.ch"
|
||||
|
||||
#ifndef HB_CDP_SUPPORT_OFF
|
||||
# include "hbapicdp.h"
|
||||
#endif
|
||||
|
||||
#ifdef HB_TRIGVAR_BYREF
|
||||
#include "hbxvm.h"
|
||||
#include "hbstack.h"
|
||||
#endif
|
||||
|
||||
static USHORT s_uiRddId = ( USHORT ) -1;
|
||||
static RDDFUNCS dbfSuper;
|
||||
static const RDDFUNCS dbfTable = { ( DBENTRYP_BP ) hb_dbfBof,
|
||||
@@ -220,6 +228,137 @@ static void hb_dbfSetBlankRecord( DBFAREAP pArea )
|
||||
memset( pPtr, '\0', ( ULONG ) pArea->uiRecordLen - ulSize );
|
||||
}
|
||||
|
||||
/*
|
||||
* Executes user trigger function
|
||||
*/
|
||||
static BOOL hb_dbfTriggerDo( DBFAREAP pArea, int iEvent,
|
||||
int iField, PHB_ITEM pItem )
|
||||
{
|
||||
BOOL fResult = TRUE;
|
||||
|
||||
if( hb_vmRequestQuery() == 0 )
|
||||
{
|
||||
if( hb_vmRequestReenter() )
|
||||
{
|
||||
#ifdef HB_TRIGVAR_BYREF
|
||||
LONG lOffset = 0;
|
||||
|
||||
if( pItem )
|
||||
{
|
||||
lOffset = hb_stackTopOffset() - hb_stackBaseOffset();
|
||||
hb_vmPush( pItem );
|
||||
}
|
||||
#endif
|
||||
|
||||
hb_vmPushDynSym( pArea->pTriggerSym );
|
||||
hb_vmPushNil();
|
||||
/* nEvent */
|
||||
hb_vmPushInteger( iEvent );
|
||||
/* nArea */
|
||||
hb_vmPushInteger( pArea->uiArea );
|
||||
/* nFieldPos (GET/PUT) */
|
||||
hb_vmPushInteger( iField );
|
||||
/* xTrigVal (PREUSE/GET/PUT) */
|
||||
if( pItem )
|
||||
{
|
||||
hb_xvmPushLocalByRef( ( SHORT ) lOffset );
|
||||
hb_vmDo( 4 );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* SIx3 makes: hb_vmPushInteger( 0 ); */
|
||||
hb_vmDo( 3 );
|
||||
}
|
||||
|
||||
#ifdef HB_TRIGVAR_BYREF
|
||||
if( pItem )
|
||||
{
|
||||
hb_itemMove( pItem, hb_stackItemFromBase( lOffset ) );
|
||||
hb_stackPop();
|
||||
}
|
||||
#endif
|
||||
fResult = hb_parl( -1 );
|
||||
hb_vmRequestRestore();
|
||||
}
|
||||
}
|
||||
|
||||
return fResult;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set user trigger function
|
||||
*/
|
||||
static void hb_dbfTriggerSet( DBFAREAP pArea, PHB_ITEM pTrigger )
|
||||
{
|
||||
char * szName = hb_itemGetCPtr( pTrigger );
|
||||
|
||||
pArea->pTriggerSym = *szName ? hb_dynsymFindName( szName ) : NULL;
|
||||
if( pArea->pTriggerSym && !hb_dynsymIsFunction( pArea->pTriggerSym ) )
|
||||
pArea->pTriggerSym = NULL;
|
||||
pArea->fTrigger = pArea->pTriggerSym != NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set encryption password
|
||||
*/
|
||||
static BOOL hb_dbfPasswordSet( DBFAREAP pArea, PHB_ITEM pPasswd )
|
||||
{
|
||||
BYTE byBuffer[ 8 ];
|
||||
ULONG ulLen = 0;
|
||||
BOOL fSet = !pArea->fHasMemo && HB_IS_STRING( pPasswd );
|
||||
BOOL fKeySet = FALSE;
|
||||
|
||||
if( fSet )
|
||||
{
|
||||
ulLen = hb_itemGetCLen( pPasswd );
|
||||
if( ulLen > 0 )
|
||||
{
|
||||
if( ulLen < 8 )
|
||||
{
|
||||
memcpy( byBuffer, hb_itemGetCPtr( pPasswd ), ulLen );
|
||||
memset( byBuffer + ulLen, '\0', 8 - ulLen );
|
||||
}
|
||||
else
|
||||
memcpy( byBuffer, hb_itemGetCPtr( pPasswd ), 8 );
|
||||
}
|
||||
}
|
||||
|
||||
if( pArea->pCryptKey )
|
||||
hb_itemPutCL( pPasswd, ( char * ) pArea->pCryptKey, 8 );
|
||||
else
|
||||
hb_itemClear( pPasswd );
|
||||
|
||||
if( fSet )
|
||||
{
|
||||
if( pArea->pRecord && pArea->fPositioned )
|
||||
{
|
||||
SELF_GOCOLD( ( AREAP ) pArea );
|
||||
pArea->fValidBuffer = FALSE;
|
||||
}
|
||||
if( pArea->pCryptKey )
|
||||
{
|
||||
/* clean the memory with password key - though it's not
|
||||
* a serious actions in such case ;-)
|
||||
*/
|
||||
memset( pArea->pCryptKey, '\0', 8 );
|
||||
hb_xfree( pArea->pCryptKey );
|
||||
pArea->pCryptKey = NULL;
|
||||
}
|
||||
if( ulLen > 0 )
|
||||
{
|
||||
/* at this moment only one encryption method is used,
|
||||
I'll add other later, [druzus] */
|
||||
pArea->bCryptType = DB_CRYPT_SIX;
|
||||
pArea->pCryptKey = ( BYTE * ) hb_xgrab( 8 );
|
||||
/* SIX encode the key with its own value before use */
|
||||
hb_sxEnCrypt( byBuffer, pArea->pCryptKey, byBuffer, 8 );
|
||||
fKeySet = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return fKeySet;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the total number of records.
|
||||
*/
|
||||
@@ -1213,7 +1352,11 @@ static ERRCODE hb_dbfAppend( DBFAREAP pArea, BOOL bUnLockAll )
|
||||
if( SELF_GOCOLD( ( AREAP ) pArea ) == FAILURE )
|
||||
return FAILURE;
|
||||
|
||||
/* TODO: EVENT_APPEND call (stopped) */
|
||||
if( pArea->fTrigger )
|
||||
{
|
||||
if( !hb_dbfTriggerDo( pArea, EVENT_APPEND, 0, NULL ) )
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
if( pArea->fReadonly )
|
||||
{
|
||||
@@ -1295,7 +1438,11 @@ static ERRCODE hb_dbfDeleteRec( DBFAREAP pArea )
|
||||
{
|
||||
HB_TRACE(HB_TR_DEBUG, ("hb_dbfDeleteRec(%p)", pArea));
|
||||
|
||||
/* TODO: EVENT_DELETE call (stopped) */
|
||||
if( pArea->fTrigger )
|
||||
{
|
||||
if( !hb_dbfTriggerDo( pArea, EVENT_DELETE, 0, NULL ) )
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
if( pArea->lpdbPendingRel )
|
||||
{
|
||||
@@ -1615,6 +1762,13 @@ static ERRCODE hb_dbfGetValue( DBFAREAP pArea, USHORT uiIndex, PHB_ITEM pItem )
|
||||
hb_itemRelease( pError );
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
if( pArea->fTrigger )
|
||||
{
|
||||
if( !hb_dbfTriggerDo( pArea, EVENT_GET, uiIndex + 1, pItem ) )
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
@@ -1639,6 +1793,19 @@ static ERRCODE hb_dbfGoCold( DBFAREAP pArea )
|
||||
|
||||
if( pArea->fRecordChanged )
|
||||
{
|
||||
if( pArea->fTrigger )
|
||||
{
|
||||
/* The pending relation may move the record pointer so we should
|
||||
disable them for trigger evaluation */
|
||||
LPDBRELINFO lpdbPendingRel = pArea->lpdbPendingRel;
|
||||
pArea->lpdbPendingRel = NULL;
|
||||
|
||||
hb_dbfTriggerDo( pArea, EVENT_UPDATE, 0, NULL );
|
||||
|
||||
/* Restore disabled pending relation */
|
||||
pArea->lpdbPendingRel = lpdbPendingRel;
|
||||
}
|
||||
|
||||
/* Write current record */
|
||||
if( ! hb_dbfWriteRecord( pArea ) )
|
||||
return FAILURE;
|
||||
@@ -1778,7 +1945,8 @@ static ERRCODE hb_dbfPutValue( DBFAREAP pArea, USHORT uiIndex, PHB_ITEM pItem )
|
||||
LPFIELD pField;
|
||||
/* this buffer is for date and number conversion,
|
||||
* DBASE documentation defines maximum numeric field size as 20
|
||||
* but Clipper allows to create longer fields so I remove this limit, Druzus
|
||||
* but Clipper allows to create longer fields so I removed this
|
||||
* limit [druzus]
|
||||
*/
|
||||
char szBuffer[ 256 ];
|
||||
PHB_ITEM pError;
|
||||
@@ -1786,6 +1954,12 @@ static ERRCODE hb_dbfPutValue( DBFAREAP pArea, USHORT uiIndex, PHB_ITEM pItem )
|
||||
|
||||
HB_TRACE(HB_TR_DEBUG, ("hb_dbfPutValue(%p, %hu, %p)", pArea, uiIndex, pItem));
|
||||
|
||||
if( pArea->fTrigger )
|
||||
{
|
||||
if( !hb_dbfTriggerDo( pArea, EVENT_PUT, uiIndex, pItem ) )
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
if( pArea->lpdbPendingRel )
|
||||
{
|
||||
if( SELF_FORCEREL( ( AREAP ) pArea ) != SUCCESS )
|
||||
@@ -2020,6 +2194,12 @@ static ERRCODE hb_dbfRecall( DBFAREAP pArea )
|
||||
{
|
||||
HB_TRACE(HB_TR_DEBUG, ("hb_dbfRecall(%p)", pArea));
|
||||
|
||||
if( pArea->fTrigger )
|
||||
{
|
||||
if( !hb_dbfTriggerDo( pArea, EVENT_RECALL, 0, NULL ) )
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
if( pArea->lpdbPendingRel )
|
||||
{
|
||||
if( SELF_FORCEREL( ( AREAP ) pArea ) != SUCCESS )
|
||||
@@ -2129,11 +2309,16 @@ static ERRCODE hb_dbfSetFieldExtent( DBFAREAP pArea, USHORT uiFieldExtent )
|
||||
static ERRCODE hb_dbfClose( DBFAREAP pArea )
|
||||
{
|
||||
HB_TRACE(HB_TR_DEBUG, ("hb_dbfClose(%p)", pArea));
|
||||
|
||||
if( pArea->fTrigger )
|
||||
{
|
||||
if( !hb_dbfTriggerDo( pArea, EVENT_PRECLOSE, 0, NULL ) )
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
/* Reset parent rel struct */
|
||||
pArea->lpdbPendingRel = NULL;
|
||||
|
||||
SUPER_CLOSE( ( AREAP ) pArea );
|
||||
|
||||
/* Update record and unlock records */
|
||||
if( pArea->hDataFile != FS_ERROR )
|
||||
{
|
||||
@@ -2145,16 +2330,18 @@ static ERRCODE hb_dbfClose( DBFAREAP pArea )
|
||||
|
||||
/* Update header */
|
||||
if( pArea->fUpdateHeader )
|
||||
{
|
||||
SELF_WRITEDBHEADER( ( AREAP ) pArea );
|
||||
}
|
||||
|
||||
/* It's not Clipper compatible but it reduces the problem with
|
||||
byggy Windows network setting */
|
||||
if( hb_set.HB_SET_HARDCOMMIT )
|
||||
{
|
||||
SELF_FLUSH( ( AREAP ) pArea );
|
||||
}
|
||||
}
|
||||
|
||||
SUPER_CLOSE( ( AREAP ) pArea );
|
||||
|
||||
if( pArea->hDataFile != FS_ERROR )
|
||||
{
|
||||
hb_fsClose( pArea->hDataFile );
|
||||
pArea->hDataFile = FS_ERROR;
|
||||
}
|
||||
@@ -2200,6 +2387,12 @@ static ERRCODE hb_dbfClose( DBFAREAP pArea )
|
||||
pArea->szMemoFileName = NULL;
|
||||
}
|
||||
|
||||
if( pArea->fTrigger )
|
||||
{
|
||||
hb_dbfTriggerDo( pArea, EVENT_POSTCLOSE, 0, NULL );
|
||||
pArea->fTrigger = FALSE;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
@@ -2218,7 +2411,10 @@ static ERRCODE hb_dbfCreate( DBFAREAP pArea, LPDBOPENINFO pCreateInfo )
|
||||
|
||||
HB_TRACE(HB_TR_DEBUG, ("hb_dbfCreate(%p, %p)", pArea, pCreateInfo));
|
||||
|
||||
pArea->lpdbOpenInfo = pCreateInfo;
|
||||
|
||||
pFileName = hb_fsFNameSplit( ( char * ) pCreateInfo->abName );
|
||||
|
||||
if( hb_set.HB_SET_DEFEXTENSIONS && ! pFileName->szExtension )
|
||||
{
|
||||
pItem = hb_itemPutC( pItem, "" );
|
||||
@@ -2226,6 +2422,7 @@ static ERRCODE hb_dbfCreate( DBFAREAP pArea, LPDBOPENINFO pCreateInfo )
|
||||
{
|
||||
hb_itemRelease( pItem );
|
||||
hb_xfree( pFileName );
|
||||
pArea->lpdbOpenInfo = NULL;
|
||||
return FAILURE;
|
||||
}
|
||||
pFileName->szExtension = hb_itemGetCPtr( pItem );
|
||||
@@ -2238,7 +2435,7 @@ static ERRCODE hb_dbfCreate( DBFAREAP pArea, LPDBOPENINFO pCreateInfo )
|
||||
hb_xfree( pFileName );
|
||||
|
||||
pItem = hb_itemPutL( pItem, FALSE );
|
||||
fRawBlob = SELF_RDDINFO( SELF_RDDNODE( pArea ), RDDI_BLOB_SUPPORT, 0, pItem ) == SUCCESS &&
|
||||
fRawBlob = SELF_RDDINFO( SELF_RDDNODE( pArea ), RDDI_BLOB_SUPPORT, pCreateInfo->ulConnection, pItem ) == SUCCESS &&
|
||||
hb_itemGetL( pItem );
|
||||
|
||||
if( pArea->bTableType == 0 )
|
||||
@@ -2247,6 +2444,7 @@ static ERRCODE hb_dbfCreate( DBFAREAP pArea, LPDBOPENINFO pCreateInfo )
|
||||
if( SELF_INFO( ( AREAP ) pArea, DBI_TABLETYPE, pItem ) != SUCCESS )
|
||||
{
|
||||
hb_itemRelease( pItem );
|
||||
pArea->lpdbOpenInfo = NULL;
|
||||
return FAILURE;
|
||||
}
|
||||
pArea->bTableType = hb_itemGetNI( pItem );
|
||||
@@ -2258,6 +2456,7 @@ static ERRCODE hb_dbfCreate( DBFAREAP pArea, LPDBOPENINFO pCreateInfo )
|
||||
if( SELF_INFO( ( AREAP ) pArea, DBI_LOCKSCHEME, pItem ) != SUCCESS )
|
||||
{
|
||||
hb_itemRelease( pItem );
|
||||
pArea->lpdbOpenInfo = NULL;
|
||||
return FAILURE;
|
||||
}
|
||||
pArea->bLockType = hb_itemGetNI( pItem );
|
||||
@@ -2278,6 +2477,7 @@ static ERRCODE hb_dbfCreate( DBFAREAP pArea, LPDBOPENINFO pCreateInfo )
|
||||
if( SELF_INFO( ( AREAP ) pArea, DBI_MEMOTYPE, pItem ) != SUCCESS )
|
||||
{
|
||||
hb_itemRelease( pItem );
|
||||
pArea->lpdbOpenInfo = NULL;
|
||||
return FAILURE;
|
||||
}
|
||||
pArea->bMemoType = ( BYTE ) hb_itemGetNI( pItem );
|
||||
@@ -2286,9 +2486,7 @@ static ERRCODE hb_dbfCreate( DBFAREAP pArea, LPDBOPENINFO pCreateInfo )
|
||||
pArea->bCryptType = DB_CRYPT_NONE;
|
||||
|
||||
if( pItem )
|
||||
{
|
||||
hb_itemRelease( pItem );
|
||||
}
|
||||
|
||||
if( pArea->uiFieldCount * sizeof( DBFFIELD ) + sizeof( DBFHEADER ) +
|
||||
( pArea->bTableType == DB_DBF_VFP ? 1 : 2 ) > UINT16_MAX )
|
||||
@@ -2300,6 +2498,7 @@ static ERRCODE hb_dbfCreate( DBFAREAP pArea, LPDBOPENINFO pCreateInfo )
|
||||
hb_errPutFileName( pError, ( char * ) pCreateInfo->abName );
|
||||
SELF_ERROR( ( AREAP ) pArea, pError );
|
||||
hb_itemRelease( pError );
|
||||
pArea->lpdbOpenInfo = NULL;
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
@@ -2338,6 +2537,7 @@ static ERRCODE hb_dbfCreate( DBFAREAP pArea, LPDBOPENINFO pCreateInfo )
|
||||
|
||||
if( pArea->hDataFile == FS_ERROR )
|
||||
{
|
||||
pArea->lpdbOpenInfo = NULL;
|
||||
return FAILURE;
|
||||
}
|
||||
}
|
||||
@@ -2474,6 +2674,7 @@ static ERRCODE hb_dbfCreate( DBFAREAP pArea, LPDBOPENINFO pCreateInfo )
|
||||
hb_errPutFileName( pError, ( char * ) pCreateInfo->abName );
|
||||
SELF_ERROR( ( AREAP ) pArea, pError );
|
||||
hb_itemRelease( pError );
|
||||
pArea->lpdbOpenInfo = NULL;
|
||||
return FAILURE;
|
||||
}
|
||||
pThisField++ ;
|
||||
@@ -2504,6 +2705,25 @@ static ERRCODE hb_dbfCreate( DBFAREAP pArea, LPDBOPENINFO pCreateInfo )
|
||||
pArea->cdPage = hb_cdp_page;
|
||||
#endif
|
||||
|
||||
pItem = hb_itemNew( NULL );
|
||||
if( SELF_RDDINFO( SELF_RDDNODE( pArea ), RDDI_PENDINGPASSWORD,
|
||||
pCreateInfo->ulConnection, pItem ) == SUCCESS )
|
||||
{
|
||||
if( hb_dbfPasswordSet( pArea, pItem ) )
|
||||
pArea->fTableEncrypted = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
hb_itemClear( pItem );
|
||||
if( SELF_RDDINFO( SELF_RDDNODE( pArea ), RDDI_PASSWORD,
|
||||
pCreateInfo->ulConnection, pItem ) == SUCCESS )
|
||||
{
|
||||
if( hb_dbfPasswordSet( pArea, pItem ) )
|
||||
pArea->fTableEncrypted = TRUE;
|
||||
}
|
||||
}
|
||||
hb_itemRelease( pItem );
|
||||
|
||||
if( !fRawBlob )
|
||||
{
|
||||
/* Force write new header */
|
||||
@@ -2515,6 +2735,7 @@ static ERRCODE hb_dbfCreate( DBFAREAP pArea, LPDBOPENINFO pCreateInfo )
|
||||
if( pBuffer )
|
||||
hb_xfree( pBuffer );
|
||||
SELF_CLOSE( ( AREAP ) pArea );
|
||||
pArea->lpdbOpenInfo = NULL;
|
||||
return errCode;
|
||||
}
|
||||
|
||||
@@ -2528,6 +2749,7 @@ static ERRCODE hb_dbfCreate( DBFAREAP pArea, LPDBOPENINFO pCreateInfo )
|
||||
if( pBuffer )
|
||||
hb_xfree( pBuffer );
|
||||
SELF_CLOSE( ( AREAP ) pArea );
|
||||
pArea->lpdbOpenInfo = NULL;
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
@@ -2555,6 +2777,7 @@ static ERRCODE hb_dbfCreate( DBFAREAP pArea, LPDBOPENINFO pCreateInfo )
|
||||
if( errCode != SUCCESS )
|
||||
{
|
||||
SELF_CLOSE( ( AREAP ) pArea );
|
||||
pArea->lpdbOpenInfo = NULL;
|
||||
return errCode;
|
||||
}
|
||||
|
||||
@@ -2564,6 +2787,7 @@ static ERRCODE hb_dbfCreate( DBFAREAP pArea, LPDBOPENINFO pCreateInfo )
|
||||
|
||||
/* Update the number of record for corrupted headers */
|
||||
pArea->ulRecCount = hb_dbfCalcRecCount( pArea );
|
||||
pArea->lpdbOpenInfo = NULL;
|
||||
|
||||
/* Position cursor at the first record */
|
||||
return SELF_GOTOP( ( AREAP ) pArea );
|
||||
@@ -2714,62 +2938,25 @@ static ERRCODE hb_dbfInfo( DBFAREAP pArea, USHORT uiIndex, PHB_ITEM pItem )
|
||||
break;
|
||||
|
||||
case DBI_PASSWORD:
|
||||
hb_dbfPasswordSet( pArea, pItem );
|
||||
break;
|
||||
|
||||
case DBI_TRIGGER:
|
||||
if( HB_IS_LOGICAL( pItem ) )
|
||||
pArea->fTrigger = hb_itemGetL( pItem );
|
||||
else
|
||||
{
|
||||
BYTE byBuffer[ 8 ];
|
||||
ULONG ulLen = 0;
|
||||
BOOL fSet = !pArea->fHasMemo && HB_IS_STRING( pItem );
|
||||
|
||||
if( fSet )
|
||||
{
|
||||
ulLen = hb_itemGetCLen( pItem );
|
||||
if( ulLen > 0 )
|
||||
{
|
||||
if( ulLen < 8 )
|
||||
{
|
||||
memcpy( byBuffer, hb_itemGetCPtr( pItem ), ulLen );
|
||||
memset( byBuffer + ulLen, '\0', 8 - ulLen );
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy( byBuffer, hb_itemGetCPtr( pItem ), 8 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( pArea->pCryptKey )
|
||||
hb_itemPutCL( pItem, ( char * ) pArea->pCryptKey, 8 );
|
||||
else
|
||||
hb_itemClear( pItem );
|
||||
|
||||
if( fSet )
|
||||
{
|
||||
if( pArea->fPositioned )
|
||||
{
|
||||
errCode = SELF_GOCOLD( ( AREAP ) pArea );
|
||||
pArea->fValidBuffer = FALSE;
|
||||
}
|
||||
if( pArea->pCryptKey )
|
||||
{
|
||||
/* clean the memory with password key - though it's not
|
||||
* a serious actions in such case ;-)
|
||||
*/
|
||||
memset( pArea->pCryptKey, '\0', 8 );
|
||||
hb_xfree( pArea->pCryptKey );
|
||||
pArea->pCryptKey = NULL;
|
||||
}
|
||||
if( ulLen > 0 )
|
||||
{
|
||||
/* at this moment only one encryption method is used,
|
||||
I'll add other later, [druzus] */
|
||||
pArea->bCryptType = DB_CRYPT_SIX;
|
||||
pArea->pCryptKey = ( BYTE * ) hb_xgrab( 8 );
|
||||
/* SIX encode the key with its own value before use */
|
||||
hb_sxEnCrypt( byBuffer, pArea->pCryptKey, byBuffer, 8 );
|
||||
}
|
||||
}
|
||||
PHB_DYNS pTriggerSym = pArea->pTriggerSym;
|
||||
if( HB_IS_STRING( pItem ) )
|
||||
hb_dbfTriggerSet( pArea, pItem );
|
||||
hb_itemPutC( pItem, pTriggerSym ? hb_dynsymName( pTriggerSym ) : NULL );
|
||||
}
|
||||
break;
|
||||
|
||||
case DBI_OPENINFO:
|
||||
hb_itemPutPtr( pItem, pArea->lpdbOpenInfo );
|
||||
break;
|
||||
|
||||
case DBI_DB_VERSION:
|
||||
case DBI_RDD_VERSION:
|
||||
{
|
||||
@@ -2955,7 +3142,7 @@ static ERRCODE hb_dbfOpen( DBFAREAP pArea, LPDBOPENINFO pOpenInfo )
|
||||
ERRCODE errCode;
|
||||
USHORT uiFlags, uiFields, uiSize, uiCount, uiSkip;
|
||||
BOOL fRetry, fRawBlob;
|
||||
PHB_ITEM pError, pFileExt, pItem;
|
||||
PHB_ITEM pError, pItem;
|
||||
PHB_FNAME pFileName;
|
||||
BYTE * pBuffer;
|
||||
LPDBFFIELD pField;
|
||||
@@ -2965,19 +3152,53 @@ static ERRCODE hb_dbfOpen( DBFAREAP pArea, LPDBOPENINFO pOpenInfo )
|
||||
|
||||
HB_TRACE(HB_TR_DEBUG, ("hb_dbfOpen(%p, %p)", pArea, pOpenInfo));
|
||||
|
||||
pArea->lpdbOpenInfo = pOpenInfo;
|
||||
|
||||
pItem = hb_itemNew( NULL );
|
||||
|
||||
if( SELF_RDDINFO( SELF_RDDNODE( pArea ), RDDI_PENDINGTRIGGER,
|
||||
pOpenInfo->ulConnection, pItem ) == SUCCESS )
|
||||
{
|
||||
if( HB_IS_STRING( pItem ) )
|
||||
hb_dbfTriggerSet( pArea, pItem );
|
||||
}
|
||||
|
||||
if( !pArea->fTrigger )
|
||||
{
|
||||
if( SELF_RDDINFO( SELF_RDDNODE( pArea ), RDDI_TRIGGER,
|
||||
pOpenInfo->ulConnection, pItem ) == SUCCESS )
|
||||
{
|
||||
if( HB_IS_STRING( pItem ) )
|
||||
hb_dbfTriggerSet( pArea, pItem );
|
||||
}
|
||||
}
|
||||
|
||||
if( pArea->fTrigger )
|
||||
{
|
||||
hb_itemPutC( pItem, ( char * ) pOpenInfo->abName );
|
||||
if( !hb_dbfTriggerDo( pArea, EVENT_PREUSE, 0, pItem ) )
|
||||
{
|
||||
hb_itemRelease( pItem );
|
||||
pArea->lpdbOpenInfo = NULL;
|
||||
return FAILURE;
|
||||
}
|
||||
hb_strncpy( ( char * ) szFileName, hb_itemGetCPtr( pItem ), _POSIX_PATH_MAX );
|
||||
}
|
||||
else
|
||||
hb_strncpy( ( char * ) szFileName, ( char * ) pOpenInfo->abName, _POSIX_PATH_MAX );
|
||||
|
||||
if( !pArea->bLockType )
|
||||
{
|
||||
PHB_ITEM pItem = hb_itemNew( NULL );
|
||||
|
||||
hb_itemClear( pItem );
|
||||
if( SELF_INFO( ( AREAP ) pArea, DBI_LOCKSCHEME, pItem ) != SUCCESS )
|
||||
{
|
||||
hb_itemRelease( pItem );
|
||||
pArea->lpdbOpenInfo = NULL;
|
||||
return FAILURE;
|
||||
}
|
||||
pArea->bLockType = hb_itemGetNI( pItem );
|
||||
if( !pArea->bLockType )
|
||||
pArea->bLockType = DB_DBFLOCK_CLIP;
|
||||
hb_itemRelease( pItem );
|
||||
}
|
||||
#ifndef HB_CDP_SUPPORT_OFF
|
||||
if( pOpenInfo->cdpId )
|
||||
@@ -3002,24 +3223,20 @@ static ERRCODE hb_dbfOpen( DBFAREAP pArea, LPDBOPENINFO pOpenInfo )
|
||||
(pArea->fShared ? FO_DENYNONE : FO_EXCLUSIVE);
|
||||
pError = NULL;
|
||||
|
||||
pFileName = hb_fsFNameSplit( ( char * ) pOpenInfo->abName );
|
||||
pFileName = hb_fsFNameSplit( ( char * ) szFileName );
|
||||
/* Add default file name extension if necessary */
|
||||
if( hb_set.HB_SET_DEFEXTENSIONS && ! pFileName->szExtension )
|
||||
{
|
||||
pFileExt = hb_itemPutC( NULL, "" );
|
||||
if( SELF_INFO( ( AREAP ) pArea, DBI_TABLEEXT, pFileExt ) != SUCCESS )
|
||||
hb_itemClear( pItem );
|
||||
if( SELF_INFO( ( AREAP ) pArea, DBI_TABLEEXT, pItem ) != SUCCESS )
|
||||
{
|
||||
hb_itemRelease( pFileExt );
|
||||
hb_xfree( pFileName );
|
||||
hb_itemRelease( pItem );
|
||||
pArea->lpdbOpenInfo = NULL;
|
||||
return FAILURE;
|
||||
}
|
||||
pFileName->szExtension = hb_itemGetCPtr( pFileExt );
|
||||
pFileName->szExtension = hb_itemGetCPtr( pItem );
|
||||
hb_fsFNameMerge( ( char * ) szFileName, pFileName );
|
||||
hb_itemRelease( pFileExt );
|
||||
}
|
||||
else
|
||||
{
|
||||
hb_strncpy( ( char * ) szFileName, ( char * ) pOpenInfo->abName, _POSIX_PATH_MAX );
|
||||
}
|
||||
|
||||
/* Create default alias if necessary */
|
||||
@@ -3030,9 +3247,10 @@ static ERRCODE hb_dbfOpen( DBFAREAP pArea, LPDBOPENINFO pOpenInfo )
|
||||
}
|
||||
hb_xfree( pFileName );
|
||||
|
||||
pItem = hb_itemPutL( NULL, FALSE );
|
||||
fRawBlob = SELF_RDDINFO( SELF_RDDNODE( pArea ), RDDI_BLOB_SUPPORT, 0, pItem ) == SUCCESS &&
|
||||
hb_itemClear( pItem );
|
||||
fRawBlob = SELF_RDDINFO( SELF_RDDNODE( pArea ), RDDI_BLOB_SUPPORT, pOpenInfo->ulConnection, pItem ) == SUCCESS &&
|
||||
hb_itemGetL( pItem );
|
||||
|
||||
hb_itemRelease( pItem );
|
||||
|
||||
if( fRawBlob )
|
||||
@@ -3077,6 +3295,7 @@ static ERRCODE hb_dbfOpen( DBFAREAP pArea, LPDBOPENINFO pOpenInfo )
|
||||
if( pArea->hDataFile == FS_ERROR )
|
||||
{
|
||||
SELF_CLOSE( ( AREAP ) pArea );
|
||||
pArea->lpdbOpenInfo = NULL;
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
@@ -3088,6 +3307,7 @@ static ERRCODE hb_dbfOpen( DBFAREAP pArea, LPDBOPENINFO pOpenInfo )
|
||||
if( errCode != SUCCESS )
|
||||
{
|
||||
SELF_CLOSE( ( AREAP ) pArea );
|
||||
pArea->lpdbOpenInfo = NULL;
|
||||
return errCode;
|
||||
}
|
||||
|
||||
@@ -3133,6 +3353,7 @@ static ERRCODE hb_dbfOpen( DBFAREAP pArea, LPDBOPENINFO pOpenInfo )
|
||||
if( pBuffer )
|
||||
hb_xfree( pBuffer );
|
||||
SELF_CLOSE( ( AREAP ) pArea );
|
||||
pArea->lpdbOpenInfo = NULL;
|
||||
return errCode;
|
||||
}
|
||||
|
||||
@@ -3180,6 +3401,7 @@ static ERRCODE hb_dbfOpen( DBFAREAP pArea, LPDBOPENINFO pOpenInfo )
|
||||
if( errCode != SUCCESS )
|
||||
{
|
||||
SELF_CLOSE( ( AREAP ) pArea );
|
||||
pArea->lpdbOpenInfo = NULL;
|
||||
return errCode;
|
||||
}
|
||||
}
|
||||
@@ -3311,9 +3533,27 @@ static ERRCODE hb_dbfOpen( DBFAREAP pArea, LPDBOPENINFO pOpenInfo )
|
||||
hb_itemRelease( pError );
|
||||
}
|
||||
SELF_CLOSE( ( AREAP ) pArea );
|
||||
pArea->lpdbOpenInfo = NULL;
|
||||
return errCode;
|
||||
}
|
||||
|
||||
pItem = hb_itemNew( NULL );
|
||||
if( SELF_RDDINFO( SELF_RDDNODE( pArea ), RDDI_PENDINGPASSWORD,
|
||||
pOpenInfo->ulConnection, pItem ) == SUCCESS )
|
||||
{
|
||||
hb_dbfPasswordSet( pArea, pItem );
|
||||
}
|
||||
else
|
||||
{
|
||||
hb_itemClear( pItem );
|
||||
if( SELF_RDDINFO( SELF_RDDNODE( pArea ), RDDI_PASSWORD,
|
||||
pOpenInfo->ulConnection, pItem ) == SUCCESS )
|
||||
{
|
||||
hb_dbfPasswordSet( pArea, pItem );
|
||||
}
|
||||
}
|
||||
hb_itemRelease( pItem );
|
||||
|
||||
/* Open memo file if exists */
|
||||
if( pArea->fHasMemo )
|
||||
{
|
||||
@@ -3334,6 +3574,7 @@ static ERRCODE hb_dbfOpen( DBFAREAP pArea, LPDBOPENINFO pOpenInfo )
|
||||
if( errCode != SUCCESS )
|
||||
{
|
||||
SELF_CLOSE( ( AREAP ) pArea );
|
||||
pArea->lpdbOpenInfo = NULL;
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
@@ -3345,7 +3586,14 @@ static ERRCODE hb_dbfOpen( DBFAREAP pArea, LPDBOPENINFO pOpenInfo )
|
||||
pArea->ulRecCount = hb_dbfCalcRecCount( pArea );
|
||||
|
||||
/* Position cursor at the first record */
|
||||
return SELF_GOTOP( ( AREAP ) pArea );
|
||||
errCode = SELF_GOTOP( ( AREAP ) pArea );
|
||||
|
||||
if( pArea->fTrigger )
|
||||
hb_dbfTriggerDo( pArea, EVENT_POSTUSE, 0, NULL );
|
||||
|
||||
pArea->lpdbOpenInfo = NULL;
|
||||
|
||||
return errCode;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3419,6 +3667,12 @@ static ERRCODE hb_dbfPack( DBFAREAP pArea )
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
if( pArea->fTrigger )
|
||||
{
|
||||
if( !hb_dbfTriggerDo( pArea, EVENT_PACK, 0, NULL ) )
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
if( SELF_GOCOLD( ( AREAP ) pArea ) != SUCCESS )
|
||||
return FAILURE;
|
||||
|
||||
@@ -3667,6 +3921,12 @@ static ERRCODE hb_dbfZap( DBFAREAP pArea )
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
if( pArea->fTrigger )
|
||||
{
|
||||
if( !hb_dbfTriggerDo( pArea, EVENT_ZAP, 0, NULL ) )
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
if( SELF_GOCOLD( ( AREAP ) pArea ) != SUCCESS )
|
||||
return FAILURE;
|
||||
|
||||
@@ -4527,6 +4787,17 @@ static ERRCODE hb_dbfExit( LPRDDNODE pRDD )
|
||||
|
||||
if( pRDD->lpvCargo )
|
||||
{
|
||||
LPDBFDATA pData = ( LPDBFDATA ) pRDD->lpvCargo;
|
||||
|
||||
if( pData->szTrigger )
|
||||
hb_xfree( pData->szTrigger );
|
||||
if( pData->szPendingTrigger )
|
||||
hb_xfree( pData->szPendingTrigger );
|
||||
if( pData->szPasswd )
|
||||
hb_xfree( pData->szPasswd );
|
||||
if( pData->szPendingPasswd )
|
||||
hb_xfree( pData->szPendingPasswd );
|
||||
|
||||
hb_xfree( pRDD->lpvCargo );
|
||||
pRDD->lpvCargo = NULL;
|
||||
}
|
||||
@@ -4600,6 +4871,92 @@ static ERRCODE hb_dbfRddInfo( LPRDDNODE pRDD, USHORT uiIndex, ULONG ulConnect, P
|
||||
break;
|
||||
}
|
||||
|
||||
case RDDI_TRIGGER:
|
||||
{
|
||||
char * szTrigger = pData->szTrigger;
|
||||
BOOL fFree = FALSE;
|
||||
|
||||
if( HB_IS_STRING( pItem ) )
|
||||
{
|
||||
fFree = TRUE;
|
||||
pData->szTrigger = hb_itemGetCLen( pItem ) > 0 ?
|
||||
hb_itemGetC( pItem ) : NULL;
|
||||
}
|
||||
|
||||
if( fFree && szTrigger )
|
||||
hb_itemPutCPtr( pItem, szTrigger, strlen( szTrigger ) );
|
||||
else
|
||||
hb_itemPutC( pItem, szTrigger );
|
||||
|
||||
if( !szTrigger && !fFree )
|
||||
return FAILURE;
|
||||
|
||||
break;
|
||||
}
|
||||
case RDDI_PENDINGTRIGGER:
|
||||
if( HB_IS_STRING( pItem ) )
|
||||
{
|
||||
if( pData->szPendingTrigger )
|
||||
{
|
||||
hb_xfree( pData->szPendingTrigger );
|
||||
pData->szPendingTrigger = NULL;
|
||||
}
|
||||
if( hb_itemGetCLen( pItem ) > 0 )
|
||||
pData->szPendingTrigger = hb_itemGetC( pItem );
|
||||
}
|
||||
else if( pData->szPendingTrigger )
|
||||
{
|
||||
hb_itemPutCPtr( pItem, pData->szPendingTrigger,
|
||||
strlen( pData->szPendingTrigger ) );
|
||||
pData->szPendingTrigger = NULL;
|
||||
}
|
||||
else
|
||||
return FAILURE;
|
||||
break;
|
||||
|
||||
case RDDI_PASSWORD:
|
||||
{
|
||||
char * szPasswd = pData->szPasswd;
|
||||
BOOL fFree = FALSE;
|
||||
|
||||
if( HB_IS_STRING( pItem ) )
|
||||
{
|
||||
fFree = TRUE;
|
||||
pData->szPasswd = hb_itemGetCLen( pItem ) > 0 ?
|
||||
hb_itemGetC( pItem ) : NULL;
|
||||
}
|
||||
|
||||
if( fFree && szPasswd )
|
||||
hb_itemPutCPtr( pItem, szPasswd, strlen( szPasswd ) );
|
||||
else
|
||||
hb_itemPutC( pItem, szPasswd );
|
||||
|
||||
if( !szPasswd && !fFree )
|
||||
return FAILURE;
|
||||
|
||||
break;
|
||||
}
|
||||
case RDDI_PENDINGPASSWORD:
|
||||
if( HB_IS_STRING( pItem ) )
|
||||
{
|
||||
if( pData->szPendingPasswd )
|
||||
{
|
||||
hb_xfree( pData->szPendingPasswd );
|
||||
pData->szPendingPasswd = NULL;
|
||||
}
|
||||
if( hb_itemGetCLen( pItem ) > 0 )
|
||||
pData->szPendingPasswd = hb_itemGetC( pItem );
|
||||
}
|
||||
else if( pData->szPendingPasswd )
|
||||
{
|
||||
hb_itemPutCPtr( pItem, pData->szPendingPasswd,
|
||||
strlen( pData->szPendingPasswd ) );
|
||||
pData->szPendingPasswd = NULL;
|
||||
}
|
||||
else
|
||||
return FAILURE;
|
||||
break;
|
||||
|
||||
default:
|
||||
return SUPER_RDDINFO( pRDD, uiIndex, ulConnect, pItem );
|
||||
|
||||
|
||||
@@ -1680,6 +1680,7 @@ static ERRCODE hb_waRddInfo( LPRDDNODE pRDD, USHORT uiIndex, ULONG ulConnection,
|
||||
hb_itemPutC( pItem, hb_set.HB_SET_MFILEEXT );
|
||||
break;
|
||||
}
|
||||
/* no break - return FAILURE */
|
||||
case RDDI_TABLEEXT:
|
||||
case RDDI_ORDBAGEXT:
|
||||
case RDDI_ORDEREXT:
|
||||
|
||||
Reference in New Issue
Block a user