* include/hbapirdd.h
* source/rdd/dbcmd.c
* source/rdd/dbcmd53.c
* source/rdd/dbcmdx.c
* source/rdd/dbdetach.c
* source/rdd/dbf1.c
* source/rdd/dbsql.c
* source/rdd/delim1.c
* source/rdd/hbdbsort.c
* source/rdd/sdf1.c
* source/rdd/wacore.c
* source/rdd/wafunc.c
* source/rdd/workarea.c
* source/rdd/dbfcdx/dbfcdx1.c
* source/rdd/dbffpt/dbffpt1.c
* source/rdd/dbfnsx/dbfnsx1.c
* source/rdd/dbfntx/dbfntx1.c
* source/rdd/hbsix/sxcrypt.c
* source/rdd/hbsix/sxord.c
* source/rdd/hbsix/sxtable.c
* source/rdd/hsx/hsx.c
* source/rdd/nulsys/nulsys.c
* source/rdd/usrrdd/rdds/arrayrdd.prg
* source/rdd/usrrdd/rdds/fcomma.prg
* source/rdd/usrrdd/rdds/hscdx.prg
* source/rdd/usrrdd/rdds/logrdd.prg
* source/rdd/usrrdd/rdds/rlcdx.prg
* source/rdd/usrrdd/usrrdd.c
* SUCCESS -> HB_SUCCESS
* FAILURE -> HB_FAILURE
* ERRCODE -> HB_ERRCODE
1345 lines
39 KiB
Plaintext
1345 lines
39 KiB
Plaintext
/*
|
|
* $Id$
|
|
*/
|
|
|
|
/*
|
|
* Harbour Project source code:
|
|
* ARRAY RDD
|
|
*
|
|
* Copyright 2006 Francesco Saverio Giudice <info / at / fsgiudice / dot / com>
|
|
* www - http://www.harbour-project.org
|
|
* www - http://www.xharbour.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.
|
|
*
|
|
*/
|
|
|
|
|
|
/*
|
|
* This is a Array RDD, or Memory RDD.
|
|
* It works only in memory and actually supports standard dbf commands
|
|
* excepts indexes, orders, relations
|
|
*/
|
|
|
|
#include "rddsys.ch"
|
|
#include "hbusrrdd.ch"
|
|
#include "fileio.ch"
|
|
#include "error.ch"
|
|
#include "dbstruct.ch"
|
|
#include "common.ch"
|
|
|
|
#xtranslate THROW( <oErr> ) => ( Eval( ErrorBlock(), <oErr> ), Break( <oErr> ) )
|
|
|
|
//#define ACTIVATE_DEBUG // add xhb.lib to link
|
|
|
|
ANNOUNCE ARRAYRDD
|
|
|
|
#define DATABASE_FILENAME 1
|
|
#define DATABASE_RECORDS 2
|
|
#define DATABASE_RECINFO 3
|
|
#define DATABASE_OPENNUMBER 4
|
|
#define DATABASE_LOCKED 5
|
|
#define DATABASE_STRUCT 6
|
|
#define DATABASE_SIZEOF 6
|
|
|
|
#define RDDDATA_DATABASE 1
|
|
#define RDDDATA_SIZEOF 1
|
|
|
|
#define WADATA_DATABASE 1
|
|
#define WADATA_WORKAREA 2
|
|
#define WADATA_OPENINFO 3
|
|
#define WADATA_RECNO 4
|
|
#define WADATA_BOF 5
|
|
#define WADATA_FORCEBOF 6
|
|
#define WADATA_EOF 7
|
|
#define WADATA_TOP 8
|
|
#define WADATA_BOTTOM 9
|
|
#define WADATA_FOUND 10
|
|
#define WADATA_LOCKS 11
|
|
#define WADATA_SIZEOF 11
|
|
|
|
#define RECDATA_DELETED 1
|
|
#define RECDATA_SIZEOF 1
|
|
|
|
/*
|
|
* non work area methods receive RDD ID as first parameter
|
|
* Methods INIT and EXIT does not have to execute SUPER methods - these is
|
|
* always done by low level USRRDD code
|
|
*/
|
|
STATIC FUNCTION AR_INIT( nRDD )
|
|
|
|
/* Init DBF Hash */
|
|
USRRDD_RDDDATA( nRDD, hb_Hash() )
|
|
|
|
RETURN HB_SUCCESS
|
|
|
|
STATIC FUNCTION AR_RDDDATAINIT()
|
|
RETURN { ;
|
|
NIL ; // RDDDATA_DATABASE
|
|
}
|
|
|
|
STATIC FUNCTION AR_DATABASEINIT()
|
|
RETURN { ;
|
|
NIL ,; // DATABASE_FILENAME
|
|
{} ,; // DATABASE_RECORDS
|
|
{} ,; // DATABASE_RECINFO
|
|
0 ,; // DATABASE_OPENNUMBER
|
|
FALSE ,; // DATABASE_LOCKED
|
|
NIL ; // DATABASE_STRUCT - aStruct
|
|
}
|
|
|
|
STATIC FUNCTION AR_WADATAINIT()
|
|
RETURN { ;
|
|
NIL ,; // WADATA_DATABASE
|
|
0 ,; // WADATA_WORKAREA
|
|
NIL ,; // WADATA_OPENINFO
|
|
0 ,; // WADATA_RECNO
|
|
FALSE ,; // WADATA_BOF
|
|
FALSE ,; // WADATA_FORCEBOF // to solve an hack in dbf1.c
|
|
FALSE ,; // WADATA_EOF
|
|
FALSE ,; // WADATA_TOP
|
|
FALSE ,; // WADATA_BOTTOM
|
|
FALSE ,; // WADATA_FOUND
|
|
{} ; // WADATA_LOCKS
|
|
}
|
|
|
|
STATIC FUNCTION AR_RECDATAINIT()
|
|
RETURN { ;
|
|
FALSE ; // RECDATA_DELETED
|
|
}
|
|
|
|
/*
|
|
* methods: NEW and RELEASE receive pointer to work area structure
|
|
* not work area number. It's necessary because the can be executed
|
|
* before work area is allocated
|
|
* these methods does not have to execute SUPER methods - these is
|
|
* always done by low level USRRDD code
|
|
*/
|
|
STATIC FUNCTION AR_NEW( pWA )
|
|
|
|
/*
|
|
* Set in our private AREA item the array with slot number and
|
|
* BOF/EOF flags. There is no BOF support in HB_F* function so
|
|
* we have to emulate it and there is no phantom record so we
|
|
* cannot return EOF flag directly.
|
|
*/
|
|
USRRDD_AREADATA( pWA, AR_WADATAINIT() )
|
|
|
|
RETURN HB_SUCCESS
|
|
|
|
// Creating fields for new DBF - dbCreate() in current workarea
|
|
STATIC FUNCTION AR_CREATEFIELDS( nWA, aStruct )
|
|
LOCAL aWAData := USRRDD_AREADATA( nWA )
|
|
LOCAL nResult := HB_SUCCESS
|
|
LOCAL aFieldStruct, aField
|
|
|
|
#ifdef ACTIVATE_DEBUG
|
|
hb_ToOutDebug( "AR_CREATEFIELDS(): nWA = %i, aStruct = %s\n\r", nWA, hb_ValToExp( aStruct ) )
|
|
#endif
|
|
|
|
// Setting WA number to current WorkArea
|
|
aWAData[ WADATA_WORKAREA ] := nWA
|
|
|
|
// Create new file data structure - workarea uses a reference to database
|
|
aWAData[ WADATA_DATABASE ] := AR_DATABASEINIT()
|
|
|
|
// Store DBF Structure
|
|
aWAData[ WADATA_DATABASE ][ DATABASE_STRUCT ] := aStruct
|
|
|
|
// Set fields
|
|
UR_SUPER_SETFIELDEXTENT( nWA, Len( aStruct ) )
|
|
|
|
FOR EACH aFieldStruct IN aStruct
|
|
|
|
aField := ARRAY( UR_FI_SIZE )
|
|
aField[ UR_FI_NAME ] := aFieldStruct[ DBS_NAME ]
|
|
aField[ UR_FI_TYPE ] := HB_Decode( aFieldStruct[ DBS_TYPE ], "C", HB_FT_STRING, "L", HB_FT_LOGICAL, "M", HB_FT_MEMO, "D", HB_FT_DATE, "N", IIF( aFieldStruct[ DBS_DEC ] > 0, HB_FT_DOUBLE, HB_FT_INTEGER ) )
|
|
aField[ UR_FI_TYPEEXT ] := 0
|
|
aField[ UR_FI_LEN ] := aFieldStruct[ DBS_LEN ]
|
|
aField[ UR_FI_DEC ] := aFieldStruct[ DBS_DEC ]
|
|
UR_SUPER_ADDFIELD( nWA, aField )
|
|
|
|
NEXT
|
|
|
|
RETURN nResult
|
|
|
|
// Create database from current WA fields definition
|
|
STATIC FUNCTION AR_CREATE( nWA, aOpenInfo )
|
|
LOCAL aWAData := USRRDD_AREADATA( nWA )
|
|
LOCAL hRDDData := USRRDD_RDDDATA( USRRDD_ID( nWA ) )
|
|
LOCAL cName
|
|
LOCAL cFullName, aDBFData, nResult//, aFieldStruct, aField, aStruct
|
|
|
|
#ifdef ACTIVATE_DEBUG
|
|
hb_ToOutDebug( "AR_CREATE(): nWA = %i, aOpenInfo = %s\n\r", nWA, hb_ValToExp( aOpenInfo ) )
|
|
#endif
|
|
|
|
/* getting database infos from current workarea */
|
|
aDBFData := aWAData[ WADATA_DATABASE ]
|
|
|
|
/* setting in uppercase chars to avoid differences */
|
|
cFullName := Upper( aOpenInfo[ UR_OI_NAME ] )
|
|
|
|
/* When there is no ALIAS we will create new one using file name */
|
|
IF aOpenInfo[ UR_OI_ALIAS ] == NIL
|
|
HB_FNAMESPLIT( cFullName, , @cName )
|
|
aOpenInfo[ UR_OI_ALIAS ] := cName
|
|
ENDIF
|
|
|
|
/* Check if database is already present in memory slots */
|
|
/*
|
|
07/11/2008 FSG - dbCreate() doesn't check if a dbf file exists. So I will not check it.
|
|
If you need to check if a table exists use hb_FileArrayRdd() function that works in
|
|
similar way of File(), i.e.:
|
|
IF hb_FileArrayRdd( cFullName )
|
|
dbCreate( cFullName, aStructure, "ARRAYRDD" )
|
|
....
|
|
*/
|
|
//IF !( cFullName $ hRDDData:Keys )
|
|
|
|
/* Setting file attribs */
|
|
aDBFData[ DATABASE_FILENAME ] := cFullName
|
|
aDBFData[ DATABASE_LOCKED ] := TRUE /* I need Exclusive mode in creation */
|
|
|
|
/* Adding new database in RDD memory slots using filename as key */
|
|
hb_hSet( hRDDData, cFullName, aDBFData )
|
|
|
|
/* TODO: to clean this part
|
|
ELSE
|
|
|
|
// ERROR: database already exists
|
|
|
|
oError := ErrorNew()
|
|
|
|
oError:GenCode := EG_CREATE
|
|
oError:SubCode := 1004 // EDBF_CREATE_DBF
|
|
oError:Description := HB_LANGERRMSG( EG_CREATE ) + " (" + ;
|
|
HB_LANGERRMSG( EG_UNSUPPORTED ) + " - database already exists)"
|
|
oError:FileName := aOpenInfo[ UR_OI_NAME ]
|
|
oError:CanDefault := .T.
|
|
UR_SUPER_ERROR( nWA, oError )
|
|
|
|
RETURN HB_FAILURE
|
|
|
|
ENDIF
|
|
*/
|
|
|
|
// Set WorkArea Info
|
|
aWAData[ WADATA_WORKAREA ] := nWA
|
|
aWAData[ WADATA_OPENINFO ] := aOpenInfo // Put open informations
|
|
|
|
/* Call SUPER OPEN to finish allocating work area (f.e.: alias settings) */
|
|
nResult := UR_SUPER_OPEN( nWA, aOpenInfo )
|
|
|
|
IF nResult == HB_SUCCESS
|
|
/* Add a new open number */
|
|
aDBFData[ DATABASE_OPENNUMBER ]++
|
|
// default values for Records == 0
|
|
aWAData[ WADATA_EOF ] := aWAData[ WADATA_BOF ] := .T.
|
|
aWAData[ WADATA_RECNO ] := 1
|
|
ENDIF
|
|
|
|
RETURN nResult
|
|
|
|
STATIC FUNCTION AR_OPEN( nWA, aOpenInfo )
|
|
LOCAL cFullName, cName, hRDDData, aWAData, aDBFData
|
|
LOCAL aStruct, oError, aFieldStruct, aField, nResult
|
|
|
|
#ifdef ACTIVATE_DEBUG
|
|
hb_ToOutDebug( "AR_OPEN(): nWA = %i, aOpenInfo = %s\n\r", nWA, hb_ValToExp( aOpenInfo ) )
|
|
#endif
|
|
|
|
cFullName := Upper( aOpenInfo[ UR_OI_NAME ] )
|
|
|
|
/* When there is no ALIAS we will create new one using file name */
|
|
IF aOpenInfo[ UR_OI_ALIAS ] == NIL
|
|
HB_FNAMESPLIT( cFullName, , @cName )
|
|
aOpenInfo[ UR_OI_ALIAS ] := cName
|
|
ENDIF
|
|
|
|
//nMode := IIF( aOpenInfo[ UR_OI_SHARED ], FO_SHARED , FO_EXCLUSIVE ) + ;
|
|
// IIF( aOpenInfo[ UR_OI_READONLY ], FO_READ, FO_READWRITE )
|
|
|
|
hRDDData := USRRDD_RDDDATA( USRRDD_ID( nWA ) )
|
|
|
|
IF HB_HHasKey( hRDDData, cFullName )
|
|
|
|
aDBFData := hRDDData[ cFullName ]
|
|
aStruct := aDBFData[ DATABASE_STRUCT ]
|
|
|
|
ELSE
|
|
|
|
oError := ErrorNew()
|
|
oError:GenCode := EG_OPEN
|
|
oError:SubCode := 1000
|
|
oError:Description := HB_LANGERRMSG( EG_OPEN ) + ", memory file not found"
|
|
oError:FileName := aOpenInfo[ UR_OI_NAME ]
|
|
oError:CanDefault := .T.
|
|
UR_SUPER_ERROR( nWA, oError )
|
|
RETURN HB_FAILURE
|
|
|
|
ENDIF
|
|
|
|
// Set WorkArea Infos
|
|
aWAData := USRRDD_AREADATA( nWA )
|
|
aWAData[ WADATA_DATABASE ] := aDBFData // Put a reference to database
|
|
aWAData[ WADATA_WORKAREA ] := nWA
|
|
aWAData[ WADATA_OPENINFO ] := aOpenInfo // Put open informations
|
|
|
|
// Set fields
|
|
UR_SUPER_SETFIELDEXTENT( nWA, Len( aStruct ) )
|
|
|
|
FOR EACH aFieldStruct IN aStruct
|
|
|
|
aField := ARRAY( UR_FI_SIZE )
|
|
aField[ UR_FI_NAME ] := aFieldStruct[ DBS_NAME ]
|
|
aField[ UR_FI_TYPE ] := HB_Decode( aFieldStruct[ DBS_TYPE ], "C", HB_FT_STRING, "L", HB_FT_LOGICAL, "M", HB_FT_MEMO, "D", HB_FT_DATE, "N", IIF( aFieldStruct[ DBS_DEC ] > 0, HB_FT_DOUBLE, HB_FT_INTEGER ) )
|
|
aField[ UR_FI_TYPEEXT ] := 0
|
|
aField[ UR_FI_LEN ] := aFieldStruct[ DBS_LEN ]
|
|
aField[ UR_FI_DEC ] := aFieldStruct[ DBS_DEC ]
|
|
UR_SUPER_ADDFIELD( nWA, aField )
|
|
|
|
NEXT
|
|
|
|
/* Call SUPER OPEN to finish allocating work area (f.e.: alias settings) */
|
|
nResult := UR_SUPER_OPEN( nWA, aOpenInfo )
|
|
|
|
/* Add a new open number */
|
|
aDBFData[ DATABASE_OPENNUMBER ]++
|
|
|
|
// File already opened in exclusive mode
|
|
// I have to do this check here because, in case of error, AR_CLOSE() is called however
|
|
IF aDBFData[ DATABASE_LOCKED ]
|
|
|
|
oError := ErrorNew()
|
|
oError:GenCode := EG_OPEN
|
|
oError:SubCode := 1000
|
|
oError:Description := HB_LANGERRMSG( EG_OPEN ) + "(" + ;
|
|
HB_LANGERRMSG( EG_LOCK ) + " - already opened in exclusive mode)"
|
|
oError:FileName := aOpenInfo[ UR_OI_NAME ]
|
|
oError:CanDefault := .T.
|
|
UR_SUPER_ERROR( nWA, oError )
|
|
RETURN HB_FAILURE
|
|
|
|
ENDIF
|
|
|
|
// Open file in exclusive mode
|
|
IF !aOpenInfo[ UR_OI_SHARED ]
|
|
IF aDBFData[ DATABASE_OPENNUMBER ] == 1
|
|
aDBFData[ DATABASE_LOCKED ] := TRUE
|
|
ELSE
|
|
oError := ErrorNew()
|
|
oError:GenCode := EG_OPEN
|
|
oError:SubCode := 1000
|
|
oError:Description := HB_LANGERRMSG( EG_OPEN ) + "(" + ;
|
|
HB_LANGERRMSG( EG_LOCK ) + " - already opened in shared mode)"
|
|
oError:FileName := aOpenInfo[ UR_OI_NAME ]
|
|
oError:CanDefault := .T.
|
|
UR_SUPER_ERROR( nWA, oError )
|
|
RETURN HB_FAILURE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF nResult == HB_SUCCESS
|
|
AR_GOTOP( nWA )
|
|
ENDIF
|
|
|
|
RETURN nResult
|
|
|
|
STATIC FUNCTION AR_CLOSE( nWA )
|
|
LOCAL aWAData := USRRDD_AREADATA( nWA )
|
|
LOCAL aDBFData := aWAData[ WADATA_DATABASE ]
|
|
|
|
#ifdef ACTIVATE_DEBUG
|
|
hb_ToOutDebug( "AR_CLOSE(): nWA = %i\n\r", nWA )
|
|
#endif
|
|
|
|
IF HB_ISARRAY( aDBFData )
|
|
// decrease open number
|
|
aDBFData[ DATABASE_OPENNUMBER ]--
|
|
|
|
// unlock file
|
|
aDBFData[ DATABASE_LOCKED ] := FALSE // Exclusive mode
|
|
ENDIF
|
|
|
|
RETURN UR_SUPER_CLOSE( nWA )
|
|
|
|
STATIC FUNCTION AR_GETVALUE( nWA, nField, xValue )
|
|
LOCAL aWAData := USRRDD_AREADATA( nWA )
|
|
LOCAL aDBFData := aWAData[ WADATA_DATABASE ]
|
|
LOCAL aRecords := aDBFData[ DATABASE_RECORDS ]
|
|
LOCAL aStruct := aDBFData[ DATABASE_STRUCT ]
|
|
LOCAL nRecNo := aWAData[ WADATA_RECNO ]
|
|
|
|
#ifdef ACTIVATE_DEBUG
|
|
hb_ToOutDebug( "AR_GETVALUE(): nWA = %i, nField = %i, xValue = %s\n\r", nWA, nField, xValue )
|
|
#endif
|
|
|
|
IF nField > 0 .AND. nField <= Len( aStruct )
|
|
|
|
IF aWAData[ WADATA_EOF ]
|
|
/* We are at EOF position, return empty value */
|
|
xValue := EmptyValue( aStruct[ nField ][ DBS_TYPE ], aStruct[ nField ][ DBS_LEN ], aStruct[ nField ][ DBS_DEC ] )
|
|
ELSE
|
|
xValue := aRecords[ nRecNo ][ nField ]
|
|
ENDIF
|
|
|
|
RETURN HB_SUCCESS
|
|
|
|
ENDIF
|
|
|
|
RETURN HB_FAILURE
|
|
|
|
STATIC FUNCTION AR_PUTVALUE( nWA, nField, xValue )
|
|
LOCAL aWAData := USRRDD_AREADATA( nWA )
|
|
LOCAL aDBFData := aWAData[ WADATA_DATABASE ]
|
|
LOCAL aRecords := aDBFData[ DATABASE_RECORDS ]
|
|
LOCAL aStruct := aDBFData[ DATABASE_STRUCT ]
|
|
LOCAL nRecNo := aWAData[ WADATA_RECNO ]
|
|
LOCAL xVal
|
|
|
|
#ifdef ACTIVATE_DEBUG
|
|
hb_ToOutDebug( "AR_PUTVALUE(): nWA = %i, nField = %i, xValue = %s\n\r", nWA, nField, xValue )
|
|
#endif
|
|
|
|
IF nField > 0 .AND. nField <= Len( aStruct ) .AND. ;
|
|
IIF( ValType( xValue ) == "C" .AND. aStruct[ nField ][ DBS_TYPE ] == "M", TRUE, ValType( xValue ) == aStruct[ nField ][ DBS_TYPE ] )
|
|
|
|
xVal := PutValue( xValue, aStruct[ nField ][ DBS_TYPE ], aStruct[ nField ][ DBS_LEN ], aStruct[ nField ][ DBS_DEC ] )
|
|
|
|
//IF aWAData:APPENDACTIVE .OR. aWAData[ WADATA_EOF ]
|
|
// aWAData:PHANTOM[ nField ] := xVal
|
|
IF !aWAData[ WADATA_EOF ]
|
|
aRecords[ nRecNo ][ nField ] := xVal
|
|
ENDIF
|
|
|
|
RETURN HB_SUCCESS
|
|
|
|
ENDIF
|
|
|
|
RETURN HB_FAILURE
|
|
|
|
STATIC FUNCTION AR_GOTO( nWA, nRecord )
|
|
LOCAL aWAData := USRRDD_AREADATA( nWA )
|
|
LOCAL aDBFData := aWAData[ WADATA_DATABASE ]
|
|
LOCAL aRecords := aDBFData[ DATABASE_RECORDS ]
|
|
LOCAL nRecCount := Len( aRecords )
|
|
|
|
#ifdef ACTIVATE_DEBUG
|
|
hb_ToOutDebug( "AR_GOTO(): nWA = %i, nRecord = %i\n\r", nWA, nRecord )
|
|
#endif
|
|
|
|
//if( SELF_GOCOLD( ( AREAP ) pArea ) == HB_FAILURE )
|
|
// return HB_FAILURE;
|
|
//
|
|
//if( pArea->lpdbPendingRel )
|
|
//{
|
|
// if( pArea->lpdbPendingRel->isScoped )
|
|
// SELF_FORCEREL( ( AREAP ) pArea );
|
|
// else /* Reset parent rel struct */
|
|
// pArea->lpdbPendingRel = NULL;
|
|
//}
|
|
///* Update record count */
|
|
//if( ulRecNo > pArea->ulRecCount && pArea->fShared )
|
|
// pArea->ulRecCount = hb_dbfCalcRecCount( pArea );
|
|
|
|
|
|
IF nRecord >= 1 .AND. nRecord <= nRecCount
|
|
|
|
aWAData[ WADATA_EOF ] := aWAData[ WADATA_BOF ] := .F.
|
|
aWAData[ WADATA_RECNO ] := nRecord
|
|
|
|
//pArea->fBof = pArea->fEof = pArea->fValidBuffer = FALSE;
|
|
//pArea->fPositioned = TRUE;
|
|
|
|
ELSEIF nRecCount == 0
|
|
|
|
aWAData[ WADATA_EOF ] := aWAData[ WADATA_BOF ] := .T.
|
|
aWAData[ WADATA_RECNO ] := 1
|
|
|
|
ELSEIF nRecord <= 0
|
|
|
|
aWAData[ WADATA_BOF ] := .T.
|
|
aWAData[ WADATA_EOF ] := .F.
|
|
aWAData[ WADATA_RECNO ] := 1
|
|
|
|
|
|
ELSEIF nRecord > nRecCount
|
|
|
|
aWAData[ WADATA_BOF ] := .F.
|
|
aWAData[ WADATA_EOF ] := .T.
|
|
aWAData[ WADATA_RECNO ] := nRecCount + 1
|
|
|
|
ENDIF
|
|
|
|
RETURN HB_SUCCESS
|
|
|
|
STATIC FUNCTION AR_GOTOID( nWA, nRecord )
|
|
#ifdef ACTIVATE_DEBUG
|
|
hb_ToOutDebug( "AR_GOTOID(): nWA = %i, nRecord = %i\n\r", nWA, nRecord )
|
|
#endif
|
|
RETURN AR_GOTO( nWA, nRecord )
|
|
|
|
STATIC FUNCTION AR_GOTOP( nWA )
|
|
LOCAL aWAData := USRRDD_AREADATA( nWA )
|
|
LOCAL aDBFData := aWAData[ WADATA_DATABASE ]
|
|
LOCAL aRecords := aDBFData[ DATABASE_RECORDS ]
|
|
LOCAL aRecInfo := aDBFData[ DATABASE_RECINFO ]
|
|
LOCAL nRecCount := Len( aRecords )
|
|
|
|
#ifdef ACTIVATE_DEBUG
|
|
hb_ToOutDebug( "AR_GOTOP(): nWA = %i\n\r", nWA )
|
|
#endif
|
|
|
|
IF nRecCount == 0
|
|
|
|
aWAData[ WADATA_EOF ] := aWAData[ WADATA_BOF ] := .T.
|
|
aWAData[ WADATA_RECNO ] := 1
|
|
|
|
ELSE
|
|
|
|
aWAData[ WADATA_BOF ] := .F.
|
|
aWAData[ WADATA_EOF ] := .F.
|
|
aWAData[ WADATA_RECNO ] := 1
|
|
|
|
IF Set( _SET_DELETED ) .AND. aRecInfo[ aWAData[ WADATA_RECNO ] ][ RECDATA_DELETED ]
|
|
RETURN AR_SKIPFILTER( nWA, 1 )
|
|
ENDIF
|
|
ENDIF
|
|
|
|
RETURN HB_SUCCESS
|
|
|
|
STATIC FUNCTION AR_GOBOTTOM( nWA )
|
|
LOCAL aWAData := USRRDD_AREADATA( nWA )
|
|
LOCAL aDBFData := aWAData[ WADATA_DATABASE ]
|
|
LOCAL aRecords := aDBFData[ DATABASE_RECORDS ]
|
|
LOCAL aRecInfo := aDBFData[ DATABASE_RECINFO ]
|
|
|
|
#ifdef ACTIVATE_DEBUG
|
|
hb_ToOutDebug( "AR_GOBOTTOM(): nWA = %i\n\r", nWA )
|
|
#endif
|
|
|
|
IF Len( aRecords ) == 0
|
|
|
|
aWAData[ WADATA_EOF ] := aWAData[ WADATA_BOF ] := .T.
|
|
aWAData[ WADATA_RECNO ] := 1
|
|
|
|
ELSE
|
|
|
|
aWAData[ WADATA_BOF ] := .F.
|
|
aWAData[ WADATA_EOF ] := .F.
|
|
aWAData[ WADATA_RECNO ] := Len( aRecords )
|
|
|
|
IF Set( _SET_DELETED ) .AND. aRecInfo[ aWAData[ WADATA_RECNO ] ][ RECDATA_DELETED ]
|
|
RETURN AR_SKIPFILTER( nWA, -1 )
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
RETURN HB_SUCCESS
|
|
|
|
STATIC FUNCTION AR_SKIPFILTER( nWA, nRecords )
|
|
LOCAL aWAData := USRRDD_AREADATA( nWA )
|
|
LOCAL aDBFData := aWAData[ WADATA_DATABASE ]
|
|
LOCAL aRecInfo := aDBFData[ DATABASE_RECINFO ]
|
|
LOCAL lBof, nToSkip
|
|
|
|
#ifdef ACTIVATE_DEBUG
|
|
hb_ToOutDebug( "AR_SKIPFILTER(): nWA = %i, nRecords = %i\n\r", nWA, nRecords )
|
|
#endif
|
|
|
|
nToSkip := IIF( nRecords > 0, 1, IIF( nRecords < 0, -1, 0 ) )
|
|
|
|
IF nToSkip != 0
|
|
DO WHILE !aWAData[ WADATA_BOF ] .AND. !aWAData[ WADATA_EOF ]
|
|
IF SET( _SET_DELETED ) .AND. aRecInfo[ aWAData[ WADATA_RECNO ] ][ RECDATA_DELETED ]
|
|
IF !( AR_SKIPRAW( nWA, nToSkip ) == HB_SUCCESS )
|
|
RETURN HB_FAILURE
|
|
ENDIF
|
|
IF nToSkip < 0 .AND. aWAData[ WADATA_BOF ]
|
|
lBof := TRUE
|
|
aWAData[ WADATA_BOF ] := FALSE
|
|
nToSkip := 1
|
|
ELSEIF nToSkip > 0 .AND. aWAData[ WADATA_EOF ]
|
|
EXIT
|
|
ENDIF
|
|
LOOP
|
|
ENDIF
|
|
|
|
// FILTERS
|
|
|
|
EXIT
|
|
ENDDO
|
|
|
|
IF lBof != NIL
|
|
aWAData[ WADATA_BOF ] := TRUE
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
RETURN HB_SUCCESS
|
|
|
|
STATIC FUNCTION AR_SKIPRAW( nWA, nRecords )
|
|
LOCAL aWAData := USRRDD_AREADATA( nWA )
|
|
LOCAL lBof, lEof
|
|
LOCAL nResult
|
|
|
|
#ifdef ACTIVATE_DEBUG
|
|
hb_ToOutDebug( "AR_SKIPRAW(): nWA = %i, nRecords = %i\n\r", nWA, nRecords )
|
|
#endif
|
|
|
|
//if( pArea->lpdbPendingRel )
|
|
// SELF_FORCEREL( ( AREAP ) pArea );
|
|
|
|
//IF nRecCount > 0
|
|
|
|
IF nRecords == 0
|
|
|
|
lBof := aWAData[ WADATA_BOF ]
|
|
lEof := aWAData[ WADATA_EOF ]
|
|
|
|
nResult := AR_GOTO( nWA, aWAData[ WADATA_RECNO ] )
|
|
|
|
aWAData[ WADATA_BOF ] := lBof
|
|
aWAData[ WADATA_EOF ] := lEof
|
|
|
|
ELSEIF nRecords < 0 .AND. -nRecords >= aWAData[ WADATA_RECNO ]
|
|
|
|
nResult := AR_GOTO( nWA, 1 )
|
|
aWAData[ WADATA_BOF ] := .T.
|
|
// Hack for dbf1.c hack GOTOP
|
|
aWAData[ WADATA_FORCEBOF ] := .T.
|
|
|
|
ELSE
|
|
|
|
nResult := AR_GOTO( nWA, aWAData[ WADATA_RECNO ] + nRecords )
|
|
|
|
ENDIF
|
|
|
|
RETURN nResult // HB_SUCCESS
|
|
|
|
STATIC FUNCTION AR_BOF( nWA, lBof )
|
|
LOCAL aWAData := USRRDD_AREADATA( nWA )
|
|
|
|
#ifdef ACTIVATE_DEBUG
|
|
hb_ToOutDebug( "AR_BOF(): nWA = %i, lBof = %s\n\r", nWA, lBof )
|
|
#endif
|
|
|
|
// This is a hack to protect from dbf1.c skipraw hack
|
|
IF aWAData[ WADATA_FORCEBOF ] .AND. lBof
|
|
aWAData[ WADATA_BOF ] := lBof
|
|
aWAData[ WADATA_FORCEBOF ] := FALSE
|
|
ELSE
|
|
lBof := aWAData[ WADATA_BOF ]
|
|
ENDIF
|
|
|
|
RETURN HB_SUCCESS
|
|
|
|
STATIC FUNCTION AR_EOF( nWA, lEof )
|
|
LOCAL aWAData := USRRDD_AREADATA( nWA )
|
|
|
|
#ifdef ACTIVATE_DEBUG
|
|
hb_ToOutDebug( "AR_EOF(): nWA = %i, lEof = %s\n\r", nWA, lEof )
|
|
#endif
|
|
|
|
lEof := aWAData[ WADATA_EOF ]
|
|
|
|
RETURN HB_SUCCESS
|
|
|
|
STATIC FUNCTION AR_DELETE( nWA )
|
|
LOCAL aWAData := USRRDD_AREADATA( nWA )
|
|
LOCAL aDBFData := aWAData[ WADATA_DATABASE ]
|
|
LOCAL aRecInfo := aDBFData[ DATABASE_RECINFO ]
|
|
LOCAL aOpenInfo := aWAData[ WADATA_OPENINFO ]
|
|
LOCAL oError
|
|
|
|
#ifdef ACTIVATE_DEBUG
|
|
hb_ToOutDebug( "AR_DELETE(): nWA = %i\n\r", nWA )
|
|
#endif
|
|
|
|
IF aOpenInfo[ UR_OI_READONLY ]
|
|
|
|
oError := ErrorNew()
|
|
oError:GenCode := EG_READONLY
|
|
oError:SubCode := 1025 // EDBF_READONLY
|
|
oError:Description := HB_LANGERRMSG( EG_READONLY )
|
|
oError:FileName := aOpenInfo[ UR_OI_NAME ]
|
|
UR_SUPER_ERROR( nWA, oError )
|
|
RETURN HB_FAILURE
|
|
|
|
ENDIF
|
|
|
|
IF aOpenInfo[ UR_OI_SHARED ] .AND. !( aScan( aWAData[ WADATA_LOCKS ], aWAData[ WADATA_RECNO ] ) > 0 )
|
|
|
|
oError := ErrorNew()
|
|
oError:GenCode := EG_UNLOCKED
|
|
oError:SubCode := 1022 // EDBF_UNLOCKED
|
|
oError:Description := HB_LANGERRMSG( EG_UNLOCKED )
|
|
oError:FileName := aOpenInfo[ UR_OI_NAME ]
|
|
UR_SUPER_ERROR( nWA, oError )
|
|
RETURN HB_FAILURE
|
|
|
|
ENDIF
|
|
|
|
IF Len( aRecInfo ) > 0 .AND. aWAData[ WADATA_RECNO ] <= Len( aRecInfo )
|
|
aRecInfo[ aWAData[ WADATA_RECNO ] ][ RECDATA_DELETED ] := .T.
|
|
ENDIF
|
|
|
|
RETURN HB_SUCCESS
|
|
|
|
STATIC FUNCTION AR_DELETED( nWA, lDeleted )
|
|
LOCAL aWAData := USRRDD_AREADATA( nWA )
|
|
LOCAL aDBFData := aWAData[ WADATA_DATABASE ]
|
|
LOCAL aRecInfo := aDBFData[ DATABASE_RECINFO ]
|
|
|
|
#ifdef ACTIVATE_DEBUG
|
|
hb_ToOutDebug( "AR_DELETED(): nWA = %i, lDeleted = %s\n\r", nWA, lDeleted )
|
|
#endif
|
|
|
|
//lDeleted := .F.
|
|
IF Len( aRecInfo ) > 0 .AND. aWAData[ WADATA_RECNO ] <= Len( aRecInfo )
|
|
lDeleted := aRecInfo[ aWAData[ WADATA_RECNO ] ][ RECDATA_DELETED ]
|
|
ELSE
|
|
lDeleted := .F.
|
|
ENDIF
|
|
|
|
RETURN HB_SUCCESS
|
|
|
|
STATIC FUNCTION AR_APPEND( nWA, nRecords )
|
|
LOCAL aWAData := USRRDD_AREADATA( nWA )
|
|
LOCAL aDBFData := aWAData[ WADATA_DATABASE ]
|
|
LOCAL aRecords := aDBFData[ DATABASE_RECORDS ]
|
|
LOCAL aRecInfo := aDBFData[ DATABASE_RECINFO ]
|
|
LOCAL aStruct := aDBFData[ DATABASE_STRUCT ]
|
|
LOCAL aOpenInfo := aWAData[ WADATA_OPENINFO ]
|
|
LOCAL oError, aRecord
|
|
|
|
#ifdef ACTIVATE_DEBUG
|
|
hb_ToOutDebug( "AR_APPEND(): nWA = %i, nRecords = %s\n\r", nWA, nRecords )
|
|
#endif
|
|
|
|
HB_SYMBOL_UNUSED( nRecords )
|
|
|
|
IF aOpenInfo[ UR_OI_READONLY ]
|
|
|
|
oError := ErrorNew()
|
|
oError:GenCode := EG_READONLY
|
|
oError:SubCode := 1025 // EDBF_READONLY
|
|
oError:Description := HB_LANGERRMSG( EG_READONLY )
|
|
oError:FileName := aOpenInfo[ UR_OI_NAME ]
|
|
//oError:OsCode := fError()
|
|
oError:CanDefault := .T.
|
|
oError:CanRetry := .T.
|
|
UR_SUPER_ERROR( nWA, oError )
|
|
RETURN HB_FAILURE
|
|
|
|
ENDIF
|
|
|
|
aRecord := BlankRecord( aStruct )
|
|
aAdd( aRecords, aRecord )
|
|
aAdd( aRecInfo, AR_RECDATAINIT() )
|
|
AR_GOBOTTOM( nWA )
|
|
|
|
/* TODO: SHARED ACCESS */
|
|
|
|
RETURN HB_SUCCESS
|
|
|
|
STATIC FUNCTION AR_RECID( nWA, nRecNo )
|
|
LOCAL aWAData := USRRDD_AREADATA( nWA )
|
|
LOCAL aDBFData := aWAData[ WADATA_DATABASE ]
|
|
LOCAL aRecords := aDBFData[ DATABASE_RECORDS ]
|
|
LOCAL nRecCount := Len( aRecords )
|
|
|
|
#ifdef ACTIVATE_DEBUG
|
|
hb_ToOutDebug( "AR_RECID(): nWA = %i, nRecNo = %s\n\r", nWA, nRecNo )
|
|
#endif
|
|
|
|
IF aWAData[ WADATA_EOF ]
|
|
nRecNo := nRecCount + 1
|
|
ELSE
|
|
nRecNo := aWAData[ WADATA_RECNO ]
|
|
ENDIF
|
|
|
|
RETURN HB_SUCCESS
|
|
|
|
STATIC FUNCTION AR_RECCOUNT( nWA, nRecords )
|
|
LOCAL aWAData := USRRDD_AREADATA( nWA )
|
|
LOCAL aDBFData := aWAData[ WADATA_DATABASE ]
|
|
LOCAL aRecords := aDBFData[ DATABASE_RECORDS ]
|
|
|
|
#ifdef ACTIVATE_DEBUG
|
|
hb_ToOutDebug( "AR_RECCOUNT(): nWA = %i, nRecords = %s\n\r", nWA, nRecords )
|
|
#endif
|
|
|
|
nRecords := Len( aRecords )
|
|
|
|
RETURN HB_SUCCESS
|
|
|
|
STATIC FUNCTION AR_ZAP( nWA )
|
|
LOCAL aWAData := USRRDD_AREADATA( nWA )
|
|
LOCAL aDBFData := aWAData[ WADATA_DATABASE ]
|
|
LOCAL aOpenInfo := aWAData[ WADATA_OPENINFO ]
|
|
LOCAL oError
|
|
|
|
#ifdef ACTIVATE_DEBUG
|
|
hb_ToOutDebug( "AR_ZAP(): nWA = %i\n\r", nWA )
|
|
#endif
|
|
|
|
IF aOpenInfo[ UR_OI_READONLY ]
|
|
|
|
oError := ErrorNew()
|
|
oError:GenCode := EG_READONLY
|
|
oError:SubCode := 1025 // EDBF_READONLY
|
|
oError:Description := HB_LANGERRMSG( EG_READONLY )
|
|
oError:FileName := aOpenInfo[ UR_OI_NAME ]
|
|
UR_SUPER_ERROR( nWA, oError )
|
|
RETURN HB_FAILURE
|
|
|
|
ENDIF
|
|
|
|
IF aOpenInfo[ UR_OI_SHARED ]
|
|
|
|
oError := ErrorNew()
|
|
oError:GenCode := EG_SHARED
|
|
oError:SubCode := 1023 // EDBF_SHARED
|
|
oError:Description := HB_LANGERRMSG( EG_SHARED )
|
|
oError:FileName := aOpenInfo[ UR_OI_NAME ]
|
|
UR_SUPER_ERROR( nWA, oError )
|
|
RETURN HB_FAILURE
|
|
|
|
ENDIF
|
|
|
|
// empty records
|
|
aDBFData[ DATABASE_RECORDS ] := {}
|
|
aDBFData[ DATABASE_RECINFO ] := {}
|
|
|
|
// move to 0 recno
|
|
AR_GOTO( nWA, 0 )
|
|
|
|
RETURN HB_SUCCESS
|
|
|
|
STATIC FUNCTION AR_ORDINFO( nWA, xMsg, xValue )
|
|
HB_SYMBOL_UNUSED( nWA )
|
|
HB_SYMBOL_UNUSED( xMsg )
|
|
HB_SYMBOL_UNUSED( xValue )
|
|
|
|
#ifdef ACTIVATE_DEBUG
|
|
hb_ToOutDebug( "AR_ORDINFO(): nWA = %i, xMsg = %s, xValue = %s\n\r", nWA, xMsg, xValue )
|
|
#endif
|
|
|
|
/*
|
|
LOCAL hRDDData := USRRDD_RDDDATA( USRRDD_ID( nWA ) )
|
|
LOCAL aOpenInfo := hRDDData[ nWA ]:OPENINFO
|
|
LOCAL aWAData := USRRDD_AREADATA( nWA )
|
|
LOCAL oError
|
|
|
|
Tracelog( "nWA, xMsg, xValue", nWA, xMsg, xValue )
|
|
|
|
IF aOpenInfo[ UR_OI_READONLY ]
|
|
|
|
oError := ErrorNew()
|
|
oError:GenCode := EG_READONLY
|
|
oError:SubCode := 1025 // EDBF_READONLY
|
|
oError:Description := HB_LANGERRMSG( EG_READONLY )
|
|
oError:FileName := aOpenInfo[ UR_OI_NAME ]
|
|
UR_SUPER_ERROR( nWA, oError )
|
|
RETURN HB_FAILURE
|
|
|
|
ENDIF
|
|
|
|
IF aOpenInfo[ UR_OI_SHARED ]
|
|
|
|
oError := ErrorNew()
|
|
oError:GenCode := EG_SHARED
|
|
oError:SubCode := 1023 // EDBF_SHARED
|
|
oError:Description := HB_LANGERRMSG( EG_SHARED )
|
|
oError:FileName := aOpenInfo[ UR_OI_NAME ]
|
|
UR_SUPER_ERROR( nWA, oError )
|
|
RETURN HB_FAILURE
|
|
|
|
ENDIF
|
|
|
|
aWAData[ ARRAY_RECORDS ] := {}
|
|
aWAData[ ARRAY_RECINFO ] := {}
|
|
AR_GOTO( nWA, 0 )
|
|
*/
|
|
|
|
RETURN HB_SUCCESS
|
|
|
|
/*
|
|
* This function have to exist in all RDD and then name have to be in
|
|
* format: <RDDNAME>_GETFUNCTABLE
|
|
*/
|
|
FUNCTION ARRAYRDD_GETFUNCTABLE( pFuncCount, pFuncTable, pSuperTable, nRddID )
|
|
LOCAL cSuperRDD := NIL /* NO SUPER RDD */
|
|
LOCAL aMyFunc[ UR_METHODCOUNT ]
|
|
|
|
aMyFunc[ UR_INIT ] := ( @AR_INIT() )
|
|
aMyFunc[ UR_NEW ] := ( @AR_NEW() )
|
|
aMyFunc[ UR_CREATE ] := ( @AR_CREATE() )
|
|
aMyFunc[ UR_CREATEFIELDS ] := ( @AR_CREATEFIELDS() )
|
|
aMyFunc[ UR_OPEN ] := ( @AR_OPEN() )
|
|
aMyFunc[ UR_CLOSE ] := ( @AR_CLOSE() )
|
|
aMyFunc[ UR_BOF ] := ( @AR_BOF() )
|
|
aMyFunc[ UR_EOF ] := ( @AR_EOF() )
|
|
aMyFunc[ UR_APPEND ] := ( @AR_APPEND() )
|
|
aMyFunc[ UR_DELETE ] := ( @AR_DELETE() )
|
|
aMyFunc[ UR_DELETED ] := ( @AR_DELETED() )
|
|
aMyFunc[ UR_SKIPFILTER ] := ( @AR_SKIPFILTER() )
|
|
aMyFunc[ UR_SKIPRAW ] := ( @AR_SKIPRAW() )
|
|
aMyFunc[ UR_GOTO ] := ( @AR_GOTO() )
|
|
aMyFunc[ UR_GOTOID ] := ( @AR_GOTOID() )
|
|
aMyFunc[ UR_GOTOP ] := ( @AR_GOTOP() )
|
|
aMyFunc[ UR_GOBOTTOM ] := ( @AR_GOBOTTOM() )
|
|
aMyFunc[ UR_RECID ] := ( @AR_RECID() )
|
|
aMyFunc[ UR_RECCOUNT ] := ( @AR_RECCOUNT() )
|
|
aMyFunc[ UR_GETVALUE ] := ( @AR_GETVALUE() )
|
|
aMyFunc[ UR_PUTVALUE ] := ( @AR_PUTVALUE() )
|
|
aMyFunc[ UR_ZAP ] := ( @AR_ZAP() )
|
|
aMyFunc[ UR_ORDINFO ] := ( @AR_ORDINFO() )
|
|
|
|
RETURN USRRDD_GETFUNCTABLE( pFuncCount, pFuncTable, pSuperTable, nRddID, ;
|
|
cSuperRDD, aMyFunc )
|
|
|
|
INIT PROCEDURE ARRAYRDD_INIT()
|
|
rddRegister( "ARRAYRDD", RDT_FULL )
|
|
RETURN
|
|
|
|
/* -------------------------------------------------- */
|
|
/* UTILITY FUNCTIONS */
|
|
/* -------------------------------------------------- */
|
|
|
|
/*
|
|
hb_EraseArrayRdd() function is equivalent of FErase() function, but works here in memory
|
|
*/
|
|
|
|
FUNCTION hb_EraseArrayRdd( cFullName )
|
|
LOCAL nReturn := HB_FAILURE
|
|
LOCAL aDBFData, oError
|
|
LOCAL nRDD, aRDDList
|
|
LOCAL hRDDData
|
|
|
|
aRDDList := RDDLIST( RDT_FULL )
|
|
nRDD := AScan( aRDDList, "ARRAYRDD" )
|
|
|
|
IF nRDD > 0
|
|
|
|
nRDD -- // HACK: Possibly an error of nRDD value in AR_INIT() ? - TODO
|
|
|
|
hRDDData := USRRDD_RDDDATA( nRDD )
|
|
|
|
IF hRDDData != NIL
|
|
|
|
IF ISCHARACTER( cFullName )
|
|
cFullName := Upper( cFullName )
|
|
// First search if memory dbf exists
|
|
IF HB_HHasKey( hRDDData, cFullName )
|
|
|
|
// Get ARRAY data
|
|
aDBFData := hRDDData[ cFullName ]
|
|
|
|
// Check if there are current opened workarea
|
|
IF aDBFData[ DATABASE_OPENNUMBER ] > 0
|
|
|
|
oError := ErrorNew()
|
|
|
|
oError:GenCode := EG_UNSUPPORTED
|
|
oError:SubCode := 1000 // EDBF_UNSUPPORTED
|
|
oError:Description := HB_LANGERRMSG( EG_UNSUPPORTED ) + " (" + ;
|
|
"database in use)"
|
|
oError:FileName := cFullName
|
|
oError:CanDefault := .T.
|
|
//UR_SUPER_ERROR( 0, oError )
|
|
Throw( oError )
|
|
|
|
nReturn := HB_FAILURE
|
|
|
|
ELSE
|
|
|
|
// Delete database from slot
|
|
hb_HDel( hRDDData, cFullName )
|
|
nReturn := HB_SUCCESS
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ELSE
|
|
|
|
oError := ErrorNew()
|
|
|
|
oError:GenCode := EG_UNSUPPORTED
|
|
oError:SubCode := 1000 // EDBF_UNSUPPORTED
|
|
oError:Description := HB_LANGERRMSG( EG_UNSUPPORTED ) + " (" + ;
|
|
"ARRAYRDD not inizialized)"
|
|
oError:FileName := cFullName
|
|
oError:CanDefault := .T.
|
|
//UR_SUPER_ERROR( 0, oError )
|
|
Throw( oError )
|
|
|
|
nReturn := HB_FAILURE
|
|
|
|
ENDIF
|
|
ELSE
|
|
|
|
oError := ErrorNew()
|
|
|
|
oError:GenCode := EG_UNSUPPORTED
|
|
oError:SubCode := 1000 // EDBF_UNSUPPORTED
|
|
oError:Description := HB_LANGERRMSG( EG_UNSUPPORTED ) + " (" + ;
|
|
"ARRAYRDD not in use)"
|
|
oError:FileName := cFullName
|
|
oError:CanDefault := .T.
|
|
//UR_SUPER_ERROR( 0, oError )
|
|
Throw( oError )
|
|
|
|
nReturn := HB_FAILURE
|
|
|
|
ENDIF
|
|
|
|
RETURN nReturn
|
|
|
|
/*
|
|
hb_FileArrayRdd( cFullName ) --> lExist
|
|
This function is equivalent of File() function, but works here in memory
|
|
*/
|
|
|
|
FUNCTION hb_FileArrayRdd( cFullName )
|
|
LOCAL nReturn := HB_FAILURE
|
|
LOCAL oError
|
|
LOCAL nRDD, aRDDList
|
|
LOCAL hRDDData
|
|
|
|
aRDDList := RDDLIST( RDT_FULL )
|
|
nRDD := AScan( aRDDList, "ARRAYRDD" )
|
|
|
|
IF nRDD > 0
|
|
|
|
nRDD -- // HACK: Possibly an error of nRDD value in AR_INIT() ? - TODO
|
|
|
|
hRDDData := USRRDD_RDDDATA( nRDD )
|
|
|
|
IF hRDDData != NIL
|
|
|
|
IF ISCHARACTER( cFullName )
|
|
cFullName := Upper( cFullName )
|
|
// First search if memory dbf exists
|
|
IF HB_HHasKey( hRDDData, cFullName )
|
|
|
|
nReturn := HB_SUCCESS
|
|
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ELSE
|
|
|
|
oError := ErrorNew()
|
|
|
|
oError:GenCode := EG_UNSUPPORTED
|
|
oError:SubCode := 1000 // EDBF_UNSUPPORTED
|
|
oError:Description := HB_LANGERRMSG( EG_UNSUPPORTED ) + " (" + ;
|
|
"ARRAYRDD not inizialized)"
|
|
oError:FileName := cFullName
|
|
oError:CanDefault := .T.
|
|
//UR_SUPER_ERROR( 0, oError )
|
|
Throw( oError )
|
|
|
|
nReturn := HB_FAILURE
|
|
|
|
ENDIF
|
|
|
|
ELSE
|
|
|
|
oError := ErrorNew()
|
|
|
|
oError:GenCode := EG_UNSUPPORTED
|
|
oError:SubCode := 1000 // EDBF_UNSUPPORTED
|
|
oError:Description := HB_LANGERRMSG( EG_UNSUPPORTED ) + " (" + ;
|
|
"ARRAYRDD not in use)"
|
|
oError:FileName := cFullName
|
|
oError:CanDefault := .T.
|
|
//UR_SUPER_ERROR( 0, oError )
|
|
Throw( oError )
|
|
|
|
nReturn := HB_FAILURE
|
|
|
|
ENDIF
|
|
RETURN ( nReturn == HB_SUCCESS )
|
|
|
|
STATIC FUNCTION BlankRecord( aStruct )
|
|
LOCAL nLenStruct := Len( aStruct )
|
|
LOCAL aRecord := Array( nLenStruct )
|
|
LOCAL nField
|
|
|
|
FOR nField := 1 TO nLenStruct
|
|
aRecord[ nField ] := EmptyValue( aStruct[ nField ][ DBS_TYPE ], aStruct[ nField ][ DBS_LEN ], aStruct[ nField ][ DBS_DEC ] )
|
|
NEXT
|
|
|
|
RETURN aRecord
|
|
|
|
STATIC FUNCTION PutValue( xValue, cType, nLen, nDec )
|
|
LOCAL xVal
|
|
|
|
DO CASE
|
|
CASE cType == "C"
|
|
xVal := PadR( xValue, nLen )
|
|
CASE cType == "M"
|
|
xVal := xValue // No limit for a memo field
|
|
CASE cType == "N"
|
|
xVal := Val( Str( xValue, nLen, nDec ) )
|
|
OTHERWISE
|
|
xVal := xValue
|
|
ENDCASE
|
|
|
|
RETURN xVal
|
|
|
|
|
|
STATIC FUNCTION EmptyValue( cType, nLen, nDec )
|
|
LOCAL xVal
|
|
|
|
DEFAULT nLen TO 0
|
|
DEFAULT nDec TO 0
|
|
|
|
DO CASE
|
|
CASE cType == "C" .OR. cType == "M"
|
|
xVal := Space( nLen )
|
|
CASE cType == "D"
|
|
xVal := CToD( "" )
|
|
CASE cType == "L"
|
|
xVal := FALSE
|
|
CASE cType == "N"
|
|
xVal := Val( Str( 0, nLen, nDec ) )
|
|
ENDCASE
|
|
RETURN xVal
|
|
|
|
/******************
|
|
* Function .......: hb_Decode( <var>, [ <case1,ret1 [,...,caseN,retN] ] [, <def> ]> ) ---> <xRet>
|
|
* Author .........: Francesco Saverio Giudice
|
|
* Date of creation: 25/01/1991
|
|
* Last revision ..: 24/01/2006 1.13 - rewritten for xHarbour and renamed in hb_Decode()
|
|
*
|
|
* Decode a value from a list.
|
|
*******************/
|
|
STATIC FUNCTION HB_Decode(...)
|
|
|
|
LOCAL aParams, nParams, xDefault
|
|
LOCAL xVal, cKey, xRet
|
|
LOCAL aValues, aResults, n, i, nPos, nLen
|
|
|
|
aParams := hb_aParams()
|
|
nParams := PCount()
|
|
xDefault := NIL
|
|
|
|
DO CASE
|
|
|
|
CASE nParams > 1 // More parameters, real case
|
|
|
|
xVal := aParams[ 1 ]
|
|
|
|
aDel( aParams, 1, TRUE ) // Resize params
|
|
nParams := Len( aParams )
|
|
|
|
// if I have a odd number of members, last is default
|
|
IF ( nParams % 2 <> 0 )
|
|
xDefault := aTail( aParams )
|
|
// Resize again deleting last
|
|
aDel( aParams, nParams, TRUE )
|
|
nParams := Len( aParams )
|
|
ENDIF
|
|
|
|
// Ok because I have no other value than default, I will check if it is a complex value
|
|
// like an array or an hash, so I can get it to decode values
|
|
IF xDefault <> NIL .AND. ;
|
|
( ISARRAY( xDefault ) .OR. ;
|
|
ValType( xDefault ) == "H" )
|
|
|
|
// If it is an array I will restart this function creating a linear call
|
|
IF ISARRAY( xDefault ) .AND. Len( xDefault ) > 0
|
|
|
|
// I can have a linear array like { 1, "A", 2, "B", 3, "C" }
|
|
// or an array of array couples like { { 1, "A" }, { 2, "B" }, { 3, "C" } }
|
|
// first element tell me what type is
|
|
|
|
// couples of values
|
|
IF ISARRAY( xDefault[ 1 ] )
|
|
|
|
//// If i have an array as default, this contains couples of key / value
|
|
//// so I have to convert in a linear array
|
|
|
|
nLen := Len( xDefault )
|
|
|
|
// Check if array has a default value, this will be last value and has a value
|
|
// different from an array
|
|
IF ! ISARRAY( ValType( xDefault[ nLen ] ) )
|
|
|
|
aParams := Array( ( nLen - 1 ) * 2 )
|
|
|
|
n := 1
|
|
FOR i := 1 TO nLen - 1
|
|
aParams[ n++ ] := xDefault[ i ][ 1 ]
|
|
aParams[ n++ ] := xDefault[ i ][ 2 ]
|
|
NEXT
|
|
|
|
aAdd( aParams, xDefault[ nLen ] )
|
|
|
|
ELSE
|
|
|
|
// I haven't a default
|
|
|
|
aParams := Array( Len( xDefault ) * 2 )
|
|
|
|
n := 1
|
|
FOR i := 1 TO Len( xDefault )
|
|
aParams[ n++ ] := xDefault[ i ][ 1 ]
|
|
aParams[ n++ ] := xDefault[ i ][ 2 ]
|
|
NEXT
|
|
|
|
ENDIF
|
|
ELSE
|
|
// I have a linear array
|
|
|
|
aParams := xDefault
|
|
ENDIF
|
|
|
|
|
|
// If it is an hash, translate it in an array
|
|
ELSEIF ValType( xDefault ) == "H"
|
|
|
|
aParams := Array( Len( xDefault ) * 2 )
|
|
|
|
i := 1
|
|
FOR EACH cKey IN xDefault:Keys
|
|
aParams[ i++ ] := cKey
|
|
aParams[ i++ ] := xDefault[ cKey ]
|
|
NEXT
|
|
|
|
ENDIF
|
|
|
|
// Then add Decoding value at beginning
|
|
aIns( aParams, 1, xVal, TRUE )
|
|
|
|
// And run decode() again
|
|
xRet := hb_ExecFromArray( @hb_Decode(), aParams )
|
|
|
|
ELSE
|
|
|
|
// Ok let's go ahead with real function
|
|
|
|
// Combine in 2 lists having elements as { value } and { decode }
|
|
aValues := Array( nParams / 2 )
|
|
aResults := Array( nParams / 2 )
|
|
|
|
i := 1
|
|
FOR n := 1 TO nParams - 1 STEP 2
|
|
aValues[ i ] := aParams[ n ]
|
|
aResults[ i ] := aParams[ n + 1 ]
|
|
i++
|
|
NEXT
|
|
|
|
// Check if value exists (valtype of values MUST be same of xVal,
|
|
// otherwise I will get a runtime error)
|
|
// TODO: Have I to check also between different valtypes, jumping different ?
|
|
nPos := AScan( aValues, {|e| e == xVal } )
|
|
|
|
IF nPos == 0 // Not Found, returning default
|
|
|
|
xRet := xDefault // it could be also nil because not present
|
|
|
|
ELSE
|
|
|
|
xRet := aResults[ nPos ]
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
CASE nParams == 0 // No parameters
|
|
xRet := NIL
|
|
|
|
CASE nParams == 1 // Only value to decode as parameter, return an empty value of itself
|
|
xRet := DecEmptyValue( aParams[ 1 ] )
|
|
|
|
ENDCASE
|
|
|
|
RETURN xRet
|
|
|
|
STATIC FUNCTION DecEmptyValue( xVal )
|
|
LOCAL xRet
|
|
LOCAL cType := ValType( xVal )
|
|
|
|
SWITCH cType
|
|
CASE 'C' // Char
|
|
CASE 'M' // Memo
|
|
xRet := ""
|
|
EXIT
|
|
CASE 'D' // Date
|
|
xRet := CTOD('')
|
|
EXIT
|
|
CASE 'L' // Logical
|
|
xRet := .F.
|
|
EXIT
|
|
CASE 'N' // Number
|
|
xRet := 0
|
|
EXIT
|
|
CASE 'B' // code block
|
|
xRet := {|| NIL }
|
|
EXIT
|
|
CASE 'A' // array
|
|
xRet := {}
|
|
EXIT
|
|
CASE 'H' // hash
|
|
xRet := {=>}
|
|
EXIT
|
|
CASE 'U' // undefined
|
|
xRet := NIL
|
|
EXIT
|
|
CASE 'O' // Object
|
|
xRet := NIL // Or better another value ?
|
|
EXIT
|
|
OTHERWISE
|
|
// Create a runtime error for new datatypes
|
|
xRet := ""
|
|
IF xRet == 0 // BANG!
|
|
ENDIF
|
|
ENDSWITCH
|
|
|
|
RETURN xRet
|