/*
 * $Id$
 */

/*
 * The following parts are Copyright of the individual authors.
 * www - http://www.harbour-project.org
 *
 * Copyright 1999 Luiz Rafael Culik <culik@sl.conex.net>
 *    DB*() documentation
 *    ORD*() documentation
 *    RDD*() documentation
 *
 * See doc/license.txt for licensing terms.
 *
 */

/*  $DOC$
 *  $FUNCNAME$
 *     AFIELDS()
 *  $CATEGORY$
 *      DATA BASE
 *  $ONELINER$
 *      Fills referenced arrays with database field information
 *  $SYNTAX$
 *      AFields(<aNames>[,<aTypes>][,<aLen>][,<aDecs>]) --> <nFields>
 *  $ARGUMENTS$
 *      <aNames>  Array of field names
 *      <aTypes>  Array of field names
 *      <aLens>  Array of field names
 *      <aDecs>  Array of field names
 *  $RETURNS$
 *      <nFields> Number od fields in a database or work area
 *  $DESCRIPTION$
 *      This function will fill a series of arrays with field
 *      names,field types,field lenghts, and number of field
 *      decimal positions for the currently selected or designed
 *      database. Each array parallels the different descriptors
 *      of a file's structure.The first array will consist of the
 *      names of the fields in the current work area.All other arrays
 *      are optional and will be filled with the corrensponding data.
 *      This function will return zero if no parameters are specified
 *      or if no database is avaliable in the current work area.Otherwise,
 *      the number of fields or the lenght of the shortest array argument,
 *      witchever is smaller, will be returned.
 *  $EXAMPLES$
 *      FUNCTION Main()
 *         LOCAL aNames:={},aTypes:={},aLens:={},aDecs:={},nFields:=0
 *
 *         USE Test
 *
 *         dbGoTop()
 *         nFields:=aFields(aNames,aTypes,aLens,aDecs)
 *
 *         ? "Number of fields", nFields
 *
 *         RETURN NIL
 *  $STATUS$
 *      R
 *  $COMPLIANCE$
 *      AFIELDS() is fully CA-Clipper compliant.
 *  $SEEALSO$
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *     ALIAS()
 *  $CATEGORY$
 *      DATA BASE
 *  $ONELINER$
 *      Returns the alias name of a work area
 *  $SYNTAX$
 *      Alias([<nWorkArea>]) --> <cWorkArea>
 *  $ARGUMENTS$
 *      <nWorkArea> Number of a work area
 *  $RETURNS$
 *      <cWorkArea> Name of alias
 *  $DESCRIPTION$
 *      This function returns the alias of the work area indicated by <nWorkArea>
 *      If <nWorkArea> is not provided, the alias of the current work area is
 *      returned.
 *  $EXAMPLES$
 *      FUNCTION Main()
 *
 *      USE Test
 *      select 0
 *      qOut( IF(Alias()=="","No Name",Alias()))
 *      Test->(qOut(Alias())
 *      qOut(Alias(1))
 *
 *      RETURN NIL
 *  $STATUS$
 *      R
 *  $COMPLIANCE$
 *      ALIAS() is fully CA-Clipper compliant.
 *  $SEEALSO$
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *      DBEVAL()
 *  $CATEGORY$
 *      DATA BASE
 *  $ONELINER$
 *      Performs a code block operation on the current DATA BASE
 *  $SYNTAX$
 *      DBEVAL( <bBlock>,
 *      [<bFor>], [<bWhile>],
 *      [<nNext>], [<nRecord>],
 *      [<lRest>] ) --> NIL
 *  $ARGUMENTS$
 *      <bBlock> Operation that is to be performed
 *      <bFor> Code block for the For condition
 *      <bWhile> Code block for the WHILE condition
 *      <nNext> Number of NEXT records  to process
 *      <nRecord> Record number to work on exactly
 *      <lRest> Toggle to rewind record pointer
 *  $RETURNS$
 *      DBEVAL() always returns NIL
 *  $DESCRIPTION$
 *        Performs a code block operation on the current DATA BASE
 *  $EXAMPLES$
 *      FUNCTION Main()
 *         LOCAL nCount
 *
 *         USE Test
 *
 *         dbGoto( 4 )
 *         ? RecNo()
 *         COUNT TO nCount
 *         ? RecNo(), nCount
 *         COUNT TO nCount NEXT 10
 *         ? RecNo(), nCount
 *
 *         RETURN NIL
 *  $STATUS$
 *      S
 *  $COMPLIANCE$
 *      DBEVAL is fully CA-Clipper compliant.
 *  $SEEALSO$
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *     DBF()
 *  $CATEGORY$
 *      DATA BASE
 *  $ONELINER$
 *      Alias name of a work area
 *  $SYNTAX$
 *      Dbf() --> <cWorkArea>
 *  $RETURNS$
 *      <cWorkArea> Name of alias
 *  $DESCRIPTION$
 *      This function returns the same alias name ofthe currently selected work
 *      area.
 *  $EXAMPLES$
 *      FUNCTION Main()
 *
 *         USE Test
 *
 *         select 0
 *         qOut( IF(DBF()=="","No Name",DBF()))
 *         Test->(qOut(DBF())
 *         qOut(Alias(1))
 *
 *         RETURN NIL
 *  $STATUS$
 *      R
 *  $COMPLIANCE$
 *      DBF() is fully CA-Clipper compliant.
 *  $SEEALSO$
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *     BOF()
 *  $CATEGORY$
 *      DATA BASE
 *  $ONELINER$
 *      Test for the beggining-of-file condition
 *  $SYNTAX$
 *      BOF() --> <lBegin>
 *  $RETURNS$
 *      BOF() Logical true (.T.) or false (.F.)
 *  $DESCRIPTION$
 *      This function determines if the beggining of the file marker has been
 *      reached. If so, the function will return a logical true (.T.); otherwise,
 *      a logical false(.F.) will be returned.
 *      By default, BOF() will apply to the currently selected database unless
 *      the function is preceded by an alias
 *  $EXAMPLES$
 *      FUNCTION Main()
 *        USE Tests NEW
 *        DBGOTOP()
 *        ? "Is Eof()",EOF()
 *        DBGOBOTTOM()
 *        ? "Is Eof()",EOF()
 *        USE
 *     RETURN NIL
 *  $STATUS$
 *      R
 *  $COMPLIANCE$
 *      BOF() is fully CA-Clipper compliant.
 *  $SEEALSO$
 *    EOF(),FOUND(),LASTREC()
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *     DBAPPEND()
 *  $CATEGORY$
 *      DATA BASE
 *  $ONELINER$
 *      Appends a new record to a database file.
 *  $SYNTAX$
 *      DbAppend(<<lLock>]) --> NIL
 *  $ARGUMENTS$
 *      <lLock> Toggle to release record locks
 *  $RETURNS$
 *      DbAppend() always returns NIL
 *  $DESCRIPTION$
 *     This function add a new record to the end of the database
 *     in the selected or aliased work area. All fields in that
 *     database will be given empty data values - character fields
 *     will be filled with blank spaces,date fields with CTOD('//'),
 *     numeric fields with 0,logical fields with .F., and memo fields
 *     with NULL bytes.The header of the database is not updated until
 *     the record is flushed from the buffer and the contents are
 *     written to the disk.
 *     Under a networking enviroment, DBAPPEND() performs an addi-
 *     tional operation: It attrmps to lock the newly added record. If
 *     the database file is currently locked or if a locking assignment
 *     if made to LASTREC()+1,NETERR() will return a logical true (.T.)
 *     immediately after the DBAPPEND() function. This function does
 *     not unlock the locked records.
 *     If <lLock> is passed a logical true (.T.) value, it will
 *     release the record locks, which allows the application to main-
 *     tain multiple record locks during an appending operation. The
 *     default for this parameter is a logical false (.F.).
 *  $EXAMPLES$
 *      FUNCTION Main()
 *
 *         USE Test
 *         local cName="HARBOUR",nId=10
 *         Test->(DbAppend())
 *         Replace Test->Name wit cName,Id with nId
 *         Use
 *         RETURN NIL
 *  $STATUS$
 *      R
 *  $COMPLIANCE$
 *      DBAPPEND() is fully CA-Clipper compliant.
 *  $SEEALSO$
 *      DBUNLOCK(0,DBUNLOCKALL()
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *     DBCLEARFILTER()
 *  $CATEGORY$
 *      DATA BASE
 *  $ONELINER$
 *      Clears the current filter condiction in a work area
 *  $SYNTAX$
 *      DbClearFilTer() -> NIL
 *  $RETURNS$
 *      DbClearFilTer() always returns NIL
 *  $DESCRIPTION$
 *        This function clears any active filter condiction
 *      for the current or selected work area.
 *  $EXAMPLES$
 *      Function Main()
 *
 *       Use Test
 *
 *       Set Filter to Left(Test->Name,2) == "An"
 *
 *       Dbedit()
 *
 *       Test->(DbClearFilter())
 *
 *       USE
 *
 *       Return Nil
 *  $STATUS$
 *      R
 *  $COMPLIANCE$
 *      DBCLEARFILTER() is fully CA-Clipper compliant.
 *  $SEEALSO$
 *      DBSETFILTER(),DBFILTER()
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *     DBCLOSEALL()
 *  $CATEGORY$
 *      DATA BASE
 *  $ONELINER$
 *      Close all open files in all work areas.
 *  $SYNTAX$
 *      DbCloseAll() -> NIL
 *  $RETURNS$
 *      DBCLOSEALL() always return NIL
 *  $DESCRIPTION$
 *      This function close all open databases and all associated
 *      indexes.In addition, it closes all format files and moves
 *      the work area pointer to the first position
 *  $EXAMPLES$
 *      Function Main()
 *
 *       Use Test New
 *
 *       DbEdit()
 *
 *       Use Test1 New
 *
 *       DbEdit()
 *
 *       DbCloseAll()
 *
 *       USE
 *
 *       Return Nil
 *  $STATUS$
 *      R
 *  $COMPLIANCE$
 *      DBCLOSEALL() is fully CA-Clipper compliant.
 *  $SEEALSO$
 *      DBUSEAREA(),DBCLOSEAREA()
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *     DBCLOSEAREA()
 *  $CATEGORY$
 *      DATA BASE
 *  $ONELINER$
 *      Close a database file in a work area.
 *  $SYNTAX$
 *      DbCloseArea() -> NIL
 *  $RETURNS$
 *      DbCloseArea() always returns NIL.
 *  $DESCRIPTION$
 *      This function  will close any database open in the selected
 *      or aliased work area.
 *  $EXAMPLES$
 *      Function Main()
 *
 *       Use Test
 *
 *       Dbedit()
 *
 *       Test->(DbCloseArea())
 *
 *       USE
 *
 *       Return Nil
 *  $STATUS$
 *      R
 *  $COMPLIANCE$
 *      DBCLOSEAREA() is fully CA-Clipper compliant.
 *  $SEEALSO$
 *      DBUSEAREA(),DBCLOSEALL()
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *      DBCOMMIT()
 *  $CATEGORY$
 *      DATA BASE
 *  $ONELINER$
 *      Updates all index and database buffers for a given workarea
 *  $SYNTAX$
 *     DBCOMMIT() --> NIL
 *  $RETURNS$
 *      DBCOMMIT() always returns NIL.
 *  $DESCRIPTION$
 *      This function updates all of the information for a give,selected,
 *      or active workarea.This operation includes all database and index
 *      buffers for that work area only. This function does not update all
 *      open work areas.
 *  $EXAMPLES$
 *      FUNCTION Main()
 *      LOCAL cName:=SPACE(40)
 *      LOCAL nId:=0
 *      USE Test EXCLUSIVE NEW
 *      //
 *      @ 10, 10 GET cName
 *      @ 11, 10 GET nId
 *      READ
 *      //
 *      IF UPDATED()
 *         APPEND BLANK
 *         REPLACE Tests->Name WITH cName
 *         REPLACE Tests->Id WITH nId
 *         Tests->( DBCOMMIT() )
 *      ENDIF
 *      RETURN NIL
 *  $STATUS$
 *      R
 *  $COMPLIANCE$
 *      This function is CA-Clipper compliant
 *  $SEEALSO$
 *      DBCLOSEALL(),DBCOMMITALL(),DBUNLOCK()
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *      DBCOMMITALL()
 *  $CATEGORY$
 *      DATA BASE
 *  $ONELINER$
 *      Flushes the memory buffer and performs a hard-disk write
 *  $SYNTAX$
 *      DBCOMMIT() --> NIL
 *  $RETURNS$
 *      DBCOMMIT() always returns NIL.
 *  $DESCRIPTION$
 *      This function performs a hard-disk write for all work areas.
 *      Before the disk write is performed,all buffers are flushed.
 *      open work areas.
 *  $EXAMPLES$
 *      FUNCTION Main()
 *      LOCAL cName:=SPACE(40)
 *      LOCAL nId:=0
 *      USE Test EXCLUSIVE NEW
 *      USE TestId New INDEX Testid
 *      //
 *      @ 10, 10 GET cName
 *      @ 11, 10 GET nId
 *      READ
 *      //
 *      IF UPDATED()
 *         APPEND BLANK
 *         REPLACE Tests->Name WITH cName
 *         REPLACE Tests->Id WITH nId
 *         IF !TestId->(DBSEEK(nId))
 *            APPEND BLANK
 *            REPLACE Tests->Id WITH nId
 *         ENDIF
 *      ENDIF
 *      DBCOMMITALL()
 *      RETURN NIL
 *  $STATUS$
 *      R
 *  $COMPLIANCE$
 *      This function is CA-Clipper compliant.
 *  $SEEALSO$
 *     DBCLOSEALL(),DBCOMMIT(),DBUNLOCK()
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *      __DBCONTINUE()
 *  $CATEGORY$
 *      DATA BASE
 *  $ONELINER$
 *      Resume a pending LOCATE
 *  $SYNTAX$
 *      __DbCONTINUE()   -> NIL
 *  $RETURNS$
 *      __DbCONTINUE()  Always return nil
 *  $DESCRIPTION$
 *      __DBCONTINUE is a database command that searches from the current record
 *      position for the next record meeting the most recent LOCATE condition
 *      executed in the current work area.  It terminates when a match is found
 *      or end of file is encountered.  If __DBCONTINUE is successful, the matching
 *      record becomes the current record and FOUND() returns true (.T.); if
 *      unsuccessful, FOUND() returns false (.F.).
 *
 *      Each work area may have an active LOCATE condition.  In CA-Clipper, a
 *      LOCATE condition remains pending until a new LOCATE condition is
 *      specified.  No other commands release the condition.
 *
 *      Notes
 *
 *      Scope and WHILE condition: Note that the scope and WHILE
 *      condition of the initial LOCATE are ignored; only the FOR condition
 *      is used with CONTINUE.  If you are using a LOCATE with a WHILE
 *      condition and want to continue the search for a matching record, use
 *      SKIP and then repeat the original LOCATE statement adding REST as the
 *      scope.
 *
 *  $EXAMPLES$
 *     This example scans records in Sales.dbf for a particular
 *      salesman and displays a running total sales amounts:
 *
 *      LOCAL nRunTotal := 0
 *      USE Sales NEW
 *      LOCATE FOR Sales->Salesman = "1002"
 *      DO WHILE FOUND()
 *         ? Sales->Salesname, nRunTotal += Sales->Amount
 *         __DBCONTINUE()
 *      ENDDO
 *
 *     This example demonstrates how to continue if the pending
 *      LOCATE scope contains a WHILE condition:
 *
 *      LOCAL nRunTotal := 0
 *      USE Sales INDEX Salesman NEW
 *      SEEK "1002"
 *      LOCATE REST WHILE Sales->Salesman = "1002";
 *            FOR Sales->Amount > 5000
 *      DO WHILE FOUND()
 *         ? Sales->Salesname, nRunTotal += Sales->Amount
 *         SKIP
 *         LOCATE REST WHILE Sales->Salesman = "1002";
 *            FOR Sales->Amount > 5000
 *      ENDDO
 *
 *  $STATUS$
 *      R
 *  $COMPLIANCE$
 *      This function is CA-Clipper compliant.
 *  $SEEALSO$
 *      EOF(),FOUND()
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *      DBCREATE()
 *  $CATEGORY$
 *      DATA BASE
 *  $ONELINER$
 *      Creates an empty database from a array.
 *  $SYNTAX$
 *      DBCREATE(<cDatabase>, <aStruct>,[<cDriver>],[<lOpen>],
 *      [<cAlias>]) --> NIL
 *  $ARGUMENTS$
 *      <cDatabase> Name of database to be create
 *      <aStruct>   Name of a multidimensional array that contains the a database
 *                  structure
 *      <cDriver>   Name of the RDD
 *      <lOpen>     Toggle to Open the create File
 *      <cAlias>    Name of database Alias
 *  $RETURNS$
 *      DBCREATE() always returns NIL.
 *  $DESCRIPTION$
 *      This function creates the database file specified as <cDatabase> from the
 *      multidimensional array <aStruct>.If no file extension is use with <cDatabase>
 *      the .DBF extension is assumed.
 *      The array specified in <aStruct> must follow a few guidelines when being
 *      built prior to a call to DBCREATE():
 *
 *      - All subscripts values in the second dimension must be set to proper values
 *
 *      - The fourth subscript value in the second dimension - which contains
 *        the decimal value-must he specified. even 1kw nonnumeric fields.
 *
 *      - The second subscript value in the second dimension-which contains
 *        the field data type-must contain a proper value: C, D, L, M or N
 *        It is possible to use additional letters (or clarity (e.g., 'Numeric'
 *        for 'N'): however, the first letter of this array element must
 *        be a proper value.
 *
 *      The DBCREATE( ) function does not use the decimal field to
 *      calculate the length of a character held longer than 256. Values
 *      up to the maximum length of a character field (which is 65,519 bytes)
 *      are stored directly in the database in the length attribute if that
 *      database was created via this function. However, a file containing
 *      fields longer than 256 bytes is not compatible with any interpreter.
 *
 *      The <cDriver> parameter specifies the name of the Replaceable Da-
 *      tabase Driver to use to create the database. If it is not specified, then the
 *      Replaceable Database Driver in the current work area is tised.
 *      The <lOpen> parameter specifies if the already created database is to be opened,
 *      The <cAlias> parameter specifies the alias name for the new opened database
 *  $EXAMPLES$
 *      function main()
 *
 *      local nI, aStruct := { { "CHARACTER", "C", 25, 0 }, ;
 *                          { "NUMERIC",   "N",  8, 0 }, ;
 *                          { "DOUBLE",    "N",  8, 2 }, ;
 *                          { "DATE",      "D",  8, 0 }, ;
 *                          { "LOGICAL",   "L",  1, 0 }, ;
 *                          { "MEMO1",     "M", 10, 0 }, ;
 *                          { "MEMO2",     "M", 10, 0 } }
 *
 *      REQUEST DBFCDX
 *
 *      dbCreate( "testdbf", aStruct, "DBFCDX", .t., "MYALIAS" )
 *
 *      RETURN NIL
 *  $STATUS$
 *      R
 *  $COMPLIANCE$
 *      This function is Not CA-Clipper compliant
 *  $SEEALSO$
 *      AFIELDS(),DBSTRUCT()
 *  $INCLUDE$
 *      "Dbstruct.ch"
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *      DBDELETE()
 *  $CATEGORY$
 *      DATA BASE
 *  $ONELINER$
 *      Marks records for deletion in a database.
 *  $SYNTAX$
 *      DBDELETE() --> NIL
 *  $RETURNS$
 *      DBDELETE() always returns NIL.
 *  $DESCRIPTION$
 *      This function marks a record for deletion in the selected
 *      or aliased work area.If the DELETED setting is on, the record
 *      will still be visible until the record pointer in that work area
 *      is moved to another record.
 *      In a networking situation, this function requires that the record
 *      be locked prior to issuing the DBDELETE() function.
 *  $EXAMPLES$
 *      nId:=10
 *      USE TestId INDEX TestId NEW
 *      IF TestId->(DBSEEK(nId))
 *         IF TestId->(RLOCK())
 *            DBDELETE()
 *         ENDIF
 *      ENDIF
 *      USE
 *  $STATUS$
 *      R
 *  $COMPLIANCE$
 *      This function is CA-Clipper compliant
 *  $SEEALSO$
 *      DBRECALL()
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *      DBFILTER()
 *  $CATEGORY$
 *      Data Base
 *  $ONELINER$
 *      Return the filter expression in a work area
 *  $SYNTAX$
 *      DBFILTER() --> cFilter
 *  $RETURNS$
 *      DBFILTER() returns the filter expression.
 *  $DESCRIPTION$
 *      This function return the expression of the SET FILTER TO command
 *      for the current or designated work area. If no filter condition
 *      is present,a NULL string will be returned.
 *  $EXAMPLES$
 *      USE Test INDEX Test NEW
 *      SET FILTER TO Name= "Harbour"
 *      USE TestId INDEX TestId NEW
 *      SET FILTER TO Id = 1
 *      SELECT Test
 *      //
 *      ? DBFILTER()
 *      ? TestId->(DBFILTER())
 *  $STATUS$
 *      R
 *  $COMPLIANCE$
 *      This function is CA-Clipper compliant
 *  $SEEALSO$
 *      DBRELATION(),DBRSELECT()
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *      DBGOBOTTOM()
 *  $CATEGORY$
 *      Data Base
 *  $ONELINER$
 *      Moves the record pointer to the bottom of the database.
 *  $SYNTAX$
 *      DBGOBOTTOM() --> NIL
 *  $RETURNS$
 *      DBGOBOTTOM() always returns NIL.
 *  $DESCRIPTION$
 *      This function moves the record pointer in the selected or aliased
 *      work area to the end of the file.The position of the record pointer
 *      is affected by the values in the index key or by an active FILTER
 *      condition.Otherwise,if no index is active or if no filter condition
 *      is present,the value of the record pointer will be LASTREC().
 *  $EXAMPLES$
 *      USE Tests
 *      DBGOTOP()
 *      ? RECNO()
 *      DBGOBOTTOM()
 *      ? RECNO()
 *      USE
 *  $STATUS$
 *      R
 *  $COMPLIANCE$
 *      This function is CA-Clipper compliant
 *  $SEEALSO$
 *      BOF(),EOF(),DBSKIP(),DBSEEK(),DBGOTOP()
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *      DBGOTO()
 *  $CATEGORY$
 *      Data Base
 *  $ONELINER$
 *      Position the record pointer to a specific location.
 *  $SYNTAX$
 *      DBGOTO(<xRecordNumber>) --> NIL
 *  $ARGUMENTS$
 *      <xRecordNumber> Record number or unique identity
 *  $RETURNS$
 *      DBGOTO() always returns NIL.
 *  $DESCRIPTION$
 *      This function places the record pointer,if working with a .DBF file,
 *      in selected or aliased work area at the record number specified by
 *      <xRecordNumber>.The position if not affected by an active index or
 *      by any enviromental SET condiction.
 *      Issuing a DBGOTO(RECNO()) call in a network enviroment will refresh
 *      the database and index buffers.This is the same as a DBSKIP(0) call.
 *      The parameter <xRecordNumber> may be something other than a record
 *      number.In some data formats, for example, the value of <xRecordNumber>
 *      is a unique primary key while in other formats,<xRecordNumber> could
 *      be an array offset if the data set was an array.
 *  $EXAMPLES$
 *
 *      The following example uses DBGOTO() to iteratively process
 *      every fourth record:
 *
 *      DBUSEAREA( .T., "DBFNTX", "Sales", "Sales", .T. )
 *      //
 *      // toggle every fourth record
 *      DO WHILE !EOF()
 *         DBGOTO( RECNO() + 4 )
 *         Sales->Group := "Bear"
 *      ENDDO
 *
 *  $STATUS$
 *      R
 *  $COMPLIANCE$
 *      This function is CA-Clipper compliant.
 *  $SEEALSO$
 *      BOF(),EOF(),DBGOTOP(),DBGOBOTTOM(),DBSEEK(),DBSKIP()
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *      DBGOTOP()
 *  $CATEGORY$
 *      Data Base
 *  $ONELINER$
 *      Moves the record pointer to the bottom of the database.
 *  $SYNTAX$
 *      DBGOTOP() --> NIL
 *  $RETURNS$
 *      DBGOTOP() always returns NIL.
 *  $DESCRIPTION$
 *      This function moves the record pointer in the selected or aliased
 *      work area to the top of the file.The position of the record pointer
 *      is affected by the values in the index key or by an active FILTER
 *      condition.Otherwise,if no index is active or if no filter condition
 *      is present,the value of RECNO() will be 1.
 *  $EXAMPLES$
 *      USE Tests
 *      DBGOTOP()
 *      ? RECNO()
 *      DBGOBOTTOM()
 *      ? RECNO()
 *      USE
 *  $STATUS$
 *      R
 *  $COMPLIANCE$
 *      This function is CA-Clipper compliant
 *  $SEEALSO$
 *      BOF(),EOF(),DBSKIP(),DBSEEK(),DBGOBOTTOM()
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *      DBRECALL()
 *  $CATEGORY$
 *      Data Base
 *  $ONELINER$
 *      Recalls a record previousy marked for deletion.
 *  $SYNTAX$
 *      DBRECALL() --> NIL
 *  $RETURNS$
 *      DBRECALL() always returns NIL.
 *  $DESCRIPTION$
 *      This function unmarks those records marked for deletion nd reactivates
 *      them in the aliased or selected work area.If a record is DELETED and
 *      the DELETED setting is on, the record will still be visible for a
 *      DBRECALL() provided that the database record pointer has not been
 *      skipped.Once a record marked for deletion with the DELETE setting ON
 *      has been skipped, it no longer canbe brought back with DBRECALL().
 *  $EXAMPLES$
 *      USE Test NEW
 *      DBGOTO(10)
 *      DBDELETE()
 *      ? DELETED()
 *      DBRECALL()
 *      ? DELETED()
 *      USE
 *  $STATUS$
 *      R
 *  $COMPLIANCE$
 *      This function is CA-Clipper compliant
 *  $SEEALSO$
 *      DBDELETE()
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *      DBRLOCK()
 *  $CATEGORY$
 *      Data Base
 *  $ONELINER$
 *      This function locks the record basedon identify
 *  $SYNTAX$
 *      DBRLOCK([<xIdentity>]) --> lSuccess
 *  $ARGUMENTS$
 *      <xIdentity> Record indetifier
 *  $RETURNS$
 *      DBRLOCK() returns a logical true (.T.) if lock was successful
 *  $DESCRIPTION$
 *      This function attempts to lock a record which is indentified
 *      by <xIdentity> in the active data set.If the lock is successful
 *      the function will return a logical true (.T.) value;otherwise
 *      a logical false (.F.) will be returned.If <xIdentity> is not
 *      passed it will be assumed to lock the current active record/data item.
 *  $EXAMPLES$
 *      FUNCTION Main()
 *      LOCAL x:=0
 *      USE Tests New
 *      FOR x:=1 to reccount()
 *        IF !DBRLOCK()
 *          DBUNLOCK()
 *        ENDIF
 *      NEXT
 *      USE
 *  $STATUS$
 *      R
 *  $COMPLIANCE$
 *      This function is CA-Clipper compliant
 *  $SEEALSO$
 *      DBUNLOCK(),DBUNLOCKALL(),FLOCK(),RLOCK()
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *      DBRLOCKLIST()
 *  $CATEGORY$
 *      Data Base
 *  $ONELINER$
 *      This function return a list of records in the database work area
 *  $SYNTAX$
 *      DBRLOCKLIST() --> aRecordLocks
 *  $RETURNS$
 *      <aRecordList> is an array of lock records
 *  $DESCRIPTION$
 *      This function will return an array of locked records in a given
 *      and active work area.If the return array is an empty array
 *      (meaning no elements in it),then there are no locked record in that
 *      work area.
 *  $EXAMPLES$
 *      FUNCTION Main()
 *      LOCAL aList:={}
 *      LOCAL x:=0
 *      USE Tests NEW
 *      DBGOTO(10)
 *      RLOCK()
 *      DBGOTO(100)
 *      RLOCK()
 *      aList:=DBRLOCKLIST()
 *      FOR x:=1 TO LEN(aList)
 *         ? aList[x]
 *      NEXT
 *      USE
 *      RETURN NIL
 *  $STATUS$
 *      R
 *  $COMPLIANCE$
 *      This function is CA-Clipper compliant
 *  $SEEALSO$
 *      RLOCK(),DBRLOCK(),DBRUNLOCK()
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *      DBRUNLOCK()
 *  $CATEGORY$
 *      Data Base
 *  $ONELINER$
 *      Unlocks a record base on its indentifier
 *  $SYNTAX$
 *      DBRUNLOCK([<xIdentity>]) --> NIL
 *  $ARGUMENTS$
 *      <xIdentity> Record indentifier,tipicaly a record number
 *  $RETURNS$
 *      DBRUNLOCK() always returns NIL.
 *  $DESCRIPTION$
 *      This function will attempt to unlock the record specified as
 *      <xIdentity>,which in a .DBF format is the record number.If not
 *      specified,them the current active record/data item will be
 *      unlocked
 *  $EXAMPLES$
 *      FUNCTION Main()
 *      USE Tests New
 *      DBGOTO(10)
 *      IF RLOCK()
 *         ? Tests->ID
 *         DBRUNLOCK()
 *      ENDIF
 *      USE
 *      RETURN NIL
 *  $STATUS$
 *      R
 *  $COMPLIANCE$
 *      This function is CA-Clipper compliant
 *  $SEEALSO$
 *      RLOCK(),DBRLOCK(),DBRLOCKLIST()
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *      DBSEEK()
 *  $CATEGORY$
 *      Data Base
 *  $ONELINER$
 *      Searches for a value based on an active index.
 *  $SYNTAX$
 *      DBSEEK(<expKey>, [<lSoftSeek>],[<lFindLast>]) --> lFound
 *  $ARGUMENTS$
 *      <expKey> Any expression
 *      <lSoftSeek> Toggle SOFTSEEK condition
 *      <lFindLast> is an optional logical value that set the current
 *      record position to the last record if successful
 *  $RETURNS$
 *      DBSEEK() returns logical true (.T.) if found, otherwise false
 *  $DESCRIPTION$
 *      This function searches for the first record in a database file whose index
 *      key matches <expKey>. If the item is found, the function will return a logical
 *      true (.T.), the value of FOUND() wilI be a logical true (.T.), and the value of
 *      EOF() wilI be a logical false (.F.). If no item is found. then the function will
 *      return a logical false, the value of FOUND( ) will be a logical false (.F.), and
 *      the value of EOF( ) will be a logical true (.T.).
 *      This function always "rewinds" the database pointer and starts the search from
 *      the top of the file.
 *      If the SOFTSEEK flag is on or if <lSoftSeek> is set to a logical true (.T.)
 *      the value of FOUND() wilI be a logical false and EOF() will he a logical
 *      false if there is an item in the index key with a greater value than the key
 *      expression <expKey>; at this point the record pointer will position itself on that
 *      record. However, if there is no greater key in the index,EOF() will return a
 *      logical true (.T.) value. If <lSoftSeek> is not passed, the function will look
 *      to the internal status of SOFTSEEK before performing the operation. The default
 *      of <lSoftSeek> is a logical false (.F.)
 *
 *  $EXAMPLES$
 *      FUNCTION Main()
 *      USE Tests New INDEX Tests
 *      DBGOTO(10)
 *      nId:=Tests->nId
 *      IF Tests->(DBSEEK(nId))
 *        IF RLOCK()
 *           ? Tests->Name
 *           DBRUNLOCK()
 *        ENDIF
 *      ENDIF
 *      USE
 *      RETURN NIL
 *
 *      ACCEPT "Employee name: " TO cName
 *      IF ( Employee->(DBSEEK(cName)) )
 *         Employee->(ViewRecord())
 *      ELSE
 *         ? "Not found"
 *      END
 *
 *  $STATUS$
 *      S
 *  $COMPLIANCE$
 *      DBSEEK() is  Compatible with CA-Clipper 5.3
 *  $SEEALSO$
 *      DBGOBOTTOM(),DBGOTOP(),DBSKIP(),EOF(),BOF(),FOUND()
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *      DBSELECTAREA()
 *  $CATEGORY$
 *      Data Base
 *  $ONELINER$
 *      Change to another work area
 *  $SYNTAX$
 *      DBSELECTAREA(<xArea>) --> NIL
 *  $ARGUMENTS$
 *      <xArea> Alias or work area
 *  $RETURNS$
 *      DBSELECTAREA() always returns NIL.
 *  $DESCRIPTION$
 *      This function moves the Harbour internal primary focus to the work
 *      area designated by <xArea>. If <xArea> is numeric, them it will
 *      select the numeric work area;if <xArea> is character,then it will
 *      select the work area with the alias name.
 *      DBSELECTAREA(0) will select the next avaliable and unused work area.
 *      Up to 255 work areas are supported.Each work area has its own alias
 *      and record pointer, as well as its own FOUND(),DBFILTER(),DBRSELECT(),
 *      and DBRELATION() function values.
 *  $EXAMPLES$
 *      FUNCTION Main()
 *      LOCAL nId
 *      USE Tests NEW INDEX Tests
 *      USE Tests1 NEW INDEX Tests1
 *      DBSELECTAREA(1)
 *      nId:=Tests->Id
 *      DBSELECTAREA(2)
 *      IF DBSEEK(nId)
 *         ? Tests1->cName
 *      ENDIF
 *      DBCLOSEALL()
 *      RETURN NIL
 *  $STATUS$
 *      R
 *  $COMPLIANCE$
 *      This function is CA-CLIPPER compatible.
 *  $SEEALSO$
 *      DBUSEAREA(),SELECT()
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *      DBSETDRIVER()
 *  $CATEGORY$
 *      Data Base
 *  $ONELINER$
 *      Establishes the name of replaceable daabas driver for a selected work area
 *  $SYNTAX$
 *      DBSETDRIVER([<cDriver>]) --> cCurrentDriver
 *  $ARGUMENTS$
 *      <cDriver> Optional database driver name
 *  $RETURNS$
 *      DBSETDRIVER() returns the name of active driver
 *  $DESCRIPTION$
 *      This function returns the name of the current database driver for the
 *      selected work area. The default will be "DBFNTX". If specified,<cDriver>
 *      contains the name of the database driver that should be used to activate
 *      and manage the work area.If the specified driver is not avaliable,this
 *      function will have no effect.
 *  $EXAMPLES$
 *      DBSETDRIVER("ADS")
 *  $STATUS$
 *      R
 *  $COMPLIANCE$
 *      This function is CA-Clipper compatible
 *  $SEEALSO$
 *      DBUSEAREA()
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *      DBSKIP()
 *  $CATEGORY$
 *      Data Base
 *  $ONELINER$
 *      Moves the record pointer in the selected work area.
 *  $SYNTAX$
 *      DBSKIP([<nRecords>]) --> NIL
 *  $ARGUMENTS$
 *      <nRecords> Numbers of records to move record pointer.
 *  $RETURNS$
 *      DBSKIP() always returns NIL.
 *  $DESCRIPTION$
 *      This function moves the record pointer <nRecords> in the selected or
 *      aliased work area.The default value for <nRecords> will be 1.
 *      A DBSKIP(0) will flush and refresh the internal database bufer and make
 *      any changes made to the record visible without moving the record pointer
 *      in either direction.
 *  $EXAMPLES$
 *      FUNCTION Main()
 *      USE Tests NEW
 *      DBGOTOP()
 *      WHILE !EOF()
 *        ? Tests->Id,Tests->Name
 *        DBSKIP()
 *      ENDDO
 *      USE
 *      RETURN NIL
 *  $STATUS$
 *      R
 *  $COMPLIANCE$
 *      This function is CA-CLIPPER compatible
 *  $SEEALSO$
 *    BOF(),DBGOBOTTOM(),DBGOTOP(),DBSEEK(),EOF()
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *      DBSETFILTER()
 *  $CATEGORY$
 *      Data Base
 *  $ONELINER$
 *      Establishes a filter condition for a work area.
 *  $SYNTAX$
 *      DBSETFILTER(<bCondition>, [<cCondition>]) --> NIL
 *  $ARGUMENTS$
 *      <bCondition> Code block expression for filtered evaluation.
 *      <cCondition> Optional character expression of code block.
 *  $RETURNS$
 *      DBSETFILTER() always returns NIL.
 *  $DESCRIPTION$
 *      This function masks a database so that only those records that meet the
 *      condition prescribed by the expression in the code block <bCondition>
 *      and literally expressed as <cCondition> are visible.
 *      If <cCondition> is not passed to this function,then the DBFILTER()
 *      function will return an empty string showing no filter in that work area
 *      which in fact,would be not correct.
 *  $EXAMPLES$
 *      FUNCTION Main()
 *      USE Tests NEW
 *      DBSETFILTER({|| Tests->Id <100},"Tests->Id <100")
 *      DBGOTOP()
 *
 *  $STATUS$
 *      R
 *  $COMPLIANCE$
 *      This function is CA-Clipper compliant.
 *  $SEEALSO$
 *      DBFILTER(),DBCLEARFILTER()
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *      DBSTRUCT()
 *  $CATEGORY$
 *      Data Base
 *  $ONELINER$
 *      Creates a multidimensional array of a database structure.
 *  $SYNTAX$
 *      DBSTRUCT() --> aStruct
 *  $RETURNS$
 *      DBSTRUCT() returns an array pointer to database structure
 *  $DESCRIPTION$
 *      This function returns a multidimensional array.This array has array
 *      pointers to other arrays,each of which contains the characteristic
 *      of a field in the active work area.The lenght of this array is based
 *      in the number of fields in that particular work area.In other words,
 *      LEN(DBSTRUCT()) is equal to the value obtained from FCOUNT().
 *      Each subscript position
 *  $EXAMPLES$
 *      FUNCTION Main()
 *      LOCAL aStru,x
 *      USE Tests NEW
 *      aStru:=DBSTRUCT()
 *      FOR x:=1 TO LEN(aStru)
 *        ? aStru[x,1]
 *      NEXT
 *      USE
 *      RETURN NIL
 *  $STATUS$
 *      R
 *  $COMPLIANCE$
 *      This function is CA-Clipper compliant
 *  $SEEALSO$
 *      AFIELDS()
 *  $INCLUDE$
 *      DbStruct.ch
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *      DBUNLOCK()
 *  $CATEGORY$
 *      Data Base
 *  $ONELINER$
 *      Unlock a record or release a file lock
 *  $SYNTAX$
 *      DBUNLOCK() --> NIL
 *  $RETURNS$
 *      DBUNLOCK() always returns NIL.
 *  $DESCRIPTION$
 *      This function releases the file or record lock in the currently selected
 *      or aliased work area.It will not unlock an associated lock in a related data-
 *      bases.
 *  $EXAMPLES$
 *      nId:=10
 *      USE TestId INDEX TestId NEW
 *      IF TestId->(DBSEEK(nId))
 *         IF TestId->(RLOCK())
 *            DBDELETE()
 *         ELSE
 *             DBUNLOCK()
 *         ENDIF
 *      ENDIF
 *      USE
 *  $STATUS$
 *      R
 *  $COMPLIANCE$
 *      This function is CA-Clipper compatible.
 *  $SEEALSO$
 *      DBUNLOCKALL(),FLOCK(),RLOCK()
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *      DBUNLOCKALL()
 *  $CATEGORY$
 *      Data Base
 *  $ONELINER$
 *      Unlocks all records and releases all file locks in all work areas.
 *  $SYNTAX$
 *      DBUNLOCKALL() --> NIL
 *  $RETURNS$
 *      DBUNLOCKALL() always returns NIL.
 *  $DESCRIPTION$
 *      This function will remove all file and record locks in all work area.
 *  $EXAMPLES$
 *      nId:=10
 *      USE Tests INDEX TestId NEW
 *      USE Tests1 INDEX Tests NEW
 *      IF TestId->(DBSEEK(nId))
 *         IF TestId->(RLOCK())
 *            DBDELETE()
 *         ELSE
 *            DBUNLOCK()
 *         ENDIF
 *      ELSE
 *         DBUNLOCKALL()
 *      ENDIF
 *      USE
 *  $STATUS$
 *      R
 *  $COMPLIANCE$
 *      This function is CA Clipper compliant
 *  $SEEALSO$
 *      DBUNLOCK(),FLOCK(),RLOCK()
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *      DBUSEAREA()
 *  $CATEGORY$
 *      Data Base
 *  $ONELINER$
 *      Opens a work area and uses a database file.
 *  $SYNTAX$
 *      DBUSEAREA( [<lNewArea>], [<cDriver>], <cName>, [<xcAlias>],
 *      [<lShared>], [<lReadonly>]) --> NIL
 *  $ARGUMENTS$
 *     <lNewArea>  A optional logical expression for the new work area
 *     <cDriver>   Database driver name
 *     <cName>     File Name
 *     <xcAlias>   Alias name
 *     <lShared>   Shared/exclusive status flag
 *     <lReadonly> Read-write status flag.
 *  $RETURNS$
 *      DBUSEAREA() always returns NIL.
 *  $DESCRIPTION$
 *      This function opens an existing database named <cName> in the current
 *      work area. If <lNewArea> is set to a logical true (.T.) value, then
 *      the database <cName> will be opened in the next available and unused
 *      work area. The default value of <lNewArea> is a logical false (.F.).
 *      If used, <cDriver> is the name of the database driver associated with
 *      the file <cName> that is opened. The default for this will be the value
 *      of DBSETDRlVER().
 *      IF used, <xcAlias> contains the alias name for that work area, If not
 *      specified, the root name of the database specified in <cName> will be
 *      used.
 *      If <lShared> is set to a logical true (.T.) value, the database that
 *      is specified in <cName> will be opened by the user EXCLUSIVELY. Thus
 *      locking it from all other nodes or users on the network. If <lShared> is
 *      set to a logical false (.F.) value, then the database will be in SHARED
 *      mode. If <lShared> is not passed, then the function will turn to the
 *      internal setting of SET EXCLUSIVE to determine a setting.
 *      If <lReadOnly> is specified, the file will be set to READ ONLY mode.
 *      If it is not specified, the file will he opened in normal read-write
 *      mode.
 *  $EXAMPLES$
 *      DBUSEAREA(.T.,,"Tests")
 *  $STATUS$
 *      R
 *  $COMPLIANCE$
 *      This function is CA-Clipper compliant
 *  $SEEALSO$
 *      DBCLOSEAREA(),DBSETDRIVER(),SELECT(),SET()
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *      __DBZAP()
 *  $CATEGORY$
 *      Data Base
 *  $ONELINER$
 *      Remove all records from the current database file
 *  $SYNTAX$
 *      __DbZap()  -> NIL
 *  $RETURNS$
 *      __DbZap()   will always return nil
 *  $DESCRIPTION$
 *      __DbZap( is a database command that permanently removes all records from
 *   files open in the current work area.  This includes the current database
 *   file, index files, and associated memo file.  Disk space previously
 *   occupied by the ZAPped files is released to the operating system.
 *   __DbZap() performs the same operation as DELETE ALL followed by PACK but is
 *   almost  instantaneous.
 *
 *   To ZAP in a network environment, the current database file must be USEd
 *   EXCLUSIVEly.
 *
 *  $EXAMPLES$
 *      This example demonstrates a typical ZAP operation in a network
 *      environment:
 *
 *      USE Sales EXCLUSIVE NEW
 *      IF !NETERR()
 *         SET INDEX TO Sales, Branch, Salesman
 *         __dbZAP()
 *         CLOSE Sales
 *      ELSE
 *         ? "Zap operation failed"
 *         BREAK
 *      ENDIF
 *  $STATUS$
 *      R
 *  $COMPLIANCE$
 *      This function is CA Clipper compliant
 *  $END$
 */

