
                PIA : Penpoint Information Architecture

                                By

                          Satya Yenigalla


Overview	2
Penpoint  Information Architecture  (PIA)	2
Introduction	2
PIA's Charter	3
Remote Versus Local Databases	3
PenPoint	4
Definitions  of Terms	4
Service Architecture	4
PIA Elements	6
PIA Datatypes	6
PIA access methods	7
Database Connections	7
Database Driver Capabilities	8
Common Access Messages	9
Service Messages	9
Query Messages  for sending requests	9
Query Messages for receiving results	10
Query Messages for data definitions	10
Query Messages for miscellaneous category	10
Penpoint Information Architecture (PIA) Header File	11
msgSMOpen	15
msgSMCharacteristics	17
msgDbDeclareCursor	18
msgDbOpenCursor	20
msgDbBuildDoQuery	21
msgDbPrepare	22
msgDbBind	23
msgDbCloseCursor	24
msgDbDeleteCursor	25
msgDbColCount	26
msgDbColDescribe	27
msgDbFetch	28
msgDbTables	29
msgDbColumns	30
msgDbIndexes	31
msgDbTransaction	32
msgDbError	33
Appendix A	34
Appendix B	36
Issues, concerns, ideas, etc.	36



Overview

Information processing is moving from stand-alone, conventional data
management to networked systems. Heterogeneous connectivity, gateway
access, and distributed computing are the themes for the 90's.

In order for database systems to be successful in this decade, they
must support not only the current stand-alone computing environments
but also the newer networked models. Another challenge the database
world is facing today is the need to provide applications with
uniform access to data, regardless of location, access method, and
database management system.

The support for multiple API's and the ability to connect and talk to
multiple computing environments have become the key factors in
determining the popularity of the current database systems.  The
database applications need to be decoupled from database access 
methods.  One approach is to define a standard interface and allow
client database drivers to implement the access methods that target
one or more database management systems.  In the pen-based
environment,  this approach leads to the notion of  services 
(database drivers)  which can be installed and invoked on demand.    

Penpoint  Information Architecture  (PIA) 

Introduction

Information storage and management has always been a critical
component of any computer environment, all the way from personal
computers to mainframes.  With the advent of PenPoint and tablet
computers,  a whole new arena  of database computing is opening up. 
What is needed from GO's perspective is a Penpoint Information 
Architecture (PIA)  which permits uniform  access to data, regardless
of location, access method, and database management system.   PIA is
a comprehensive architecture for database  connectivity on pen-based
computers.   It defines a database  application interface providing
common access to multiple  database  servers.

PIA  assumes that there are and always will be many viable 
communication methods, data protocols, and DBMS capabilities.   PIA's
goal is to allow for different  technologies to be used together by
defining standard interfaces  between them.  This approach gives 
implementors  independence to support both the standard (RDA & OSI) 
and proprietary based  technology.




PIA's Charter

PIA's charter is two fold.  First, to provide a common registration
mechanism to all kinds and types of databases.  This provides a
common look and feel to the user access of all the databases
registered under  PenPoint.  Centralizing the registration activity 
not only avoids redundancy of effort by the third parties  but also
provide a consistent mechanism to  register the databases.  

Secondly, and most importantly are the access methods.  PIA consists
of a set of messages that allow  the application developers to  build
database applications.  These messages are discussed in greater
detail in the chapters to follow.

Registration  of  databases provided by the PenPoint system  is
mandatory,  while adhering  to the  PIA   access methods  is
optional  but  highly desirable.



Remote Versus Local Databases

PIA provides database connectivity to both local and remote databases.
Local databases are the data stores that reside on the client
machine, that is penbased computer.  Examples in this category are
dBase files, Paradox files and so on.  In the case of dBase and
Paradox under PenPoint, the respective database drivers must parse the
SQL query made by an application and execute it directly against the
file itself, since there is no underlying DBMS engine to act as
database server.  However,  due to size and performance reasons,
these drivers can only support a subset of SQL. Such a subset is 
shown in APPENDIX A.









PenPoint

Definitions  of Terms

For those readers not familiar with the GO's terminology, here is a
brief explanation of the essential components of the PenPoint system.

OBJECT  is  the basic entity  of PenPoint systems.  It  responds to a
predefined set of messages. Objects encapsulate data and data access
methods.

