...
Setting up for Application Development
All the necessarily files for application development are available in the form of the EDMdeveloperSeat EDMsdk toolkit and they are:
On the WINDOWS platform:
- <EDM home directory>\Toolkit\Include\sdai.h
The EDMI header file.
- <EDM home directory>\Toolkitbin\Lib\edmikit400.lib
<EDM home directory>\Toolkitbin\Lib\edmikit400.dll
The EDMinterface library.
- <EDM home directory>\Toolkit\Include\cpp_edmi.h
The EDMinterface/C++ header file.
- <EDM home directory>\Toolkit\Libbin\cpp_edmi.lib
<EDM home directory>\Toolkitbin\Lib\cpp_edmi.dll
The EDMinterface/C++ library.
- <EDM home directory>\Toolkit\Lib\jexpress1-11.dll
<EDM home directory>\Toolkit\Lib\ jexpress1-11ts.dll
The EDMinterface/Java native library.
- <EDM home directory>\Java\jexpress-1-11.jar
The EDMinterface/Java archive.
- <EDM home directory>\Toolkit\Lib\edmivb.dll
The EDMinterface/VB library.
All dll files belonging to the EDM toolkit, will during EDM installation be installed in the WINDOWS system directory, i.e. it is not necessary to add <EDM_home_directory>\Toolkit\lib to the PATH.
The <EDM home directory>\Java\jexpress-1-11.jar will be added to the CLASSPATH during installation of EDM.
Visual C++ options (version 5.0/6.0)
In Project Settings:C/C++ folder:
Category PreprocessorAdd _STDC_in Preprocessor definitions (Settings for All configuration)
Ad<EDM home directory>\Toolkit\Includein Additional include directories (Settings for All configuration)
Category Code Generation Struct member alignment: 8 Bytes (Settings for All configurations)
Use run-time library: Multithreaded (Settings for Win 32 Release)
Use run-time library: Debug Multithreaded (Settings for Win 32 debug)
On UNIX platforms:
...
On UNIX platforms:
- <EDM home directory>/sdai.h
The EDMI header file.
- <EDM home directory>/edmi/edmi.a
The EDMinterface static library.
- <EDM home directory>/edmi/jexpress1-11.so
The EDMinterface shared library (including The EDMinterface/Java native library)
- <EDM home directory>/jar/jexpress-1-11.jar
The EDMinterface/Java archive.
ANSI C conformance option should be used when compiling C. Also add <EDM_home_directory> /edmi to the preprocessor #include file search path.
If you follow the instructions found in EDMassistVolume II during installation no further setup is needed. The LD_LIBRARY_PATH (LIBPATH) and CLASSPATH will then be defined each time you log in.
Manipulating EDM databases.
As indicated previously in this chapter, a newly created EDMdatabase contains two distinct repositories, namely a dictionary repository and a data repository. The two repositories can be manipulated by the same set of EDMinterface functions.
Database operations
The following functions handle EDM databases.
- edmiCreateDatabase.
- edmiOpenDatabase.
- edmiCloseDatabase.
- edmiDeleteDatabase.
Repository operations
The following functions initializes and closes a repository:
...
- edmiCreateRepository
- edmiDeleteRepository
- edmiDeleteRepositoryBN
- edmiGetRepository
- edmiGetRepositoryOpenMode
- edmiGetRepositoryOpenModeBN
- edmiOpenRepository
- edmiOpenRepositoryBN
Model operations
The principal functions to initialize and close models are:
...
- edmiConvertModelBN
- edmiConvertModelsBN
- edmiCopyModel
- edmiCopyModelBN
- edmiCreateModel
- edmiCreateModelBN
- edmiDeleteModel.
- edmiDeleteModelBN.
- edmiDeleteModelContents.
- edmiGetModel
- edmiGetModelBN
- edmiGetModelOpenMode
- edmiGetModelOpenModeBN
- edmiGetModelRepository
Instance operations
The principal functions to create and delete instances are:
...
- edmiAggrDifference
- edmiAggrIntersection
- edmiAggrUnion
- edmiIsAggrSubset
- edmiIsAggrSuperset
Attribute operations
The functions to set attribute values are:
...
The EDM macro functions.
The EDMinterface also provides a set of functions with high level functionality. These functions are referred to as the EDMI macro functions.
EDMexpressCompiler |edmiDefine
.Schema functions|
| EDMp21Handler . | edmiReadStepFile, edmiWriteStepFile |
|EDMmodelConverter .edmiConvertModel
functions|
|EDMmodelChecker .edmiValidate
functions|
Two sample applications:
The two applications found below are clearly quite simplified ones. Nevertheless, they demonstrate the basic principles, which are just as applicable to a complex application.
Example One: Hello world
/---------------------------------------------------------------/
/* */
/* C-LateBinding hello example: */
/* - Creates and opens a database. */
/* - Compiles an EXPRESS schema. */
/* - Creates a data model. */
/* - Populates an instance. */
/* - Retrieves an attribute value. */
/* */
/* --------------------------------------------------------------*/
#include <stdio.h>
#include "sdai.h"
#define DBLOC "db"
#define EXP_FILE "hello.exp"
#define DBNAME "db"
#define DBPASSW "db"
#define MYSCHEMA "hello_schema"
#define MYMODEL "HELLO"
#define DIA_FILE "comp.dia"
#define STEP_FILE "hello.stp"
void main()
{
long rstat,nwarnings,nerrors;
SdaiRepository data_repository;
SdaiSession sessionId;
SdaiModel mymodel;
SdaiInstance hello_instance;
SdaiString hello_world;
char c;
/------------------------------------------/
/* CREATE DATABASE AND OPEN SESSION */
/* -----------------------------------------*/
rstat = edmiDeleteDatabase(DBLOC,DBNAME,DBPASSW);
rstat = sdaiErrorQuery();
rstat = edmiCreateDatabase(DBLOC,DBNAME,DBPASSW);
rstat = edmiOpenDatabase(DBLOC,DBNAME,DBPASSW);
sessionId = sdaiOpenSession();
if(rstat = sdaiErrorQuery()) goto err;
/------------------------------------------/
/* COMPILE THE SCHEMA */
/* -----------------------------------------*/
if(rstat = edmiDefineSchema(EXP_FILE, DIA_FILE, NULL, 0, &nwarnings, &nerrors)) goto err;
if(nerrors){
printf("\nErrors when compiling %s",EXP_FILE);
goto end;
}
/-----------------------------------------------------/
/* OPEN THE DATA REPOSITORY,CREATE A MODEL AND OPEN IT */
/* ----------------------------------------------------*/
data_repository = sdaiOpenRepositoryBN("DataRepository");
mymodel = sdaiCreateModelBN(data_repository,MYMODEL,MYSCHEMA);
mymodel = sdaiOpenModelBN(data_repository,MYMODEL,sdaiRW);
if(rstat = sdaiErrorQuery()) goto err;
/-----------------------------------------------------/
/* POPULATE INSTANCE */
/* ----------------------------------------------------*/
hello_instance = sdaiCreateInstanceBN(mymodel,"HELLO");
sdaiPutAttrBN(hello_instance,"HELLO",sdaiSTRING,"Hello world!");
if(rstat = sdaiErrorQuery()) goto err;
/-----------------------------------------------------/
/* RETRIEVE ATTRIBUTE VALUE */
/* ----------------------------------------------------*/
sdaiGetAttrBN(hello_instance,"HELLO",sdaiSTRING,&hello_world);
if(rstat = sdaiErrorQuery()) goto err;
printf("\n%s\n",hello_world);
goto end;
err:
/-------/
/* ERROR */
/* ------*/
printf("\nERROR: rstat= %d: %s",rstat,edmiGetErrorText(rstat));
end:
/-----------------/
/* CLOSE DATABASE */
/* ----------------*/
edmiCloseDatabase("");
if(rstat){
printf("\nError\n");
} else {
printf("\nNo error\n");
}
#ifdef _WINDOWS
c = getchar();
#endif
}
Example two: The Flinstone family:
/------------------------------------------------------------/
/* */
/* C-LateBinding example. */
/* This small application demonstrates the most basic edmi */
/* functionality as it: */
/* - Creates and opens a database. */
/* - Compiles an EXPRESS schema. */
/* - Creates a data model. */
/* - Populates instances. */
/* - Relates instances. */
/* - Populates aggregates */
/* - Looks up instances. */
/* - Retrieves attribute values. */
/* - Performes aggregate iteration. */
/* - Exports a STEP file. */
/* */
/* The CHECK_ERR macro checks the edmi error code. */
/* For the purpose of readabilty the usage of macro has */
/* been restricted. */
/* In a real application one should perhaps condsider more */
/* frequent usage in order to achieve robust code. */
/* */
/* -----------------------------------------------------------*/
#include <stdio.h>
#include "sdai.h"
#define DBLOC "db"
#define EXP_FILE "family.exp"
#define DBNAME "db"
#define DBPASSW "db"
#define MYSCHEMA "family_schema"
#define MYMODEL "FAMILY"
#define DIA_FILE "comp.dia"
#define STEP_FILE "family.stp"
#define CHECK_ERR(file,line) \
casefile = file; \
caseline = line; \
if (rstat = sdaiErrorQuery()) goto err;
void main()
{
long rstat,nwarnings,nerrors;
SdaiRepository data_repository;
SdaiSession sessionId;
SdaiErrorCode sdaiError;
SdaiModel mymodel;
SdaiInstance the_flintstones;
SdaiInstance fred_flintstone;
SdaiInstance wilma_flintstone;
SdaiInstance pebbles_flintstone;
SdaiInstance rocky_flintstone;
SdaiInstance ff,wife,child,mother,family;
SdaiAggr pets,children,the_pets;
SdaiString given_name,surname,pet_name,family_name,adress;
SdaiInteger index,hits,number_of_children,number_of_pets;
SdaiIterator iter;
char c;
char* casefile;
int caseline;
/------------------------------------------/
/* CREATE DATABASE AND OPEN SESSION */
/* -----------------------------------------*/
rstat = edmiDeleteDatabase(DBLOC,DBNAME,DBPASSW);
rstat = sdaiErrorQuery();
rstat = edmiCreateDatabase(DBLOC,DBNAME,DBPASSW);
rstat = edmiOpenDatabase(DBLOC,DBNAME,DBPASSW);
sessionId = sdaiOpenSession();
CHECK_ERR(_FILE,LINE_);
/------------------------------------------/
/* COMPILE THE SCHEMA */
/* -----------------------------------------*/
rstat = edmiDefineSchema(EXP_FILE,DIA_FILE,NULL,0 ,&nwarnings,&nerrors);
CHECK_ERR(_FILE,LINE_);
if(nerrors){
printf("\nErrors when compiling %s",EXP_FILE);
goto end;
}
/-----------------------------------------------------/
/* OPEN THE DATA REPOSITORY,CREATE A MODEL AND OPEN IT */
/* ----------------------------------------------------*/
data_repository = sdaiOpenRepositoryBN("DataRepository");
mymodel = sdaiCreateModelBN(data_repository,MYMODEL,MYSCHEMA);
mymodel = sdaiOpenModelBN(data_repository,MYMODEL,sdaiRW);
CHECK_ERR(_FILE,LINE_);
/-----------------------------------------------------/
/* POPULATE A FAMILY INSTANCE */
/* ----------------------------------------------------*/
the_flintstones = sdaiCreateInstanceBN(mymodel,"FAMILY");
sdaiPutAttrBN(the_flintstones,"NAME",sdaiSTRING,"Flintstones");
sdaiPutAttrBN(the_flintstones,"ADRESS",sdaiSTRING,"Bedrock");
CHECK_ERR(_FILE,LINE_);
/-----------------------------------------------------/
/* POPULATE Fred Flintstone */
/* ----------------------------------------------------*/
fred_flintstone = sdaiCreateInstanceBN(mymodel,"MAN");
sdaiPutAttrBN(fred_flintstone,"GIVEN_NAME",sdaiSTRING,"Fred");
sdaiPutAttrBN(fred_flintstone,"SURNAME",sdaiSTRING,"Flintstone");
sdaiPutAttrBN(fred_flintstone,"FAMILY",sdaiINSTANCE,the_flintstones);
CHECK_ERR(_FILE,LINE_);
/-----------------------------------------------------/
/* POPULATE Wilma Flintstone */
/* ----------------------------------------------------*/
wilma_flintstone = sdaiCreateInstanceBN(mymodel,"WOMAN");
sdaiPutAttrBN(wilma_flintstone,"GIVEN_NAME",sdaiSTRING,"Wilma");
sdaiPutAttrBN(wilma_flintstone,"SURNAME",sdaiSTRING,"Flintstone");
sdaiPutAttrBN(wilma_flintstone,"FAMILY",sdaiINSTANCE,the_flintstones);
CHECK_ERR(_FILE,LINE_);
/-----------------------------------------------------/
/* MARRIAGE */
/* ----------------------------------------------------*/
sdaiPutAttrBN(fred_flintstone,"WIFE",sdaiINSTANCE,wilma_flintstone);
CHECK_ERR(_FILE,LINE_);
/-----------------------------------------------------/
/* POPULATE Pebbles Flintstone (daughter) */
/* ----------------------------------------------------*/
pebbles_flintstone = sdaiCreateInstanceBN(mymodel,"WOMAN");
sdaiPutAttrBN(pebbles_flintstone,"GIVEN_NAME",sdaiSTRING,"Pebbles");
sdaiPutAttrBN(pebbles_flintstone,"SURNAME",sdaiSTRING,"Flintstone");
sdaiPutAttrBN(pebbles_flintstone,"FATHER",sdaiINSTANCE,fred_flintstone);
sdaiPutAttrBN(pebbles_flintstone,"MOTHER",sdaiINSTANCE,wilma_flintstone);
sdaiPutAttrBN(pebbles_flintstone,"FAMILY",sdaiINSTANCE,the_flintstones);
CHECK_ERR(_FILE,LINE_);
/-----------------------------------------------------/
/* POPULATE Rocky Flintstone (son) */
/* ----------------------------------------------------*/
rocky_flintstone = sdaiCreateInstanceBN(mymodel,"MAN");
sdaiPutAttrBN(rocky_flintstone,"GIVEN_NAME",sdaiSTRING,"Rocky");
sdaiPutAttrBN(rocky_flintstone,"SURNAME",sdaiSTRING,"Flintstone");
sdaiPutAttrBN(rocky_flintstone,"FATHER",sdaiINSTANCE,fred_flintstone);
sdaiPutAttrBN(rocky_flintstone,"MOTHER",sdaiINSTANCE,wilma_flintstone);
sdaiPutAttrBN(rocky_flintstone,"FAMILY",sdaiINSTANCE,the_flintstones);
CHECK_ERR(_FILE,LINE_);
/-----------------------------------------------------/
/* POPULATE THE FLINTSTONE PETS */
/* ----------------------------------------------------*/
pets = sdaiCreateAggrBN(the_flintstones,"PETS");
sdaiAdd(pets,sdaiSTRING,"Dino");
sdaiAdd(pets,sdaiSTRING,"Hoppy");
sdaiAdd(pets,sdaiSTRING,"Gazoo");
CHECK_ERR(_FILE,LINE_);
/-----------------------------------------------------/
/* EXPORT MODEL TO STEP FILE */
/* ----------------------------------------------------*/
rstat = edmiWriteStepFile("DataRepository",NULL,MYMODEL,STEP_FILE,
NULL,NULL,EDM_IDENTIFIERS,8,
&nwarnings,&nerrors,&sdaiError);
if(rstat){
if(rstat != edmiESTEPWRITE){
CHECK_ERR(_FILE,LINE_);
} else {
printf("\n%d errors, %d warnings during export to:
%s",nerrors,nwarnings,STEP_FILE);
rstat = 0;
}
}
/-----------------------------------------------------/
/* LOOKUP Fred Flinstone */
/* ----------------------------------------------------*/
index = 0;
hits = 1;
rstat = edmiSelectInstancesBN(mymodel,"MAN","(GIVEN_NAME = 'Fred') AND
(SURNAME = 'Flintstone')",
0,sizeof(SdaiInstance),&index,&hits,&ff);
CHECK_ERR(_FILE,LINE_);
if(hits != 1){
printf("\nLookup failed. Should never happen!");
rstat = 1;
goto end;
}
sdaiGetAttrBN(ff,"FAMILY",sdaiINSTANCE,&family);
sdaiGetAttrBN(family,"NAME",sdaiSTRING,&family_name);
sdaiGetAttrBN(family,"ADRESS",sdaiSTRING,&adress);
CHECK_ERR(_FILE,LINE_);
printf("\nThe %s family lives in %s.",family_name,adress);
if(family_name) edmiFree(family_name);
if(adress) edmiFree(adress);
/-----------------------------------------------------/
/* GET FREDs WIFE AND THEIR COMMON CHILDREN */
/* ----------------------------------------------------*/
sdaiGetAttrBN(ff,"WIFE",sdaiINSTANCE,&wife);
sdaiGetAttrBN(wife,"GIVEN_NAME",sdaiSTRING,&given_name);
sdaiGetAttrBN(wife,"SURNAME",sdaiSTRING,&surname);
CHECK_ERR(_FILE,LINE_);
printf("\nFred Flinstone is married to %s %s.",given_name,surname);
if(given_name) edmiFree(given_name);
if(surname) edmiFree(surname);
printf("\nThey have the children: ");
sdaiGetAttrBN(ff,"CHILDREN",sdaiAGGR,&children);
number_of_children = sdaiGetMemberCount(children);
for(index = 0; index < number_of_children; ++index){
/* Using index to get element */
edmiGetAggrElement(children,index,sdaiINSTANCE,&child);
sdaiGetAttrBN(child,"MOTHER",sdaiINSTANCE,&mother);
if(mother == wife){
sdaiGetAttrBN(child,"GIVEN_NAME",sdaiSTRING,&given_name);
sdaiGetAttrBN(child,"SURNAME",sdaiSTRING,&surname);
printf("%s %s",given_name,surname);
if(index < (number_of_children-1)) printf(" and "); else printf(".");
if(given_name) edmiFree(given_name);
if(surname) edmiFree(surname);
}
}
CHECK_ERR(_FILE,LINE_);
/-----------------------------------------------------/
/* GET THE FLINTSTONE PETS */
/* ----------------------------------------------------*/
printf("\nThe Flintstones have the pets: ");
sdaiGetAttrBN(family,"PETS",sdaiAGGR,&the_pets);
number_of_pets = sdaiGetMemberCount(the_pets);
index = 0;
iter = sdaiCreateIterator(the_pets);
while(sdaiNext(iter)){
++index;
/* Using iterator to get element */
sdaiGetAggrByIterator(iter,sdaiSTRING,&pet_name);
printf("%s",pet_name);
if(index < (number_of_pets)) printf(" and "); else printf(".");
if(pet_name) edmiFree(pet_name);
}
sdaiDeleteIterator(iter);
CHECK_ERR(_FILE,LINE_);
goto end;
err:
/-------/
/* ERROR */
/* ------*/
printf("\nError at: %s,%d\nrstat= %d:
%s",casefile,caseline,rstat,edmiGetErrorText(rstat));
end:
/-----------------/
/* CLOSE DATABASE */
/* ----------------*/
edmiCloseDatabase("");
if(rstat){
printf("\nOOPS!\n");
} else {
printf("\nYabba-Dabba-Doo!\n");
}
#ifdef _WINDOWS
c = getchar();
#endif
}