Contents IndexThe DBTools interface DBTools functions

User's Guide
   Part V. The SQL Anywhere Programming Interfaces
     Chapter 35. Using the Database Tools Interface
      Using the DBTools interface

This section provides an overview of how to develop applications that use the DBTools interface for managing SQL Anywhere databases.

Top of page


Using the import libraries

In order to use the DBTools functions, you must link your application against a DBTools import library which contains the required function definitions.

Supported platforms

Import libraries are operating system-specific and can be compiler-specific. Import libraries for the DBTools interface are provided with SQL Anywhere, and can be found in the LIB subdirectory of each operating system directory, under the SQL Anywhere installation directory. The provided DBTools import libraries are as follows:

Operating system Compiler Library
Windows NT/95 Watcom WIN32\DBTLSTW.LIB
Windows NT/95 Microsoft WIN32\DBTLSTM.LIB
Windows NT/95 Borland WIN32\DBTLSTB.LIB
Windows 3.x All WIN\DBTOOLSW.LIB
OS/2 All OS2\DBTOOLS2.LIB

Top of page


Starting and finishing use of the DBTools library

Before using any other DBTools functions, you must call DBToolsInit. When you are finished using the DBTools DLL, you must call DBToolsFini.

The primary purpose of the DBToolsInit and DBToolsFini functions is to allow the DBTools dll to load the SQL Anywhere language DLL. The language DLL contains localized versions of all error messages and prompts that DBTools uses internally. If DBToolsFini is not called, the reference count of the language DLL is not decremented, and it will not be unloaded, so be careful to ensure there is a matched pair of DBToolsInit/DBToolsFini calls.

The following code fragment illustrates how to initialize and clean up DBTools:

     // Declarations
     a_dbtools_info    info;
     short                ret;
     
     //Initialize the a_dbtools_info structure
     memset( &info, 0, sizeof( a_dbtools_info) );
     info.errorrtn = (MSG_CALLBACK)MyErrorRtn;
     
     // initialize DBTools
     ret = DBToolsInit( &info );
     if( ret != EXIT_OKAY ) {
         // DLL initialization failed
         ...
     }
     // call some DBTools routines . . .
     ...
     // cleanup the DBTools dll
     DBToolsFini( &info );

Top of page


Calling the DBTools functions

All the tools are run by first filling out a structure, and then calling a function (or entry point) in the DBTools DLL. Each entry point takes a pointer to a single structure as argument.

The following example shows how to use the DBBackup function. The example is for either Windows 95 or Windows NT operating systems.

     // Initialize the structure
     a_backup_db backup_info;
     memset( &backup_info, 0, sizeof( backup_info ) );
     
     // Fill out the structure
     backup_info.version = DB_TOOLS_VERSION_NUMBER;
     backup_info.output_dir = "C:\BACKUP";
     backup_info.connectparms ="uid=dba;pwd=sql;dbf=sademo.db";
     backup_info.startline = "DBENG50.EXE";
     backup_info.confirmrtn = (MSG_CALLBACK) ConfirmRtn ;
     backup_info.errorrtn = (MSG_CALLBACK) ErrorRtn ;
     backup_info.msgrtn = (MSG_CALLBACK) MessageRtn ;
     backup_info.statusrtn = (MSG_CALLBACK) StatusRtn ;
     backup_info.backup_database = TRUE;
     
     // start the backup
     DBBackup( &backup_info );

  For information about the members of the DBTools structures, see "DBTools structures".

Top of page


Using callback functions

Several elements in DBTools structures are of type MSG_CALLBACK. These are pointers to callback functions.

Uses of callback functions

Callback functions allow DBTools functions to return control of operation to the user's calling application. The DBTools library uses callback functions to handle messages sent to the user by the DBTools functions, for four purposes:

Assigning a callback function to a structure

In operating systems other than Windows 3.x, you can directly assign a callback routine to the structure. The following statement is an example using a backup structure:

     backup_info.errorrtn = (MSG_CALLBACK) MyFunction

MSG_CALLBACK is defined in the DLLAPI.H header file supplied with SQL Anywhere. The definitions allow tools routines to call back to Calling application with messages that should be displayed in the appropriate user interface, whether that be a Windowing environment, standard output on character-based systems, or other user interface.

If you are developing for Windows 3.x, you must use the MakeProcInstance Windows API thunking function when assigning values to the elements. The following statement is an example using a backup structure:

     backup_info.errorrtn =
         (MSG_CALLBACK)MakeProcInstance(
         (FARPROC)MyFunction, hInst );

After you have finished with the DLL, you must free Callback thunk using the FreeProcInstance Windows API function:

     FreeProcInstance( (FARPROC) backup_info.errorrtn );

If no function is assigned to the structure member, then the message is ignored.

Confirmation callback function example

The following example confirmation routine asks the user to answer YES or NO to a prompt, and returns the user's selection:

     extern short _callback ConfirmRtn(
             char far * question )
     {
         int ret;
         if( question != NULL ) {
             ret = MessageBox( HwndParent, question,
             "Confirm", MB_ICONEXCLAMTION|MB_YESNO );
         }
         return( 0 );
     }

Error callback function example