METHODS are procedures within an object  that operate on the object's
data.  Methods govern the behavior and functionality of an object.

MESSAGES  are the external access to the methods.  Messages are
predefined protocols sent to an object.

DYNAMIC LINKED LIBRARIES (DLLs) are special program modules that
contain executable code but cannot be run as programs. Instead,
programs  load the appropriate DLLs and excute the code in the
libraries by linking to them dynamically.  The chief advantage of
DLLs is that they reduce the amount of memory needed by a program. 
Once the library is loaded, the system also shares it with any other
program that needs it.


Service Architecture

PIA uses the PenPoint services architecture. A database service is one
of the prime examples of a Dynamic Linked Library (DLL).  Depending
upon the target database,  corresponding services  can be installed,
opened, and access methods be executed.  Upon completion the services
can be closed and deinstalled.  

Database Drivers (services or DLLs) are the ones a PIA based
application can invoke on demand to gain access to a particular data
store. A standard interface between applications and these drivers is
the key by which both application developers and the driver
implementors will gain the needed synergy to shuttle data between
applications and data stores.

A database service is implemented as a  DLL.  Service instances can be
created dynamically after the service has been installed or  created
by the user with the Connections Notebook.  Service instances remain
active as long as the service is installed, unless they are
explicitly destroyed.  

Each service instance belongs to one or more service managers. 
Service managers categorize  related services that have the same API,
and provide the client interface for finding and opening services. 
Service instances for databases must belong to theDatabases service
manager.



 









PIA Elements

In the heterogeneous database connectivity world, the key goal is to
provide a common view of data.  Standardizing on data types is the
first step towards this goal.  Different datatypes supported on
different DBMS are  mapped to the standard set of PIA datatypes.

PIA Datatypes

PIA Types       Data Type        Description
=========       =========        ===========

CHAR            Character (n)    Character String of fixed length n

CHAR            Character        Variable length character string
                Varying (n)      with a maximum string of n

S16             SMALLINT         Exact numeric, signed, precision 
                                 5, with scale zero

S32             INTEGER          Exact numeric, signed, precision 
                                 10, with scale zero

U32             LONG             Exact numeric, signed, precision >
INTEGER         INTEGER          10, with scale zero

DECIMAL         Decimal (p,s)    Exact numeric, signed, precision 
                                 p, scale s

DECIMAL         Numeric (p,s)    Exact numeric, signed, precision 
                                 p, scale s

FLOAT           REAL             Approximate numeric, signed, 
                                 mantissa precision 7

FLOAT           FLOAT            Approximate numeric, signed 
                                 mantissa precision 7

DOUBLE          DOUBLE           Approximate numeric, signed,
                PRECISION        mantissa precision 15
 
OS_DATE_TIME    DATE             Date - year, month and days

OS_DATE_TIME    TIME             Time - hours, minutes, seconds,  
                                 and  hundredths

OS_DATE_TIME    DATETIME         Combination of above two

BINARY          P_UNKNOWN        Binary data values

    


These PIA datatypes are  comprehensive enough to accommodate all the
values stored in all the database servers.  



PIA access methods

The PenPoint system is based on message based protocols, where objects
are the basic entities responding to predefined set of messages. 
Messages invoke methods that actually implement the access
mechanism.  The access methods in the database world can be
categorized as below.

o	responsible for connecting to the target  databases

o	sending  queries to the target databases

o	receiving  results of the queries,  and any status 
        or error conditions

o	transaction processing 

o	catalog management (schema information tables)

It is not a requirement that all database drivers support the entire 
API.   Again, the driver implementation may only support a subset of
what the database system can offer. So, it's the driver's
responsibility to alert the applications of their capabilities.




Database Connections

One of the key objectives of PIA is to provide the database
connection.  This is a complex problem because there are no
established standards on connecting to a target database. The flavor
of connecting to target databases differs from one system to another.
For instance in the case of DB2, in addition to  userid/password pair
to access a mainframe, there  are extra security monitors, like ACF/2
or RACF,  where more clearance is needed.  In the case of dBase, one
has to specify the DOS files with extensions .dbf corresponding to
the tables desired.  In the case of the Sybase SQL server, one needs
to specify a userid/password pair and the database name, if the
default database is not desired.  

