Examples

The source code of the examples and the data needed to run them can be found in the following directory of the Tamino API for C documentation: <TaminoInstallDir>/SDK/TaminoAPI4C/Documentation/inoapi4c/examples/. All examples use a database with the default name "mydb"; the name can be changed by changing the argument to the tac_init() calls.

The following topics are covered below:


Determine the Tamino Version

As a first example of using the Tamino API for C, we shall illustrate how to ask a specific database for the corresponding Tamino version number. The source code reads:

01:  /********************************************************
02:   *  Copyright (c) 2004 SOFTWARE AG, All Rights reserved
03:   ********************************************************
04:   *  - ask a Tamino database for its version number
05:   ********************************************************/
06:  
07:  #include <stdio.h>
08:  #include "TaminoAPI4C.h"
09:
10:  #define checkERROR(a)	if(a != TAC_SUCCESS) goto error
11:
12:  int main()
13:  {
14:     TAC_HANDLE handle;
15:     const char *response;
16:
17:     /* initialize the API */
18:     if ((handle = tac_init("mydb")) < 0) goto error;
19:
20:     /* ask for the Tamino version */
21:     checkERROR(tac_diagnose(handle, "version"));
22:
23:     /* display the Tamino response */
24:     checkERROR(tac_last_xml_response(handle, &response));
25:     printf("%s", response);
26:
27:     /* finalize the API */
28:     checkERROR(tac_end(handle));
29:
30:     return 0;
31:
32:     /* error handling */
33:  error:
34:     (void) tac_get_messagetext(handle, &response);
35:     printf("%s\n", response);
36:     (void) tac_end(handle);
37:
38:     return 1;
39:  }

In line 08, we include the provided header file TaminoAPI4C.h, which contains predefined constants and function prototypes. The macro in line 10 makes the error handling easier and the source code more readable. The API is initialized in line 18 through a call to tac_init(). If the returned handle is valid, it has a non-negative value that will be used as the first argument to subsequent API calls. The Tamino version is determined in line 21 by a call to tac_diagnose() and the result is displayed as an XML string through a call to tac_last_xml_response() in lines 24-25. The API is finalized in line 28 by calling tac_end(). Error handling is done in lines 33-36 by calling tac_get_messagetext() and printing the result to stdout.

When compiling the above example, link it with the shared library from the Tamino API for C, this is either TaminoAPI4C.lib (Windows) or libTaminoAPI4C.so (UNIX).

Load and Retrieve XML and Non-XML Documents

The next example loads XML and non-XML (binary) data into a Tamino database. The structure is given by a Tamino schema and all data is loaded from files using the file handling routines described in detail in the section File Handling Reference. The source code reads:

01:  /********************************************************
02:   *  Copyright (c) 2004 SOFTWARE AG, All Rights reserved
03:   ********************************************************
04:   *  - load and retrieve data into/from Tamino database
05:   ********************************************************/
06:  #include <stdio.h>
07:  #include "TaminoAPI4C.h"
08:  #include "TaminoAPI4C_2.h"
09:
10:  #define checkERROR(a)   if(a != TAC_SUCCESS) goto error
11:
12:  int main()
13:  {
14:     TAC_HANDLE handle;
15:     const char *response;
16:
17:     /* initialize the API */
18:     if ((handle = tac_init("mydb")) < 0) goto error;
19:
20:     /* load Tamino schema definition from file */
21:     checkERROR(tac_define_from_file(handle, "TAC_samples.tsd"));
22:
23:     /* load XML entries from file into Tamino collection */
24:     checkERROR(tac_process_from_file(handle, "RealEstate",
25:                                      "TAC_samples.xml"));
26:
27:     /* load non-XML data from file into Tamino collection */
28:     checkERROR(tac_load_from_file(handle, "RealEstate",
29:                "images/sample1.jpg", "TAC_sample1.jpg", "image/jpeg"));
30:     checkERROR(tac_load_from_file(handle, "RealEstate",
31:                "images/sample2.jpg", "TAC_sample2.jpg", "image/jpeg"));
32:
33:     /* check for entries in the Tamino collection */
34:     checkERROR(tac_xql(handle, "RealEstate", "/images"));
35:
36:     /* display the Tamino response */
37:     checkERROR(tac_last_xml_response(handle, &response));
38:     printf("%s\n", response);
39:
40:     /* undefine the above defined schema (clean-up) */
41:     checkERROR(tac_undefine(handle, "RealEstate"));
42:
43:     /* finalize the API */
44:     checkERROR(tac_end(handle));
45:
46:     return 0;
47:
48:  /* error handling */
49:  error:
50:     (void) tac_get_messagetext(handle, &response);
51:     printf("%s\n", response);
52:     tac_end(handle);
53:
54:     return 1;
55:  }

