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

/* $DOC$
   $TEMPLATE$
      Function
   $NAME$
      dbEval()
   $CATEGORY$
      API
   $SUBCATEGORY$
      Execute and Execution
   $ONELINER$
      Performs a code block operation on the current Database
   $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 Database
   $EXAMPLES$
      PROCEDURE Main()
         LOCAL nCount

         USE test

         dbGoto( 4 )
         ? RecNo()
         COUNT TO nCount
         ? RecNo(), nCount
         COUNT TO nCount NEXT 10
         ? RecNo(), nCount

         RETURN
   $STATUS$
      S
   $COMPLIANCE$
      C
   $FILES$
      Library is rdd
   $SEEALSO$
      Eval()
   $END$
 */

/* $DOC$
   $TEMPLATE$
      Function
   $NAME$
      Dbf()
   $CATEGORY$
      API
   $SUBCATEGORY$
      Database
   $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$
      PROCEDURE Main()

         USE test
         SELECT 0
         ? iif( Dbf() == "", "No Name", Dbf() )
         ? test->( Dbf() )
         ? Alias( 1 )

         RETURN
   $STATUS$
      R
   $COMPLIANCE$
      C
   $FILES$
      Library is rdd
   $SEEALSO$
      Alias()
   $END$
 */

/* $DOC$
   $TEMPLATE$
      Function
   $NAME$
      dbAppend()
   $CATEGORY$
      API
   $SUBCATEGORY$
      Database
   $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 hb_SToD(),
      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 additional
      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$
      PROCEDURE Main()
         LOCAL cName := "Harbour", nId := 10
         USE test
         test->( dbAppend() )
         REPLACE test->Name WITH cName, test->Id WITH nId
         USE
         RETURN
   $STATUS$
      R
   $COMPLIANCE$
      C
   $FILES$
      Library is rdd
   $SEEALSO$
      dbUnlock(), dbUnlockAll()
   $END$
 */

/* $DOC$
   $TEMPLATE$
      Function
   $NAME$
      dbClearFilter()
   $CATEGORY$
      API
   $SUBCATEGORY$
      Database
   $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$
      PROCEDURE Main()
         USE test
         SET FILTER TO Left( test->Name, 2 ) == "An"
         dbEdit()
         Test->( dbClearFilter() )
         USE
         RETURN
   $STATUS$
      R
   $COMPLIANCE$
      C
   $FILES$
      Library is rdd
   $SEEALSO$
      dbSetFilter(), dbFilter()
   $END$
 */

/* $DOC$
   $TEMPLATE$
      Function
   $NAME$
      dbCloseAll()
   $CATEGORY$
      API
   $SUBCATEGORY$
      Database
   $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$
      PROCEDURE Main()
         USE test NEW
         dbEdit()
         USE test1 NEW
         dbEdit()
         dbCloseAll()
         USE
         RETURN
   $STATUS$
      R
   $COMPLIANCE$
      C
   $FILES$
      Library is rdd
   $SEEALSO$
      dbUseArea(), dbCloseArea()
   $END$
 */

/* $DOC$
   $TEMPLATE$
      Procedure
   $NAME$
      dbCloseArea()
   $CATEGORY$
      API
   $SUBCATEGORY$
      Database
   $ONELINER$
      Close a database file in a work area.
   $SYNTAX$
      dbCloseArea()
   $DESCRIPTION$
      This function  will close any database open in the selected
      or aliased work area.
   $EXAMPLES$
      PROCEDURE Main()
         USE test
         dbEdit()
         Test->( dbCloseArea() )
         USE
         RETURN
   $STATUS$
      R
   $COMPLIANCE$
      C
   $FILES$
      Library is rdd
   $SEEALSO$
      dbUseArea(), dbCloseAll()
   $END$
 */

/* $DOC$
   $TEMPLATE$
      Procedure
   $NAME$
      dbCommit()
   $CATEGORY$
      API
   $SUBCATEGORY$
      Database
   $ONELINER$
      Updates all index and database buffers for a given workarea
   $SYNTAX$
      dbCommit()
   $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$
      PROCEDURE 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
   $STATUS$
      R
   $COMPLIANCE$
      C
   $FILES$
      Library is rdd
   $SEEALSO$
      dbCloseAll(), dbCommitAll(), dbUnlock()
   $END$
 */