The approach that makes the most sense in the PenPoint system
environment is to allow applications to retain control for
connection. PIA uses the  mechanism where the application has the
knowledge of the  parameters necessary to connect to a target 
database.  This is one area will evolve in  future versions. 


Database Driver Capabilities

It is important for an application to know the capabilities of the
database driver.  This knowledge helps applications to better
understand the presence or absence of certain features. In a way
database driver capabilities reflect what the database server can do. 
This feature helps the application developers interrogate the API and
find out various capabilities that each database driver has to offer.

msgSMCharacteristics can be used to enumerate the information about
the database driver. It can list an array of details, some of which
are as follows.

Driver version, driver name, query capability, type of locking
mechanism,  transaction management etc.




Common Access Messages

The  messages listed below  are a combination of service manager
messages and PIA access messages.  Together, they form a set of
messages  that enable to develop database applications.  They are
categorized  logically from an application developers standpoint into
messages that enable  connections, send requests,  receive results and
other miscellaneous features. 

Service Messages
//  Service manager messages for connections, open,
//  close, characteristics etc. 

        msgIMFind
        msgSMGetCharacteristics
        msgSMBind
        msgSMOpen
        msgSMClose
        msgSMUnbind

Note:	for  a  complete  description  of  these  and  other  service 
        messages please  refer to  PenPoint  API  Reference , Volume II, 
        Part 10, Chapters  1 & 2.  This material  gives you  an excellent  
        description of  what   the services are capable of offering.

The above specified service messages  enable the database connections,
and  enumerate the characteristics of a chosen service.   By  using
these service messages, applications as well as driver implementors 
have a  centralized control  of  quering and managing all the 
entities that belong to  theDatabases Service Manager, which has
already been created for you.  

Query Messages  for sending requests

        msgDbPrepare
        msgDbBind
        msgDbDeclareCursor
        msgDbOpenCursor
        msgDbCloseCursor
        msgDbDeleteCursor
        msgDbBuildDoQuery


Query Messages for receiving results

        msgDbColCount
        msgDbColDescribe
        msgDbNumRows
        msgDbFetch

Query Messages for data definitions

        msgDbTables
        msgDbColumns
        msgDbIndexes

Query Messages for miscellaneous category

        msgDbTransaction
        msgDbError
        



/***********************************************************************

      File:  pia.h

      (C) Copyright 1991 by GO Corporation, All Rights Reserved.

      Author:      Satya Yenigalla

        Date:      21 August 1991

      This file contains the standard definitions for the 
      PenPoint Information  Architecture (PIA).  PIA is an 
      open standard for PenPoint that allows database applications 
      to access data from multiple back-end DBMS systems for which 
      a database driver exists.

NOTE: In case of any differences between the defines in this readme file
      and the actual pia.h (header file), the latter one is more accurate.

***********************************************************************/

#ifndef SERVICE_INCLUDED
#include <service.h>
#endif

/*==============    MESSAGES   ========================*/

#define   msgDbPrepare		        MakeMsg  (clsDbService, 1  )
#define   msgDbBind     	       	MakeMsg  (clsDbService, 2  )
#define   msgDbDeclareCursor		MakeMsg  (clsDbService, 3  )
#define   msgDbOpenCursor 	       	MakeMsg  (clsDbService, 4  )
#define   msgDbCloseCursor	       	MakeMsg  (clsDbService, 5  ) 
#define   msgDbDeleteCursor 		MakeMsg  (clsDbService, 6  )
#define   msgDbBuildDoQuery		MakeMsg  (clsDbService, 7  )
#define   msgDbColCount		        MakeMsg  (clsDbService, 8  )
#define   msgDbColDescribe	        MakeMsg  (clsDbService, 9  )
#define   msgDbFetch 			MakeMsg  (clsDbService, 10 )
#define   msgDbTables			MakeMsg  (clsDbService, 11 )
#define   msgDbColumns			MakeMsg  (clsDbService, 12 )
#define   msgDbIndexes			MakeMsg  (clsDbService, 13 )
#define   msgDbTransaction		MakeMsg  (clsDbService, 14 )
#define   msgDbError		        MakeMsg  (clsDbService, 15 )




/* PIA datatype  for host variables  */

typedef  enum PIA_TYPE  {
      PIA_STRING,
      PIA_CHAR,
      PIA_SIGNED_16,
      PIA_SIGNED_32,
      PIA_UNSIGNED_16,
      PIA_UNSIGNED_32,
      PIA_DECIMAL,
      PIA_FLOAT,
      PIA_DOUBLE,
      PIA_OS_DATE_TIME,
      PIA_BINARY
}   PIA_TYPE,   *P_PIA_TYPE;


/*   COLUMN  structure  used in the msgDbColDescribe */
/*   COLUMN - aka   ATTRIBUTE, FIELD.   */

typedef  U16       COL_OFST,       *P_COL_OFST;  // Ofst to a col in a tuple
typedef  U16       COL_COUNT,      *P_COL_COUNT; // # of cols in a relation
typedef  U16       COL_LEN,        *P_COL_LEN;   // Length of the column
typedef  U16       COL_INX,        *P_COL_INX;   // A particular column's number


typedef  struct     {
      P_CHAR   	   colName;
      PIA_TYPE	   dataTypes;   //  datatypes supported by PIA.
      COL_LEN	   colLength;   //  length of the column
      COL_INX	   colCount;    //  a particular column's number
      COL_OFST	   colOfst;     //  offset of the column in tuple
}   COL_DESC,    * P_COL_DESC;


/*  Error  number  returned  by  messages   */

typedef   S32      PIA_ERROR,   * P_PIA_ERROR ;


/*  Schema Inforamation Tables, for Tables and Columns  */

/*  Table   information */

typedef   P_CHAR        TABLE_NAME;
typedef   U16           TABLE_NUM;
typedef   U32           CARDINALITY;
typedef   P_CHAR        TABLE_OWR;

/*  Column  information  */

typedef  P_CHAR            COLUMN_NAME;
typedef  U16               COLUMN_NUMBER;
typedef  PIA_TYPE          COLUMN_TYPE;
typedef  U16               COLUMN_LENGTH;
typedef  BOOLEAN           NULL_ALLOWED;
typedef  BOOLEAN           COLUMN_UPDATE;



/* database   location  */

typedef  enum PIA_DB_TYPE  {
       LOCAL_DB,
       REMOTE_DB,
}   PIA_DB_TYPE;

/* Capabilities  of the database  drivers and its  components    */

/* Locking  capabilities   */

typedef  struct  LOCK_CAP  {
         BOOLEAN    lockSupported;
}   LOCK_CAP,  * P_LOCK_CAP;



/*  Transaction  Management  capabilities   */

typedef  struct  TRANS_CAP  {
         BOOLEAN      transmgmt;
}   TRANS_CAP,  * P_TRANS_CAP;


/*  Types  of  querying  capabilities  supported  on the database  driver  */

typedef  enum  QUERY_CAP  {
         SELECTABLE		=   flag1,
         UPDATABLE		=   flag2,
         ALTERABLE		=   flag3,
         DELETABLE		=   flag4,
         INSERTABLE		=   flag5,
}   QUERY_CAP,  * P_QUERY_CAP;

/*  Capabilities  structure   */

typedef struct PIA_SERVICE_CAP  {
         QUERY_CAP		        queryCap;  //  Bitwise  OR
                                                   //  of query capabilities
         TRANS_CAP      	      	transcap;
         LOCK_CAP       		lockcap;
         OS_MILLISECONDS		timeOut;
         U8		            	drvVersion;
}   PIA_SERVICE_CAP,  * P_PIA_SERVICE_CAP;



/***********************************************************************

   msgSMOpen


   pArgs :        P_SM_OPEN_CLOSE
   Returns :      STATUS
   Description :  This message opens the service, given its handle. The
   handle can be obtained by msgIMFind. Before doing an Open,
   the client should bind to the service by msgSMBind.


   typedef struct SM_OPEN_CLOSE {
      OBJECT       handle;   // Handle of service to open
      OBJECT       caller;   // Object making this call   
      P_ARGS       pArgs;    // service specific open parameters
      OBJECT       service;  // In: (SMClose)  Out: (SMOpen)     
   }  SM_OPEN_CLOSE,   *P_SM_OPEN_CLOSE;

***********************************************************************/


#define  PIA_DB_OPEN(n)       struct  {                  \
              PIA_ERROR        drvErrCode ;              \
              PIA_ERROR        dbErrCode  ;              \
              P_UNKNOWN        connectParams [(n)];      \
}

