This info is intended for all those who are working on wrappers or mediators that use CSL/SSL v1.0. Technical details will follow. The CSL/SSL v1.0 library has been updated to fix a few bugs as well as add a few new features. If your program links with "libtmcomm.a", "libtmssl.a", or "libtmcsl.a", you need to recompile your program to make sure that it still works. If you are writing Tsimmis wrapper or mediator that is intended to be able to connect with Mobie browser, you HAVE TO modify your program to support the partial fetch protocols now. If you don't modify your program, Mobie browser will not be able to perform partial fetch with your wrapper or mediator. Partial fetch can be supported by your wrapper in two ways. The simplest way is to rely on the SSL library to handle everything. The other way (preferred) is to provide "native" partial fetch ability. If you rely on SSL to do partial fetch, your wrapper will retrieve all objects from the native source after a query as before. Then you can pass the objects to the SSL library. SSL library caches the objects in memory and performs partial fetch on the cached objects. This kind of partial fetch will be called "default partial fetch" from now on. As usuall, the SSL library and CSL library contains a set of built-in default functions to support the default partial fetch behaviors without the need to make big modifications to your program. If you plan on using the preferred "native" partial support, you wrapper will have to be "smarter". You will need to provide (partial) objects from any portion of the result object space on demand. You can use your own caching scheme or using the partial fetch ability of your "native" source. This method is harder to implement than the previous one since it requires you to rewrite the way you fetch objects from the native source. The following describes the minimal set of things that you need to do in order for SSL library to handle partial fetch for you. (i.e. you need to do the following to have the default partial fetch ability.)
obj = TM_NewObject(...); TM_ObjectSetOid(obj, tmCreateRef(obj, NULL)); /* add this */You may not use your own kind of object id unless you are willing to write two more functions (see *).
/* ********************************************************************** * SybaseFetch -- Fetches result from last executed query. * This function calls Sybase library function to extract all tuples * from the query. Then OEM objects are created based on the tuples * extracted. This function can be called repeatly after a query is * submitted. However, it only retrieves objects from Sybase source * at most once after every query. * * RETURNS: * TM_NO_ERROR - no error * TM_QUERY_FAILED - query failed * **********************************************************************/ TM_Error SybaseFetch(TM_ConnEnd *conn, uint8 fetchType, TM_Data *objRef, TM_Object **result) { TM_Object *root; TM_Error err; DBPROCESS *dbproc; RETCODE retCode; if ((sDB == NULL) || (querySuccess == 0)) { return TM_FETCH_FAILED; } /* -- BEGIN CHANGE -- */ /* * the following is now commented out since the function needs to * support all fetch types. */ /* if (fetchType != TM_FETCH_ALL) { return TM_NO_SUPPORT; } */ /* -- END CHANGE -- */ answerObj.flags = 0; answerObj.label = "answer"; answerObj.type = "set"; /* * The global variable 'needFetch' variable is used to ensure that this * function retrieves at most once from Sybase source after every query * submission. The variable is set to '1' in the 'tmQuery' function. */ if (needFetch) { dbproc = sDB->dbproc; while ((retCode = dbresults(sDB->dbproc)) != NO_MORE_RESULTS) { if ((retCode == SUCCEED) && (DBROWS(sDB->dbproc))) { if (ExtractOEMResult(sDB->dbproc, &answerObj, tupleName, single) != TM_NO_ERROR) { return TM_FETCH_FAILED; } } } needFetch = 0; } /* BEGIN CHANGE */ /* * If you want to use SSL library to perform partial fetch, you should * not send your objects in this function. You must let the SSL to * send the objects for you. Alternatively, you can copy the code * from "tmssl.c" to do your own version of send which must * understand how to fetch the correct objects and send them * depending on the fetch type. */ /* return TM_DefaultSendAll(conn, &answerObj); */ /* * You must now return the root objects (regardless of the fetch type) * in the "result" parameter. You must return TM_NEED_SEND to signal * SSL library to send the objects for you. Note that this function * does not delete the objects before it returns since the SSL library * rely on the existance of these objects for partial fetch. * * This function also does not worry about the fetch type. SSL library * takes care of finding the needed objects using the returned pointer * to the "root" object. This function always returns the full object * tree. */ *result = &answerObj; return TM_NEED_SEND; /* END CHANGE */ }If you are interested in producing a "native" partial fetch wrapper, please contact Jiang (jwu@db.stanford.edu). We suspect that the above mentioned method will work ok for now since it requires minimal changes. Feel free to contact Jiang if you have any problems or encounter bugs.