The following is an example implementation of an error message handling routine, which displays the error message in a message box.

     extern short _callback ErrorRtn(
             char far * errorstr )
     {
         if( errorstr != NULL ) {
             ret = MessageBox( HwndParent, errorstr,
             "Backup Error", MB_ICONSTOP|MB_OK );
         }
         return( 0 );
     }

Message callback function example

A common implementation of a message callback function outputs the message to the screen:

     extern short _callback MessageRtn(
             char far * errorstr )
     {
         if( messagestr != NULL ) {
         OutputMessageToWindow( messagestr );
         }
         return( 0 );
     }

Status callback function example

A status callback routine is called when the tools needs to display the status of an operation (like the percentage done unloading a table). Again, a common implementation would just output the message to the screen:

     extern short _callback StatusRtn(
             char far * statusstr )
     {
         if( statusstr == NULL ) {
             return FALSE;
         }
         OutputMessageToWindow( statustr );
         return TRUE;
     }

Top of page


Version numbers and compatibility

Each structure has a member which indicates the version number. You should use this version member to hold the version of the DBTools library your application was developed against. The current version of the DBTools library is included as the constant in the DBTOOLS.H header file.

To assign the current version number to a structure:

Compatibility

The version number allows your application to continue working against newer versions of the DBTools library. The DBTools functions use the version number supplied by your application to allow the application to work, even if new members have been added to the DBTools structure.

Applications will not work against older versions of the DBTools library.

Top of page


Using bit fields

Many of the DBTools structures use bit fields to hold Boolean information in a compact manner. For example, the backup structure has the following bit fields:

     char                backup_database    : 1;
     char                backup_logfile    : 1;
     char                backup_writefile: 1;
     char                no_confirm    : 1;
     char                quiet        : 1;
     char                rename_log    : 1;
     char                truncate_log : 1;
     char                rename_local_log: 1;

Each bit field is one bit long, indicated by the 1 to the right of the colon in the structure declaration..

You assign an integer value of 0 or 1 to a bit field to pass Boolean information to the structure.

Top of page


An example

The following program illustrates the use of the DBTools library in the context of a backup program:

     #define WINNT
     
     #include <stdio.h>
     #include "windows.h"
     #include "string.h"
     #include "dbtools.h"
     
     extern short _callback ConfirmCallBack(char far * str)
     {
         if( MessageBox( NULL, str, "Backup",
              MB_YESNO|MB_ICONQUESTION ) == IDYES ) {
             return 1;
         }
         return 0;
     }
     
     extern short _callback MessageCallBack( char far * str )
     {
         if( str != NULL ) {
             fprintf( stdout, str );
             fprintf( stdout, "\n" );
             fflush( stdout );
         }
         return 0;
     }
     
     extern short _callback StatusCallBack( char far * str )
     {
         if( str != NULL ) {
             fprintf( stdout, str );
             fprintf( stdout, "\n" );
             fflush( stdout );
         }
         return 0;
     }
     
     extern short _callback ErrorCallBack( char far * str )
     {
         if( str != NULL ) {
             fprintf( stdout, str );
             fprintf( stdout, "\n" );
             fflush( stdout );
         }
         return 0;
     }
     
     
     // Main entry point into the program.
     int main( int argc, char * argv[] )
     {
         a_backup_db    backup_info;
         char        dir_name[ _MAX_PATH + 1];
         char        connect[ 256 ];
         short        ret;
         HINSTANCE        hinst;
         FARPROC        proc_addr;
     
         // Always initialize to 0 so new versions
         //of the structure will be compatible.
         memset( &backup_info, 0, sizeof( a_backup_db ) );
         backup_info.version = DB_TOOLS_VERSION_NUMBER;
         backup_info.quiet = 0;
         backup_info.no_confirm = 0;
         backup_info.confirmrtn = (MSG_CALLBACK)ConfirmCallBack;
         backup_info.errorrtn = (MSG_CALLBACK)ErrorCallBack;
         backup_info.msgrtn = (MSG_CALLBACK)MessageCallBack;
         backup_info.statusrtn = (MSG_CALLBACK)StatusCallBack;
     
         if( argc > 1 ) {
             strncpy( dir_name, argv[1], _MAX_PATH );
         } else {
             // DBTools does not expect (or like) the
             // trailing slash
             strcpy( dir_name, "c:\\temp" );
         }
         backup_info.output_dir = dir_name;
     
         if( argc > 2 ) {
             strncpy( connect, argv[2], 255 );
         } else {
             // Assume that the engine is already running.
             strcpy( connect, "UID=dba;PWD=sql;DBN=sademo" );
         }
         backup_info.connectparms = connect;
         backup_info.startline = "";
         backup_info.quiet = 0;
         backup_info.no_confirm = 0;
         backup_info.backup_database = 1;
         backup_info.backup_logfile = 1;
         backup_info.backup_writefile = 1;
         backup_info.rename_log = 0;
         backup_info.truncate_log = 0;
     
         hinst = LoadLibrary( "dbtl50t.dll" );
         if( hinst == NULL ) {
             // Failed
             return 0;
         }
     
         proc_addr = GetProcAddress( (HMODULE)hinst,
             "_DBBackup@4" );
     
         (*proc_addr)( &backup_info );
         FreeLibrary( hinst );
         return 0;
     }

Top of page


Contents IndexThe DBTools interface DBTools functions