typedef     PIA_DB_OPEN(1)   * P_PIA_DB_OPEN ;

/*

   The Service-specific open parameters (pArgs)  is PIA_DB_OPEN.  
   The connectParams element of this structure consists of :
                               0 : Database Userid
                               1 : Database Password
                               2 : Userid of the Server
                               3 : Password of the Server


   These 0 through 3 connectParams are the UserIds and Passwords for 
   connecting to the right database on the right server.  These are 
   followed by the Network parameters :
   (example of network parameters for Oracle via Appletalk)

                               4 : Network 
                               5 : ZoneName
                               6 : Service

   These network parameters will vary according to the type of network 
   and the kind of parameters the network demands to make a connection. 

   The pArgs, service specific connectParams [(n)]  for msgSMOpen 
   consists of a fixed part - connectParams [0]   thru   connectParams [3], 
   and a variable part starting at connectParams [4] which is 
   implementation defined.
                           
*/





/***********************************************************************

   msgSMCharacteristics


   pArgs :          SM_GET_CHARACTERISTICS
   Returns :        STATUS
   Description :  Gets the characteristics of the specified service instance.
   Characteristics are service-specific properties of a particular service.
   The service will return the service-specific characteristics
   via pArgs->pBuf.  pArgs->len specifies the maximum size of
   client's buffer.  If pArgs->len is 0  then the service should return
   actual size of its characteristics in pArgs->len and not pass back
   any data. Clients then allocate this space and make the call again
   with pArgs->len set to this size. 

   typedef     struct   SM_GET_CHARACTERISTICS  {
                        OBJECT      handle;   // Handle of item to get characteristics of.
                        P_UNKNOWN   pBuf;     // Out through Ptr: Characteristics buffer.
                        U16         len;      // In/Out: Buffer size. If 0, actual size ret.
   }   SM_GET_CHARACTERISTICS, * P_SM_GET_CHARACTERISTICS;

Note: Even though these are service characteristics, they mostly relate 
to the DBMS it interacts.

***********************************************************************/


   typedef  struct PIA_DRIVER_CAP    {
                  PIA_SERVICE_CAP          serviceCap;
   }   PIA_DRIVER_CAP,   *P_PIA_DRIVER_CAP;


/*

   pBuf is a pointer to the buffer described by P_PIA_DRIVER_CAP data
   structure. This data structure enumerates various capabilities this 
   service can offer. Some of which are as follows:  what kind of queries 
   can be executed, type of locking scheme supported, transaction 
   management etc.

   This list will be subject to future changes, to accommodate desirable 
   requests from ISV's.

*/




/***********************************************************************

   msgDbDeclareCursor

   pArgs :          P_PIA_DECLARE_CURSOR
   Returns :        STATUS
   Description :  This message declares a cursor and associates the 
   query with the cursor.  Query is not executed at this time.  

***********************************************************************/


/*   Types  of call back  functions.  These  functions will be called by 
     the database service to ask the application some data  (for the 
     bind variables)  or to supply it the fetched data (for the select-
     variables).  The parameteres  :
             -  the name of the host  variable (can be NULL)
             -  the type of the data  (PIA_TYPE)
             -  a pointer  to the buffer
                  -  in which you have to store the data (bind variables)
                  -  where you can find the fetched data (select variables)
             -   the length of the data
             -   a userparameter, not modified by the driver, just passed
        The use of these functions is optional, the alternative is to 
        get/pass the data via the buffers.
*/

typedef  void  (EXPORTED  * GetProcType)
                   (char     *     varName,
                    short          type,
                    char     *     varBuff,
                    short    *     len,
                    long           userParam) ;

typedef   void  (EXPORTED   * SetProcType)
                 (char      *   varName,
                  short         type,
                  char      *   varBuff,
                  short         len,
                  long          userParam) ;


typedef  struct   HOST_VARS   {
         P_CHAR		varName;
         PIA_TYPE		dataType;
         S32			rowSize;
         P_UNKNOWN	buffPtr;
}   HOST_VARS,    *P_HOST_VARS;


