Database Manipulation


The section in this chapter, "Using MicroStation Database Servers from Initapps" provides information on how to use MDL to interface MicroStation to databases.

Session Debug

There are various debug commands that will help diagnose problems when interacting with databases. Here is a breakdown of all of the debug commands and their effects:

CommandEffect
session debug onTurns debug on for server.ma.
session debug offTurns debug off for both server.ma and the SQL server.
session debug toggleToggles the current server.ma debug session setting.
session debug ipc onTurns debug on for the packets being sent between dbload.ma and the SQL server.
session debug ipc offTurns ipc debug off for the SQL server.
session debug ipc toggleToggles ipc debug for the SQL server.
session debug external onTurns debug on for the SQL server.
session debug external offTurns debug off for the SQL server.
session debug external toggleToggles debug for the SQL server.

 

Configuration Variables

MS_SERVER

This is the task name of your mdl loader application.

MS_LINKTYPE

This is the same environment variable that was needed in earlier versions of MicroStation. It specifies the type of links that are understood by the server. The first in the list is the type that will be written.

MS_SESSION_DEBUG

Setting this configuration variableto 1 starts debugging on database initialization. This can be beneficial when investigating situations when SERVER.MA is not loading.

Using MicroStation Database Servers from Initapps

MicroStation database servers can be started for use by an initapp. Typically MicroStation is configured for use with a database by designating the "server" MDL application as a design file application (dgnapp). The server gets the value of the MS_SERVER environment variable and starts the mdl loader. The MDL loader will determine the name of the external server by getting the MS_DBEXT environment variable and start the external server. When a MicroStation initapp is started, no design file has been attached, so the dgnapps, including the server application, have not yet been started.

Therefore, before using one of the database servers, mdlSystem_loadMdlProgram must be called to load the MDL server server.ma. When mdlSystem_loadMdlProgram is called it should be given the argument FRONTEND. This will notify the loader that it is being loaded from an initapp. A loader must know that it is being started as an initapp because MicroStation sends several startup messages to the server when the server is launched as a dgnapp. The FRONTEND argument will ensure that the loader simulates this "handshaking."

To complete the process of making the database server available from an initapp, log on to the database by issuing a connect statement with mdlDB_activeDatabase.

If the initapp will put MicroStation in graphics mode, further considerations must be made. If control will return to the initapp after MicroStation exits graphics, the server connection must be reestablished as above from the reload hook if the database is to be accessed from the initapp. This is necessary because MicroStation unloads all MDL applications including the loader when exiting graphics and returning to the initapp. When the reload function is finished with the server, it must unload the loader so the server is properly terminated.

Sample Database Initapp

The following code is presented as a sample skeleton initapp that uses a database server. The main routine first initializes the database server and does any necessary pre-processing of the database. The initapp then enters graphics, sets a reload function and attaches a DGN file. The reload function is called when MicroStation exits graphics. The database server is reloaded and any post-processing of the database is done here. Finally, the server is terminated and MicroStation is exited.

- You need to create an ODBC data source called GIS and point it to the delivered GIS.mdb delivered example for this to work. /*--------------------------------------------------------------------+
|
| $Copyright: (c) 2006 Bentley Systems, Incorporated.
| All rights reserved. $
|
+--------------------------------------------------------------------*/
/*-----------------------------------------------------------------+
| dbinit.mc
|
| To execute from the command line: ustation.exe -WAdbinit.ma
|
+-----------------------------------------------------------------*/
/*-----------------------------------------------------------------+
| Include Files
| +-----------------------------------------------------------------*/
#include <mdl.h>
#include <cexpr.h>
#include <system.h>
#include <global.h>
#include <dbdefs.h>
#include <dberrs.h>
#include <userfnc.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <msdb.fdf>
#include <mssystem.fdf>
#include <rdbmslib.fdf>

/*-----------------------------------------------------------------+
| Private Global Variables
|
+------------------------------------------------------------------*/
/*-----------------------------------------------------------------+
| Major Public Code Section
|
+------------------------------------------------------------------*/
/*--------------------------------------------------------------------+
|
| dbAttach
|
+--------------------------------------------------------------------*/
Private void dbAttach
(
char *database, /* => Database connect string */
char *cfgFile /* => Database connection type i.e. ODBC, ORACLE, ... */
)
{
DatabaseProfile profileP;
int status;
char buffer[255];
char cfgVarValue[MAXFILELENGTH];
char cfgFileSpec[MAXFILELENGTH];

/* Detatch database in a polite manner */
mdlDB_activeDatabase (" ");
/* Remove existing database variable values */
mdlSystem_deleteCfgVar ("MS_DBASE");
mdlSystem_deleteCfgVar ("MS_SERVER");
mdlSystem_deleteCfgVar ("MS_LINKTYPE");
/* Unload server to guarantee a clean load of database cfg file */
if (mdlSystem_getTaskStatistics (NULL, "server") == SUCCESS)
mdlSystem_unloadMdlProgram ("server");
/* Find the path to the database configuration directory */
mdlSystem_getCfgVar (cfgVarValue, "_USTN_DATABASE", MAXFILELENGTH);
/* Create a Filespec for database configuration file to open */
sprintf (cfgFileSpec, "%s%s.cfg", mdlSystem_expandCfgVar(cfgVarValue), cfgFile);

/* Load database configuration file */
status = mdlSystem_processCfgVarFile (cfgFileSpec, CFGVAR_LEVEL_USER);
if (status == SUCCESS)
{
status = mdlSystem_loadMdlProgram ("server.ma", "server", "FRONTEND");
if (status == SUCCESS)
{
/* Determine the database connection just loaded */
status = mdlDB_databaseProfile (&profileP);
/* If database is ORACLE connect this way */

// 0 == Added by Keith Bertram - Bentley 2/3/2009

if (0 == strcmpi (profileP.brand.brandName, "ORACLE"))
{
sprintf (buffer, "connect %s", database);
status = mdlDB_processSQL (buffer);
}
else
{
/* ... else connect this way */
status = mdlDB_activeDatabase (database);
if (status != SUCCESS)
printf ("Unable to connect!");
}
}
else
{
printf ("Unable to load server.ma!");
}
}
else
{
printf ("Unable to locate config file!");
}
}

/*-----------------------------------------------------------------+
| name reloadFunction
|
| This function is called by MicroStation after the
| user closes the design file opened in main.
|
+-----------------------------------------------------------------*/
void reloadFunction
(
int argc,
char *argv[]
)
{
char buffer[256];
int status;
/* The database server is unloaded by MicroStation when closing the
design file. If more work needs to be done with the database, the
server must be reactivated. */
dbAttach ("gis", "ODBC");
/* do any necessary "cleanup" work with the database */
status=mdlDB_sqlQuery(buffer, "select owner from parcel where mslink=1");
/* unload the loader here so the server is properly terminated */
mdlSystem_unloadMdlProgram("server");
/* exit the MDL initapp and MicroStation will exit */
mdlSystem_exit(0, 1);
}
/*-----------------------------------------------------------------+
|
| name main
|
+-----------------------------------------------------------------*/
cmdName main()
{
char buffer[256];
int status;
dbAttach ("gis", "ODBC");
/* do any necessary setup work with the database */
status=mdlDB_sqlQuery(buffer, "select owner from parcel where mslink=1");
printf("query result <%s>\n", buffer);
mdlSystem_enterGraphics();
/* Set the function MDL should call when it needs to reload this
MDL application. This function will be called, for example, when
the user chooses to close the current design file. */
mdlSystem_setFunction(SYSTEM_RELOAD_PROGRAM, reloadFunction);
mdlSystem_newDesignFile("database");

return status;
}


#----------------------------------------------------------------------
#
# dbinit.mke
#
# $Copyright: (c) 2006 Bentley Systems, Incorporated.
# All rights reserved. $
#
#----------------------------------------------------------------------
#----------------------------------------------------------------------
#
# Compile Applications with only an MC file.
#
#----------------------------------------------------------------------
appName = dbinit
baseDir = $(_MakeFilePath)
%include mdl.mki
#----------------------------------------------------------------------
# Create output directories
#----------------------------------------------------------------------
always:
~mkdir $(o)
#----------------------------------------------------------------------
# Compile MC Source
#----------------------------------------------------------------------
$(o)$(appName).mo : $(baseDir)$(appName).mc
$(mdlapps)$(appName).ma : $(o)$(appName).mo $(mdlLibs)rdbmslib.dlo