Function DbRelease() Foundation

Transfers an alias name from the current work space into the Zero space.

DbRelease( [<nWorkArea>|<cAlias>], [<bAreaBlock>] ) --> lSuccess
area <nWorkArea>
<nWorkArea> is a positive integer specifying the work area whose alias name is to be transferred into the Zero space. It defaults to the number of the current work area.
Alternately, <cAlias> can be specified for <nWorkArea>. If used, <cAlias> is a character string containing the alias name to transfer.
The optional argument <bAreaBlock> specifies a code block to be associated with the work area.

The function DbRelease() returns .T. (true) when the alias name is successfully transferred into the Zero space, otherwise it is .F. (false).


Together with DbRequest(), the function DbRelease() allows the utilization of the work space concept of Xbase++. Work spaces are used for database access across multiple work areas. Each thread has one work space with a maximum of 65.000 work areas. Within work areas, database files are opened and database fields can be accessed. Access to field variables of one database is bound to the work area where the database file is opened. Normally, a work area exists only in the thread where the database is opened (work areas are local to a thread).

Using DbRelease() and DbRequest() makes it possible to exchange alias names between two work spaces. The alias name is the reference to an open database. Thus, a specific work area can be accessed from different threads while the corresponding database is opened once. This allows the advantages of multi-threading in database programming to be utilized. For example, a complex database query can be started in a separate thread while the user is entering data in the main application thread. The user does not need to wait for the operation to finish but can be notified when the query is complete.

Exchanging alias names between work spaces always involves a virtual work space, the Zero space. Function DbRelease() releases the alias name of a work area in the current work space. It is then collected in the Zero space and transferred to a work area of another work space when DbRequest() is called. If the work area is linked to other work areas (SET RELATION) alias names of all child work areas are transferred as well.

The second parameter <bAreaBlock> is used to define an operation to be performed within a work area of another work space. It is a code block that is associated with the work area's alias name. When the alias name is transferred using DbRequest(), the code block is retrieved as well. It can then be passed to the function Eval() in order to perform the database operation.

When an alias name is transferred to the Zero space, database access in the corresponding work area is not possible. The work area is then not used and function Used() returns .F. (false). However, the database file is still open.

Perform database operations in a separate thread

// The example demonstrates how a database query can 
// be performed in a separate thread. The task is to count 
// all customers whose last name is Thompson. This is 
// accomplished by a thread that executes the procedure 
// DbOperation(). This procedure is called from a code block 
// which is passed to DbRelease(). 

   LOCAL bFor    := {|| Trim(FIELD->LASTNAME) == "Thompson" } 
   LOCAL bJob    := {|| DbCount( bFor ) } 
   LOCAL oThread := Thread():new() 

   USE Customer                          // open database 

   oThread:start( "DbOperation" )        // thread executes code 
   ? "Thread started" 
   WAIT "Press a key to release work area" 

   DbRelease( , bJob )                   // start query 

   ? "Database operation (Query) runs in separate thread" 
   ? "Used()", Used()                    // alias exists now 
   ? "Performing some other tasks"       // in the work space of 
                                         // the second thread. 
   DbRequest( , , @bJob, .T. )           // Get alias back 

   ? "Result of query:", Eval( bJob )    // display result in 
                                         // main thread and 
   CLOSE Customer                        // close database 

PROCEDURE DbOperation                    // Procedure for any 
   LOCAL bBlock, xResult                 // database operation. 

   IF DbRequest( , , @bBlock, .T. )      // Wait for work area. 
      xResult := Eval( bBlock )          // Perform operation. 
      DbRelease( , {|| xResult } )       // Release work area and 
   ENDIF                                 // return result within 
                                         // a code block. 

FUNCTION DbCount( bFor )                 // Count all records 
   LOCAL nCount := 0                     // that match a 
   GO TOP                                // condition. 
   DO WHILE ! Eof() 
      IF Eval( bFor ) 
         nCount ++ 
RETURN nCount 

If you see anything in the documentation that is not correct, does not match your experience with the particular feature or requires further clarification, please use this form to report a documentation issue.