#define PIA_DECLARE_CURSOR(n)   struct    {  \
            P_CHAR	   cursorName;       \
            P_CHAR	   query;            \
            S8	   	   numBinds,         \
         		   numSelects;       \
            U32		   flags;	     \
            S32		   drvErrCode,       \
			   dbErrCode;        \
            P_UNKNOWN	   userParam;        \
            GetProcType	   getValue;         \
            SetProcType	   setValue,         \
		           appendValue;      \
            HOST_VARS	   hostVars [(n)];   \
} 

typedef     PIA_DECLARE_CURSOR(1)    *P_PIA_DECLARE_CURSOR;


/***********************************************************************

   msgDbOpenCursor


   pArgs :          P_PIA_OPEN_CURSOR
   Returns :        STATUS
   Description :  This message  executes a previously  declared query,
   identifying it through its unique name.

***********************************************************************/


typedef   struct  PIA_OPEN_CURSOR   {
            P_CHAR                  cursorName;
            PIA_ERROR               drvErrCode;
            PIA_ERROR               dbErrCode;
            S16                     parseOfst; // in case of db parsing error
}   PIA_OPEN_CURSOR,  * P_PIA_OPEN_CURSOR;


/***********************************************************************

   msgDbBuildDoQuery


   pArgs :        P_PIA_BLD_DO_QUERY
   Returns :      STATUS
   Description :  This message taken  on  'extended'  sql-query,  
   parses it and  fills in a P_PIA_DECLARE_CURSOR  structure for you.  
   This structure can then be used in the  Declare Cursor - message. 
   The user still has to supply the flags , userParam, setValue,
   etc - fields.  Because this msg allocates the declareCusor, the 
   user has to deallocate it after use.
   
***********************************************************************/


typedef   struct  PIA_BLD_DO_QUERY  {
            P_CHAR                 doQuery;        // extended SQL - query
            PIA_ERROR              errCode;
            P_PIA_DECLARE_CURSOR   declareCursor;  // Out: pointer to
                                                   // DECLARE_CURSOR structure
}   PIA_BLD_DO_QUERY,  *P_PIA_BLD_DO_QUERY;




/***********************************************************************

   msgDbPrepare


   pArgs :        P_PIA_PREPARE
   Returns :      STATUS
   Description :  This message prepares the query.  Once the query is 
   prepared,  it is ready to accept the host variable values provided thru
   msgDbBind.
   The prepare sends the query to the database for parsing and
   declaration of its host variables.
   A queryNumber, uniquely identifying the query, is returned.
   Error codes  can be returned in the queryInfo field.

***********************************************************************/


#define   PIA_PREPARE(n)   struct  {	      \
               U32       queryNumber;	      \
               S16       parseOfst;	      \
               PIA_DECLARE_CURSOR (n)  queryInfo;  \
}

typedef   PIA_PREPARE(1)        *P_PIA_PREPARE;



/***********************************************************************

   msgDbBind


   pArgs :        P_PIA_BIND
   Returns :      STATUS
   Description :  This message binds the host variable values with the query
   that has been prepared thru msgDbPrepare  and executes
   the query.


***********************************************************************/

typedef  struct  PIA_BIND   {
              U32	  queryNumber;    // In: number of prepared query
              PIA_ERROR	  drvErrCode;
              PIA_ERROR	  dbErrCode;
}   PIA_BIND,    * P_PIA_BIND;




/***********************************************************************

   msgDbCloseCursor


   pArgs :        P_PIA_CLOSE_CURSOR
   Returns :      STATUS
   Description :  Closes the cursor. All cursor locks are released during this
   time. When the cursor is reopened, it points to the first tuple of
   the result set.

***********************************************************************/


typedef   struct  PIA_CLOSE_CURSOR {
            P_CHAR                  cursorName;
            PIA_ERROR               drvErrCode;
            PIA_ERROR               dbErrCode;
}   PIA_CLOSE_CURSOR,  *P_PIA_CLOSE_CURSOR;


/***********************************************************************

   msgDbDeleteCursor


   pArgs :           P_PIA_DELETE_CURSOR
   Returns :        STATUS
   Description :  Deletes the cursor.  This is different from closing 
   the cursor. This message actually deletes the cursor from existence. 
   
***********************************************************************/


typedef   struct  PIA_DELETE_CURSOR {
            P_CHAR                  cursorName; 
            PIA_ERROR               drvErrCode;
            PIA_ERROR               dbErrCode;
}   PIA_DELETE_CURSOR,   *P_PIA_DELETE_CURSOR;


