Research Division EED/Controls Software
Release Note 135.0
OA and LAL Databases PC User Access
Julia Kozlovsky
August 23, 1993
Introduction
The Epicure Device Database holds information about devices and
provides a way of manipulating and accessing devices for data acquisition.
Several sets of routines exist for accessing the database via VAX/VMS.
However, accessing the Database with the same routines via the network from
PCs is impossible, since due to system differences between PC and VAX, the
format of the routines is not compatible. It was therefore decided to keep
the OA and LAL database files in an area accessible to the individual PCs via
network and to write a set of database accessing routines that are
PC-specific. The new db_pc_ routines are the PC equivalent of the
db_ routines for the VAX.
Overview
The Device Database is a dual database which has both centralized and
distributed elements. The Source database is the master copy which is
maintained on a single network node, whereas multiple copies of the OA
and LAL databases are distributed to several network nodes. The Optimized
Access (OA) and the Look-Aside-List (LAL) databases are derived from the
source database. They are optimized by using hash tables for device
lookup, storing the database records in contiguous memory and sharing
information between devices. The VAX users can get database information
by using the Epicure db_, dbsa_, or dbrpt_ services.
In order to be able to access database information via PC, it was necessary
to write a PC-specific equivalent of db_ routines, since there are
several system-specific differences (disscussed below) which make
it impossible to use db_ calls on PCs. OA and LAL database files will
be stored in an area accessible to the PCs via network and the users will
use db_pc_ routines to access database information in much the same way
as they did from the VAX.
PC Specifics
The new db_pc_ routines are implemented in Borland C++ and read the OA
and LAL files directly (instead of using the database server like
db_ routines do), so they are dependant on the particular features of
the system and the software. The effort was made to make the db_pc_
routines as similar to the db_ routines (from the point of view of
the user) as possible, but the user must be mindful of several important
differences.
First, some data structures changed because data types had to be converted:
- C++ uses IEEE floating point format (VAX uses VME format);
- C++ has no variant structure type;
- int data type in C++ is 16 bits long, not 32;
- C++ structures may not contain members of incomplete type (example:
char data[] is illegal as a structure member);
- C++ does not allow bit fields larger than 16 bits;
- In C++, the status of 0 is normal, 1 signifies error.
All the data structures for db_pc_ calls are in the following header
files:
- ''dbpcuser.h''
- - property and attribute codes; some property
and attribute structures and data types;
- ''oapcdata.h''
- - more property and attribute data types;
- ''dapspc.h''
- - DAP structures;
- ''ftdpc.h''
- - FTD structures;
Another difference to note is that device name strings are no longer
passed in by descriptors, but as a NULL-terminated string of characters.
Users must also remember that certain properties defined in ''dbpcuser.h''
are not defined for OA and LAL databases:
- DB_C_PRP_XTEXT,
- DB_C_PRP_HISTORY,
- DB_C_PRP_CONTROLLER_TYPE,
- DB_C_PRP_TPL_NAME_FORMAT.
Querying the database
An application must do the following to retrieve the information from
the database via PC:
- Open OA and LAL files, verify their version numbers and build
dates, reserve memory and read in the hash root for quick data
lookup (db_pc_init);
- Build a list of database requests (db_pc_add_request_*);
- Execute the list: read in the data an keep it in reserved memory
(db_pc_process_wait);
- Get the data (db_pc_get_data_*);
- Free the request list and the memory reserved for returned data
(db_pc_free_request_list). Attention: after this routine is called,
the data that was retrieved by db_pc_get_data_pointer is wiped out;
- When the database session is over, release all the memory reserved
for the hash roots (db_pc_completion).
The application must include the .h'' header file which
contains the function prototypes for db_pc_ calls.
Note, that such calls as db_pc_name_to_di, db_pc_di_to_name and
db_pc_get_dirange do not have to be put on a request list, since they
request information and return it all in one shot.
Routines Descriptions
Note: error reporting is handled differently for the db_pc_ routines
than for the db_ routines: any file or memory allocation error is reported
immediately and the program is interrupted, whereas all other errors
are only displayed after calling db_pc_signal_failure(status) or
SIGNAL_FAILURE(status). For all calls, status is returned as either
0 (normal) or 1 (error), and only after the status is passed to signal_failure
routines, the specific error is reported. The exact error codes are never
visible to the user, only a text message is displayed.
- status = db_pc_init()
- Open the OA and LAL files and verify their
versions and build dates, allocate memory and read in the hash root,
providing quick data lookup.
Possible errors:
- No hash root data available
- OA serial number mismatch
- LAL serial number mismatch
- status = db_pc_di_to_name(di, name)
- Return the name of a device
given its device index.
- di
- - device index. A longword passed by value.
- name
- - device name. A DB_S_NAME+1-character-long, null-terminated
string passed by value.
Possible errors:
- The initialization routines have not been called
- Device has been deleted
- No such device
- status = db_pc_name_to_di(name, di)
- Return the index of a device
given its name.
- name
- - device name. A DB_S_NAME+1-character-long, null-terminated
string passed by value.
- di
- - device index. A longword passed by reference.
Possible errors:
- The initialization routines have not been called
- Device has been deleted
- Device has been renamed
- No such device
- status = db_pc_get_dirange(low_di, high_di)
- This routine returns
the minimum and the maximum DIs in the OA and LAL databases.
- low_di
- - lowest DI in the OA and LAL databases. A longword
passed by reference.
- high_di
- - highest DI in the OA and LAL databases. A longword
passed by reference.
Possible errors:
- The initialization routines have not been called
- No hash root data available
- status = db_pc_add_request_di(di, prop, [attr
- , handle)] This
routine adds a request to the Database request list for the program.
The device is specified by its device index.
- di
- - device index. A longword passed by value.
- prop
- - property code (DB_C_PRP_...). Passed by value.
- attr
- - attribute code (DB_C_ATR..., use DB_C_ATR_NONE or 0 for
those properties with no attributes). Passed by value.
- handle
- - address of a longword to receive the returned identifier
to be used with the db_pc_get_data_ routines. Passed by reference.
Possible errors:
- The initialization routines have not been called
- Invalid property
- Attribute out of range
- No attributes defined for this property
- Must have an attribute for this property
- No such attribute defined for this property
- No requests allowed
- status = db_pc_add_request_name(name, prop, [attr
- , handle)] This
routine adds a request to the Database request list for the program.
The device is specified by its name.
- name
- - device name. A DB_S_NAME+1-character-long, null-terminated
string passed by value.
- prop
- - property code (DB_C_PRP_...). Passed by value.
- attr
- - attribute code (DB_C_ATR..., use DB_C_ATR_NONE or 0 for
those properties with no attributes). Passed by value.
- handle
- - address of a longword to receive the returned identifier
to be used with the db_pc_get_data_ routines. Passed by reference.
Possible errors:
- The initialization routines have not been called
- Invalid property
- Attribute out of range
- No attributes defined for this property
- Must have an attribute for this property
- No such attribute defined for this property
- No requests allowed
- status = db_pc_process_wait()
- Call after the request list is
completed to process all requests. The routine returns when all the data
is read into the internal memory.
Possible errors:
- The initialization routines have not been called
- No outstanding requests
- Property does not currently exist
- Attribute does not currently exist
- status = db_pc_get_data_pointer(handle, datptr, [retlen
- )] This
routine returns a pointer to the requested data which is located in
temporarily allocated memory.
- handle
- - retrieval identifier from the db_pc_add_request_ routines
for the requested data. A longword passed by value.
- datptr
- - address of a pointer to the data in the internal memory.
The pointer itself is passed by reference.
- retlen
- - actual length of the returned data (in bytes). A longword
passed by reference.
Possible errors:
- The initialization routines have not been called
- No data available
- status = db_pc_get_data(handle, [maxlen
- , retbuf, [retlen])] This
routine copies the requested data location into a user-provided buffer.
The user has the responsibility to reserve enough memory.
- handle
- - retrieval identifier from the db_pc_add_request_ routines
for the requested data. A longword passed by value.
- maxlen
- - size of the buffer (in bytes) for the returned data.
A longword passed by value.
- retbuf
- - the buffer in which the data is to be returned. Passed
by reference.
- retlen
- - actual length of the returned data (in bytes). A longword
passed by reference.
Possible errors:
- The initialization routines have not been called
- No data available
- Data has been truncated
- status = db_pc_get_data_length(handle, retlen)
- This routine
returns the length of the requested data.
- handle
- - retrieval identifier from the db_pc_add_request_ routines
for the requested data. A longword passed by value.
- retlen
- - actual length of the returned data (in bytes). A longword
passed by reference.
Possible errors:
- The initialization routines have not been called
- No data available
- status = db_pc_free_request_list()
- Free all of the memory
allocated for the requests and the returned data, reset the flags.
Possible errors:
- The initialization routines have not been called
- status = db_pc_completion()
- This routine must be called after
the database session is over. Free the memory allocated for the hash roots.
Possible errors:
- The initialization routines have not been called
- db_pc_signal_failure(status)
- If one of the db_pc_ routines has
returned an error, report the exact error.
- status
- - as returned by other db_pc_ calls: 0 (normal) or 1 (error).
The exact error codes are hidden, only a text message is displayed.
The Demo Program
This program demonstrates the use of most db_pc_ routines. It gets
property and attribute information from two database devices. Note
how the data is handled differently depending on the data type.
/* this demo program demonstrates the use of db_pc_ routines */
#include "dbpc.h" /* db_pc_ routine decalarations etc. */
main ()
{
int sts; /* status returned from db_pc_ calls */
/* names of two database devices */
char device_name_one[DB_S_NAME+1] = "PE3SEM "
char device_name_two[DB_S_NAME+1];
long di_one, di_two = 4199769; /* indexes of two database device */
long lo_di; /* lowest allocated device index */
long hi_di; /* highest allocated device index */
long source_class_handle, addressing_handle, scaling_handle,
beamline_handle, dap_handle;/* various request handles */
char source[DB_S_SOURCE_CLASS]; /* device source class */
struct
{
union
{
struct DB_ADDRESSING addr;
struct DB_SYNTHETIC_ADDR synaddr;
}addrs;
union dap_u dap;
} *addressing; /* holds addressing and dap information */
union
{
struct DB_ANALOG_SCALING analog;
struct DB_ACNET_PDB pdb;
} *device_scaling; /* holds scaling information */
struct DB_BEAMLINES *beamline; /* pointer to a beamline structure */
long dap; /* device dap type */
unsigned long ret_lng; /* length of the returned data */
/* open the database files, compare serial numbers,
* allocate dynamic memory and read the hash root into it */
sts = db_pc_init();
SIGNAL_FAILURE(sts);
/* for a given device name give device index */
sts = db_pc_name_to_di(device_name_one, &di_one);
SIGNAL_FAILURE(sts);
/* for a given device index, give device name */
sts = db_pc_di_to_name(di_two, device_name_two);
SIGNAL_FAILURE(sts);
/* build a list of database requests, using two
* different types of _add_request_ calls */
sts = db_pc_add_request_di(di_one, DB_C_PRP_READING, DB_C_ATR_SOURCE_CLASS,
&source_class_handle);
SIGNAL_FAILURE(sts);
sts = db_pc_add_request_di(di_one, DB_C_PRP_READING, DB_C_ATR_ADDRESSING,
&addressing_handle);
SIGNAL_FAILURE(sts);
sts = db_pc_add_request_di(di_one, DB_C_PRP_READING, DB_C_ATR_SCALING,
&scaling_handle);
SIGNAL_FAILURE(sts);
sts = db_pc_add_request_name(device_name_two, DB_C_PRP_BEAMLINE, 0,
&beamline_handle);
SIGNAL_FAILURE(sts);
sts = db_pc_add_request_name(device_name_two, DB_C_PRP_DAP_TYPE, 0,
&dap_handle);
SIGNAL_FAILURE(sts);
/* process the request list */
sts = db_pc_process_wait();
SIGNAL_FAILURE(sts);
/* get the data */
/* note that one could also get source by using the _get_data_pointer call */
sts = db_pc_get_data(source_class_handle, sizeof(source), source, &ret_lng);
SIGNAL_FAILURE(sts);
/* one could also get the addressing by using the _get_data call */
sts = db_pc_get_data_pointer(addressing_handle, &addressing, &ret_lng);
SIGNAL_FAILURE(sts);
/* same as above */
sts = db_pc_get_data_pointer(scaling_handle, &device_scaling, &ret_lng);
SIGNAL_FAILURE(sts);
/* ATTENTION: the beamline structure is of undetermined length,
* so it is always necessary to use the _get_data_pointer call */
sts = db_pc_get_data_pointer(beamline_handle, &beamline, &ret_lng);
SIGNAL_FAILURE(sts);
/* for dap, one could also use the _get_data_pointer call */
sts = db_pc_get_data(dap_handle, sizeof(long), &dap, &ret_lng);
SIGNAL_FAILURE(sts);
/* delete the request list, free memory etc. */
sts = db_pc_free_request_list();
SIGNAL_FAILURE(sts);
/* return the current high/low device index values */
sts = db_pc_get_dirange(&lo_di, &hi_di);
SIGNAL_FAILURE(sts);
/* The session is over, free memory */
sts = db_pc_completion();
SIGNAL_FAILURE(sts);
return(0);
}
Security, Privacy, Legal
rwest@fsus04.fnal.gov