gtpa2m1t | Application Programming |
This section provides information about some of the characteristics that are unique to TPFCS application programs.
To access TPFCS data stores and collections, the application must do the following:
Calling the TO2_createEnv function accomplishes all of these goals.
The TO2_createEnv function is issued once by each ECB for each data store in the database that is accessed by that ECB. In other words, if the application will be creating collections in multiple data stores, the application will have to issue a TO2_createEnv for each data store. The environment block that is created is built in ECB private storage and, therefore, cannot be shared among ECBs and its pointer cannot be saved to be used by other ECBs.
A pointer to the environment block is returned by the TO2_createEnv function so that your application can access the database. The environment block that is created is used on almost all the TPFCS function calls. The collection creation functions (TO2_create...) use the environment block to determine in which data store to create the collection.
Because the TPFCS system can usually determine the correct data store to work with from the persistent identifier (PID) of the collection, the data store of the environment passed to a function call does not need to be the same as the data store in which the collection was created. For example, an environment could be created with the TPFDB data store and be used by an application to access any collection already created in any data store. However, if a target collection PID is not included on a function call (such as with the TO2_atDSdictKey function), the appropriate data store environment must be used.
When the ECB has completed accessing the TPFCS database, enter a TO2_deleteEnv function call to allow TPFCS to clean up and release any allocated system resources that it is still holding.
The following type definitions are found in the c$to2.h header file:
When a TPFCS function is successful, it returns a positive value to the application program. When an error occurs in an attempt to process a TPFCS function, TPFCS sets an error code in the environment block and returns TO2_ERROR (which is defined as zero) to the application program. Once the application identifies that an error has occurred, it can query the environment block using the TO2_getErrorCode function to determine the specific error that has occurred. If additional text describing the error is desired, the error code can be passed to the TO2_getErrorText function. Error processing is handled the same way regardless of the type of function being called. See Types of Functions for more information.
For more information about error codes, see the TPF C/C++ Language Support User's Guide.
By convention, TPF API return codes indicate successful or unsuccessful completion by returning positive or zero values, respectively. This convention is violated somewhat by TPFCS API functions returning positive or zero values for true or false results, respectively.
To distinguish an unsuccessful API return code from a Boolean zero result, use the TO2_getErrorCode function call for error value retrieval. A zero error code value indicates a successful return of TO2_IS_FALSE while a nonzero error code value indicates an error return from the Boolean API function.
The following logic might be used in an application program to test for an error on a Boolean function:
TO2_isEmpty
If a value of TO2_ERROR (0) is returned, this indicates that either an error has occurred or a value of TO2_IS_FALSE has been returned. If a value of TO2_IS_TRUE is returned, this indicates that no error has occurred.
TO2_getErrorCode
If a value of TO2_IS_FALSE (0) is returned, this indicates that no error has occurred. All other values returned from TO2_getErrorCode indicate the error that occurred.
TO2_getErrorText
When an error occurs in the attempt to process a function, TPFCS sets an error code in the environment block and returns a 0 to the application program. The following example shows how an application can check to see if an error occurs when calling a Boolean TPFCS function.
#include <c$to2.h> /* Needed for TO2 API Functions */ #include <stdio.h> /* APIs for standard I/O functions */ TO2_PID cursor; TO2_ENV_PTR env_ptr; TO2_ERR_CODE err_code; /* TO2 error code value */ TO2_ERR_TEXT_PTR err_text_ptr; /* TO2 error code text pointer */
·
·
·
/**********************************************************************/ /* Are there more elements after the current one? */ /**********************************************************************/ if (TO2_more(&cursor,env_ptr) == TO2_ERROR) { err_code = TO2_getErrorCode(env_ptr); if (err_code != TO2_IS_FALSE) { printf("TO2_more failed!\n"); err_text_ptr = TO2_getErrorText(env_ptr, err_code); printf("The error is: %s\n", err_text_ptr); } else printf("There are no more elements after the current element.\n"); } else printf("There are more elements after the current element.\n");
To access a collection, the application must determine the PID of the collection. The recommended approach is to place the PIDs of data store anchor collections in the data store application dictionary and assign a symbolic name to each one as the key. This dictionary, which has the preassigned name of DS_USER_DICT, is accessed by establishing an environment for the target data store and using the TO2_...DSdict... type functions. For example, you can use the TO2_atDSdictNewKeyPut function to store the PID of an anchor in the dictionary. You can retrieve the PID of an anchor with the TO2_atDSdictKey function. The dictionary uses EBCDIC keys of 64 bytes with data elements of up to 1000 bytes.
The TPF dictionary (the application dictionary of TPFDB, the base TPFCS data store) can be accessed with a special set of functions (TO2_...TPF...). This allows all applications access to a common dictionary without needing to establish an environment for a particular data store. A possible use for this dictionary is to associate applications with data stores.
The examples in this section describe the steps that could be followed for initial population of a data store and for application startup.
When a data store is first created, the startup flow for an application that initially populates the data store could be as follows:
Optionally, you can associate particular applications with this data store by doing the following:
The startup flow for a typical application could be as follows:
Make the following assumptions: