Retro video games delivered to your door every month!
Click above to get retro games delivered to your door ever month!
X-Hacker.org- Force 4.0 Reference - dynopen() open database using dynamic alias http://www.X-Hacker.org [<<Previous Entry] [^^Up^^] [Next Entry>>] [Menu] [About The Guide]
 dynopen()           Open database using dynamic alias
------------------------------------------------------------------------------
 Declaration
   database.hdr

 Syntax
   func _PALIAS dynopen extern
   param value _PALIAS pAlias, ;
         const char    cFileName, ;
         value uint    uMode

 Arguments
   pAlias is a pointer to an alias.

   cFileName is the name of the database file to be opened.

   uMode is the database open mode.

 Return
   A pointer to the dynamic alias. The pointer is zero if the database could
   not be opened, or if an implicit allocation has failed.

 Description
   The dynopen() function opens a database without the need of hardcoding
   its structure in a dbfdef block. The alias structure passed to the
   function via the pAlias parameter is filled in with structural
   information by the function itself, according to the characteristics
   of the existing database file specified by the cFileName parameter.

   The aliases manipulated by dynopen() can subsequently be used with
   all functions that accept an alias as a parameter (like areccount()).
   The alias override operator can also be used with these alias variables,
   e. g. !sDbfDyn append blank will work.

   The alias field operator (dbf->field) can not be applied to dynamic
   aliases, because the field names are not known at compile time (use the
   normal database system, not the dynamic one, if they are known). As a
   consequence of the lacking -> operator, field values of dynamic
   databases can only be assigned and retrieved by using the dbrep...()
   functions.

   The same dynamic alias can be reused with different databases during
   subsequent calls to dynopen(), as long as the support buffer (see below)
   is large enough to satisfy the needs of each database.

   The dynopen() function can also be used with non-dynamic aliases whose
   structure is hardcoded in the application's source. Conversely, the
   open command can be used for reopening dynamic aliases that have been
   opened previously with the dynopen() function (a runtime error occurs
   if dynopen() was not yet called with that alias).

   The uMode parameter to dynopen() determines the open mode. The parameter
   can contain flags for shared, exclusive and read only modes, moreover
   can indicate if integer fields in the database are to be treated as
   signed. Constants for open modes are declared in database.hdr.

   Dynamic aliases consist of two parts: a fixed size alias structure, and
   a support buffer whose size depends on the complexity of the databases
   opened using the particular alias. Dynamic aliases and their support
   buffer can be allocated by either of the three methods described below.

   (1) Allocate dynamic alias in the data segment

   A fixed size dynamic alias can be allocated at compile time in the data
   segment by declaring an empty dbfdef and a support buffer outside of a
   code block. The scope of the alias can be public or static.

   If the alias buffer is initialized, then it must be the first one of
   the initialized public and static variables in the module. If the
   alias buffer is non-initialized, then no initialized public and static
   variable can be in the same module. The recommended practice is to
   initialize the alias buffer and place it as the very first public
   variable in the module. A module with a dynamic alias declared in the
   data segment must not contain other dbfdef blocks. When allocating the
   support buffer in the data segment, keep in mind that the total size
   of data objects in that segment can not exceed 64 Kbytes.

   (2) Allocate dynamic alias on the stack

   A fixed size dynamic alias can be allocated at compile time on the stack
   by declaring a local alias with a support buffer.

   The support buffer MUST ALWAYS IMMEDIATELY PRECEDE the dynamic alias in
   the local vardef block. The local dynamic alias can be made visible
   through the application by sending it around as parameter to the
   functions using it. The application's runtime stack must be large enough
   for the support buffer allocation (cf. the -S compiler switch).

   (3) Allocate dynamic alias from the runtime heap memory

   A dynamic alias and its support buffer can be allocated at runtime. To do
   this, the pAlias parameter must be set to zero when calling the dynopen()
   function. A pointer to the allocated alias is returned from the call,
   which can be used in subsequent database operations.

   The alias pointer obtained this way is guaranteed to suffice the database
   in context, but not others. Use independent calls to dynopen() for each
   database. In general, heap aliases are more flexible than statically
   allocated ones.

 Example
   #define EXAMPLE_DATABASE
   #define _DYNALIAS_
   #define _ALIASPTR_
   #include example.hdr

   #define BUFFER_SIZE 300                     // alias buffer size
   
   vardef static
      byte aBuffer[ BUFFER_SIZE ] := 0         // alias buffer in data segment
   enddef
   
   dbfdef sAlias static
   enddef
   
   proc OpenDataSegment
   // Open database using static alias and buffer allocated in data segment
   if dynopen( &sAlias, "stest.dbf", DO_SHARED ) // open database
      ? afieldname( &sAlias, 1 )
      close sAlias                             // close database
   endif
   endproc
   
   proc OpenLocal
   // Open database using local alias and buffer allocated in stack segment
   vardef
      byte  aBuffer[ BUFFER_SIZE ]             // alias buffer in stack segment
      alias sAlias                             // dynamic alias
   enddef
   if dynopen( &sAlias, "stest.dbf", DO_SHARED ) // open database
      ? afieldname( &sAlias, 1 )
      close sAlias                             // close database
   endif
   endproc
   
   proc OpenAllocated
   param value uint nBufSize
   // Open database using allocation by this function
   vardef
      _PALIAS pDbf
   enddef
   pDbf := malloc( sizeof( alias ) + nBufSize ) // allocate alias
   if dynopen( pDbf, "stest.dbf", DO_SHARED )   // open database
      ? afieldname( pDbf, 1 )
      close databases                           // close database
      free( pDbf )
   endif
   endproc
   
   proc OpenDynamic
   // Open database using allocation by library
   vardef
      _PALIAS pDbf
   enddef
   pDbf := dynopen( 0, "stest.dbf", DO_SHARED ) // open database
   if pDbf
      ? afieldname( pDbf, 1 )
      dynclose( pDbf )                          // close database
   endif
   endproc
   
   proc Test_dynopen
   // Demonstrate four methods to open a database without knowing its structure
   vardef
      uint nBufSize                            // necessary buffer size
   enddef
   nBufSize := dyncheckbuffer( "stest.dbf" )   // query necessary buffer size
   if nBufSize <= BUFFER_SIZE                  // if buffer is big enough
      OpenLocal()                              // method 1
      OpenDataSegment()                        // method 2
   endif
   OpenDynamic()                               // method 3
   OpenAllocated( nBufSize )                   // method 4
   endproc

   proc main
   Test_dynopen()
   endproc

See Also: dyncheckbuffer() dynclose()

Online resources provided by: http://www.X-Hacker.org --- NG 2 HTML conversion by Dave Pearson