This section provides an overview of how to develop applications that use the DBTools interface for managing SQL Anywhere databases.
In order to use the DBTools functions, you must link your application against a DBTools import library which contains the required function definitions.
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 |
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 );
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".
Several elements in DBTools structures are of type MSG_CALLBACK. These are pointers to 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:
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.
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 );
}
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 );
}
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 );
}
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;
}
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.
backup_info.version = DB_TOOLS_VERSION_NUMBER;
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.
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.
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;
}