/*  $DOC$
 *  $COMMANDNAME$
 *      ZAP
 *  $CATEGORY$
 *      Command
 *  $ONELINER$
 *      Remove all records from the current database file
 *  $SYNTAX$
 *      ZAP
 *  $DESCRIPTION$
 *      This command removes all of the records from the database in the
 *      current work area.This operation also updates any index file in
 *      use at the time of this operation.In addition, this command removes
 *      all items within an associated memo file.
 *      In a network enviroment,any file that is about to be ZAPped must
 *      be used exclusively.
 *  $EXAMPLES$
 *      USE Tests NEW index Tests
 *      ZAP
 *      USE
 *  $STATUS$
 *      R
 *  $COMPLIANCE$
 *      This command is CA Clipper compliant
 *  $SEEALSO$
 *      DELETE,PACK,USE
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *      DELETED()
 *  $CATEGORY$
 *      Data Base
 *  $ONELINER$
 *      Tests the record's deletion flag.
 *  $SYNTAX$
 *      DELETED() --> lDeleted
 *  $RETURNS$
 *      DELETED() return a logical true (.T.) or false (.F.).
 *  $DESCRIPTION$
 *      This function returns a logical true (.T.) is the current record in the
 *      selected or designated work area ha ben marked for deletion.If not, the
 *      function will return a logical false (.F.).
 *  $EXAMPLES$
 *      FUNCTION Main()
 *      USE Test New
 *      DBGOTO()
 *      DBDELETE()
 *      ? "Is Record Deleted",Test->(DELETED())
 *      DBRECALL()
 *      USE
 *      RETURN NIL
 *  $STATUS$
 *      R
 *  $COMPLIANCE$
 *      This function is CA-Clipper compliant
 *  $SEEALSO$
 *      DBDELETE()
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *      EOF()
 *  $CATEGORY$
 *      DATA BASE
 *  $ONELINER$
 *      Test for end-of-file condition.
 *  $SYNTAX$
 *      EOF() --> <lEnd>
 *  $RETURNS$
 *      <lEnd> A logical true (.T.) or false (.F.)
 *  $DESCRIPTION$
 *      This function determines if the end-of-file marker has been reached.
 *      If it has, the function will return a logical true (.T.); otherwise
 *      a logical false (.F.) will be returnd
 *  $EXAMPLES$
 *      FUNCTION Main()
 *        USE Tests NEW
 *        DBGOTOP()
 *        ? "Is Eof()",EOF()
 *        DBGOBOTTOM()
 *        ? "Is Eof()",EOF()
 *        USE
 *     RETURN NIL
 *  $STATUS$
 *      R
 *  $COMPLIANCE$
 *      EOF() is fully CA-Clipper compliant.
 *  $SEEALSO$
 *    BOF(),FOUND(),LASTREC()
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *      FCOUNT()
 *  $CATEGORY$
 *      Data Base
 *  $ONELINER$
 *      Counts the number of fields in an active database.
 *  $SYNTAX$
 *      FCOUNT() --> nFields
 *  $RETURNS$
 *      <nFields> Return the number of fields
 *  $DESCRIPTION$
 *      This function returns the number of fields in the current or designated
 *      work area.If no database is open in this work area, the function will
 *      return 0.
 *  $EXAMPLES$
 *      FUNCTION Main()
 *        USE Tests NEW
 *        ? "This database have ",Tests->(FCOUNT()),"Fields"
 *        USE
 *      RETURN Nil
 *  $STATUS$
 *      R
 *  $COMPLIANCE$
 *      This function is CA-Clipper compliant
 *  $SEEALSO$
 *      FIELDNAME(),TYPE()
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *      FIELDGET()
 *  $CATEGORY$
 *      Data Base
 *  $ONELINER$
 *      Obtains the value  of a specified field
 *  $SYNTAX$
 *      FIELDGET(<nField>) --> ValueField
 *  $ARGUMENTS$
 *      <nField> Is the numeric field position
 *  $RETURNS$
 *      <ValueField>  Any expression
 *  $DESCRIPTION$
 *      This function returns the value of the field at the <nField>th location
 *      in the selected or designed work area.If the value in <nField> does not
 *      correspond to n avaliable field position in this work area, the function
 *      will return a NIL data type.
 *  $EXAMPLES$
 *      FUNCTION Main()
 *      USE Test NEW
 *      ? Test->(FieldGet(1))
 *      USE
 *      RETURN NIL
 *  $STATUS$
 *      R
 *  $COMPLIANCE$
 *      This function is CA-Clipper Compliant.
 *  $SEEALSO$
 *      FIELDPUT()
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *      FIELDNAME()
 *  $CATEGORY$
 *      Data Base
 *  $ONELINER$
 *      Return the name of a field at a numeric field location.
 *  $SYNTAX$
 *      FIELDNAME/FIELD(<nPosition>) --> cFieldName
 *  $ARGUMENTS$
 *      <nPosition> Field order in the database.
 *  $RETURNS$
 *      <cFieldName> returns the field name.
 *  $DESCRIPTION$
 *      This function return the name of the field at the <nPosition>th position.
 *      If the numeric value passed to this function does not correspond to an
 *      existing field in the designated or selected work area,this function
 *      will return a NULL byte.
 *  $EXAMPLES$
 *      FUNCTION Main()
 *        LOCAL x
 *        USE Tests NEW
 *        FOR x := 1 to Tests->(FCOUNT())
 *          ? "Field Name",FieldName(x)
 *        NEXT
 *        USE
 *      RETURN Nil
 *  $STATUS$
 *      R
 *  $COMPLIANCE$
 *      This function is CA-Clipper compatible.
 *  $SEEALSO$
 *    DBSTRUCT(),FCOUNT(),LEN(),VALTYPE()
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *      FIELDPOS()
 *  $CATEGORY$
 *      Data Base
 *  $ONELINER$
 *      Return the ordinal position of a field.
 *  $SYNTAX$
 *      FIELDPOS(<cFieldName>) --> nFieldPos
 *  $ARGUMENTS$
 *      <cFieldName> Name of a field.
 *  $RETURNS$
 *      <nFieldPos> is ordinal position of the field.
 *  $DESCRIPTION$
 *      This function return the ordinal position of the specified field <cField>
 *      in the current or aliased work areaIf there isn't  field under the name
 *      of <cField> or of no database is open in the selected work area, the func-
 *      tion will return a 0.
 *  $EXAMPLES$
 *      FUNCTION Main()
 *      USE Test NEW
 *      ? Test->(FIELDPOS("ID"))
 *      USE
 *      RETURN NIL
 *  $STATUS$
 *      R
 *  $COMPLIANCE$
 *      This function is CA-Clipper compliant.
 *  $SEEALSO$
 *      FIELDGET(),FIELDPUT()
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *      FIELDPUT()
 *  $CATEGORY$
 *      Data Base
 *  $ONELINER$
 *      Set the value of a field variable
 *  $SYNTAX$
 *      FIELDPUT(<nField>, <expAssign>) --> ValueAssigned
 *  $ARGUMENTS$
 *      <nField> The field numeric position
 *  
 *      <expAssign> Expression to be assigned to the specified field
 *  $RETURNS$
 *      <ValueAssigned> Any expression
 *  $DESCRIPTION$
 *      This function assings the value in <expAssing> to the <nField>th
 *      field in the current or designated work area.If the operation is
 *      successful,the return value of the function will be the same value
 *      assigned to the specified field.If the operation is not successful,
 *      the function will return a NIL data type
 *  $EXAMPLES$
 *      USE Tests New
 *      FIELDPUT(1,"Mr. Jones")
 *      USE
 *  $STATUS$
 *      R
 *  $COMPLIANCE$
 *      This function is CA-Clipper compatible.
 *  $SEEALSO$
 *      FIELDGET()
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *      FLOCK()
 *  $CATEGORY$
 *      Data Base
 *  $ONELINER$
 *      Locks a file
 *  $SYNTAX$
 *      FLOCK() --> lSuccess
 *  $RETURNS$
 *      <lSuccess> A true (.T.) value, if the lock was successful;otherwise
 *      false (.F.)
 *  $DESCRIPTION$
 *      This function returns a logical true (.T.0 if a file lock is
 *      attempted and is successfully placed on the current or designated
 *      database.This function will also unlock all records locks placed
 *      by the same network station.
 *  $EXAMPLES$
 *      USE Tests New
 *      IF FLOCK()
 *         SUM Tests->Ammount
 *      ENDIF
 *      USE
 *  $STATUS$
 *      R
 *  $COMPLIANCE$
 *      This function is CA-Clipper compatible
 *  $SEEALSO$
 *      RLOCK()
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *      FOUND()
 *  $CATEGORY$
 *      Data Base
 *  $ONELINER$
 *      Determine the success of a previous search operation.
 *  $SYNTAX$
 *      FOUND() --> lSuccess
 *  $ARGUMENTS$
 *
 *  $RETURNS$
 *      <lSuccess> A logical true (.T.) is successful;otherwise, false (.F.)
 *  $DESCRIPTION$
 *      This function is used to test if the previous SEEK,LOCATE,CONTINUE,
 *      or FIND operation was successful.Each wrk area has its own FOUND()
 *      flag,so that a FOUND() condition may be tested in unselected work
 *      areas by using an alias.
 *  $EXAMPLES$
 *      nId:=100
 *      USE Tests NEW INDEX Tests
 *      SEEK nId
 *      IF FOUND()
 *        ? Tests->Name
 *      ENDIF
 *      USE
 *  $STATUS$
 *      R
 *  $COMPLIANCE$
 *      This function is CA-Clipper compatible
 *  $SEEALSO$
 *      EOF()
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *      HEADER()
 *  $CATEGORY$
 *      Data Base
 *  $ONELINER$
 *      Return the length of a database file header 
 *  $SYNTAX$
 *      HEADER() --> nBytes
 *  $RETURNS$
 *      <nBytes> The numeric size of a database file header in bytes
 *  $DESCRIPTION$
 *      This function returns the number of bytes in the header of the
 *      selected database ot the database in the designated work area.
 *
 *      If used in conjunction with the LASTREC(),RECSIZE() and DISKSPACE()
 *      functions,this functions is capable of implementing a backup and
 *      restore routine.
 *  $EXAMPLES$
 *      USE Tests New
 *      ? Header()
 *  $STATUS$
 *      R
 *  $COMPLIANCE$
 *      This function is CA-Clipper compatible
 *  $SEEALSO$
 *      DISKSPACE(),LASTREC(),RECSIZE()
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *      INDEXORD()
 *  $CATEGORY$
 *      Data Base
 *  $ONELINER$
 *      Return the order position of the controlling index
 *  $SYNTAX$
 *      INDEXORD() --> nOrder
 *  $RETURNS$
 *     <nOrder>  an integer numeric value.  The value returned is
 *     equal to the position of the controlling index in the list of open
 *     indexes for the current work area.  A value of zero indicates that there
 *     is no controlling index and records are being accessed in natural order.
 *     If no database file is open, INDEXORD() will also return a zero.
 *  $DESCRIPTION$
 *     INDEXORD() is a database function that determines the position of the
 *     controlling index in the list of index files opened by the last
 *     USE...INDEX or SET INDEX TO in the current work area.  It is often
 *     useful to save the last controlling index so it can be restored later.
 *
 *     By default, INDEXORD() operates on the currently selected work area.  It
 *     will operate on an unselected work area if you specify it as part of an
 *     aliased expression (see example below).
 *  $EXAMPLES$
 *      This example uses INDEXORD() to save the current order.  After
 *      changing to a new order, it uses the saved value to restore the
 *      original order:
 *
 *      USE Customer INDEX Name, Serial NEW
 *      nOrder := INDEXORD()                  // Result: 1
 *      SET ORDER TO 2
 *      ? INDEXORD()                          // Result: 2
 *      SET ORDER TO nOrder
 *      ? INDEXORD()                          // Result: 1
 *
 *     This example uses an aliased expression to determine the order
 *      number of the controlling index in an unselected work area:
 *
 *      USE Sales INDEX Salesman, CustNum NEW
 *      USE Customer INDEX Name, Serial NEW
 *      ? Sales->(INDEXORD())                 // Result: 1
 *  $STATUS$
 *      S
 *  $COMPLIANCE$
 *      This function is CA Clipper compliant
 *  $SEEALSO$
 *      INDEXKEY()
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *      LASTREC()
 *  $CATEGORY$
 *      Data Base
 *  $ONELINER$
 *      Determine the number of records in the current (.dbf) file
 *  $SYNTAX$
 *      LASTREC() | RECCOUNT()* --> nRecords
 *  $RETURNS$
 *      <nRecords > the number of physical records in the current database
 *      file as an integer numeric value.  Filtering commands such as SET FILTER
 *      or SET DELETED have no effect on the return value.  LASTREC() returns
 *      zero if there is no database file in USE in the current work area.
 *  $DESCRIPTION$
 *      LASTREC() is a database function that determines the number of physical
 *      records in the current database file.  LASTREC() is identical to
 *      RECCOUNT() which is supplied as a compatibility function.
 *
 *      By default, LASTREC() operates on the currently selected work area.  It
 *      will operate on an unselected work area if you specify it as part of an
 *      aliased expression (see example below).
 *  $EXAMPLES$
 *      This example illustrates the relationship between LASTREC(),
 *      RECCOUNT(), and COUNT:
 *
 *      USE Sales NEW
 *      ? LASTREC(), RECCOUNT()          // Result: 84 84
 *      //
 *      SET FILTER TO Salesman = "1001"
 *      COUNT TO nRecords
 *      ? nRecords, LASTREC()            // Result: 14 84
 *
 *      This example uses an aliased expression to access the number
 *      of records in a open database file in an unselected work area:
 *
 *      USE Sales NEW
 *      USE Customer NEW
 *      ? LASTREC(), Sales->(LASTREC())
 *  $STATUS$
 *      R
 *  $COMPLIANCE$
 *      This function is CA Clipper compatible
 *  $SEEALSO$
 *      EOF()
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *      LUPDATE()
 *  $CATEGORY$
 *      Data Base
 *  $ONELINER$
 *      Return the last modification date of a (.dbf) file
 *  $SYNTAX$
 *      LUPDATE() --> dModification
 *  $ARGUMENTS$
 *
 *  $RETURNS$
 *      <dModification>  the date of last change to the open database file in
 *      the current work area.  If there is no database file in USE, LUPDATE()
 *      returns a blank date.
 *  $DESCRIPTION$
 *      LUPDATE() is a database function that determines the date the database
 *      file in the current work area was last modified and CLOSEd.  By default,
 *      LUPDATE() operates on the currently selected work area.  It will operate
 *      on an unselected work area if you specify it as part of an aliased
 *      expression as shown in the example below.
 *  $EXAMPLES$
 *      This example demonstrates that the modification date of
 *      database file is not changed until the database file is closed:
 *
 *      ? DATE()                  // Result: 09/01/90
 *      USE Sales NEW
 *      ? LUPDATE()               // Result: 08/31/90
 *      //
 *      APPEND BLANK
 *      ? LUPDATE()               // Result: 08/31/90
 *      CLOSE DATABASES
 *      //
 *      USE Sales NEW
 *      ? LUPDATE()               // Result: 09/01/90
 *
 *      This example uses an aliased expression to access LUPDATE()
 *      for a database file open in an unselected work area:
 *
 *      USE Sales NEW
 *      USE Customer NEW
 *      ? LUPDATE(), Sales->(LUPDATE())
 *  $STATUS$
 *      R
 *  $COMPLIANCE$
 *      This function is CA Clipper compliant
 *  $SEEALSO$
 *  FIELDNAME(),LASTREC(),RECSIZE()
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *      NETERR()
 *  $CATEGORY$
 *      Data Base
 *  $ONELINER$
 *      Determine if a network command has failed
 *  $SYNTAX$
 *      NETERR([<lNewError>]) --> lError
 *  $ARGUMENTS$
 *      <lNewError> if specified sets the value returned by NETERR() to the
 *      specified status.  <lNewError> can be either true (.T.) or false (.F.).
 *      Setting NETERR() to a specified value allows the runtime error handler
 *      to control the way certain file errors are handled.  For more
 *      information, refer to Errorsys.prg.
 *  $RETURNS$
 *      NETERR() returns true (.T.) if a USE or APPEND BLANK fails.  The initial
 *      value of NETERR() is false (.F.).  If the current process is not running
 *      under a network operating system, NETERR() always returns false (.F.).
 *  $DESCRIPTION$
 *      NETERR() is a network function.  It is a global flag set by USE,
 *      USE...EXCLUSIVE, and APPEND BLANK in a network environment.  It is used
 *      to test whether any of these commands have failed by returning true
 *      (.T.) in the following situations:
 *
 *      NETERR() Causes
 *      
 *      Command             Cause
 *      
 *      USE                 USE EXCLUSIVE by another process
 *      USE...EXCLUSIVE     USE EXCLUSIVE or USE by another process
 *      APPEND BLANK        FLOCK() or RLOCK() of LASTREC() + 1 by another user
 *      
 *
 *      NETERR() is generally applied in a program by testing it following a USE
 *      or APPEND BLANK command.  If it returns false (.F.), you can perform the
 *      next operation.  If the command is USE, you can open index files.  If it
 *      is APPEND BLANK, you can assign values to the new record with a REPLACE
 *      or @...GET command.  Otherwise, you must handle the error by either
 *      retrying the USE or APPEND BLANK, or terminating the current operation
 *      with a BREAK or RETURN.
 *  $EXAMPLES$
 *      This example demonstrates typical usage of NETERR().  If the
 *      USE succeeds, the index files are opened and processing continues.
 *      If the USE fails, a message displays and control returns to the
 *      nearest BEGIN SEQUENCE construct:
 *
 *      USE Customer SHARED NEW
 *      IF !NETERR()
 *         SET INDEX TO CustNum, CustOrders, CustZip
 *      ELSE
 *         ? "File is in use by another"
 *         BREAK
 *      ENDIF
 *  $STATUS$
 *      R
 *  $COMPLIANCE$
 *      This function is CA Clipper compliant
 *  $SEEALSO$
 *      FLOCK(),RLOCK()
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *      ORDBAGEXT()
 *  $CATEGORY$
 *      Data Base
 *  $ONELINER$
 *      Return the default Order Bag RDD extension
 *  $SYNTAX$
 *      ORDBAGEXT() --> cBagExt
 *  $RETURNS$
 *      <cBagExt> a character expression.
 *  $DESCRIPTION$
 *      ORDBAGEXT() is an Order management function that returns a character
 *      expression that is the default Order Bag extension of the current or
 *      aliased work area.  cBagExt is determined by the RDD active in the
 *      current work area.
 *
 *      ORDBAGEXT() supersedes the INDEXEXT() and is not recommended.
 *
 *  $EXAMPLES$
 *     USE sample VIA "DBFNTX"
 *     ? ORDBAGEXT()      //  Returns .ntx
 *
 *  $STATUS$
 *      S
 *  $COMPLIANCE$
 *      This function is CA Clipper compliant
 *  $SEEALSO$
 *      INDEXEXT(),ORDBAGNAME()
 *  $INCLUDE$
 *
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *      ORDBAGNAME()
 *  $CATEGORY$
 *      Data Base
 *  $ONELINER$
 *      Return the Order Bag name of a specific Order
 *  $SYNTAX$
 *      ORDBAGNAME(<nOrder> | <cOrderName>) --> cOrderBagName
 *  $ARGUMENTS$
 *     <nOrder> is an integer that identifies the position in the Order
 *   List of the target Order whose Order Bag name is sought.
 *
 *     <cOrderName> is a character string that represents the name of the
 *   target Order whose Order Bag name is sought.
 *
 *  $RETURNS$
 *     ORDBAGNAME() returns a character string, the Order Bag name of the
 *   specific Order.
 *  $DESCRIPTION$
 *     ORDBAGNAME() is an Order management function that lets you access the
 *   name of the Order Bag in which <cOrderName> resides.  You may identify
 *   the Order as a character string or with an integer that represents its
 *   position in the Order List.  In case of duplicate names, ORDBAGNAME()
 *   only recognizes the first matching name.
 *  $EXAMPLES$
 *     The following example uses ORDBAGNAME() with the default
 *      DBFNTX driver:
 *
 *      USE Customer VIA "DBFNTX" NEW
 *      SET INDEX TO CuAcct, CuName, CuZip
 *      ORDBAGNAME( 2 )               // Returns: CuName
 *      ORDBAGNAME( 1 )               // Returns: CuAcct
 *      ORDBAGNAME( 3 )               // Returns: CuZip
 *
 *
 *     In this example, Customer.cdx contains three orders named
 *      CuAcct, CuName, CuZip:
 *
 *      USE Customer VIA "DBFCDX" NEW
 *      SET INDEX TO Customer
 *      ORDBAGNAME( "CuAcct" )        // Returns: Customer
 *      ORDBAGNAME( "CuName" )        // Returns: Customer
 *      ORDBAGNAME( "CuZip" )         // Returns: Customer
 *  $TESTS$
 *
 *  $STATUS$
 *      S
 *  $COMPLIANCE$
 *
 *  $SEEALSO$
 *      ORDBAGEXT()
 *  $INCLUDE$
 *
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *      ORDCONDSET()
 *  $CATEGORY$
 *      Data Base
 *  $ONELINER$
 *      Set the Condition and scope for an order
 *  $SYNTAX$
 *      ORDCONSET([<cForCondition>],
 *        [<bForCondition>],
 *        [<lAll>],
 *        [<bWhileCondition>],
 *        [<bEval>],
 *        [<nInterval>],
 *        [<nStart>],
 *        [<nNext>],
 *        [<nRecord>],
 *        [<lRest>],
 *        [<lDescend>],
 *        [<lAdditive>],
 *        [<lCurrent>],
 *        [<lCustom>],
 *        [<lNoOptimize>])
 *  $ARGUMENTS$
 *      <cForCondition> is a string that specifies the FOR condition for the
 *   order.
 *     <bForCondition> is a code block that defines a FOR condition that
 *   each record within the scope must meet in order to be processed. If
 *   a record does not meet the specified condition,it is ignored and the
 *   next  record is processed.Duplicate keys values are not added to the
 *   index file when a FOR condition is Used.
 *  $RETURNS$
 *
 *  $DESCRIPTION$
 *
 *  $EXAMPLES$
 *
 *  $TESTS$
 *
 *  $STATUS$
 *      S
 *  $COMPLIANCE$
 *      ORDCONDSET() is CA-Clipper compliant
 *  $SEEALSO$
 *
 *  $INCLUDE$
 *
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *      ORDCREATE()
 *  $CATEGORY$
 *      Data Base
 *  $ONELINER$
 *      Create an Order in an Order Bag
 *  $SYNTAX$
 *     ORDCREATE(<cOrderBagName>,[<cOrderName>],    <cExpKey>,
 *      [<bExpKey>], [<lUnique>]) --> NIL
 *  $ARGUMENTS$
 *     <cOrderBagName> is the name of a disk file containing one or more
 *   Orders.  You may specify <cOrderBagName> as the filename with or without
 *   the pathname or extension.  If you do not include the extension as part
 *   of <cOrderBagName> HARBOUR uses the default extension of the current
 *   RDD.
 *
 *     <cOrderName> is the name of the Order to be created.
 *
 *     Note: Although both <cOrderBagName> and <cOrderName> are both
 *   optional, at least one of them must be specified.
 *
 *     <cExpKey> is an expression that returns the key value to place in
 *   the Order for each record in the current work area.  <cExpKey> can
 *   represent a character, date, logical, or numeric data type.  The maximum
 *   length of the index key expression is determined by the database driver.
 *
 *     <bExpKey> is a code block that evaluates to a key value that is
 *   placed in the Order for each record in the current work area.  If you do
 *   not supply <bExpKey>, it is macro-compiled from <cExpKey>.
 *
 *     <lUnique> is an optional logical value that specifies whether a
 *   unique Order is to be created.  If <lUnique> is omitted, the current
 *   global _SET_UNIQUE setting is used.
 *  $RETURNS$
 *      ORDCREATE() always returns NIL.
 *  $DESCRIPTION$
 *     ORDCREATE() is an Order management function that creates an Order in the
 *   current work area.  It works like DBCREATEINDEX() except that it lets
 *   you create Orders in RDDs that recognize multiple-Order Bags.
 *   ORDCREATE() supersedes the DBCREATEINDEX() function because of this
 *   capability, and is the preferred function.
 *
 *     The active RDD determines the Order capacity of an Order Bag.  The
 *   default  DBFNTX and the DBFNDX drivers only support single-Order Bags,
 *   while other RDDs may support multiple-Order Bags (e.g., the DBFCDX and
 *   DBFMDX drivers).
 *
 *     In RDDs that support production or structural indexes (e.g., DBFCDX,
 *   DBFMDX), if you specify a Tag but do not specify an Order Bag, the Tag is
 *   created and added to the index.  If no production or structural index
 *   exists, it will be created and the Tag will be added to it.  When using
 *   RDDs that support multiple Order Bags, you must explicitly SET ORDER (or
 *   ORDSETFOCUS()) to the desired controlling Order.  If you do not specify
 *   a controlling Order, the data file will be viewed in natural Order.
 *
 *     If <cOrderBagName> does not exist, it is created in accordance with the
 *   RDD in the current or specified work area.
 *
 *    If <cOrderBagName> exists and the RDD specifies that Order Bags can only
 *   contain a single Order, <cOrderBagName> is erased and the new Order is
 *   added to the Order List in the current or specified work area.
 *
 *     If <cOrderBagName> exists and the RDD specifies that Order Bags can
 *   contain multiple Tags, <cOrderName> is created if it does not already
 *   exist, otherwise <cOrderName> is replaced in <cOrderBagName> and the
 *   Order is added to the Order List in the current or specified work area.
 *  $EXAMPLES$
 *     The following example demonstrates ORDCREATE() with the DBFNDX
 *      driver:
 *
 *      USE Customer VIA "DBFNDX" NEW
 *      ORDCREATE( "CuAcct",, "Customer->Acct" )
 *
 *
 *     The following example demonstrates ORDCREATE() with the
 *      default DBFNTX driver:
 *
 *      USE Customer VIA "DBFNTX" NEW
 *      ORDCREATE( "CuAcct", "CuAcct", "Customer->Acct", ;
 *            {|| Customer->Acct } )
 *
 *     The following example demonstrates ORDCREATE() with the FoxPro
 *      driver, DBFCDX:
 *
 *      USE Customer VIA "DBFCDX" NEW
 *      ORDCREATE( "Customer", "CuAcct", "Customer->Acct" )
 *
 *     This example creates the Order "CuAcct" and adds it to the
 *      production index (Order Bag) "Customer".  The production index , will
 *      be created if it doesn't exist:
 *
 *      USE Customer VIA "DBFMDX" NEW
 *      ORDCREATE( , "CuAcct", "Customer->Acct" )
 *  $TESTS$
 *
 *  $STATUS$
 *      S
 *  $COMPLIANCE$
 *
 *  $SEEALSO$
 *      DBCREATEINDEX()
 *  $INCLUDE$
 *
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *      ORDDESTROY()
 *  $CATEGORY$
 *      Data Base
 *  $ONELINER$
 *      Remove a specified Order from an Order Bag
 *  $SYNTAX$
 *          ORDDESTROY(<cOrderName> [, <cOrderBagName> ]) --> NIL
 *  $ARGUMENTS$
 *     <cOrderName> is the name of the Order to be removed from the current
 *   or specified work area.
 *
 *     <cOrderBagName> is the name of a disk file containing one or more
 *   Orders.  You may specify <cOrderBagName> as the filename with or without
 *   the pathname or appropriate extension.  If you do not include the
 *   extension as part of <cOrderBagName> HARBOUR uses the default
 *   extension of the current RDD.
 *  $RETURNS$
 *      ORDDESTROY() always returns NIL.
 *  $DESCRIPTION$
 *     ORDDESTROY() is an Order management function that removes a specified
 *   Order from multiple-Order Bags.
 *
 *     The active RDD determines the Order capacity of an Order Bag.  The
 *   default DBFNTX and the DBFNDX drivers only support single-Order Bags,
 *   while other RDDs may support multiple-Order Bags (e.g., the DBFCDX and
 *   DBPX drivers).
 *
 *     Note:  RDD suppliers may define specific behaviors for this command.
 *
 *     Warning!  ORDDESTROY() is not supported for DBFNDX and DBFNTX.
 *  $EXAMPLES$
 *     This example demonstrates ORDDESTROY() with the FoxPro driver,
 *      DBFCDX:
 *
 *      USE Customer VIA "DBFCDX" NEW
 *      SET INDEX TO Customer, CustTemp
 *      ORDDESTROY( "CuAcct", "Customer" )
 *  $TESTS$
 *
 *  $STATUS$
 *      S
 *  $COMPLIANCE$
 *
 *  $SEEALSO$
 *      ORDCREATE()
 *  $INCLUDE$
 *
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *      ORDFOR()
 *  $CATEGORY$
 *      Data Base
 *  $ONELINER$
 *      Return the FOR expression of an Order
 *  $SYNTAX$
 *     ORDFOR(<cOrderName> | <nOrder>
 *      [, <cOrderBagName>]) --> cForExp
 *
 *  $ARGUMENTS$
 *     <cOrderName> is the name of the target Order, whose cForExp is
 *   sought.
 *
 *     <nOrder> is an integer that identifies the position in the Order
 *   List of the target Order whose cForExp is sought.
 *
 *     <cOrderBagName> is the name of an Order Bag containing one or more
 *   Orders.  You may specify <cOrderBagName> as the filename with or without
 *   the pathname or appropriate extension.  If you do not include the
 *   extension as part of <cOrderBagName> HARBOUR uses the default
 *   extension of the current RDD.
 *  $RETURNS$
 *     ORDFOR() returns a character expression, cForExp, that represents the
 *   FOR condition of the specified Order.  If the Order was not created
 *   using the FOR clause the return value will be an empty string ("").  If
 *   the database driver does not support the FOR condition, it may either
 *   return an empty string ("") or raise an "unsupported function" error,
 *   depending on the driver.
 *  $DESCRIPTION$
 *     ORDFOR() is an Order management function that returns the character
 *   string, cForExp, that represents the logical FOR condition of the Order,
 *   <cOrderName> or <nOrder>.
 *  $EXAMPLES$
 *     This example retrieves the FOR condition from an Order:
 *
 *      USE Customer NEW
 *      INDEX ON  Customer->Acct ;
 *         TO  Customer          ;
 *         FOR Customer->Acct > "AZZZZZ"
 *
 *      ORDFOR( "Customer" )      // Returns: Customer->Acct > "AZZZZZ"
 *  $TESTS$
 *
 *  $STATUS$
 *      S
 *  $COMPLIANCE$
 *
 *  $SEEALSO$
 *      ORDKEY(),ORDCREATE(),ORDNAME(),ORDNUMBER()
 *  $INCLUDE$
 *
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *      ORDKEY()
 *  $CATEGORY$
 *      Data Base
 *  $ONELINER$
 *      Return the key expression of an Order
 *  $SYNTAX$
 *     ORDKEY(<cOrderName> | <nOrder>
 *      [, <cOrderBagName>]) --> cExpKey
 *  $ARGUMENTS$
 *     <cOrderName> is the name of an Order, a logical ordering of a
 *   database.
 *
 *     <nOrder> is an integer that identifies the position in the Order
 *   List of the target Order whose cExpKey is sought.
 *
 *     <cOrderBagName> is the name of a disk file containing one or more
 *   Orders.  You may specify <cOrderBagName> as the filename with or without
 *   the pathname or appropriate extension.  If you do not include the
 *   extension as part of <cOrderBagName> HARBOUR uses the default
 *   extension of the current RDD.
 *  $RETURNS$
 *      Returns a character string, cExpKey.
 *  $DESCRIPTION$
 *     ORDKEY() is an Order management function that returns a character
 *   expression, cExpKey, that represents the key expression of the specified
 *   Order.
 *
 *     You may specify the Order by name or with a number that represents its
 *   position in the Order List.  Using the Order name is the preferred
 *   method.
 *
 *     The active RDD determines the Order capacity of an Order Bag.  The
 *   default DBFNTX and the DBFNDX drivers only support single-Order Bags,
 *   while other RDDs may support multiple-Order Bags (e.g., the DBFCDX and
 *   DBFMDX drivers).
 *  $EXAMPLES$
 *     This example retrieves the index expression from an Order:
 *
 *      USE Customer NEW
 *      INDEX ON  Customer->Acct  ;
 *         TO  Customer           ;
 *         FOR Customer->Acct > "AZZZZZ"
 *
 *      ORDKEY( "Customer" )      // Returns: Customer->Acct
 *  $TESTS$
 *
 *  $STATUS$
 *      S
 *  $COMPLIANCE$
 *
 *  $SEEALSO$
 *      ORDFOR(),ORDNAME(),ORDNUMBER()
 *  $INCLUDE$
 *
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *      ORDLISTADD()
 *  $CATEGORY$
 *      Data Base
 *  $ONELINER$
 *      Add Orders to the Order List
 *  $SYNTAX$
 *     ORDLISTADD(<cOrderBagName>
 *      [, <cOrderName>]) --> NIL
 *  $ARGUMENTS$
 *     <cOrderBagName> is the name of a disk file containing one or more
 *   Orders.  You may specify <cOrderBagName> as the filename with or without
 *   the pathname or appropriate extension.  If you do not include the
 *   extension as part of <cOrderBagName> HARBOUR uses the default
 *   extension of the current RDD.
 *
 *     <cOrderName> the name of the specific Order from the Order Bag to be
 *   added to the Order List of the current work area.  If you do not specify
 *   <cOrderName>, all orders in the Order Bag are added to the Order List of
 *   the current work area.
 *  $RETURNS$
 *      ORDLISTADD() always returns NIL.
 *  $DESCRIPTION$
 *     ORDLISTADD() is an Order management function that adds the contents of
 *   an Order Bag , or a single Order in an Order Bag, to the Order List.
 *   This function lets you extend the Order List without issuing a SET INDEX
 *   command that, first, clears all the active Orders from the Order List.
 *
 *     Any Orders already associated with the work area continue to be active.
 *   If the newly opened Order Bag contains the only Order associated with
 *   the work area, it becomes the controlling Order; otherwise, the
 *   controlling Order remains unchanged.
 *
 *     After the new Orders are opened, the work area is positioned to the
 *   first logical record in the controlling Order.
 *
 *     ORDLISTADD() is similar to the SET INDEX command or the INDEX clause of
 *   the USE command, except that it does not clear the Order List prior to
 *   adding the new order(s).
 *
 *     ORDLISTADD() supersedes the DBSETINDEX() function.
 *
 *     The active RDD determines the Order capacity of an Order Bag.  The
 *   default  DBFNTX and the DBFNDX drivers only support single-Order Bags,
 *   while other RDDs may support multiple-Order Bags (e.g., the DBFCDX and
 *   DBPX drivers).  When using RDDs that support multiple Order Bags, you
 *   must explicitly SET ORDER (or ORDSETFOCUS()) to the desired controlling
 *   Order.  If you do not specify a controlling Order, the data file will be
 *   viewed in natural Order.
 *  $EXAMPLES$
 *     In this example Customer.cdx contains three orders, CuAcct,
 *      CuName, and CuZip.  ORDLISTADD() opens Customer.cdx but only uses the
 *      order named CuAcct:
 *
 *      USE Customer VIA "DBFCDX" NEW
 *      ORDLISTADD( "Customer", "CuAcct" )
 *  $TESTS$
 *
 *  $STATUS$
 *      S
 *  $COMPLIANCE$
 *
 *  $SEEALSO$
 *      DBSETINDEX()
 *  $INCLUDE$
 *
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *      ORDLISTCLEAR()
 *  $CATEGORY$
 *      Data Base
 *  $ONELINER$
 *      Clear the current Order List
 *  $SYNTAX$
 *      ORDLISTCLEAR() --> NIL
 *  $ARGUMENTS$
 *
 *  $RETURNS$
 *      ORDLISTCLEAR() always returns NIL.
 *  $DESCRIPTION$
 *     ORDLISTCLEAR() is an Order management function that removes all Orders
 *   from the Order List for the current or aliased work area.  When you are
 *   done, the Order List is empty.
 *
 *    This function supersedes the function DBCLEARINDEX().
 *
 *  $EXAMPLES$
 *   USE Sales NEW
 *   SET INDEX TO SaRegion, SaRep, SaCode
 *   .
 *   . < statements >
 *   .
 *   ORDLISTCLEAR()      // Closes all the current indexes
 *  $TESTS$
 *
 *  $STATUS$
 *      S
 *  $COMPLIANCE$
 *
 *  $SEEALSO$
 *    DBCLEARINDEX()
 *  $INCLUDE$
 *
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *      ORDLISTREBUILD()
 *  $CATEGORY$
 *      Data Base
 *  $ONELINER$
 *      Rebuild all Orders in the Order List of the current work area
 *  $SYNTAX$
 *      ORDLISTREBUILD() --> NIL
 *  $ARGUMENTS$
 *
 *  $RETURNS$
 *      ORDLISTREBUILD() always returns NIL.
 *  $DESCRIPTION$
 *     ORDLISTREBUILD() is an Order management function that rebuilds all the
 *   orders in the current or aliased Order List.
 *
 *     To only rebuild a single Order use the function ORDCREATE().
 *
 *     Unlike ORDCREATE(), this function rebuilds all Orders in the Order List.
 *   It is equivalent to REINDEX.
 *
 *  $EXAMPLES$
 *   USE Customer NEW
 *   SET INDEX TO CuAcct, CuName, CuZip
 *   ORDLISTREBUILD()     // Causes CuAcct, CuName, CuZip to
 *                        // be rebuilt
 *
 *  $TESTS$
 *
 *  $STATUS$
 *      S
 *  $COMPLIANCE$
 *
 *  $SEEALSO$
 *      ORDCREATE()
 *  $INCLUDE$
 *
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *      ORDNAME()
 *  $CATEGORY$
 *      Data Base
 *  $ONELINER$
 *      Return the name of an Order in the Order List
 *  $SYNTAX$
 *      ORDNAME(<nOrder>[,<cOrderBagName>])
 *      --> cOrderName
 *  $ARGUMENTS$
 *     <nOrder> is an integer that identifies the position in the Order
 *   List of the target Order whose database name is sought.
 *
 *     <cOrderBagName> is the name of a disk file containing one or more
 *   Orders.  You may specify <cOrderBagName> as the filename with or without
 *   the pathname or appropriate extension.  If you do not include the
 *   extension as part of <xcOrderBagName> HARBOUR uses the default
 *   extension of the current RDD.
 *  $RETURNS$
 *     ORDNAME() returns the name of the specified Order in the current Order
 *   List or the specified Order Bag if opened in the Current Order list.
 *  $DESCRIPTION$
 *     ORDNAME() is an Order management function that returns the name of the
 *   specified Order in the current Order List.
 *
 *     If <cOrderBagName> is an Order Bag that has been emptied into the
 *   current Order List, only those Orders in the Order List that correspond
 *   to <cOrderBagName> Order Bag are searched.
 *
 *     The active RDD determines the Order capacity of an Order Bag.  The
 *   default DBFNTX and the DBFNDX drivers only support single-Order Bags,
 *   while other RDDs may support multiple-Order Bags (e.g., the DBFCDX and
 *   DBPX drivers).
 *  $EXAMPLES$
 *     This example retrieves the name of an Order using its position
 *      in the order list:
 *
 *      USE Customer NEW
 *      SET INDEX TO CuAcct, CuName, CuZip
 *      ORDNAME( 2 )                        // Returns: CuName
 *
 *     This example retrieves the name of an Order given its position
 *      within a specific Order Bag in the Order List:
 *
 *      USE Customer NEW
 *      SET INDEX TO Temp, Customer
 *      // Assume Customer contains CuAcct, CuName, CuZip
 *      ORDNAME( 2, "Customer" )            // Returns: CuName
 *  $TESTS$
 *
 *  $STATUS$
 *      S
 *  $COMPLIANCE$
 *
 *  $SEEALSO$
 *      ORDFOR(),ORDKEY(),ORDNUMBER()
 *  $INCLUDE$
 *
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *      ORDNUMBER()
 *  $CATEGORY$
 *      Data Base
 *  $ONELINER$
 *      Return the position of an Order in the current Order List
 *  $SYNTAX$
 *     ORDNUMBER(<cOrderName>
 *      [, <cOrderBagName>]) --> nOrderNo
 *  $ARGUMENTS$
 *     <cOrderName> the name of the specific Order whose position in the
 *   Order List is sought.
 *
 *     <cOrderBagName> is the name of a disk file containing one or more
 *   Orders.  You may specify <cOrderBagName> as the filename with or without
 *   the pathname or appropriate extension.  If you do not include the
 *   extension as part of <cOrderBagName> HARBOUR uses the default
 *   extension of the current RDD.
 *  $RETURNS$
 *     Returns nOrderNo, an integer that represents the position of the
 *   specified Order in the Order List.
 *  $DESCRIPTION$
 *     ORDNUMBER() is an Order management function that lets you determine the
 *   position in the current Order List of the specified Order.  ORDNUMBER()
 *   searches the Order List in the current work area and returns the
 *   position of the first Order that matches <cOrderName>.    If
 *   <cOrderBagName> is the name of an Order Bag newly emptied into the
 *   current Order List, only those orders in the Order List that have been
 *   emptied from <cOrderBagName> are searched.
 *
 *     If <cOrderName> is not found ORDNUMBER() raises a recoverable runtime
 *   error.
 *
 *     The active RDD determines the Order capacity of an Order Bag.  The
 *   default DBFNTX driver only supports single-Order Bags, while other RDDs
 *   may support multiple-Order Bags (e.g., the DBFCDX and DBPX drivers).
 *  $EXAMPLES$
 *   USE Customer VIA "DBFNTX" NEW
 *   SET INDEX TO CuAcct, CuName, CuZip
 *   ORDNUMBER( "CuName" )            // Returns: 2
 *  $TESTS$
 *
 *  $STATUS$
 *      S
 *  $COMPLIANCE$
 *
 *  $SEEALSO$
 *      INDEXORD()
 *  $INCLUDE$
 *
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *      ORDSETFOCUS()
 *  $CATEGORY$
 *      Data Base
 *  $ONELINER$
 *      Set focus to an Order in an Order List
 *  $SYNTAX$
 *     ORDSETFOCUS([<cOrderName> | <nOrder>]
 *      [,<cOrderBagName>]) --> cPrevOrderNameInFocus
 *
 *  $ARGUMENTS$
 *     <cOrderName> is the name of the selected Order, a logical ordering
 *   of a database.  ORDSETFOCUS() ignores any invalid values of
 *   <cOrderName>.
 *
 *     <nOrder> is a number representing the position in the Order List of
 *   the selected Order.
 *
 *     <cOrderBagName> is the name of a disk file containing one or more
 *   Orders.  You may specify <cOrderBagName> as the filename with or without
 *   the pathname or appropriate extension.  If you do not include the
 *   extension as part of <cOrderBagName> HARBOUR uses the default
 *   extension of the current RDD.
 *  $RETURNS$
 *      ORDSETFOCUS() returns the Order Name of the previous controlling Order.
 *  $DESCRIPTION$
 *     ORDSETFOCUS() is an Order management function that returns the Order
 *   Name of the previous controlling Order and optionally sets the focus to
 *   an new Order.
 *
 *     If you do not specify <cOrderName> or <nOrder>, the name of the
 *   currently controlling order is returned and the controlling order
 *   remains unchanged.
 *
 *     All Orders in an Order List are properly updated no matter what
 *   <cOrderName> is the controlling Order.  After a change of controlling
 *   Orders, the record pointer still points to the same record.
 *
 *     The active RDD determines the Order capacity of an Order Bag.  The
 *   default DBFNTX driver only supports single-Order Bags, while other RDDs
 *   may support multiple-Order Bags (e.g., the DBFCDX and DBPX drivers).
 *
 *     ORDSETFOCUS() supersedes INDEXORD().
 *  $EXAMPLES$
 *
 *   USE Customer VIA "DBFNTX" NEW
 *   SET INDEX TO CuAcct, CuName, CuZip
 *   ? ORDSETFOCUS( "CuName" )        // Displays: "CuAcct"
 *   ? ORDSETFOCUS()                  // Displays: "CuName"
 *  $TESTS$
 *
 *  $STATUS$
 *      S
 *  $COMPLIANCE$
 *
 *  $SEEALSO$
 *
 *  $INCLUDE$
 *
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *      RDDLIST()
 *  $CATEGORY$
 *      Data Base
 *  $ONELINER$
 *      Return an array of the available Replaceable Database Drivers
 *  $SYNTAX$
 *      RDDLIST([<nRDDType>]) --> aRDDList
 *  $ARGUMENTS$
 *     <nRDDType> is an integer that represents the type of the RDD you
 *   wish to list.  The constants RDT_FULL and RDT_TRANSFER represent the two
 *   types of RDDs currently available.
 *
 *   RDDType Summary
 *   
 *   Constant       Value     Meaning
 *   
 *   RDT_FULL       1         Full RDD implementation
 *   RDT_TRANSFER   2         Import/Export only driver
 *   
 *
 *     RDT_FULL identifies full-featured RDDs that have all the capabilities
 *   associated with an RDD.
 *
 *     RDT_TRANSFER identifies RDDs of limited capability.  They can only
 *   transfer records between files.  You cannot use these limited RDD
 *   drivers to open a file in a work area.  The SDF and DELIM drivers are
 *   examples of this type of RDD.  They are only used in the implementation
 *   of APPEND FROM and COPY TO with SDF or DELIMITED files.
 *  $RETURNS$
 *     RDDLIST() returns a one-dimensional array of the RDD names registered
 *   with the application as <nRDDType>.
 *  $DESCRIPTION$
 *     RDDLIST() is an RDD function that returns a one-dimensional array that
 *   lists the available RDDs.
 *
 *     If you do not supply <nRDDType>, all available RDDs, regardless of type,
 *   are returned.
 *  $EXAMPLES$
 *     In this example RDDLIST() returns an array containing the
 *      character strings, "DBF", "SDF", "DELIM", "DBFCDX", and "DBFNTX":
 *
 *      REQUEST DBFCDX
 *
 *      .
 *      . < statements >
 *      .
 *
 *      aRDDs := RDDLIST()
 *
 *            // Returns {"DBF", SDF", "DELIM", "DBFCDX", "DBFNTX" }
 *
 *     In this example, RDDLIST() returns an array containing the
 *      character strings, "SDF" and "DELIM":
 *
 *      #include "rddsys.ch"
 *      .
 *      . < statements >
 *      .
 *      aImpExp := RDDLIST( RDT TRANSFER )
 *
 *  $TESTS$
 *
 *  $STATUS$
 *      R
 *  $COMPLIANCE$
 *
 *  $SEEALSO$
 *
 *  $INCLUDE$
 *      RDDSYS.CH
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *      RDDNAME()
 *  $CATEGORY$
 *      Data Base
 *  $ONELINER$
 *      Return the name of the currently active RDD
 *  $SYNTAX$
 *      RDDNAME() --> cRDDName
 *  $ARGUMENTS$
 *
 *  $RETURNS$
 *      Returns a character string, cRDDName, the registered name of the active
 *   RDD in the current or specified work area.
 *  $DESCRIPTION$
 *      RDDNAME() is an RDD function that returns a character string, cRDDName,
 *   the name of the active RDD in the current or specified work area.
 *
 *      You can specify a work area other than the currently active work area by
 *   aliasing the function.
 *  $EXAMPLES$
 *   USE Customer VIA "DBFNTX" NEW
 *   USE Sales    VIA "DBFCDX" NEW
 *
 *   ? RDDNAME()                          // Returns: DBFCDX
 *   ? Customer->( RDDNAME() )            // Returns: DBFNTX
 *   ? Sales->( RDDNAME() )               // Returns: DBFCDX
 *  $TESTS$
 *
 *  $STATUS$
 *      R
 *  $COMPLIANCE$
 *
 *  $SEEALSO$
 *      RDDLIST()
 *  $INCLUDE$
 *
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *      RDDSETDEFAULT()
 *  $CATEGORY$
 *      Data Base
 *  $ONELINER$
 *      Set or return the default RDD for the application
 *  $SYNTAX$
 *      RDDSETDEFAULT([<cNewDefaultRDD>])
 *      --> cPreviousDefaultRDD
 *
 *  $ARGUMENTS$
 *      <cNewDefaultRDD> is a character string, the name of the RDD that is
 *   to be made the new default RDD in the application.
 *  $RETURNS$
 *      RDDSETDEFAULT() returns a character string, cPreviousDefaultRDD, the
 *   name of the previous default driver.  The default driver is the driver
 *   that HARBOUR uses if you do not explicitly specify an RDD with the
 *   VIA clause of the USE command.
 *  $DESCRIPTION$
 *      RDDSETDEFAULT() is an RDD function that sets or returns the name of the
 *   previous default RDD driver and, optionally, sets the current driver to
 *   the new RDD driver specified by cNewDefaultRDD.  If <cNewDefaultDriver>
 *   is not specified, the current default driver name is returned and
 *   continues to be the current default driver.
 *
 *    This function replaces the DBSETDRIVER() function.
 *  $EXAMPLES$
 *   // If the default driver is not DBFNTX, make it the default
 *
 *   IF ( RDDSETDEFAULT() != "DBFNTX" )
 *      cOldRdd := RDDSETDEFAULT( "DBFNTX" )
 *   ENDIF
 *  $TESTS$
 *
 *  $STATUS$
 *      R
 *  $COMPLIANCE$
 *
 *  $SEEALSO$
 *      DBSETDRIVER()
 *  $INCLUDE$
 *
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *      RECCOUNT()
 *  $CATEGORY$
 *      Data Base
 *  $ONELINER$
 *      Determine the number of records in the current (.dbf) file
 *  $SYNTAX$
 *      RECCOUNT()* | LASTREC() --> nRecords
 *  $ARGUMENTS$
 *
 *  $RETURNS$
 *     RECCOUNT() returns the number of physical records in the current
 *   database file as an integer numeric value.  Filtering commands such as
 *   SET FILTER or SET DELETED have no effect on the return value.
 *   RECCOUNT() returns zero if there is no database file open in the current
 *   work area.
 *
 *  $DESCRIPTION$*
 *     RECCOUNT() is a database function that is a synonym for LASTREC().  By
 *   default, RECCOUNT() operates on the currently selected work area.  It
 *   will operate on an unselected work area if you specify it as part of an
 *   aliased expression (see example below).
 *  $EXAMPLES$
 *     This example illustrates the relationship between COUNT and
 *      RECCOUNT():
 *
 *      USE Sales NEW
 *      ? RECCOUNT()                      // Result: 84
 *      //
 *      SET FILTER TO Salesman = "1001"
 *      COUNT TO nRecords
 *      ? nRecords                        // Result: 14
 *      ? RECCOUNT()                      // Result: 84
 *
 *     This example uses an aliased expression to access the number
 *      of records in an unselected work area:
 *
 *      USE Sales NEW
 *      USE Customer NEW
 *      ? RECCOUNT(), Sales->(RECCOUNT())
 *  $TESTS$
 *
 *  $STATUS$
 *      R
 *  $COMPLIANCE$
 *
 *  $SEEALSO$
 *      EOF(),LASTREC()
 *  $INCLUDE$
 *
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *      RECNO()
 *  $CATEGORY$
 *      Data Base
 *  $ONELINER$
 *      Return the identity at the position of the record pointer
 *  $SYNTAX$
 *      RECNO() --> Identity
 *  $ARGUMENTS$
 *
 *  $RETURNS$
 *     RECNO() returns the identity found at the position of the record
 *   pointer.
 *  $DESCRIPTION$
 *     RECNO() is a database function that returns the identity found at the
 *   current position of the record pointer.  Identity is a unique value
 *   guaranteed by the structure of the data file to reference a specific
 *   record of data file.  The data file need not be a traditional Xbase
 *   file.  Therefore, unlike earlier versions of HARBOUR, the value
 *   returned need not be a numeric data type.
 *
 *     Under all RDDs, RECNO() returns the value at the position of the record
 *   pointer; the data type and other characteristics of this value are
 *   determined by the content of the accessed data and the RDD active in the
 *   current work area.  In an Xbase database this value is the record
 *   number.
 *  $EXAMPLES$
 *   USE Sales VIA "DBFNTX"
 *   .
 *   . < statements >
 *   .
 *   DBGOTOP()
 *   RECNO()            // Returns 1
 *  $TESTS$
 *
 *  $STATUS$
 *      R
 *  $COMPLIANCE$
 *
 *  $SEEALSO$
 *      DBGOTO()
 *  $INCLUDE$
 *
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *      RECSIZE()
 *  $CATEGORY$
 *      Data Base
 *  $ONELINER$
 *      Determine the record length of a database (.dbf) file
 *  $SYNTAX$
 *      RECSIZE() --> nBytes
 *  $ARGUMENTS$
 *
 *  $RETURNS$
 *     RECSIZE() returns, as a numeric value, the record length, in bytes, of
 *   the database file open in the current work area.  RECSIZE() returns zero
 *   if no database file is open.
 *  $DESCRIPTION$
 *     RECSIZE() is a database function that determines the length of a record
 *   by summing the lengths of each field then adding one for the DELETED()
 *   status flag.  When this value is multiplied by LASTREC(), the product is
 *   the amount of space occupied by the file's records.
 *
 *     RECSIZE() is useful in programs that perform automatic file backup.
 *   When used in conjunction with DISKSPACE(), the RECSIZE() function can
 *   assist in ensuring that sufficient free space exists on the disk before a
 *   file is stored.
 *
 *     By default, RECSIZE() operates on the currently selected work area.  It
 *   will operate on an unselected work area if you specify it as part of an
 *   aliased expression (see example below).
 *  $EXAMPLES$
 *     The following user-defined function, DbfSize(), uses RECSIZE()
 *      to calculate the size of the current database file:
 *
 *      FUNCTION DbfSize
 *         RETURN ((RECSIZE() * LASTREC()) + HEADER() + 1)
 *
 *     This example illustrates the use of RECSIZE() to determine the
 *      record length of database files open in unselected work areas:
 *
 *      USE Customer NEW
 *      USE Sales NEW
 *      //
 *      ? RECSIZE(), Customer->(RECSIZE())
 *      ? DbfSize(), Customer->(DbfSize())
 *  $TESTS$
 *
 *  $STATUS$
 *      R
 *  $COMPLIANCE$
 *
 *  $SEEALSO$
 *  DISKSPACE(),FIELDNAME(),HEADER(),LASTREC()
 *  $INCLUDE$
 *
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *      RLOCK()
 *  $CATEGORY$
 *      Data Base
 *  $ONELINER$
 *      Lock the current record in the active work area
 *  $SYNTAX$
 *      RLOCK() --> lSuccess
 *  $ARGUMENTS$
 *
 *  $RETURNS$
 *     RLOCK() returns true (.T.) if the record lock is obtained; otherwise, it
 *   returns false (.F.).
 *  $DESCRIPTION$
 *     RLOCK() is a network function that locks the current record, preventing
 *      other users from updating the record until the lock is released.
 *      RLOCK() provides a shared lock, allowing other users read-only access to
 *      the locked record while allowing only the current user to modify it.  A
 *      record lock remains until another record is locked, an UNLOCK is
 *      executed, the current database file is closed, or an FLOCK() is obtained
 *      on the current database file.
 *
 *      For each invocation of RLOCK(), there is one attempt to lock the current
 *      record, and the result is returned as a logical value.  An attempt to
 *      obtain a record lock fails if another user currently has a file or
 *      record lock, or EXCLUSIVE USE of the database file.  An attempt to
 *      RLOCK() in an empty database returns true (.T.).
 *
 *      By default, RLOCK() operates on the currently selected work area.  It
 *      will operate on an unselected work area if you specify it as part of an
 *      aliased expression (see example below).  This feature is useful since
 *      RLOCK() does not automatically attempt a record lock for related files.
 *
 *      As a general rule, RLOCK() operates solely on the current record.  This
 *      includes the following commands:
 *
 *      @...GET
 *
 *      DELETE (single record)
 *
 *      RECALL (single record)
 *
 *      REPLACE (single record)
 *
 *
 *      Notes
 *
 *      SET RELATION: HARBOUR does not automatically lock all
 *      records in the relation chain when you lock the current work area
 *      record.  Also, an UNLOCK has no effect on related work areas.
 *  $EXAMPLES$
 *     This example deletes a record in a network environment, using
 *      RLOCK():
 *
 *      USE Customer INDEX CustName SHARED NEW
 *      SEEK "Smith"
 *      IF FOUND()
 *         IF RLOCK()
 *            DELETE
 *            ? "Smith deleted"
 *         ELSE
 *            ? "Record in use by another"
 *         ENDIF
 *      ELSE
 *         ? "Smith not in Customer file"
 *      ENDIF
 *      CLOSE
 *
 *      This example specifies RLOCK() as an aliased expression to
 *      lock a record in an unselected work area:
 *
 *      USE Sales SHARED NEW
 *      USE Customer SHARED NEW
 *      //
 *      IF !Sales->(RLOCK())
 *         ? "The current Sales record is in use by another"
 *      ENDIF
 *  $TESTS$
 *
 *  $STATUS$
 *      R
 *  $COMPLIANCE$
 *
 *  $SEEALSO$
 *      FLOCK()
 *  $INCLUDE$
 *
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *      SELECT()
 *  $CATEGORY$
 *      Data Base
 *  $ONELINER$
 *      Determine the work area number of a specified alias
 *  $SYNTAX$
 *      SELECT([<cAlias>]) --> nWorkArea
 *  $ARGUMENTS$
 *      <cAlias> is the target work area alias name.
 *  $RETURNS$
 *      SELECT() returns the work area of the specified alias as a integer
 *      numeric value.
 *  $DESCRIPTION$
 *      SELECT() is a database function that determines the work area number of
 *      an alias.  The number returned can range from zero to 250.  If <cAlias>
 *      is not specified, the current work area number is returned.  If <cAlias>
 *      is specified and the alias does not exist, SELECT() returns zero.
 *
 *      Note:  The SELECT() function and SELECT command specified with an
 *      extended expression argument look somewhat alike.  This shouldn't be a
 *      problem since the SELECT() function is not very useful on a line by
 *      itself
 *  $EXAMPLES$
 *     This example uses SELECT() to determine which work area
 *      USE...NEW selected:
 *
 *      USE Sales NEW
 *      SELECT 1
 *      ? SELECT("Sales")          // Result: 4
 *
 *      To reselect the value returned from the SELECT() function, use
 *      the SELECT command with the syntax, SELECT (<idMemvar>), like this:
 *
 *      USE Sales NEW
 *      nWorkArea:= SELECT()
 *      USE Customer NEW
 *      SELECT (nWorkArea)
 *  $TESTS$
 *
 *  $STATUS$
 *      R
 *  $COMPLIANCE$
 *
 *  $SEEALSO$
 *      ALIAS(),USED()
 *  $INCLUDE$
 *
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *      USED()
 *  $CATEGORY$
 *      Data Base
 *  $ONELINER$
 *      Determine whether a database file is in USE
 *  $SYNTAX$
 *      USED() --> lDbfOpen
 *  $ARGUMENTS$
 *
 *  $RETURNS$
 *      USED() returns true (.T.) if there is a database file in USE; otherwise,
 *      it returns false (.F.).
 *  $DESCRIPTION$
 *      USED() is a database function that determines whether there is a
 *      database file in USE in a particular work area.  By default, USED()
 *      operates on the currently selected work area.  It will operate on an
 *      unselected work area if you specify it as part of an aliased expression.
 *  $EXAMPLES$
 *      This example determines whether a database file is in USE in
 *      the current work area:
 *
 *      USE Customer NEW
 *      ? USED()              // Result: .T.
 *      CLOSE
 *      ? USED()              // Result: .F.
 *  $TESTS$
 *
 *  $STATUS$
 *      R
 *  $COMPLIANCE$
 *
 *  $SEEALSO$
 *      ALIAS(),SELECT()
 *  $INCLUDE$
 *
 *  $END$
 */

