Using More than One Database

You saw on the C Program Structure page how LIBMAKE automatically generates a call to db_open(). When db_open is called, the global variable db_nr is set to the number of the database that you open, and another global variable, db_generation, is set to the generation number specified in the call to db_open().

The values held in db_nr and db_generation are used to determine which database to use by all the database access functions.

If you wish to open a second database, and your program will switch between the two databases, these global variables must be saved before you make the second call to db_open, and you will have to set the variables as necessary to access each database.

Suppose that you create a copy of the SALESORD database called SALES2. If your program uses LIBMAKE to open the SALESORD database, you can open SALES2 as follows:

int salesord_dbnr,salesord_generation,sales2_db_nr,sales2_db_generation;
salesord_db_nr = db_nr;
salesord_db_generation = db_generation;
db_open("SALES2", 11, SHARED + PRIVATE_DB);
sales2_db_nr = db_nr;
sales2_db_generation = db_generation;

If you later wish to use database functions on the SALESORD database, you must first reset db_nr and db_generation as follows:

db_nr = salesord_db_nr;
db_generation = salesord_db_generation;
rec_fech_main(EQUAL,&order_header.l); /* goes to salesord */
To switch back to using the SALES2 database, reset db_nr and db_generation again:

db_nr = sales2_db_nr;
db_generation = sales2_db_generation;
rec_fech_main(EQUAL,&order_header.l); /* goes to sales2 */

It is very easy to forget to set the db_generation variable. If you do forget this, you may be lucky and encounter a system error such as system error 80. If you are unlucky you may end up with mangled data on your database, because the data independence mechanism relies on the value of db_generation being correct.

Accessing multiple databases - A Better Way

From 4.620, If you want to access more than one database, and especially if you want to have more than one connection to DP4 (for instance, because you are accessing multiple servers using srv_connect()) you may find it more convenient to use the functions contained in dp4dbapi.h rather than the C functions this manual concentrates on. In fact the dp4dbapi.h functions are the "fundamental" functions in 4.620, and the C library functions just call them. These functions are also intended to replace the dp4dyn interface functions. There is a one to one mapping between the C functions described in this manual and the functions in dp4dbapi.h. The only differences are as follows:

The dp4dbapi.h functions are also similar to the functions available in dp4dyn, but with the following differences:

Going back to the example in the previous section, we could now access the two databases together very easily, for example:

DCONN *salesord_conn = dp4_db_open(conn,"salesord",11,SHARED+PRIVATE_DB,0,0,0);
DCONN *salesw_conn = dp4_db_open(conn,"sales2",11,SHARED+PRIVATE_DB,0,0,0);
BOOLEAN found;
for (found = dp4_rec_fetch(salesord_conn,&order_header.l,FIRST,0,0,0) > 0;found;
     found = dp4_rec_fetch(salesord_conn,&order_header.l,NEXT,0,0,0) > 0)
   if (dp4_db_fetch(sales2_conn,&order_header.l,EQUAL,0,0,0) <= 0)
     printf("Order %n is on salesord but not sales2\n",order_header.order_nr);

This code would be no more complicated even if the two databases were on two different servers! (apart from the fact that you would have to open a connection to the other server)

You can use a mixture of the new and old style functions in a single program, but you should not mix calls to the two sets of functions on the same connection. In particular you must not call dp4_db_open() on the global connection handle used by the DP4 C library, otherwise you will not get a new connection handle, but the existing global connection will be reused.

For C++ programmers, the dp4dbase files, contained in the dp4dyn subdirectory, should be a convenient way of using the dp4dbapi version of the DP4 database functions. dp4dbase.h and dp4dbase.cpp are a source code compatible replacement of the old dp4class interface.

Anyone planning to use dp4dbapi directly from a C program should note that it is not intended that you mix calls to the dp4dbapi library and the traditional C library. This has not been tested and there might be some problems with doing this - although the C library is now implemented as a wrapper around dp4dbapi, there are some differences in how the data used internally by dp4dbapi is created when it is used from the DP4 C library.