/* $DOC$
   $TEMPLATE$
      Procedure
   $NAME$
      dbCommitAll()
   $CATEGORY$
      API
   $SUBCATEGORY$
      Database
   $ONELINER$
      Flushes the memory buffer and performs a hard-disk write
   $SYNTAX$
      dbCommit()
   $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$
      PROCEDURE 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
   $STATUS$
      R
   $COMPLIANCE$
      C
   $FILES$
      Library is rdd
   $SEEALSO$
      dbCloseAll(), dbCommit(), dbUnlock()
   $END$
 */

/* $DOC$
   $TEMPLATE$
      Procedure
   $NAME$
      dbCreate()
   $CATEGORY$
      API
   $SUBCATEGORY$
      Database
   $ONELINER$
      Creates an empty database from a array.
   $SYNTAX$
      dbCreate( <cDatabase>, <aStruct>, [<cDriver>], [<lOpen>],
                [<cAlias>] )
   $ARGUMENTS$
      <cDatabase> Name of database to be create

      <aStruct>   Name of a multidimensional array that contains the
                  database structure

      <cDriver>   Name of the RDD

      <lOpenNew>  3-way toggle to Open the file in New or Current workarea:

                       <table>
                       NIL     The file is not opened.
                       True    It is opened in a New area.
                       False   It is opened in the current area.
                  </table>

      <cAlias>    Name of database Alias
   $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 65519 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
      Database Driver to use to create the database. If it is not
      specified, then the Replaceable Database Driver in the current work
      area is used.

      The <lOpenNew> parameter specifies if the already created database is
      to be opened, and where.  If NIL, the file is not opened. If True,
      it is opened in a New area, and if False it is opened in the current
      area (closing any file already occupying that area).
      The <cAlias> parameter specifies the alias name for the new opened
      database.
   $EXAMPLES$
      PROCEDURE 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
   $STATUS$
      R
   $COMPLIANCE$
      This function is not CA-Cl*pper compliant
   $FILES$
      Library is rdd
      Header is dbstruct.ch
   $SEEALSO$
      AFields()*, dbStruct()
   $END$
 */

/* $DOC$
   $TEMPLATE$
      Procedure
   $NAME$
      dbDelete()
   $CATEGORY$
      API
   $SUBCATEGORY$
      Database
   $ONELINER$
      Mark a record for deletion in a database.
   $SYNTAX$
      dbDelete()
   $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$
      C
   $FILES$
      Library is rdd
   $SEEALSO$
      dbRecall()
   $END$
 */

/* $DOC$
   $TEMPLATE$
      Function
   $NAME$
      dbFilter()
   $CATEGORY$
      API
   $SUBCATEGORY$
      Database
   $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$
      C
   $FILES$
      Library is rdd
   $SEEALSO$
      dbRelation(), dbRSelect()
   $END$
 */

/* $DOC$
   $TEMPLATE$
      Procedure
   $NAME$
      dbGoBottom()
   $CATEGORY$
      API
   $SUBCATEGORY$
      Database
   $ONELINER$
      Moves the record pointer to the bottom of the database.
   $SYNTAX$
      dbGoBottom()
   $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$
      C
   $FILES$
      Library is rdd
   $SEEALSO$
      Bof(), Eof(), dbSkip(), dbSeek(), dbGoTop()
   $END$
 */

/* $DOC$
   $TEMPLATE$
      Procedure
   $NAME$
      dbGoto()
   $CATEGORY$
      API
   $SUBCATEGORY$
      Database
   $ONELINER$
      Position the record pointer to a specific location.
   $SYNTAX$
      dbGoto( <xRecordNumber> )
   $ARGUMENTS$
      <xRecordNumber> Record number or unique identity
   $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 is not affected by an active index or
      by any enviromental SET condiction.

      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.

      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.
   $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$
      C
   $FILES$
      Library is rdd
   $SEEALSO$
      Bof(), Eof(), dbGoTop(), dbGoBottom(), dbSeek(), dbSkip()
   $END$
 */

/* $DOC$
   $TEMPLATE$
      Procedure
   $NAME$
      dbGoTop()
   $CATEGORY$
      API
   $SUBCATEGORY$
      Database
   $ONELINER$
      Moves the record pointer to the top of the database.
   $SYNTAX$
      dbGoTop()
   $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$
      C
   $FILES$
      Library is rdd
   $SEEALSO$
      Bof(), Eof(), dbSkip(), dbSeek(), dbGoBottom()
   $END$
 */

