Category : C Source Code
Archive   : CUG168.ZIP
Filename : SEL.C
#include "sdbio.h"
extern int dbv_token;
extern char dbv_tstring[];
extern int dbv_tvalue;
/* db_select - select a set of tuples from a set of relations */
struct sel *db_select(fmt,a1,a2,a3,a4,a5,a6,a7,a8,a9)
char *fmt;
{
struct sel *slptr;
/* check for a command line */
if (fmt != NULL)
db_scan(fmt,a1,a2,a3,a4,a5,a6,a7,a8,a9);
/* allocate a sel structure */
if ((slptr = malloc(sizeof(struct sel))) == NULL)
return (db_nerror(INSMEM));
/* initialize the structure */
slptr->sl_rels = NULL;
slptr->sl_attrs = NULL;
slptr->sl_where = NULL;
slptr->sl_bindings = NULL;
/* parse the list of selected attributes */
if (!get_sattrs(slptr)) {
db_done(slptr);
return (NULL);
}
/* check for "from" clause */
if (db_token() == FROM) {
db_ntoken();
if (!get_srels(slptr)) {
db_done(slptr);
return (NULL);
}
}
else {
if (!srelation(slptr,"sdbcur",NULL)) {
db_done(slptr);
return (NULL);
}
}
/* check the list of selected attributes */
if (!check_attrs(slptr)) {
db_done(slptr);
return (NULL);
}
/* check for the existance of a "where" clause */
if (db_token() == WHERE) {
db_ntoken();
/* parse the boolean expression */
if (!db_compile(slptr)) {
db_done(slptr);
return (FALSE);
}
}
/* return the new selection structure */
return (slptr);
}
/* db_retrieve - retrieve a set of tuples from a set of relations */
struct sel *db_retrieve(fmt,a1,a2,a3,a4,a5,a6,a7,a8,a9)
char *fmt;
{
struct sel *slptr;
/* check for a command line */
if (fmt != NULL)
db_scan(fmt,a1,a2,a3,a4,a5,a6,a7,a8,a9);
/* allocate a sel structure */
if ((slptr = malloc(sizeof(struct sel))) == NULL)
return (db_nerror(INSMEM));
/* initialize the structure */
slptr->sl_rels = NULL;
slptr->sl_attrs = NULL;
slptr->sl_where = NULL;
slptr->sl_bindings = NULL;
/* check for selected relations clause */
if (db_token() == ID) {
if (!get_srels(slptr)) {
db_done(slptr);
return (NULL);
}
}
else {
if (!srelation(slptr,"sdbcur",NULL)) {
db_done(slptr);
return (NULL);
}
}
/* check the list of selected attributes */
if (!check_attrs(slptr)) {
db_done(slptr);
return (NULL);
}
/* check for the existance of a "where" clause */
if (db_token() == WHERE) {
db_ntoken();
/* parse the boolean expression */
if (!db_compile(slptr)) {
db_done(slptr);
return (FALSE);
}
}
/* return the new selection structure */
return (slptr);
}
/* db_done(slptr) - finish a selection */
db_done(slptr)
struct sel *slptr;
{
struct sattr *saptr,*nxtsa;
struct srel *srptr,*nxtsr;
struct binding *bdptr,*nxtbd;
/* free the selected attribute blocks */
for (saptr = slptr->sl_attrs; saptr != NULL; saptr = nxtsa) {
nxtsa = saptr->sa_next;
if (saptr->sa_rname != NULL)
free(saptr->sa_rname);
free(saptr->sa_aname);
if (saptr->sa_name != NULL)
free(saptr->sa_name);
free(saptr);
}
/* close the scans and free the selected relation blocks */
for (srptr = slptr->sl_rels; srptr != NULL; srptr = nxtsr) {
nxtsr = srptr->sr_next;
if (srptr->sr_name != NULL)
free(srptr->sr_name);
db_rclose(srptr->sr_scan);
free(srptr);
}
/* free the where clause */
db_fcode(slptr);
/* free the user bindings */
for (bdptr = slptr->sl_bindings; bdptr != NULL; bdptr = nxtbd) {
nxtbd = bdptr->bd_next;
free(bdptr);
}
/* free the selection structure */
free(slptr);
}
/* db_fetch(slptr) - fetch the next tuple from a selection */
int db_fetch(slptr)
struct sel *slptr;
{
struct srel *srptr;
struct binding *bdptr;
/* clear the update flags */
for (srptr = slptr->sl_rels; srptr != NULL; srptr = srptr->sr_next)
srptr->sr_update = FALSE;
/* find a matching tuple */
while (process(slptr->sl_rels))
if (db_interpret(slptr)) {
for (bdptr = slptr->sl_bindings; bdptr != NULL; bdptr = bdptr->bd_next)
db_aget(bdptr->bd_attr,bdptr->bd_vtuple,bdptr->bd_vuser);
return (TRUE);
}
/* no matches, failure return */
return (FALSE);
}
/* db_update - update modified tuples */
int db_update(slptr)
struct sel *slptr;
{
struct srel *srptr;
/* check each selected relation for updates */
for (srptr = slptr->sl_rels; srptr != NULL; srptr = srptr->sr_next)
if (srptr->sr_update)
if (!db_rupdate(srptr->sr_scan))
return (FALSE);
/* return successfully */
return (TRUE);
}
/* db_store - store tuples */
int db_store(slptr)
struct sel *slptr;
{
struct srel *srptr;
/* check each selected relation for stores */
for (srptr = slptr->sl_rels; srptr != NULL; srptr = srptr->sr_next)
if (srptr->sr_update)
if (!db_rstore(srptr->sr_scan))
return (FALSE);
/* return successfully */
return (TRUE);
}
/* db_bind - bind a user buffer to the value of an attribute */
int db_bind(slptr,rname,aname,avalue)
struct sel *slptr; char *rname,*aname,*avalue;
{
struct binding *newbd;
struct srel *srptr;
/* allocate and initialize a binding structure */
if ((newbd = malloc(sizeof(struct binding))) == NULL)
return (db_ferror(INSMEM));
newbd->bd_vuser = avalue;
/* find the attribute */
if (!find_attr(slptr,rname,aname,&newbd->bd_vtuple,&srptr,&newbd->bd_attr))
return (FALSE);
/* link the new binding into the binding list */
newbd->bd_next = slptr->sl_bindings;
slptr->sl_bindings = newbd;
/* return successfully */
return (TRUE);
}
/* db_get - get the value of an attribute */
int db_get(slptr,rname,aname,avalue)
struct sel *slptr; char *rname,*aname,*avalue;
{
struct srel *srptr;
struct attribute *aptr;
char *vptr;
/* find the attribute */
if (!find_attr(slptr,rname,aname,&vptr,&srptr,&aptr))
return (FALSE);
/* get the attribute value */
db_aget(aptr,vptr,avalue);
/* return successfully */
return (TRUE);
}
/* db_put - put the value of an attribute */
int db_put(slptr,rname,aname,avalue)
struct sel *slptr; char *rname,*aname,*avalue;
{
struct srel *srptr;
struct attribute *aptr;
char *vptr;
/* find the attribute */
if (!find_attr(slptr,rname,aname,&vptr,&srptr,&aptr))
return (FALSE);
/* put the attribute value */
db_aput(aptr,vptr,avalue);
/* mark the tuple as updated */
srptr->sr_update = TRUE;
/* return successfully */
return (TRUE);
}
/* db_sattr - get selected attribute type, pointer, and length */
int db_sattr(slptr,rname,aname,ptype,pptr,plen)
struct sel *slptr; char *rname,*aname;
int *ptype; char **pptr; int *plen;
{
struct srel *srptr;
struct attribute *aptr;
if (!find_attr(slptr,rname,aname,pptr,&srptr,&aptr))
return (FALSE);
*ptype = aptr->at_type;
*plen = aptr->at_size;
return (TRUE);
}
/* get_sattrs(slptr) - get selected attributes */
static get_sattrs(slptr)
struct sel *slptr;
{
struct sattr *newsattr,*lastsattr;
/* check for "*" or blank field meaning all attributes are selected */
if (db_token() == '*') {
db_ntoken();
return (TRUE);
}
else if (db_token() != ID)
return (TRUE);
/* parse a list of attribute names */
lastsattr = NULL;
while (TRUE) {
/* get attribute name */
if (db_ntoken() != ID)
return (db_ferror(SYNTAX));
/* allocate a selected attribute structure */
if ((newsattr = malloc(sizeof(struct sattr))) == NULL)
return (db_ferror(INSMEM));
/* initialize the selected attribute structure */
newsattr->sa_next = NULL;
/* save the attribute name */
if ((newsattr->sa_aname = malloc(strlen(dbv_tstring)+1)) == NULL) {
free(newsattr);
return (db_ferror(INSMEM));
}
strcpy(newsattr->sa_aname,dbv_tstring);
/* check for "." meaning "
if (db_token() == '.') {
db_ntoken();
/* the previous ID was really the relation name */
newsattr->sa_rname = newsattr->sa_aname;
/* check for attribute name */
if (db_ntoken() != ID) {
free(newsattr->sa_aname); free(newsattr);
return (db_ferror(SYNTAX));
}
/* save the attribute name */
if ((newsattr->sa_aname = malloc(strlen(dbv_tstring)+1)) == NULL) {
free(newsattr->sa_aname); free(newsattr);
return (db_ferror(INSMEM));
}
strcpy(newsattr->sa_aname,dbv_tstring);
}
else
newsattr->sa_rname = NULL;
/* check for alternate attribute name */
if (db_token() == ID) {
db_ntoken();
/* allocate space for the alternate name */
if ((newsattr->sa_name = malloc(strlen(dbv_tstring)+1)) == NULL) {
if (newsattr->sa_rname != NULL)
free(newsattr->sa_rname);
free(newsattr->sa_aname);
free(newsattr);
return (db_ferror(INSMEM));
}
strcpy(newsattr->sa_name,dbv_tstring);
}
else
newsattr->sa_name = NULL;
/* link the selected attribute structure into the list */
if (lastsattr == NULL)
slptr->sl_attrs = newsattr;
else
lastsattr->sa_next = newsattr;
lastsattr = newsattr;
/* check for more attributes */
if (db_token() != ',')
break;
db_ntoken();
}
/* return successfully */
return (TRUE);
}
/* get_srels(slptr) - get selected relations */
static get_srels(slptr)
struct sel *slptr;
{
char rname[KEYWORDMAX+1],*aname;
/* get the list of selected relations */
while (TRUE) {
/* check for relation name */
if (db_ntoken() != ID)
return (db_ferror(SYNTAX));
strcpy(rname,dbv_tstring);
/* check for alternate relation name */
if (db_token() == ID) {
db_ntoken();
aname = dbv_tstring;
}
else
aname = NULL;
/* add the relation name to the list */
if (!srelation(slptr,rname,aname))
return (FALSE);
/* check for more selected relations */
if (db_token() != ',')
break;
db_ntoken();
}
/* return successfully */
return (TRUE);
}
/* srelation - select a relation */
static srelation(slptr,rname,aname)
struct sel *slptr; char *rname,*aname;
{
struct srel *srptr,*newsrel;
/* allocate a new selected relation structure */
if ((newsrel = malloc(sizeof(struct srel))) == NULL)
return (db_ferror(INSMEM));
/* initialize the new selected relation structure */
newsrel->sr_ctuple = FALSE;
newsrel->sr_update = FALSE;
newsrel->sr_next = NULL;
/* open the relation */
if ((newsrel->sr_scan = db_ropen(rname)) == NULL) {
free(newsrel);
return (FALSE);
}
/* check for alternate relation name */
if (aname != NULL) {
/* allocate space for the alternate name */
if ((newsrel->sr_name = malloc(strlen(aname)+1)) == NULL) {
free(newsrel);
return (db_ferror(INSMEM));
}
strcpy(newsrel->sr_name,aname);
}
else
newsrel->sr_name = NULL;
/* find the end of the list of relation names */
for (srptr = slptr->sl_rels; srptr != NULL; srptr = srptr->sr_next)
if (srptr->sr_next == NULL)
break;
/* link the new selected relation structure into the list */
if (srptr == NULL)
slptr->sl_rels = newsrel;
else
srptr->sr_next = newsrel;
/* return successfully */
return (TRUE);
}
/* check_attrs(slptr) - check the list of selected attributes */
static int check_attrs(slptr)
struct sel *slptr;
{
struct sattr *saptr;
/* check for all attributes selected */
if (slptr->sl_attrs == NULL)
return (all_attrs(slptr));
/* check each selected attribute */
for (saptr = slptr->sl_attrs; saptr != NULL; saptr = saptr->sa_next)
if (!find_attr(slptr,saptr->sa_rname,saptr->sa_aname,
&saptr->sa_aptr,&saptr->sa_srel,&saptr->sa_attr))
return (FALSE);
/* return successfully */
return (TRUE);
}
/* all_attrs(slptr) - create a list of all attributes */
static int all_attrs(slptr)
struct sel *slptr;
{
struct sattr *newsattr,*lastsattr;
struct srel *srptr;
struct attribute *aptr;
int i,astart;
/* loop through each selected relation */
lastsattr = NULL;
for (srptr = slptr->sl_rels; srptr != NULL; srptr = srptr->sr_next) {
/* loop through each attribute within the relation */
astart = 1;
for (i = 0; i < NATTRS; i++) {
/* get a pointer to the current attribute */
aptr = &srptr->sr_scan->sc_relation->rl_header.hd_attrs[i];
/* check for last attribute */
if (aptr->at_name[0] == 0)
break;
/* allocate a new selected attribute structure */
if ((newsattr = malloc(sizeof(struct sattr))) == NULL)
return (db_ferror(INSMEM));
/* initialize the new selected attribute structure */
newsattr->sa_name = NULL;
newsattr->sa_srel = srptr;
newsattr->sa_aptr = srptr->sr_scan->sc_tuple + astart;
newsattr->sa_attr = aptr;
newsattr->sa_next = NULL;
/* save the relation name */
if ((newsattr->sa_rname = malloc(RNSIZE+1)) == NULL) {
free(newsattr);
return (db_ferror(INSMEM));
}
strncpy(newsattr->sa_rname,
srptr->sr_scan->sc_relation->rl_name,
RNSIZE);
newsattr->sa_rname[RNSIZE] = 0;
/* save the attribute name */
if ((newsattr->sa_aname = malloc(ANSIZE+1)) == NULL) {
free(newsattr->sa_rname);
free(newsattr);
return (db_ferror(INSMEM));
}
strncpy(newsattr->sa_aname,
srptr->sr_scan->sc_relation->rl_header.hd_attrs[i].at_name,
ANSIZE);
newsattr->sa_aname[ANSIZE] = 0;
/* link the selected attribute into the list */
if (lastsattr == NULL)
slptr->sl_attrs = newsattr;
else
lastsattr->sa_next = newsattr;
lastsattr = newsattr;
/* update the attribute start */
astart += aptr->at_size;
}
}
/* return successfully */
return (TRUE);
}
/* find_attr - find a named attribute */
static int find_attr(slptr,rname,aname,paptr,psrel,pattr)
struct sel *slptr; char *rname,*aname;
char **paptr; struct attribute **pattr;
{
/* check for unqualified or qualified attribute names */
if (rname == NULL)
return (uattr(slptr,aname,paptr,psrel,pattr));
else
return (qattr(slptr,rname,aname,paptr,psrel,pattr));
}
/* uattr - find an unqualified attribute name */
static int uattr(slptr,aname,paptr,psrel,pattr)
struct sel *slptr; char *aname;
char **paptr; struct srel **psrel; struct attribute **pattr;
{
struct srel *srptr;
struct attribute *aptr;
int i,astart;
/* loop through each selected relation */
*pattr = NULL;
for (srptr = slptr->sl_rels; srptr != NULL; srptr = srptr->sr_next) {
/* loop through each attribute within the relation */
astart = 1;
for (i = 0; i < NATTRS; i++) {
/* get a pointer to the current attribute */
aptr = &srptr->sr_scan->sc_relation->rl_header.hd_attrs[i];
/* check for last attribute */
if (aptr->at_name[0] == 0)
break;
/* check for attribute name match */
if (db_sncmp(aname,aptr->at_name,ANSIZE) == 0) {
if (*pattr != NULL)
return (db_ferror(ATAMBG));
*paptr = srptr->sr_scan->sc_tuple + astart;
*psrel = srptr;
*pattr = aptr;
}
/* update the attribute start */
astart += aptr->at_size;
}
}
/* check whether attribute was found */
if (*pattr == NULL)
return (db_ferror(ATUNDF));
/* return successfully */
return (TRUE);
}
/* qattr - find a qualified attribute name */
static int qattr(slptr,rname,aname,paptr,psrel,pattr)
struct sel *slptr; char *rname,*aname;
char **paptr; struct srel **psrel; struct attribute **pattr;
{
struct srel *srptr;
struct attribute *aptr;
char *crname;
int i,astart;
/* loop through each selected relation */
for (srptr = slptr->sl_rels; srptr != NULL; srptr = srptr->sr_next) {
/* get relation name */
if ((crname = srptr->sr_name) == NULL)
crname = srptr->sr_scan->sc_relation->rl_name;
/* check for relation name match */
if (db_sncmp(rname,crname,RNSIZE) == 0) {
/* loop through each attribute within the relation */
astart = 1;
for (i = 0; i < NATTRS; i++) {
/* get a pointer to the current attribute */
aptr = &srptr->sr_scan->sc_relation->rl_header.hd_attrs[i];
/* check for last attribute */
if (aptr->at_name[0] == 0)
break;
/* check for attribute name match */
if (db_sncmp(aname,aptr->at_name,ANSIZE) == 0) {
*paptr = srptr->sr_scan->sc_tuple + astart;
*psrel = srptr;
*pattr = aptr;
return (TRUE);
}
/* update the attribute start */
astart += aptr->at_size;
}
/* attribute name not found */
return (db_ferror(ATUNDF));
}
}
/* relation name not found */
return (db_ferror(RLUNDF));
}
/* process(srptr) - process each tuple in a relation cross-product */
static int process(srptr)
struct srel *srptr;
{
/* always get a new tuple if this is the last relation in the list */
if (srptr->sr_next == NULL) {
/* check for beginning of new scan */
if (!srptr->sr_ctuple)
db_rbegin(srptr->sr_scan);
/* return the next tuple in the relation */
return (srptr->sr_ctuple = db_rfetch(srptr->sr_scan));
}
/* check for beginning of new scan */
if (!srptr->sr_ctuple) {
db_rbegin(srptr->sr_scan);
/* get the first tuple */
if (!db_rfetch(srptr->sr_scan))
return (FALSE);
}
/* look for a match with the remaining relations in list */
while (!process(srptr->sr_next))
/* get the next tuple in the scan */
if (!db_rfetch(srptr->sr_scan))
return (srptr->sr_ctuple = FALSE);
/* found a match at this level */
return (srptr->sr_ctuple = TRUE);
}
/* db_aget - get the value of an attribute */
db_aget(aptr,vptr,avalue)
struct attribute *aptr; char *vptr,*avalue;
{
int i;
/* get the attribute value */
for (i = 0; i < aptr->at_size; i++)
*avalue++ = vptr[i];
*avalue = EOS;
}
/* db_aput - put the value of an attribute */
db_aput(aptr,vptr,avalue)
struct attribute *aptr; char *vptr,*avalue;
{
int i;
/* initialize counter */
i = 0;
/* right justify numbers */
if (aptr->at_type == TNUM)
for (; i < aptr->at_size - strlen(avalue); i++)
vptr[i] = ' ';
/* put the attribute value */
for (; i < aptr->at_size; i++)
if (*avalue == 0)
vptr[i] = 0;
else
vptr[i] = *avalue++;
}
Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!
This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.
But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/