This repository has been archived on 2025-02-12. You can view files and clone it, but cannot push or open issues or pull requests.
NeoStats/sqlsrv/rta.h
2003-12-28 07:23:42 +00:00

878 lines
38 KiB
C

/***************************************************************
* Run Time Access
* Copyright (C) 2003 Robert W Smith (bsmith@linuxtoys.org)
*
* This program is distributed under the terms of the GNU LGPL.
* See the file COPYING file.
**************************************************************/
/***************************************************************
* rta.h -- DB API for your internal structures and tables
**************************************************************/
/** ************************************************************
* - Preamble:
* "rta" is a specialized memory resident data base interface.
* It is not a stand-alone server but a library which attaches
* to a program and offers up the program's internal structures
* and arrays as data base tables. It uses a subset of the
* Postgres protocol and is compatible with the Postgres bindings
* for "C", PHP, and the Postgres command line tool, psql.
*
* This file contains the defines, structures, and function
* prototypes for the 'rta' package.
*
* INDEX:
* - Preamble
* - Introduction and Purpose
* - Limits
* - Data Structures
* - Subroutines
* - rta UPDATE and SELECT syntax
* - Internal DB tables
* - List of all error messages
* - How to write callback routines
**************************************************************/
/** ************************************************************
* - Introduction and Purpose:
* One of the problems facing Linux is the lack of real-time
* access to status, statistics, and configuration of a service
* once it has started. We assume that to configure an
* application we will be able to ssh into the box, vi the /etc
* configuration file, and do a 'kill -1' on the process. Real
* time status and statistics are things Linux programmers don't
* even think to ask for. The problem of run time access is
* particularly pronounced for network appliances where ssh is
* not available or might not be allowed.
* Another problem for appliance designers is that more than
* one type of user interface may be required. Sometimes
* a customer requires that *no* configuration information be
* sent over an Ethernet line which transports unsecured user
* data. In such a case the customer may turn off the web
* interface and require that configuration, status, and
* statistics be sent over an RS-232 serial line. The VGA
* console, SNMP MIBs, and LDAP are also popular management
* interfaces.
* The rta package helps solve these problems by giving
* real-time access to the data structures and arrays inside a
* running program. With minimal effort, we make a program's
* data structures appear as Postgres tables in a Postgres data
* base.
* For example, say you have a structure for TCP connections
* defined as:
* struct tcpconn {
* int fd; // conn's file descriptor
* int lport; // local port number
* int dport; // destination port number
* long nsbytes; // number of sent bytes
* long nrbytes; // number of received bytes
* long nread; // number of reads on the socket
* long nwrite; // number of writes on the socket
* };
*
* You might then define an array of these structures as:
* struct tcpconn Conns[MX_CONN];
*
* The rta package allows any programming language with a
* Postgres binding to query your table of TCP connections....
* SELECT lport, dport FROM Conns WHERE fd != -1;
* UPDATE Conns SET dport = 0 WHERE fd = -1;
*
* A data base API for all of your program's configuration,
* status, and statistics makes debugging easier since you can
* view much more of your program's state with simple Postgres
* tools. A data base API makes building user interface programs
* easier since there are Postgres bindings for PHP, Tcl/Tk,
* Perl, "C", as well as many more.
* A data base API can help speed development. Carefully
* defining the tables to be used by the UI programs lets the
* core application team build the application while the UI
* developers work on the web pages, wizards, and MIBs of the
* various UI programs.
*
* Some effort is required. In order to make your arrays
* and structures available to the data base API, you need to
* tell rta about the tables and columns in the data base.
* Table information includes things like the name, start
* address, number of rows and the length of each row. Column
* information includes things like the associate table name,
* the column name, the column's data type, and whether we want
* any special functions called when the column is read or
* written (callbacks).
*
* This document describes the API offered by the rta package.
**************************************************************/
#ifndef RTA_H
#define RTA_H 1
/***************************************************************
* - Limits:
* Here are the defines which describe the internal limits
* set in the rta package. You are welcome to change these
* limits; just be sure to recompile the rta package using
* your new settings.
**************************************************************/
#include <limits.h> /* for PATH_MAX */
#include "list.h"
#include "hash.h"
/** Maximum number of tables allowed in the system.
* Your data base may not contain more than this number
* of tables. */
#define MX_TBL (500)
/** Maximum number of columns allowed in the system.
* Your data base may not contain more than this number
* of columns. */
#define MX_COL (2500)
/** Maximum number of characters in a column name, table
* name, and in help. See TBLDEF and COLDEF below. */
#define MXCOLNAME (30)
#define MXTBLNAME (30)
#define MXHELPSTR (1000)
#define MXFILENAME PATH_MAX
/** Maximum number of characters in the 'ident' field of
* the openlog() call. See the rta_dbg table below. */
#define MXDBGIDENT (20)
/** Maximum line size. SQL commands in save files may
* contain no more than MX_LN_SZ characters. Lines with
* more than MX_LN_SZ characters are silently truncated
* to MX_LN_SZ characters. */
#define MX_LN_SZ (1500)
/* Maximum number of columns allowed in a table */
#define NCMDCOLS (40)
/** The column definition (COLDEF) structure describes
* one column of a table. A table description has an
* array of COLDEFs to describe the columns in the
* table. */
typedef struct
{
/** The name of the table that has this column. */
char *table;
/** The name of the column. Must be at most MXCOLNAME
* characters in length and must be unique within a
* table. The same column name may be used in more
* than one table. */
char *name;
/** The data type of the column. Must be int, long,
* string, pointer to void, pointer to int, pointer
* to long, or pointer to string. The DB types are
* defined immediately following this structure. */
int type;
/** The number of bytes in the string if the above
* type is RTA_STR or RTA_PSTR. */
int length;
/** Number of bytes from the start of the structure to
* this column. For example, a structure with an int,
* a 20 character string, and a long, would have the
* offset of the long set to 24. Use of the function
* offsetof() is encouraged. If you have structure
* members that do not start on word boundaries and
* you do not want to use offsetof(), then consider
* using -fpack-struct with gcc. */
int offset;
/** Boolean flags which describe attributes of the
* columns. The flags are defined after this
* structure and include a "read-only" flag and a
* flag to indicate that updates to this column
* should cause a table save. (See table savefile
* described below.) */
int flags;
/** Read callback. This routine is called before the
* column value is used. Input values include the
* table name, the column name, the input SQL
* command, and the (zero indexed) row number for the
* row that is being read.
* This routine is called *each* time the column is
* read so the following would produce two calls:
* SELECT intime FROM inns WHERE intime >= 100; */
void *(*readcb) (void *tbl, char *column, char *SQL, void *data);
/** Write callback. This routine is called after an
* UPDATE in which the column is written. Input values
* include the table name, the column name, the SQL
* command, and the (zero indexed) row number of the
* modified row. See the callback section below.
* This routine is called only once after all column
* updates have occurred. For example, if there were
* a write callback attached to the addr column, the
* following SQL statement would cause the execution
* of the write callback once after both mask and addr
* have been written:
* UPDATE ethers SET mask="255.255.255.0", addr = \
* "192.168.1.10" WHERE name = "eth1";
* The callback is called for each row modified. */
void (*writecb) (char *tbl, char *column, char *SQL, int row_num);
/** A brief description of the column. This should
* include the meaning of the data in the column, the
* limits, if any, and the default values. Include
* a brief description of the side effects of changes.
* This field is particularly important for tables
* which are part of the "boundary" between the UI
* developers and the application programmers. */
char *help;
}
COLDEF;
/***************************************************************
* - Data Structures:
* Each column and table in the data base must be described
* in a data structure. Here are the data structures and
* associated defines to describe tables and columns.
**************************************************************/
/** The data types.
* String refers to an array of char. The 'length' of
* column must contain the number of bytes in the array.
*/
#define RTA_STR 0
/** Pointer to void. Use for generic pointers */
#define RTA_PTR 1
/** Integer. This is the compiler/architecture native
* integer. On Linux/gcc/Pentium an integer is 32 bits.
*/
#define RTA_INT 2
/** Long. This is the compiler/architecture native
* long long. On Linux/gcc/Pentium a long long is 64
* bits. */
#define RTA_LONG 3
/** Pointer to string. Pointer to an array of char, or
* a (**char). Note that the column length should be
* the number of bytes in the string, not sizeof(char *).
*/
#define RTA_PSTR 4
/** Pointers to int and long. */
#define RTA_PINT 5
#define RTA_PLONG 6
/** Float and pointer to float */
#define RTA_FLOAT 7
#define RTA_PFLOAT 8
#define MXCOLTYPE (RTA_PFLOAT)
/** The boolean flags.
* If the disksave bit is set any writes to the column
* causes the table to be saved to the "savefile". See
* savefile described in the TBLDEF section below. */
#define RTA_DISKSAVE (1<<0)
/** If the readonly flag is set, any writes to the
* column will fail and a debug log message will be
* sent. (For unit test you may find it very handy to
* leave this bit clear to get better test coverage of
* the corner cases.) */
#define RTA_READONLY (1<<1)
/** The table definition (TBLDEF) structure describes
* a table and is passed into the DB system by the
* rta_add_table() subroutine. */
typedef enum
{
TBL_ARRAY = 0,
TBL_LIST = 1,
TBL_HASH = 2,
} RTA_TABLETYPE;
typedef struct
{
/** The name of the table. Must be less than than
* MXTLBNAME characters in length. Must be unique
* within the DB. */
char *name;
/** Address of the first element of the first row of
* the array of structs that make up the table. */
void *address;
/** The number of bytes in each row of the table.
* This is usually a sizeof() of the structure
* associated with the table. (The idea is that we
* can get to data element E in row R with ...
* data = *(address + (R * rowlen) + offset(E)) */
int rowlen;
/** Number of rows in the table. */
int nrows;
/** the type of struct this points to? Hash, List or array */
RTA_TABLETYPE tabletype;
/** An array of COLDEF structures which describe each
* column in the table. These must be in statically
* allocated memory since the rta system references
* them while running. */
COLDEF *cols;
/** The number of columns in the table. That is, the
* number of COLDEFs defined by 'cols'. */
int ncol;
/** Save file. Path and name of a file which stores
* the non-volatile part of the table. The file has
* all of the UPDATE statements needed to rebuild the
* table. The file is rewritten in its entirety each
* time a 'savetodisk' column is updated. No file
* save is attempted if the savefile is blank. */
char *savefile;
/** Help text. A description of the table, how it is
* used, and what its intent is. A brief note to
* describe how it relate to other parts of the system
* and description of important callbacks is nice
* thing to include here. */
char *help;
}
TBLDEF;
/***************************************************************
* - Subroutines
* Here is a summary of the few routines in the rta API:
* rta_init() - initialize internal tables
* dbcommand() - I/F to Postgres clients
* egp_add_table() - add a table and its columns to the DB
* SQL_string() - execute an SQL statement in the DB
* rta_save() - save a table to a file
* rta_load() - load a table from a file
*
* The FUSE based virtual filesystem adds the following:
* rtafs_init() - mount FS and get file descriptor for it
* do_rtafs() - handle all virtual file system IO
* The above two routines are in the rtafs library. Their
* inclusion in this include file cause no harm if you are
* using only the rtadb library. Note that the rtafs library
* requires the rtadb library.
**************************************************************/
/** ************************************************************
* dbcommand(): - Depacketize and execute Postgres commands.
*
* The main application accepts TCP connections from Postgres
* clients and passes the stream of bytes (encoded SQL requests)
* from the client into the rta system via this routine. If the
* input buffer contains a complete command, it is executed, nin
* is decrement by the number of bytes consumed, and RTA_SUCCESS
* is returned. If there is not a complete command, RTA_NOCMD
* is returned and no bytes are removed from the input buffer.
* If a command is executed, the results are encoded into the
* Postgres protocol and placed in the output buffer. When the
* routine is called the input variable, nout, has the number of
* free bytes available in the output buffer, out. When the
* routine returns nout has been decremented by the size of the
* response placed in the output buffer. An error message is
* generated if the number of available bytes in the output
* buffer is too small to hold the response from the SQL command.
*
* Input: cmd - the buffer with the Postgres packet
* nin - on entry, the number of bytes in 'cmd',
* on exit, the number of bytes remaining in cmd
* out - the buffer to hold responses back to client
* nout - on entry, the number of free bytes in 'out'
* on exit, the number of remaining free bytes
* Return: RTA_SUCCESS - executed one command
* RTA_NOCMD - input did not have a full cmd
* RTA_CLOSE - client requests an orderly close
**************************************************************/
int dbcommand(char *, int *, char *, int *, int );
void deldbconnection(int connid);
/** ************************************************************
* rta_add_table(): - Register a table for inclusion in the
* DB interface. Adding a table allows external Postgres
* clients access to the table's content.
* Note that the TBLDEF structure must be statically
* allocated. The DB system keeps just the pointer to the table
* and does not copy the information. This means that you can
* change the contents of the table definition by changing the
* contents of the TBLDEF structure. This might be useful if
* you need to allocate more memory for the table and change its
* row count and address.
* An error is returned if another table by the same name
* already exists in the DB or if the table is defined without
* any columns.
* If a 'savefile' is specified, it is loaded. (See the
* rta_load() command below for more details.)
*
* Input: ptbl - pointer to the TBLDEF to add
* Return: RTA_SUCCESS - table added
* RTA_ERROR - error
**************************************************************/
int rta_add_table(TBLDEF *);
/*
* Logging function callback
*/
typedef void (*logcb) (char *logmsg);
/** ************************************************************
* rta_init(): - Initialize all internal variables and tables
* This may be called more than once.
*
* Input: None
* Return: None
**************************************************************/
void rta_init(logcb);
/* change the uname/password for authentication */
void rta_change_auth(char *uname, char *pass);
/** ************************************************************
* SQL_string(): - Execute single SQL command
*
* Executes the SQL command placed in the null-terminated string,
* cmd. The results are encoded into the Postgres protocol and
* placed in the output buffer. When the routine is called the
* input variable, nout, has the number of free bytes available
* in the output buffer, out. When the routine returns nout has
* been decremented by the size of the response placed in the
* output buffer. An error message is generated if the number
* of available bytes in the output buffer is too small to hold
* the response from the SQL command.
* This routine may be most useful when updating a table
* value in order to invoke the write callbacks. (The output
* buffer has the results encoded in the Postgres protocol and
* might not be too useful directly.)
*
* Input: cmd - the buffer with the SQL command,
* out - the buffer to hold responses back to client,
* nout - on entry, the number of free bytes in 'out'
* on exit, the number of remaining free bytes
* Return:
**************************************************************/
void SQL_string(char *, char *, int *);
/** ************************************************************
* rta_save(): - Save table to file. Saves all "savetodisk"
* columns to the path/file specified. Only savetodisk columns
* are saved. The resultant file is a list of UPDATE commands
* containing the desired data. There is one UPDATE command for
* each row in the table.
* This routine tries to minimize exposure to corrupted
* save files by opening a temp file in the same directory as
* the target file. The data is saved to the temp file and the
* system call rename() is called to atomically move the temp
* to the save file. Errors are generated if rta_save can not
* open the temp file or is unable to rename() it.
* As a general warning, note that any disk I/O can cause
* a program to block briefly and so saving and loading tables
* might cause your program to block.
*
* Input: ptbl - pointer to the TBLDEF structure for the
* table to save
* fname - null terminated string with the path and
* file name for the stored data.
* Return: RTA_SUCCESS - table saved
* RTA_ERROR - some kind of error
**************************************************************/
int rta_save(TBLDEF *, char *);
/** ************************************************************
* rta_load(): - Load a table from a file of UPDATE commands.
* The file format is a series of UPDATE commands with one
* command per line. Any write callbacks are executed as the
* update occurs.
*
* Input: ptbl - pointer to the table to be loaded
* fname - string with name of the load file
*
* Return: RTA_SUCCESS - table loaded
* RTA_ERROR - could not open the file specified
**************************************************************/
int rta_load(TBLDEF *, char *);
/* successfully executed request or command */
#define RTA_SUCCESS (0)
/* input did not have a full command */
#define RTA_NOCMD (1)
/* encountered an internal error */
#define RTA_ERROR (2)
/* DB client requests a session close */
#define RTA_CLOSE (3)
/** ************************************************************
* rtafs_init(): - Initialize the virtual file system interface
* to RTA. The single input parameter is the mount point for
* the VFS. On success, the return value is a file descriptor
* to the VFS. On failure, a -1 is returned and errno is set.
* This file descriptor should be used in subsequent select() or
* poll() calls to notify your program of file system activity.
* An important SIDE EFFECT is that the signal handlers for
* SIGHUP, SIGINT, and SIGTERM are set. The signal handler
* tries to unmount the virtual file system. This routine
* is part of the librtafs library.
* Note that FUSE requires that the owner and group of the
* mount point be the same as the owner and group of the program
* that does the mount. For example, if your mount point is
* owned by Apache, then your the UID of your program must be
* Apache as well.
*
* Input: char *mountpoint - desired mount point
*
* Return: int fd - file descriptor on success.
**************************************************************/
int rtafs_init(char *);
/** ************************************************************
* do_rtafs(): - Handle all actual virtual file system IO.
* This routine handles all file system IO for the virtual file
* system mounted by the rtafs_init() call. This routine should
* be called when there is activity on the file descriptor
* returned from rtafs_init(). It has no input or output
* parameters. This routine is part of the librtafs library.
*
* Input: (none)
*
* Return: (none)
**************************************************************/
void do_rtafs();
/** ************************************************************
* - rta UPDATE and SELECT syntax
* rta IS AN API, *NOT* A DATABASE!
* Neither the rta UPDATE nor the rta SELECT adhere to the
* Postgres equivalents. Joins are not allowed, and the WHERE
* clause supports only the AND relation. There are no locks
* or transactions.
*
* SELECT:
* SELECT column_list FROM table [where_clause] [limit_clause]
*
* SELECT supports multiple columns, '*', LIMIT, and OFFSET.
* At most MXCMDCOLS columns can be specified in the select list
* or in the WHERE clause. LIMIT restricts the number of rows
* returned to the number specified. OFFSET skips the number of
* rows specified and begins output with the next row.
* 'column_list' is a '*' or 'column_name [, column_name ...]'.
* 'where_clause' is 'col_name = value [AND col_name = value ..]'
* in which all col=val pairs must match for a row to match.
* LIMIT and OFFSET are very useful to prevent a buffer
* overflow on the output buffer of dbcommand(). They are also
* very useful for web based user interfaces in which viewing
* the data a page-at-a-time is desirable.
* Column and table names are case sensitive. If a column
* or table name is one of the reserved words it must be placed
* in quotes when used. The reserved words are: AND, FROM,
* LIMIT, OFFSET, SELECT, SET, UPDATE, and WHERE. Reserved
* words are *not* case sensitive. You may use lower case
* reserved words in your
* Comparison operator in the WHERE clause include =, >=,
* <=, >, and <.
* You can use a reserved word, like OFFSET, as a column name
* but you will need to quote it whenever you reference it in an
* SQL command (SELECT "offset" FROM tunings ...). Strings
* may contain any of the !@#$%^&*()_+-={}[]\|:;<>?,./~`
* characters. If a string contains a double quote, use a
* single quote to wrap it (eg 'The sign say "Hi mom!"'), and
* use double quotes to wrap string with embedded single quotes.
*
* Examples:
* SELECT * FROM rta_tables
*
* SELECT destIP FROM conns WHERE fd != 0
*
* SELECT destIP FROM conns WHERE fd != 0 AND lport = 80
*
* SELECT destIP, destPort FROM conns \
* WHERE fd != 0 \
* LIMIT 100 OFFSET 0
*
* SELECT destIP, destPort FROM conns \
* WHERE fd != 0 \
* LIMIT 100 OFFSET 0
*
*
* UPDATE:
* UPDATE table SET update_list [where_clause] [limit_clause]
*
* UPDATE writes values into a table. The update_list is of
* the form 'col_name = val [, col_name = val ...]. The WHERE
* and LIMIT clauses are as described above.
* An update invokes write callbacks on the affected columns.
* All data in the row is written before the callbacks are
* called.
* The LIMIT clause for updates is not standard Postgres SQL,
* but can be really useful for stepping through a table one row
* at a time. To change only the n'th row of a table, use a
* limit clause like 'LIMIT 1 OFFSET n' (n is zero-indexed).
*
* Examples:
* UPDATE conn SET lport = 0;
*
* UPDATE ethers SET mask = "255.255.255.0", \
* addr = "192.168.1.10" \
* WHERE name = "eth0"
*
* UPDATE conn SET usecount = 0 WHERE fd != 0 AND lport = 21
*
**************************************************************/
/** ************************************************************
* - Internal DB tables
* rta has five tables visible to the application:
* rta_tables: - a table of all tables in the DB
* rta_columns: - a table of all columns in the DB
* pg_user: - spoof of Postgres table needed to log on
* rta_logconfig: - controls what gets logged from rta
* egp_stats: - simple usage and error statistics
*
* The rta_tables table gives SQL access to all internal and
* registered tables. The data in the table is exactly that of
* the TBLDEF structures registered with rta_add_table(). This
* table is used for the generic table viewer and table editor
* applications used mostly for application debugging. The
* columns of rta_tables are:
* name - the name of the table
* address - the start address of the table in memory
* rowlen - number of bytes in each row of the table
* nrows - number of rows in the table
* cols - pointer to array of column definitions
* ncol - number of columns in the table
* savefile - the file used to store non-volatile columns
* help - a description of the table
*
* The rta_columns table has the column definitions of all
* columns in the DB. The data in the table is exactly that of
* the COLDEF structures registered with rta_add_table(). This
* table is used for the generic table viewer and table editor
* applications used mostly for application debugging. The
* columns of rta_columns are:
* table - the name of the column's table
* name - name of the column
* type - column's data type
* length - number of bytes columns data type
* offset - number of bytes from start of structure
* flags - Bit field for 'read-only' and 'savetodisk'
* readcb - pointer to subroutine called before reads
* writecb - pointer to subroutine called after writes
* help - a description of the column
*
* The pg_user table is provided to complete the connection
* protocol between Postgres clients and the rta package. It
* authenticates the connecting user. We spoof the protocol by
* using a read callback to add the user into the table before
* checking if the user is valid. In this way *any* user who
* connects is in the table and so is authenticated. (One
* future enhancement to rta might be to do real Postgres style
* authentication.) The columns of pg_user are:
* usename - spoofed to match any requested name
* usesysid - 100
* usecreatedb - 'f'
* usetrace - 'f'
* usesuper - 'f'
* usecatupd - 'f'
* passwd - "******"
* valuntil - ""
*
* The rta_dbgconfig table controls which errors generate
* debug log messages. See the logging section below for the
* exact mapping. The rta package generates no user level log
* messages, only debug messages. All of the fields in this
* table are volatile. You will need to set the values in your
* main program to make them seem persistent. (Try something
* like "SQL_string("UPDATE rta_dbgconfig SET dbg ....").)
* The columns of rta_dbgconfig are:
* syserr - integer, 0 means no log, 1 means log.
* This logs OS call errors like malloc()
* failures. Default is 1.
* rtaerr - integer, 0 means no log, 1 means log.
* Enables logging of errors internal to the
* rta package itself. Default is 1.
* sqlerr - integer, 0 means no log, 1 means log.
* Log any SQL request which generates an
* error reply. Error replies occur if an SQL
* request is malformed or if it requests a
* non-existent table or column. Default is 1.
* (SQL errors are usually client programming
* errors.)
* trace - integer, 0 means no log, 1 means log all
* SQL requests. Default is 0.
* target - 0: disable all debug logging
* 1: log debug messages to syslog()
* 2: log debug messages to stderr
* 3: log to both syslog() and stderr
* The default is 1. Setting the facility
* causes a close and an open of syslog().
* priority - integer. Syslog() requires a priority as
* part of all log messages. This specifies
* the priority to use when sending rta debug
* messages. Changes to this do not take
* effect until dbg_target is updated.
* 0: LOG_EMERG
* 1: LOG_ALERT
* 2: LOG_CRIT
* 3: LOG_ERR
* 4: LOG_WARNING
* 5: LOG_NOTICE
* 6: LOG_INFO
* 7: LOG_DEBUG
* Default is 3.
* facility - integer. Syslog() requires a facility as
* part of all log messages. This specifies
* the facility to use when sending rta debug
* messages. It is best to use the defines in
* .../sys/syslog.h to set this. The default
* is LOG_USER. Changes to this do not take
* effect until dbg_target is updated.
* ident - string. Syslog() requires an 'ident' string as
* part of all log messages. This specifies
* the ident string to use when sending rta debug
* messages. This is normally set to the process
* or command name. The default is "rta". Changes
* to this do not take effect until dbg_target
* is updated. This can be at most MXDBGIDENT
* characters in length.
*
* The rta_stat table contains usage and error statistics
* which might be of interest to developers. All fields are
* of type long, are read-only, and are set to zero by
* rta_init(). The columns of rta_stats are:
* nsyserr - count of failed OS calls.
* nrtaerr - count of internal rta failures.
* nsqlerr - count of SQL failures.
* nauth - count of authorizations. (==#connections)
* nupdate - count of UPDATE or file write requests
* nselect - count of SELECT or file read requests
*
**************************************************************/
/** ************************************************************
* - List of all messages
* There are two types of error messages available in the
* rta package. The first type is the error messages returned
* as part of an SQL request. The messages of this type are:
*
* 1) "ERROR: Relation '%s' does not exist"
* This reply indicates that a table requested in a SELECT
* UPDATE, or where clause does not exist. The %s is
* replaced by the name of the requested table.
* 2) "ERROR: Attribute '%s' not found\n"
* This reply indicates that a column requested in a SELECT
* UPDATE, or where clause does not exist. The %s is
* replaced by the name of the requested column.
* 3) "ERROR: SQL parse error"
* This reply indicates a mal-formed SQL request or a
* mis-match in the types of data in a where clause or in
* an update list.
* 4) "ERROR: Output buffer full"
* This reply indicates that the size of the response to
* a request exceeds the size of the output buffer. See
* dbcommand() and the 'out' and 'nout' parameters. This
* error can be avoided with a large enough output buffer
* or, preferably, with the use of LIMIT and OFFSET.
* 5) "ERROR: String too long for '%s'
* This reply indicates that an update to a column of type
* string or pointer to string would have exceeded the
* width of the column. The %s is replaced by the column
* name.
* 6) "ERROR: Can not update read-only column '%s'
* This reply indicates that an attempt to update a column
* marked as read-only. The %s is replaced by the column
* name.
*
* The other type of error messages are internal debug
* messages. Debug messages are logged using the standard
* syslog() facility available on all Linux systems. The
* default syslog "facility" used is LOG_USER but this can be
* changed by setting 'facility' in the rta_dbg table.
* You are welcome to modify syslogd in order to do post
* processing such as generating SNMP traps off these debug
* messages. All error messages of this type are send to
* syslog() as: "egp[PID]: FILE LINE#: error_message",
* where PID, FILE, and LINE# are replaced by the process ID,
* the source file name, and the line number where the error
* was detected.
* Following are the defines used to generate these debug
* and error messages. The "%s %d" at the start of each
* error string is replaced by the file name and line number
* where the error is detected. */
/** "System" errors */
#define Er_No_Mem "%s %d: Can not allocate memory\n"
#define Er_No_Save "%s %d: Table save failure. Can not open %s\n"
#define Er_No_Load "%s %d: Table load failure. Can not open %s\n"
/** "RTA" errors */
#define Er_Max_Tbls "%s %d: Too many tables in DB\n"
#define Er_Max_Cols "%s %d: Too many columns in DB\n"
#define Er_Tname_Big "%s %d: Too many characters in table name: %s\n"
#define Er_Cname_Big "%s %d: Too many characters in column name: %s\n"
#define Er_Hname_Big "%s %d: Too many characters in help text: %s\n"
#define Er_Tbl_Dup "%s %d: DB already has table named: %s\n"
#define Er_Col_Dup "%s %d: Table already has column named: %s\n"
#define Er_Col_Type "%s %d: Column contains an unknown data type: %s\n"
#define Er_Col_Flag "%s %d: Column contains unknown flag data: %s\n"
#define Er_Cmd_Cols "%s %d: Too many columns in table: %s\n"
#define Er_No_Space "%s %d: Not enough buffer space\n"
/** "SQL" errors */
#define Er_Bad_SQL "%s %d: SQL parse error: %s\n"
#define Er_Readonly "%s %d: Attempt to update readonly column: %s\n"
#define Er_BadPass "%s %d: Bad Username/Password\n"
/** "Trace" messages */
#define Er_Trace_SQL "%s %d: SQL command: %s (%s)\n"
/*************************************************************/
/** ************************************************************
* - How to write callback routines
* As mentioned above, read callbacks are executed before a
* column value is used and write callbacks are called after all
* columns have been updated. Both read and write callbacks
* return nothing (are of type void) and have the same calling
* parameters:
* - char *tblname: the name of the table referenced
* - char *colname: the name of the column referenced
* - char *sqlcmd: the text of the SQL command
* - int rowid: the zero-indexed row number of the row
* being read or written
*
* Read callbacks are particularly useful to compute things
* like sums and averages; things that aren't worth the effort
* compute continuously if it's possible to compute it just
* when it is used.
* Write callbacks can form the real engine driving the
* application. These are most applicable when tied to
* configuration changes. Write callbacks are also a useful
* place to log configuration changes.
**************************************************************/
/***************************************************************
* - Future enhancements:
* Several enhancements are possible for the rta package:
* - printf format string in the column definition
* - ability to register more than one trigger per column
* - secure login maintaining Postgres compatibility
* - IPC and support for shared tables in shared memory
* - specify pre or post for the write callback
* - table save callback (to save file to flash?)
* - execution times for table access, update
* - count(*) function
* - model output buffer mgmt on zlib to allow output streams
* - add a column data type of "table" to allow nested tables
* - add internationalization support
**************************************************************/
#endif