/***********************************************************************

   msgDbColCount


   pArgs :           P_PIA_COL_COUNT
   Returns :        STATUS
   Description :  This message is responsible for returning the number
   of columns in the result set.  This number can be used for describing 
   each column in the msgDbColDescribe.


***********************************************************************/

typedef   struct  PIA_COL_COUNT  {
            U32		  queryNumber;
            P_COL_COUNT	  colCount;    // Out : returns number of columns
            PIA_ERROR	  drvErrCode;
            PIA_ERROR	  dbErrCode;
}   PIA_COL_COUNT,  * P_PIA_COL_COUNT;




/***********************************************************************

   msgDbColDescribe


   pArgs :           P_PIA_COL_DESC
   Returns :        STATUS
   Description :  This message returns the data definitions (metadata) 
   information of the result set.  Database driver can then return 
   the mapped data types, corresponding to those returned from the database.

***********************************************************************/


typedef   struct  PIA_COL_DESC   {
            U32		   	queryNumber;
            P_COL_INX		colInx;
            P_COL_DESC		colDesc;
            PIA_ERROR		drvErrCode;
            PIA_ERROR		dbErrCode;
}   PIA_COL_DESC,  * P_PIA_COL_DESC;





/***********************************************************************

   msgDbFetch


   pArgs :        P_PIA_FETCH
   Returns :      STATUS
   Description :  This message fetches the data  from the result set 
   of the data.  Fetches a row of data as directed by the FETCH_MODE.
   Its not a requirement that all FETCH_MODE be supported by
   the driver, for reasons  that can be attributed to the database system.
   
***********************************************************************/

typedef   enum  FETCH_MODE  {
            FETCH_NEXT,
            FETCH_PREV,
            FETCH_FIRST,
            FETCH_LAST,
            FETCH_RELATIVE
}  FETCH_MODE,   *P_FETCH_MODE;

/* retrieve mode, how the data are stored in the buffers
    - row  or column wise
*/

typedef  enum   RTR_MODE   {
              ROW_WISE,
              COL_WISE
}    RTR_MODE,  *  P_RTR_MODE;

/*  dataValues  array - contains pointers to buffers  with  fetched data  */

#define    PIA_FETCH(n)  struct  {                \
   P_CHAR   			cursorName;	  \
   U32		   		queryNumber;	  \
   FETCH_MODE			fetchMode;	  \
   U32			   	tupleCount;	  \
   U32		        	tupleNum;	  \
   RTR_MODE			rtrMode;	  \
   PIA_ERROR			drvErrCode;	  \
   PIA_ERROR			dbErrCode;	  \
   P_UNKNOWN			dataValues[(n)];  \
}

typedef  PIA_FETCH(1)     *P_PIA_FETCH ;


/***********************************************************************

   msgDbTables


   pArgs :        P_PIA_DICT_TBL
   Returns :      STATUS
   Description :  The database driver will send the appropriate 
   request to the catalog to fetch the matching table names. Once 
   the query is formed, results are fetched like any other query 
   using msgDbFetch.


***********************************************************************/


/*  tableParams  array  -  used for specifying the parameters
    for obtaining the data  definitions  of a system  table 
    (database   dependent)
*/

#define  PIA_DICT_TBL(n)      struct   {                      \
              PIA_ERROR                 drvErrCode;           \
              PIA_ERROR                 dbErrCode;            \
              P_CHAR                    tableParams [(n)];    \
}

typedef    PIA_DICT_TBL(1)       *P_PIA_DICT_TBL;





/***********************************************************************

   msgDbColumns


   pArgs :        P_PIA_DICT_COLS
   Returns :      STATUS
   Description :  The driver makes the appropriate request to the catalog 
   supported  by the database system.  Once the query is formed,
   results are fetched just like any other query using msgDbFetch.


***********************************************************************/

#define  PIA_DICT_COLS(n)      struct   {	  \
              PIA_ERROR         drvErrCode;       \
              PIA_ERROR         dbErrCode;	  \
              P_CHAR            columnParams[(n)];\
}

typedef    PIA_DICT_COLS(1)       *P_PIA_DICT_COLS;