/* $DOC$
   $TEMPLATE$
      Procedure
   $NAME$
      dbRecall()
   $CATEGORY$
      API
   $SUBCATEGORY$
      Database
   $ONELINER$
      Recalls a record previousy marked for deletion.
   $SYNTAX$
      dbRecall()
   $DESCRIPTION$
      This function unmarks those records marked for deletion and
      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 can be brought back
      with dbRecall().
   $EXAMPLES$
      USE test NEW
      dbGoto( 10 )
      dbDelete()
      ? Deleted()
      dbRecall()
      ? Deleted()
      USE
   $STATUS$
      R
   $COMPLIANCE$
      C
   $FILES$
      Library is rdd
   $SEEALSO$
      dbDelete()
   $END$
 */

/* $DOC$
   $TEMPLATE$
      Function
   $NAME$
      dbRLock()
   $CATEGORY$
      API
   $SUBCATEGORY$
      Database
   $ONELINER$
      This function locks the record based on identity
   $SYNTAX$
      dbRLock( [<xIdentity>] ) --> lSuccess
   $ARGUMENTS$
      <xIdentity> Record identifier
   $RETURNS$
      dbRLock() returns a logical true (.T.) if lock was successful
   $DESCRIPTION$
      This function attempts to lock a record which is identified
      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$
      PROCEDURE Main()
         LOCAL x := 0
         USE tests NEW
         FOR x := 1 TO RecCount()
            IF ! dbRLock()
               dbUnlock()
            ENDIF
         NEXT
         USE
   $STATUS$
      R
   $COMPLIANCE$
      C
   $FILES$
      Library is rdd
   $SEEALSO$
      dbUnlock(), dbUnlockAll(), FLock(), RLock()
   $END$
 */

/* $DOC$
   $TEMPLATE$
      Function
   $NAME$
      dbRLockList()
   $CATEGORY$
      API
   $SUBCATEGORY$
      Database
   $ONELINER$
      This function return a list of locked 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 records in that
      work area.
   $EXAMPLES$
      PROCEDURE 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
   $STATUS$
      R
   $COMPLIANCE$
      C
   $FILES$
      Library is rdd
   $SEEALSO$
      RLock(), dbRLock(), dbRUnlock()
   $END$
 */

/* $DOC$
   $TEMPLATE$
      Procedure
   $NAME$
      dbRUnlock()
   $CATEGORY$
      API
   $SUBCATEGORY$
      Database
   $ONELINER$
      Unlocks a record based on its identifier
   $SYNTAX$
      dbRUnlock( [<xIdentity>] )
   $ARGUMENTS$
      <xIdentity> Record identifier, typically a record number
   $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$
      PROCEDURE Main()
         USE tests NEW
         dbGoto( 10 )
         IF RLock()
            ? tests->ID
            dbRUnlock()
         ENDIF
         USE
         RETURN
   $STATUS$
      R
   $COMPLIANCE$
      C
   $FILES$
      Library is rdd
   $SEEALSO$
      RLock(), dbRLock(), dbRLockList()
   $END$
 */

/* $DOC$
   $TEMPLATE$
      Function
   $NAME$
      dbSeek()
   $CATEGORY$
      API
   $SUBCATEGORY$
      Database
   $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() will be a logical false and Eof() will be
      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$
      PROCEDURE Main()
         USE tests NEW INDEX tests
         dbGoto( 10 )
         nId := tests->nId
         IF tests->( dbSeek( nId ) )
            IF RLock()
               ? tests->Name
               dbRUnlock()
            ENDIF
         ENDIF
         USE
         RETURN

      ACCEPT "Employee name: " TO cName
      IF Employee->( dbSeek( cName ) )
         Employee->( ViewRecord() )
      ELSE
         ? "Not found"
      ENDIF
   $STATUS$
      S
   $COMPLIANCE$
      dbSeek() is  Compatible with CA-Cl*pper 5.3
   $FILES$
      Library is rdd
   $SEEALSO$
      dbGoBottom(), dbGoTop(), dbSkip(), Eof(), Bof(), Found()
   $END$
 */

/* $DOC$
   $TEMPLATE$
      Procedure
   $NAME$
      dbSelectArea()
   $CATEGORY$
      API
   $SUBCATEGORY$
      Database
   $ONELINER$
      Change to another work area
   $SYNTAX$
      dbSelectArea( <xArea> ) -
   $ARGUMENTS$
      <xArea> Alias or work area
   $DESCRIPTION$
      This function moves the Harbour internal primary focus to the work
      area designated by <xArea>. If <xArea> is numeric, then 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$
      PROCEDURE 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
   $STATUS$
      R
   $COMPLIANCE$
      C
   $FILES$
      Library is rdd
   $SEEALSO$
      dbUseArea(), Select()
   $END$
 */

