Files
harbour-core/harbour/source/rdd/usrrdd/rdds/arrayrdd.prg
Viktor Szakats 9738d0bef5 ; Merging changes to trunk from branches/harbour-1.0 r9377.
2008-09-14 11:14 UTC+0200 Viktor Szakats (harbour.01 syenar hu)
  * contrib/gtalleg/ssf.h
    ! Fixed to compile with Cygwin.

  * contrib/hbwhat/whtsock.c
    ! Fixed for PellesC 4.5 where the inclusion order of 
      Windows headers needs to be the opposite of what 5.0 needs.

  * contrib/hbwhat/whtilst.c
    ! Fixed to compile with Cygwin.

  * contrib/hbwhat/whtinet.c
    ! Added missing Windows macro for Cygwin.
    ! Fixed three warnings with Cygwin.

  * contrib/hbwhat/whtseria.c
  * contrib/hbwhat/whtreg.c
  * contrib/hbwhat/whtini.c
    ! Removed #include "tchar.h", because it's unnecessary, 
      and breaks Cygwin.

  * contrib/hbwhat/whtsys.c
    ! Removed #include "htmlhelp.h", because it's unnecessary, 
      and breaks Cygwin.

2008-09-13 19:30 UTC+0200 Viktor Szakats (harbour.01 syenar hu)
  * contrib/gtalleg/ssf.h
    ! Turned off ASM for MSVC AMD64 mode.

  * contrib/gtalleg/Makefile
    ! Disabled for OpenWatcom. (maybe compilation could be 
      fixed somehow, if someone is interested pls look into it.)

  * doc/whatsnew.txt
  * contrib/hbfimage/fi_winfu.c
  * contrib/hbfimage/fi_wrp.c
    ! Fixed for OpenWatcom.

  * contrib/gtwvg/wvgutils.c
  * contrib/gtwvg/wvgcore.c
    ! Silenced some MinGW/PelleC cast warnings.

  * contrib/hbw32/win_prt.c
    ! Fixed GCC (MinGW/Cygwin) warnings. The solution I choose is 
      pretty ugly, if someone knows the right one, please help.
      Warning was:
      ../../win_prt.c:70: warning: missing initializer
      ../../win_prt.c:70: warning: (near initialization for `s_PortData[0].OldDCB')
    ! Fixed few remaining warnings / minor bugs.

  * contrib/hbwhat/whtlv.c
  * contrib/hbwhat/whtcomm.c
  * contrib/hbwhat/whttab.c
  * contrib/hbwhat/whttree.c
    ! Silenced MinGW 4.12 warnings.

  * contrib/hbwhat/whtdate.c
    ! Removed #include "tchar.h", which seems unnecessary and 
      fixed Cygwin compilation.

  * contrib/hbwhat/whtsock.c
    ! Changed #include order of Windows headers to satisfy PellesC 5.

  ; TOFIX1: hbct / SETFDATI() has a possible bug here (shown in PelleC 64 bit):
    ../../files.c(264): warning #2006: [ISO] Conversion from 'void *' to 'int' is compiler dependent.
    ../../files.c(264): warning #2052: Conversion from 'void *' to 'int' is undefined.
    Problem is with HFILE / HANDLE conversion.

  ; TOFIX2: Here are some remaining 64-bit problems:
    ../../hb_btree.c(643): warning #2006: [ISO] Conversion from 'void *' to 'unsigned long int' is compiler dependent.
    ../../hb_btree.c(643): warning #2052: Conversion from 'void *' to 'unsigned long int' is undefined.
    ../../hb_btree.c(739): warning #2006: [ISO] Conversion from 'ioBuffer_T *' to 'unsigned long int' is compiler dependent.
    ../../hb_btree.c(739): warning #2052: Conversion from 'ioBuffer_T *' to 'unsigned long int' is undefined.
    ../../win_dll.c(511): warning #2006: [ISO] Conversion from 'void *' to 'unsigned long int' is compiler dependent.
    ../../win_dll.c(511): warning #2052: Conversion from 'void *' to 'unsigned long int' is undefined.
    ../../win_ole.c(761): warning #2006: [ISO] Conversion from 'LPDISPATCH' to 'long int' is compiler dependent.
    ../../win_ole.c(761): warning #2052: Conversion from 'LPDISPATCH' to 'long int' is undefined.
    ../../win_ole.c(1091): warning #2006: [ISO] Conversion from 'LPDISPATCH' to 'long int' is compiler dependent.
    ../../win_ole.c(1091): warning #2052: Conversion from 'LPDISPATCH' to 'long int' is undefined.
    ../../win_ole.c(1425): warning #2006: [ISO] Conversion from 'void *' to 'long int' is compiler dependent.
    ../../win_ole.c(1425): warning #2052: Conversion from 'void *' to 'long int' is undefined.
    ../../win_ole.c(1478): warning #2006: [ISO] Conversion from 'void *' to 'long int' is compiler dependent.
    ../../win_ole.c(1478): warning #2052: Conversion from 'void *' to 'long int' is undefined.
    ../../win_regc.c(94): warning #2006: [ISO] Conversion from 'HKEY' to 'unsigned long int' is compiler dependent.
    ../../win_regc.c(94): warning #2052: Conversion from 'HKEY' to 'unsigned long int' is undefined.
    ../../win_regc.c(116): warning #2006: [ISO] Conversion from 'HKEY' to 'unsigned long int' is compiler dependent.
    ../../win_regc.c(116): warning #2052: Conversion from 'HKEY' to 'unsigned long int' is undefined.

2008-09-13 13:34 UTC+0200 Viktor Szakats (harbour.01 syenar hu)
  * doc/dirstruc.txt
    * Updated.

  - contrib/hbgf/hbgfw32
  + contrib/hbgf/hbgfwin
  * contrib/hbgf/tests/bld_b32.bat
  * contrib/hbgf/tests/bld_vc.bat
  * contrib/hbgf/Makefile
  * contrib/hbgf/hbgfwin/common.mak
  * contrib/hbgf/hbgfwin/button.prg
  * contrib/hbgf/hbgfwin/winctrl.prg
  * contrib/hbgf/hbgfwin/form.prg
  * contrib/hbgf/hbgfwin/menuitem.prg
  * contrib/hbgf/hbgfwin/menu.prg
  * contrib/hbgf/hbgfwin/edit.prg
  * contrib/hbgf/hbgfwin/Makefile
  - contrib/hbgf/hbgfwin/win32.c
  + contrib/hbgf/hbgfwin/winapi.c
  - contrib/hbgf/hbgfwin/hbgfw32.ch
  + contrib/hbgf/hbgfwin/hbgfwin.ch
    * Removed some '32's.

2008-09-13 12:28 UTC+0200 Viktor Szakats (harbour.01 syenar hu)
  * doc/whatsnew.txt
    * Updated.

2008-09-13 12:28 UTC+0200 Viktor Szakats (harbour.01 syenar hu)
  * contrib/hbw32/Makefile
  * contrib/hbw32/common.mak
  * contrib/hbw32/hbw32.ch
  + contrib/hbw32/hbwin.h
  + contrib/hbw32/win_prt.c
  + contrib/hbw32/win_tprt.prg
  + contrib/hbw32/tests/testprt1.prg
  + contrib/hbw32/tests/testprt2.prg
    + Added Windows COM port handling functions.
      Contributed by Alex Strickland.
    ; I did some changes to clean warnings, few 64-bit issues, 
      changed to use safe string functions, integrated 
      the header into hbw32.ch, added a new general C level 
      header, split BEGINDUMP into separate .c function, 
      changed to ANSI C comments, marked statics with s_, 
      fixed a few trashed string buffers and leaks in some 
      error cases. Separated tests into distinct .prgs.
      Fixed for UNICODE mode. Minor optimizations, formatting.
    ; TODO: Test WinCE build.
    ; Please test, I don't have any COM ports on my system.

2008-09-13 10:28 UTC+0200 Viktor Szakats (harbour.01 syenar hu)
  * contrib/gtwvg/wvgcore.c
  * contrib/gtwvg/wvgutils.c
    ! Fixed 64-bit problems.
    ; Pritpal, could you please review and test these changes?

2008-09-13 09:37 UTC+0200 Viktor Szakats (harbour.01 syenar hu)
  * contrib/hbvpdf/hbvpdf.prg
    ! Generic support functions made STATIC to avoid collision 
      with similarly named functions in other libs (like hbct).

  * contrib/hbvpdf/hbvpdf.prg
  * contrib/hbvpdf/hbvpdft.prg
    * Using hb_run() instead of RUN and __run().

2008-09-12 19:30 UTC+0200 Viktor Szakats (harbour.01 syenar hu)
  * contrib/gtalleg/Makefile
    * Excluded Cygwin.

  * contrib/hbwhat/Makefile
  * contrib/hbwhat/common.mak
  - contrib/hbwhat/whtdll.c
  - contrib/hbwhat/whtcall.c
    - Removed DLL related stuff from hbwhat, since we're 
      maintaining (a better working) one already in hbw32, 
      and hbwhat by itself doesn't seem to need this 
      functionality internally. Users should migrate to 
      the hbw32 functions, which work mostly similarly.

2008-09-12 19:08 UTC+0200 Viktor Szakats (harbour.01 syenar hu)
  * doc/whatsnew.txt
    * Added some build notes.

  * contrib/gtalleg/Makefile
    ! Fixed POCC, XCC compiler exlusions.
    * Excluded DMC compiler.

  * contrib/hbwhat/Makefile
    * Excluded DMC compiler.

  * contrib/hbwhat/wincorec.c
    ! Workaround for a wrong Windows API declaration in 
      __DMC__ headers.

2008-09-12 11:01 UTC+0200 Viktor Szakats (harbour.01 syenar hu)
  * contrib/hbole/tests/bld_vc.bat
  * contrib/hbw32/tests/bld_vc.bat
    ! Added missing system libs.

2008-09-12 04:03 UTC+0200 Viktor Szakats (harbour.01 syenar hu)
  * contrib/gtwvg/wvgutils.c
    ! Fix to previous fix, so it works again in 64-bit builds.
         hb_retclen( ( LPSTR ) pdlgtemplate, ( ( ULONG ) p - ( ULONG ) pdlgtemplate ) ) ; =>
         hb_retclen( ( LPSTR ) pdlgtemplate, ( ( HB_PTRDIFF ) p - ( HB_PTRDIFF ) pdlgtemplate ) ) ;
    ; This way it's now in sync with similar function in hbwhat.

2008-09-12 01:14 UTC+0200 Viktor Szakats (harbour.01 syenar hu)
  * source/rdd/usrrdd/rdds/Makefile
  + source/rdd/usrrdd/rdds/arrayrdd.prg
  + source/rdd/usrrdd/rdds/vfpcdx.prg
    + Added two usrrdd based RDDs. Borrowed from xhb.
      Works of: Francesco Saverio Giudice and 
                Miguel Angel Marchuet Frutos
    ; These were adapted to compile and link in Harbour, but 
      I did no tests, so some more - hopefully minor - changes 
      may happen to be needed.

2008-09-12 00:53 UTC+0200 Viktor Szakats (harbour.01 syenar hu)
  * contrib/rddado/adordd.prg
  * contrib/rddado/adordd.ch
    * Merged changes from xhb.
      Some hbusrrdd.ch values seem to be missing from Harbour, 
      related features will be automatically enabled if we 
      implement them in our usrrdd.
      Please test.

2008-09-11 22:55 UTC+0200 Viktor Szakats (harbour.01 syenar hu)
  * doc/whatsnew.txt
  * source/vm/cmdarg.c
    * Legacy undocumented symbols hb_hInstance and 
      hb_hPrevInstance reenabled for 1.0.1, when HB_LEGACY_LEVEL 
      is #defined. This is the default in 1.0.x. It will be 
      turned off in 1.1.0.
      I did this to not break binary compatibility of 1.0.1 
      with 1.0.0 for those apps that rely on these symbols
      (like gtwvg).

2008-09-11 21:29 UTC+0200 Viktor Szakats (harbour.01 syenar hu)
  * contrib/gtwvg/tests/bld_vc.bat
    ! Added required list of system libs.

2008-09-11 14:08 UTC+0200 Viktor Szakats (harbour.01 syenar hu)
  * source/rtl/gtpca/gtpca.c
  * source/rtl/gtwin/gtwin.c
  * source/rtl/gtwvt/gtwvt.c
  * source/rtl/gttone.c
    ! Fixed some core MSVC -W4 warnings.

  * contrib/hbnf/getenvrn.c
    ! Fixed compile problem in MSVC C++ mode surfaced after 
      recent UNICODE fix.

2008-09-11 13:13 UTC+0200 Viktor Szakats (harbour.01 syenar hu)
  * contrib/gtwvg/wvgutils.c
    ! Fixed last MSVC -W4 warnings.
    ; NOTE: Only these contribs have remaining -W4 warnings:
            hbbmcdx, hbbtree, hbct (in screen*.c).
            Plus core.

2008-09-11 12:00 UTC+0200 Viktor Szakats (harbour.01 syenar hu)
  * contrib/hbnf/fttext.c
  * contrib/hbwhat/whtdate.c
  * contrib/hbwhat/wincorec.c
  * contrib/hbwhat/whtsock.c
  * contrib/hbwhat/whtseria.c
  * contrib/hbwhat/whtdlg.c
  * contrib/hbwhat/whtsys.c
  * contrib/hbwhat/whtmisc.c
  * contrib/hbwhat/whtcdlg.c
    ! Fixed all MinGW 4.3x warnings.
    ! Added workaround for slightly wrong MinGW definition for 
      Windows DateTime_GetMonthCal() macro.

  * contrib/gtwvg/gtwvg.c
  * contrib/gtwvg/wvgutils.c
  * contrib/gtwvg/wvgcore.c
    ! Fixed all MSVC -W4 warnings.

  * contrib/gtwvg/gtwvg.h
    ! Fixed old bug, which surfaced after recently 
      fixing __MINGW__ to __MINGW32__.
      Apparently, comctl32.h is never needed here.

  * config/rules.cf
  * contrib/hbbtree/tests/bld_djgp.bat
    % Removed -gc0. Now default.

  * contrib/make_b32_all.bat
  * contrib/make_vc_all.bat
    * Minor formatting.

  * contrib/hbgt/asciisgt.c
  * utils/hbdoc/hbdoc.prg
    - Removed unnecessary version strings. This was good 
      in CVS times, but for SVN there is not much point.

  * utils/hbmake/hbmake.prg
    + Another patch session from Bill Robertson.
      Besides some further cleanups, this should fix 
      some problems with the previous version.

  * source/lang/msghuiso.c
  * source/lang/msgskiso.c
  * source/lang/msgrukoi.c
  * source/lang/msghuwin.c
  * source/lang/msgzhgb.c
  * source/lang/msgskwin.c
  * source/lang/msg_tpl.c
  * source/lang/msgruwin.c
  * source/lang/msgelwin.c
  * source/lang/msgro.c
  * source/lang/msgpt.c
  * source/lang/msghriso.c
  * source/lang/msghrwin.c
  * source/lang/msgsliso.c
  * source/lang/msgbe866.c
  * source/lang/msgslwin.c
  * source/lang/msghe862.c
  * source/lang/msgcskam.c
  * source/lang/msggl.c
  * source/lang/msgtrwin.c
  * source/lang/msgeo.c
  * source/lang/msgbgiso.c
  * source/lang/msgbgwin.c
  * source/lang/msgskkam.c
  * source/lang/msges.c
  * source/lang/msguakoi.c
  * source/lang/msgzhb5.c
  * source/lang/msgeu.c
  * source/lang/msgpl852.c
  * source/lang/msgsr852.c
  * source/lang/msguawin.c
  * source/lang/msgde.c
  * source/lang/msgtr857.c
  * source/lang/msgru866.c
  * source/lang/msgcs852.c
  * source/lang/msgfr.c
  * source/lang/msgis850.c
  * source/lang/msgnl.c
  * source/lang/msghu852.c
  * source/lang/msgsk852.c
  * source/lang/msgca.c
  * source/lang/msgplmaz.c
  * source/lang/msgpliso.c
  * source/lang/msgplwin.c
  * source/lang/msgbgmik.c
  * source/lang/msgid.c
  * source/lang/msgbg866.c
  * source/lang/msgltwin.c
  * source/lang/msgsriso.c
  * source/lang/msgel.c
  * source/lang/msgsrwin.c
  * source/lang/msgbewin.c
  * source/lang/msgdewin.c
  * source/lang/msghr437.c
  * source/lang/msghr852.c
  * source/lang/msgko.c
  * source/lang/msgua866.c
  * source/lang/msghewin.c
  * source/lang/msgit.c
  * source/lang/msgsl437.c
  * source/lang/msgsl852.c
  * source/lang/msghucwi.c
  * source/lang/msgcsiso.c
  * source/lang/msgcswin.c
  * source/lang/msgeswin.c
  * source/rtl/langapi.c
    - Cleared unnecessary version strings. This was good 
      in CVS times, but for SVN there is not much point.
2008-09-14 10:19:59 +00:00

1159 lines
34 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>))
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 )
//Tracelog( "nRDD = ", nRDD )
/* Init DBF Hash */
USRRDD_RDDDATA( nRDD, hb_Hash() )
RETURN 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 SUCCESS
// Creating fields for new DBF - dbCreate() in current workarea
STATIC FUNCTION AR_CREATEFIELDS( nWA, aStruct )
LOCAL aWAData := USRRDD_AREADATA( nWA )
LOCAL nResult := SUCCESS
LOCAL oError, aFieldStruct, aField
// 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 aField, oError, cName
LOCAL cFullName, aDBFData
/* 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 */
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 )
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 FAILURE
ENDIF
// Set WorkArea Info
aWAData[ WADATA_WORKAREA ] := nWA
aWAData[ WADATA_OPENINFO ] := aOpenInfo // Put open informations
// increase open number
aDBFData[ DATABASE_OPENNUMBER ]++
RETURN SUCCESS
STATIC FUNCTION AR_OPEN( nWA, aOpenInfo )
LOCAL cFullName, cName, hRDDData, aWAData, aDBFData
LOCAL aStruct, oError, aFieldStruct, aField, nResult, aRecInfo
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 cFullName $ hRDDData:Keys
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 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 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 FAILURE
ENDIF
ENDIF
IF nResult == SUCCESS
AR_GOTOP( nWA )
ENDIF
RETURN nResult
STATIC FUNCTION AR_CLOSE( nWA )
LOCAL aWAData := USRRDD_AREADATA( nWA )
LOCAL aDBFData := aWAData[ WADATA_DATABASE ]
// decrease open number
aDBFData[ DATABASE_OPENNUMBER ]--
// unlock file
aDBFData[ DATABASE_LOCKED ] := FALSE // Exclusive mode
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 ]
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 SUCCESS
ENDIF
RETURN 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
IF nField > 0 .AND. nField <= Len( aStruct ) .AND. ;
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 SUCCESS
ENDIF
RETURN 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 )
//if( SELF_GOCOLD( ( AREAP ) pArea ) == FAILURE )
// return 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 SUCCESS
STATIC FUNCTION AR_GOTOID( nWA, nRecord )
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 )
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 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 ]
LOCAL nRecCount := Len( aRecords )
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 SUCCESS
STATIC FUNCTION AR_SKIPFILTER( nWA, nRecords )
LOCAL aWAData := USRRDD_AREADATA( nWA )
LOCAL aDBFData := aWAData[ WADATA_DATABASE ]
LOCAL aRecords := aDBFData[ DATABASE_RECORDS ]
LOCAL aRecInfo := aDBFData[ DATABASE_RECINFO ]
LOCAL lBof, lEof, nToSkip
LOCAL nResult := SUCCESS
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 ) == SUCCESS )
RETURN 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 SUCCESS
STATIC FUNCTION AR_SKIPRAW( nWA, nRecords )
LOCAL aWAData := USRRDD_AREADATA( nWA )
LOCAL lBof, lEof
LOCAL nResult
//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 // SUCCESS
STATIC FUNCTION AR_BOF( nWA, lBof )
LOCAL aWAData := USRRDD_AREADATA( nWA )
// 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 SUCCESS
STATIC FUNCTION AR_EOF( nWA, lEof )
LOCAL aWAData := USRRDD_AREADATA( nWA )
lEof := aWAData[ WADATA_EOF ]
RETURN 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
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 FAILURE
ENDIF
IF aOpenInfo[ UR_OI_SHARED ] .AND. !( aWAData[ WADATA_RECNO ] $ aWAData[ WADATA_LOCKS ] )
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 FAILURE
ENDIF
IF Len( aRecInfo ) > 0 .AND. aWAData[ WADATA_RECNO ] <= Len( aRecInfo )
aRecInfo[ aWAData[ WADATA_RECNO ] ][ RECDATA_DELETED ] := .T.
ENDIF
RETURN SUCCESS
STATIC FUNCTION AR_DELETED( nWA, lDeleted )
LOCAL aWAData := USRRDD_AREADATA( nWA )
LOCAL aDBFData := aWAData[ WADATA_DATABASE ]
LOCAL aRecInfo := aDBFData[ DATABASE_RECINFO ]
//lDeleted := .F.
IF Len( aRecInfo ) > 0 .AND. aWAData[ WADATA_RECNO ] <= Len( aRecInfo )
lDeleted := aRecInfo[ aWAData[ WADATA_RECNO ] ][ RECDATA_DELETED ]
ELSE
lDeleted := .F.
ENDIF
RETURN 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
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 FAILURE
ENDIF
aRecord := BlankRecord( aStruct )
aAdd( aRecords, aRecord )
aAdd( aRecInfo, AR_RECDATAINIT() )
AR_GOBOTTOM( nWA )
/* TODO: SHARED ACCESS */
RETURN 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 )
IF aWAData[ WADATA_EOF ]
nRecNo := nRecCount + 1
ELSE
nRecNo := aWAData[ WADATA_RECNO ]
ENDIF
RETURN SUCCESS
STATIC FUNCTION AR_RECCOUNT( nWA, nRecords )
LOCAL aWAData := USRRDD_AREADATA( nWA )
LOCAL aDBFData := aWAData[ WADATA_DATABASE ]
LOCAL aRecords := aDBFData[ DATABASE_RECORDS ]
nRecords := Len( aRecords )
RETURN SUCCESS
STATIC FUNCTION AR_ZAP( nWA )
LOCAL aWAData := USRRDD_AREADATA( nWA )
LOCAL aDBFData := aWAData[ WADATA_DATABASE ]
LOCAL aOpenInfo := aWAData[ WADATA_OPENINFO ]
LOCAL oError
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 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 FAILURE
ENDIF
// empty records
aDBFData[ DATABASE_RECORDS ] := {}
aDBFData[ DATABASE_RECINFO ] := {}
// move to 0 recno
AR_GOTO( nWA, 0 )
RETURN SUCCESS
STATIC FUNCTION AR_ORDINFO( nWA, xMsg, xValue )
/*
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 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 FAILURE
ENDIF
aWAData[ ARRAY_RECORDS ] := {}
aWAData[ ARRAY_RECINFO ] := {}
AR_GOTO( nWA, 0 )
*/
RETURN 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 PROC ARRAYRDD_INIT()
rddRegister( "ARRAYRDD", RDT_FULL )
RETURN
/* -------------------------------------------------- */
/* UTILITY FUNCTIONS */
/* -------------------------------------------------- */
/*
EraseArrayRdd() function is equivalent of FErase() function, but works here in memory
*/
FUNCTION EraseArrayRdd( cFullName )
LOCAL nReturn := 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 cFullName $ hRDDData:Keys
// 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 := FAILURE
ELSE
// Delete database from slot
hb_HDel( hRDDData, cFullName )
nReturn := 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 := 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 := FAILURE
ENDIF
RETURN nReturn
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" .OR. cType == "M"
xVal := PadR( xValue, nLen )
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. ;
( ValType( xDefault ) == "A" .OR. ;
ValType( xDefault ) == "H" )
// If it is an array I will restart this function creating a linear call
IF ValType( xDefault ) == "A" .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 ValType( xDefault[ 1 ] ) == "A"
//// 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 !( ValType( xDefault[ nLen ] ) == "A" )
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