/***********************************************************************

   msgDbIndexes


   pArgs :        P_PIA_DICT_INDXS
   Returns :      STATUS
   Description :  Requires the driver to send the appropriate request 
   to the catalog to get the list of indexes.  Once the query is formed, 
   the results are fetched just like any other messages - msgDbFetch.

***********************************************************************/



#define  PIA_DICT_INDXS(n)    struct   {                     \
              PIA_ERROR                 drvErrCode;          \
              PIA_ERROR                 dbErrCode;           \
              P_CHAR                    indexParams[(n)];    \
}

typedef    PIA_DICT_INDXS(1)       *P_PIA_DICT_INDXS;





/***********************************************************************

   msgDbTransaction


   pArgs :        P_PIA_TRANSACTION
   Returns :      STATUS
   Description :  This message actually sets the COMMIT or ROLLBACK as
   requested by the application.


***********************************************************************/


typedef  enum  TRANS_TYPE   {
            PIA_ROLLBACK,
            PIA_COMMIT
}  TRANS_TYPE,  *P_TRANS_TYPE;

typedef   struct  PIA_TRANSACTION  {
            TRANS_TYPE         transType;
            PIA_ERROR          drvErrCode;
            PIA_ERROR          dbErrCode;
}   PIA_TRANSACTION,  *P_PIA_TRANSACTION;





/***********************************************************************

   msgDbError


   pArgs :        P_PIA_ERR_MSG
   Returns :      STATUS
   Description :  This message may be called after any message that 
   results in ERROR, WARNING OR SUCCESS_WITH_INFO.  To retrieve
   these error/warning messages, msgDbError can be issued to the
   driver.  The driver maintains in the buffer, the latest error info.
   This info stays in the buffer only until the next error occurs, at
   which time the previous error info is lost.  If more granularity is
   required as the situation demands, can be accommodated in the
   future versions.

***********************************************************************/


typedef   struct  PIA_ERR_MSG  {
            PIA_ERROR          dbError;  //  In : error  returned by db
            PIA_ERROR          errCode;  //  Out : driver  error
            S16                buffLen;  //  length  of  buffer
            P_CHAR             message;  //  ptr  to buffer with message text
}  PIA_ERR_MSG,   * P_PIA_ERR_MSG;








Appendix A

The subset API shown in Appendix A  is the recommended minimum  for
the local databases to be complaint with PIA :

select
        SELECT  selection
        FROM     tablename
        [WHERE  search_criteria]

selection
        * | column [,selection]

search_criteria
        bool_op | search_criteria OR bool_op

bool_op
       bool_factor | bool_op  AND  bool_factor

bool_factor
       [NOT] bool_primary

bool_primary
       predicate | (search_criteria)

predicate
       comparison | between | like | in

comparison
        column_name relopr constant

relopr
        = | <> | < | > | <= | =>

between
        column_name [NOT] BETWEEN constant AND constant



like 
        column_name [NOT] LIKE string

in 
        column_name [NOT] IN (value_list)
             
           
The DLL implementors are not necessarily constrained by the above
grammar. Any desirable extensions would be welcome and infact,
encouraged. One restriction, is that these extensions should conform
to the ANSI 89 SQL. 


Appendix B

Issues, concerns, ideas, etc.

Error Handling :  needs more work how each message is responsible to
handle database management system errors and  database driver errors.

International : this functionality needs more careful thought and
explanation.

Browse applications : there needs to be a description of the
requirements and implementation guidelines for writing 'browsing
applications'.  More thought need to be given in the areas of
scrollable and possibly updatable cursors simulated on the client 
side. The impact of isolation levels and drivers capability of
handling those needs more discussion.

Wireless Connectivity : when/if this is a reality, it's impact - both
in terms of opportunities and adversities it presents, needs  careful
evaluation.

Database Industry Standards:  PIA should  evolve along  the standards
set by various committees, and also by the non-standard yet creative
features offered by many database vendors.
 
Validation Test Suites: Test suites need to be developed to certify
PIA compliancy.

Future feature suggestions: Referential Integrity, new datatypes,
advanced transaction management, cursor mechanisms, 2 phase commits,
Schema Information Tables etc.

Characteristics and Capabilities: A lowest common denominator of
characteristics and capabilities have been presented in this
document.  Discussions with several ISVs and others will evolve this
feature.