/* $DOC$
   $TEMPLATE$
      Function
   $NAME$
      dbSetDriver()
   $CATEGORY$
      API
   $SUBCATEGORY$
      Database
   $ONELINER$
      Establishes the RDD name for the 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$
      C
   $FILES$
      Library is rdd
   $SEEALSO$
      dbUseArea()
   $END$
 */

/* $DOC$
   $TEMPLATE$
      Procedure
   $NAME$
      dbSkip()
   $CATEGORY$
      API
   $SUBCATEGORY$
      Database
   $ONELINER$
      Moves the record pointer in the selected work area.
   $SYNTAX$
      dbSkip( [<nRecords>] )
   $ARGUMENTS$
      <nRecords> Numbers of records to move record pointer.
   $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$
      PROCEDURE Main()
         USE tests NEW
         dbGoTop()
         DO WHILE ! Eof()
            ? tests->Id, tests->Name
            dbSkip()
         ENDDO
         USE
         RETURN
   $STATUS$
      R
   $COMPLIANCE$
      C
   $FILES$
      Library is rdd
   $SEEALSO$
      Bof(), dbGoBottom(), dbGoTop(), dbSeek(), Eof()
   $END$
 */

/* $DOC$
   $TEMPLATE$
      Procedure
   $NAME$
      dbSetFilter()
   $CATEGORY$
      API
   $SUBCATEGORY$
      Database
   $ONELINER$
      Establishes a filter condition for a work area.
   $SYNTAX$
      dbSetFilter( <bCondition>, [<cCondition>] )
   $ARGUMENTS$
      <bCondition> Code block expression for filtered evaluation.

      <cCondition> Optional character expression of code block.
   $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$
      PROCEDURE Main()
         USE tests NEW
         dbSetFilter( {|| tests->Id < 100 }, "tests->Id <100" )
         dbGoTop()
   $STATUS$
      R
   $COMPLIANCE$
      C
   $FILES$
      Library is rdd
   $SEEALSO$
      dbFilter(), dbClearFilter()
   $END$
 */

/* $DOC$
   $TEMPLATE$
      Function
   $NAME$
      dbStruct()
   $CATEGORY$
      API
   $SUBCATEGORY$
      Database
   $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$
      #include "dbstruct.ch"
      PROCEDURE Main()
         LOCAL aStru, x
         USE tests NEW
         aStru := dbStruct()
         FOR x := 1 TO Len( aStru )
            ? aStru[ x ][ DBS_NAME ]
         NEXT
         USE
         RETURN
   $STATUS$
      R
   $COMPLIANCE$
      C
   $FILES$
      Library is rdd
      Header is dbstruct.ch
   $SEEALSO$
      AFields()*
   $END$
 */

/* $DOC$
   $TEMPLATE$
      Procedure
   $NAME$
      dbUnlock()
   $CATEGORY$
      API
   $SUBCATEGORY$
      Database
   $ONELINER$
      Unlock a record or release a file lock
   $SYNTAX$
      dbUnlock()
   $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 databases.
   $EXAMPLES$
      nId := 10
      USE testid INDEX testid NEW
      IF testid->( dbSeek( nId ) )
         IF testid->( RLock() )
            dbDelete()
         ELSE
            dbUnlock()
         ENDIF
      ENDIF
      USE
   $STATUS$
      R
   $COMPLIANCE$
      C
   $FILES$
      Library is rdd
   $SEEALSO$
      dbUnlockAll(), FLock(), RLock()
   $END$
 */

/* $DOC$
   $TEMPLATE$
      Procedure
   $NAME$
      dbUnlockAll()
   $CATEGORY$
      API
   $SUBCATEGORY$
      Database
   $ONELINER$
      Unlocks all records and releases all file locks in all work areas.
   $SYNTAX$
      dbUnlockAll()
   $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$
      C
   $FILES$
      Library is rdd
   $SEEALSO$
      dbUnlock(), FLock(), RLock()
   $END$
 */

/* $DOC$
   $TEMPLATE$
      Procedure
   $NAME$
      dbUseArea()
   $CATEGORY$
      API
   $SUBCATEGORY$
      Database
   $ONELINER$
      Opens a work area and uses a database file.
   $SYNTAX$
      dbUseArea( [<lNewArea>], [<cDriver>], <cName>, [<xcAlias>],
      [<lShared>], [<lReadonly>])
   $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.
   $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 dbSetDriver().

      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$
      C
   $FILES$
      Library is rdd
   $SEEALSO$
      dbCloseArea(), dbSetDriver(), Select(), Set()
   $END$
 */
