Hi Everyone,
I am trying to write an MDL in C/C++ that should attach Meta-Data to Elements in an external MDB-Database.
I wrote already Code to make sure that the correct Database (DB) is attached, but now I have Problems how to attach the created MSLink to an element.
There is one function to write the Attributes into the DB and retrieve the MSLink:
Private int writeObjatt ( UInt32 *mslink, char *tableName, char *objidP, char *oclassP, char *ocodeP, char *icodeP, char *statusP ) { char insertStmt[MAXSTATEMENTLENGTH]; char dbColumns[5*TAGSTRINGVALLENGTH+10]; char dbValues[5*TAGSTRINGVALLENGTH+10]; int ret=-1, test1=-1; // Writing the column-names into a string sprintf(dbColumns, "objid, oclass, ocode, icode, status"); // writing the values into a string sprintf(dbValues, "'%s','%s','%s','%s','%s'", objidP, oclassP, ocodeP, icodeP, statusP); // writing the finlal SQL-Insert-Statement into a string sprintf(insertStmt, "insert into %s (%s) values (%s)", tableName, dbColumns, dbValues); fprintf(f_log, "\t(In tab2db_writeObjatt): Insert-Statement= '%s'\n", insertStmt); // Writing into Database test1 = mdlDB_addRowWithMslink(mslink, tableName, insertStmt); if(test1 == SUCCESS) ret=SUCCESS; return ret; }
Private int CallbackFunct ( ElementRef elR, void *callbackArg, // Structur with arguments for Callback-function ScanCriteriaP scP // Pointer to ScanCriteria-Object ) { int ret=SUCCESS; int test=-1, status=-1; int elType; // Element-Typ UInt32 mslink; // MSLink-Number CallbackArgStruct *data = (CallbackArgStruct*)callbackArg; MSElementP elP; EditElemHandle eh(elR, mdlScanCriteria_getModel(scP)); // Element-Handler char t_objidP[TAGSTRINGVALLENGTH], t_oclassP[TAGSTRINGVALLENGTH], t_ocodeP[TAGSTRINGVALLENGTH]; char t_icodeP[TAGSTRINGVALLENGTH], t_statusP[TAGSTRINGVALLENGTH]; // Checking Element-Type elType = eh.GetElementType(); // Pointer to element created from ElemeHandle elP = eh.GetElementP(); if(elType==CELL_HEADER_ELM || elType==LINE_ELM || elType==LINE_STRING_ELM || elType==LINE_STRING_ELM) { [...] // Retrieve Attribute-values from element // Writing Attributes into Database using the above mentioned function test = writeObjatt(&mslink, "objatt", t_objidP, t_oclassP, t_ocodeP, t_icodeP, t_statusP); //????? How to attach the MSLink to the MSElement ?????// // REPLACING the old element instead of rewriting in reason of different Size after MSLink-Attachment ?? status = ReplaceElement (elP); //??? if(test != SUCCESS) ret=-1; } return ret; }
Unknown said:I am trying to write an MDL in C/C++
For what version of MicroStation?
Unknown said:How to attach the MSLink to the MSElement?
The DB interface is rather idiosyncratic. Its terminology dates from Intergraph's hierarchical database from the 1980s, and doesn't match well with relational databases.
Look at the MDL help about DatabaseLink. It defines the struct with some comments. What you need to do is to fill in a DatabaseLink with your data, then append that linkage to your element.
DatabaseLink
You may be able to use mdlDB_buildLink() to build a linkage, but either way use mdlElement_appendAttributes() to attach the linkage to your element. Rewrite the element after attaching the linkage.
mdlDB_buildLink()
mdlElement_appendAttributes()
Regards, Jon Summers LA Solutions
Hi Jon,
many thanks for your answer, although my Problem is not solved yet.
Im working on MicroStation V8i SS4.
The structur of DatabaseLink is not very clear for me, e.g. what is meant with 'entity' in this context, is it the number of the table in mscatalog or the ElementID? And what do I have to fill in the LinkProps-structur and as dasType? In Addition I didn't found a function that uses the DatabaseLink-structure to append that linkage to an element.
I tried the following inside the function 'writeObjatt', for which I added the Parameter 'MSElement *elP':
Private int writeObjatt ( MSElement *elP, UInt32 *mslink, char *tableName, char *objidP, char *oclassP, char *ocodeP, char *icodeP, char *statusP ) { char insertStmt[MAXSTATEMENTLENGTH]; char dbColumns[5*TAGSTRINGVALLENGTH+10]; char dbValues[5*TAGSTRINGVALLENGTH+10]; int ret=-1, test1=-1, test2=-1, test3=-1; short link; int linkLength, linkType=OLEDB_LINKAGE, dasType=1; LinkProps props; UInt32 newfilePos; // Writing the column-names into a string sprintf(dbColumns, "objid, oclass, ocode, icode, status"); //writing the values into a string sprintf(dbValues, "'%s','%s','%s','%s','%s'", objidP, oclassP, ocodeP, icodeP, statusP); // writing the final SQL-Insert-Statement into a string sprintf(insertStmt, "insert into %s (%s) values (%s)", tableName, dbColumns, dbValues); //Writing into Database test1 = mdlDB_addRowWithMslink(mslink, tableName, insertStmt); // Filling the LinkProps-Structur props.information = NEWLINK; // new linkage generation mode ? props.remote = DB_PROP_REMOTE; // ?? props.modified = DB_PROP_MODIFIED; //?? props.user = DB_PROP_USER; // ?? props.linkageClass = OLEDB_ID; //?? test2 = mdlDB_buildLink(&link, &linkLength, linkType, &props, tableName, *mslink, dasType); test3 = mdlElement_appendAttributes(elP, linkLength, &link); newfilePos = mdlElement_rewrite(elP, NULL, mdlElement_getFilePos(FILEPOS_CURRENT, NULL)); if(test1 == SUCCESS && test3 == SUCCESS) ret=SUCCESS; return ret; }
It can be compiled without Problem, but it crashes Microstation during the first element I am working on. The Problem seemed to be in line 43, where the function mdlElement_appendAttributes() is called.
Is this in reason of wrong filled LinkProps-structur and dasType, or did I misunderstood something else?
Regards,
Ines Wieland
It seems you have not correctly built the "link" structure, which is typically 4 or 8 words, depending on the linkage type. The "link" should be an array.