/*  $DOC$
 *  $FUNCNAME$
 *      __RDDSETDEFAULT()
 *  $CATEGORY$
 *      Data Base
 *  $ONELINER$
 *      Set or return the default RDD for the application
 *  $SYNTAX$
 *      __RDDSETDEFAULT([<cNewDefaultRDD>])
 *      --> cPreviousDefaultRDD
 *
 *  $ARGUMENTS$
 *      <cNewDefaultRDD> is a character string, the name of the RDD that is
 *      to be made the new default RDD in the application.
 *  $RETURNS$
 *      __RDDSETDEFAULT() returns a character string, cPreviousDefaultRDD, the
 *      name of the previous default driver.  The default driver is the driver
 *      that HARBOUR uses if you do not explicitly specify an RDD with the
 *      VIA clause of the USE command.
 *  $DESCRIPTION$
 *      RDDSETDEFAULT() is an RDD function that sets or returns the name of the
 *      previous default RDD driver and, optionally, sets the current driver to
 *      the new RDD driver specified by cNewDefaultRDD.  If <cNewDefaultDriver>
 *      is not specified, the current default driver name is returned and
 *      continues to be the current default driver.
 *
 *      This function replaces the DBSETDRIVER() function.
 *  $EXAMPLES$
 *      // If the default driver is not DBFNTX, make it the default
 *
 *      IF ( __RDDSETDEFAULT() != "DBFNTX" )
 *           cOldRdd := __RDDSETDEFAULT( "DBFNTX" )
 *      ENDIF
 *  $TESTS$
 *
 *  $STATUS$
 *      R
 *  $COMPLIANCE$
 *
 *  $SEEALSO$
 *      DBSETDRIVER()
 *  $INCLUDE$
 *
 *  $END$
 */