In line 08, we include the provided header file TaminoAPI4C.h, which contains predefined constants and function prototypes. The macro in line 10 makes the error handling easier and the source code more readable. The API is initialized in line 18 through a call to tac_init(). If the returned handle is valid, it has a non-negative value that will be used as the first argument to subsequent API calls. The schema of the XML data is loaded from a file in line 21 and the corresponding data is loaded in line 24. The schema also allows for non-XML data to be inserted: two images are loaded in lines 28-31. In order to check whether the documents were loaded into the database, we submit a query in line 34 which asks for the entries of the two binary images and displays the XML result document in lines 37-38. The XML entries can be retrieved by changing the last argument in tac_xql(), for example, into "/person", "/property" or simply "*". We do a clean-up in line 41 by deleting the collection "RealEstate" which also deletes all of the previously inserted documents. The API is finalized in line 44 by calling tac_end(). The error handling is done in lines 48-54 by calling tac_get_messagetext() and printing the result to stdout.

When compiling the above example, link it with the shared library from the Tamino API for C, this is either TaminoAPI4C.lib and TaminoAPI4C_2.lib on Windows platforms or libTaminoAPI4C.so and libTaminoAPI4C_2.so on UNIX platforms.

List All Collections in a Database

The following example lists all collections available in a given Tamino database. It uses the XML parser Expat (http://www.libexpat.org/) to process the response from Tamino. The source code reads:

01:  /********************************************************
02:   *  Copyright (c) 2004 SOFTWARE AG, All Rights reserved
03:   ********************************************************
04:   * - list all collections in a Tamino database
05:   ********************************************************/
06:
07:  #include <stdio.h>
08:  #include <string.h>
09:  #include "expat.h" /* use Expat XML parser for Tamino responses */
10:  #include "TaminoAPI4C.h"
11:
12:  #define checkERROR(a)   if(a != TAC_SUCCESS) goto error
13:
14:  #ifdef _WIN32
15:  #  define strcasecmp(a, b) _stricmp(a, b) /* non-case sensitive co. */
16:  #endif
17:
18:  static void CollectionElement
19:              (void *userData, const char *name, const char **atts)
20:  {
21:    int I = 0;
22:    int *number = (int *) userData;
23:
24:    if (strcasecmp(name, "tsd:collection") == 0) {
25:      *number += 1;
26:      printf("- info: Collection #%d:", *number);
27:      while (atts[i] != NULL) {
28:        if (strcasecmp(atts[i], "name") == 0) {
29:          printf("\t%s\n", atts[i+1]);
30:        }
31:        I+=2;
32:      }
33:    }
34:  }
35:
36:  static int find_collections(TAC_HANDLE handle)
37:  {
38:    XML_Parser parser;
39:    int ret_code1, ret_code2, number = 0;
40:    const char *response;
41:
42:    /* query the database */
43:    ret_code1 = tac_xql(handle, "ino:collection", "tsd:collection");
44:    if (ret_code1 == TAC_SUCCESS) {
45:      /* process the response */
46:      parser = XML_ParserCreate(NULL);
47:      XML_SetUserData(parser, &number);
48:      XML_SetElementHandler(parser, CollectionElement, NULL);
49:      (void) tac_last_xml_response(handle, &response);
50:      if ((ret_code2 = 
51:           XML_Parse(parser, response, strlen(response), 1)) == 0) {
52:        fprintf(stderr, 
53:           "- error: while parsing Tamino response (%d)\n", ret_code2);
54:      }
55:      XML_ParserFree(parser);
56:    }
57:    return ret_code1;
58:  }
59:
60:  int main()
61:  {
62:     TAC_HANDLE handle;
63:     const char *response;
64:
65:     /* initialize the API */
66:     if ((handle = tac_init("mydb")) < 0) goto error;
67:
68:     /* ask for all collections in the Tamino database */
69:     checkERROR(find_collections(handle));
70:
71:     /* finalize the API */
72:     checkERROR(tac_end(handle));
73:
74:     return 0;
75:
76:  /* error handling */
77:  error:
78:     (void) tac_get_messagetext(handle, &response);
79:     printf("%s\n", response);
80:     tac_end(handle);
81:
82:     return 1;
83:  }

The necessary header file to use the XML parser Expat is included in line 09. In line 10 we include the provided header file TaminoAPI4C.h, which contains predefined constants and function prototypes. The macro in line 12 makes the error handling easier and the source code more readable. The macro in line 14 is necessary to allow for case-insensitive string comparisons under Windows. The main program starts in line 60 and the API is initialized in line 66 through a call to tac_init(). If the returned handle is valid, it has a non-negative value that it is used as the first argument to subsequent API calls. In line 69, we call our function find_collections, which was defined in lines 36-58. In this function, we query the Tamino database "mydb" for its collections by calling the function tac_xql() in line 43. Our function CollectionElement, which is defined in lines 18-34, is registered to the XML parser in line 48. The actual parsing is initiated in line 51, where we provide the response from the previous tac_xql() call as argument. Whenever a new opening element tag is recognized by the XML parser in the source file, the registered function CollectionElement() is called, where we do a string comparison to find the correct entries that correspond to Tamino collections. All collection names are then printed to standard output. The API is finalized in line 72 by calling tac_end(). Error handling is done in lines 77-82 by calling tac_get_messagetext() and printing the result to stdout.

When compiling the above example, link it with the static or shared library from the Expat distribution (http://www.libexpat.org/) and also with the shared library from the Tamino API for C, which is either TaminoAPI4C.lib (Windows) or libTaminoAPI4C.so (UNIX).