a small dbms (reposting sources) 3 of 3
Ozan Yigit
oz at yetti.UUCP
Tue Sep 3 06:43:34 AEST 1985
---------------- SNIP ----------- SNIP -------------- SNIP --------
#!/bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #!/bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
# sdb.c
# sel.c
# srt.c
# tbl.c
# sdbio.h
# This archive created: Mon Sep 2 16:31:17 1985
export PATH; PATH=/bin:$PATH
echo shar: extracting "'sdb.c'" '(367 characters)'
if test -f 'sdb.c'
then
echo shar: over-writing existing file "'sdb.c'"
fi
sed 's/^X//' << \SHAR_EOF > 'sdb.c'
X/* SDB - main routine */
X
X#include "stdio.h"
X#include "sdbio.h"
X
Xextern int dbv_errcode;
X
Xmain()
X{
X printf("SDB - version 2.0\n");
X db_sinit();
X db_ifile("sdb.ini");
X
X while (TRUE) {
X db_prompt("SDB> ","\t> ");
X if (!db_parse(NULL)) {
X printf("** error: %s ***\n",db_ertxt(dbv_errcode));
X db_kill();
X }
X }
X}
X
SHAR_EOF
if test 367 -ne "`wc -c 'sdb.c'`"
then
echo shar: error transmitting "'sdb.c'" '(should have been 367 characters)'
fi
echo shar: extracting "'sel.c'" '(20482 characters)'
if test -f 'sel.c'
then
echo shar: over-writing existing file "'sel.c'"
fi
sed 's/^X//' << \SHAR_EOF > 'sel.c'
X/* SDB - select data from the database */
X
X#include "sdbio.h"
X
Xextern int dbv_token;
Xextern char dbv_tstring[];
Xextern int dbv_tvalue;
X
X/* db_select - select a set of tuples from a set of relations */
Xstruct sel *db_select(fmt,a1,a2,a3,a4,a5,a6,a7,a8,a9)
X char *fmt;
X{
X struct sel *slptr;
X
X /* check for a command line */
X if (fmt != NULL)
X db_scan(fmt,a1,a2,a3,a4,a5,a6,a7,a8,a9);
X
X /* allocate a sel structure */
X if ((slptr = malloc(sizeof(struct sel))) == NULL)
X return (db_nerror(INSMEM));
X
X /* initialize the structure */
X slptr->sl_rels = NULL;
X slptr->sl_attrs = NULL;
X slptr->sl_where = NULL;
X slptr->sl_bindings = NULL;
X
X /* parse the list of selected attributes */
X if (!get_sattrs(slptr)) {
X db_done(slptr);
X return (NULL);
X }
X
X /* check for "from" clause */
X if (db_token() == FROM) {
X db_ntoken();
X if (!get_srels(slptr)) {
X db_done(slptr);
X return (NULL);
X }
X }
X else {
X if (!srelation(slptr,"sdbcur",NULL)) {
X db_done(slptr);
X return (NULL);
X }
X }
X
X /* check the list of selected attributes */
X if (!check_attrs(slptr)) {
X db_done(slptr);
X return (NULL);
X }
X
X /* check for the existance of a "where" clause */
X if (db_token() == WHERE) {
X db_ntoken();
X
X /* parse the boolean expression */
X if (!db_compile(slptr)) {
X db_done(slptr);
X return (FALSE);
X }
X }
X
X /* return the new selection structure */
X return (slptr);
X}
X
X/* db_retrieve - retrieve a set of tuples from a set of relations */
Xstruct sel *db_retrieve(fmt,a1,a2,a3,a4,a5,a6,a7,a8,a9)
X char *fmt;
X{
X struct sel *slptr;
X
X /* check for a command line */
X if (fmt != NULL)
X db_scan(fmt,a1,a2,a3,a4,a5,a6,a7,a8,a9);
X
X /* allocate a sel structure */
X if ((slptr = malloc(sizeof(struct sel))) == NULL)
X return (db_nerror(INSMEM));
X
X /* initialize the structure */
X slptr->sl_rels = NULL;
X slptr->sl_attrs = NULL;
X slptr->sl_where = NULL;
X slptr->sl_bindings = NULL;
X
X /* check for selected relations clause */
X if (db_token() == ID) {
X if (!get_srels(slptr)) {
X db_done(slptr);
X return (NULL);
X }
X }
X else {
X if (!srelation(slptr,"sdbcur",NULL)) {
X db_done(slptr);
X return (NULL);
X }
X }
X
X /* check the list of selected attributes */
X if (!check_attrs(slptr)) {
X db_done(slptr);
X return (NULL);
X }
X
X /* check for the existance of a "where" clause */
X if (db_token() == WHERE) {
X db_ntoken();
X
X /* parse the boolean expression */
X if (!db_compile(slptr)) {
X db_done(slptr);
X return (FALSE);
X }
X }
X
X /* return the new selection structure */
X return (slptr);
X}
X
X/* db_done(slptr) - finish a selection */
Xdb_done(slptr)
X struct sel *slptr;
X{
X struct sattr *saptr,*nxtsa;
X struct srel *srptr,*nxtsr;
X struct binding *bdptr,*nxtbd;
X
X /* free the selected attribute blocks */
X for (saptr = slptr->sl_attrs; saptr != NULL; saptr = nxtsa) {
X nxtsa = saptr->sa_next;
X if (saptr->sa_rname != NULL)
X free(saptr->sa_rname);
X free(saptr->sa_aname);
X if (saptr->sa_name != NULL)
X free(saptr->sa_name);
X free(saptr);
X }
X
X /* close the scans and free the selected relation blocks */
X for (srptr = slptr->sl_rels; srptr != NULL; srptr = nxtsr) {
X nxtsr = srptr->sr_next;
X if (srptr->sr_name != NULL)
X free(srptr->sr_name);
X db_rclose(srptr->sr_scan);
X free(srptr);
X }
X
X /* free the where clause */
X db_fcode(slptr);
X
X /* free the user bindings */
X for (bdptr = slptr->sl_bindings; bdptr != NULL; bdptr = nxtbd) {
X nxtbd = bdptr->bd_next;
X free(bdptr);
X }
X
X /* free the selection structure */
X free(slptr);
X}
X
X/* db_fetch(slptr) - fetch the next tuple from a selection */
Xint db_fetch(slptr)
X struct sel *slptr;
X{
X struct srel *srptr;
X struct binding *bdptr;
X
X /* clear the update flags */
X for (srptr = slptr->sl_rels; srptr != NULL; srptr = srptr->sr_next)
X srptr->sr_update = FALSE;
X
X /* find a matching tuple */
X while (process(slptr->sl_rels))
X if (db_interpret(slptr)) {
X for (bdptr = slptr->sl_bindings; bdptr != NULL; bdptr = bdptr->bd_next)
X db_aget(bdptr->bd_attr,bdptr->bd_vtuple,bdptr->bd_vuser);
X return (TRUE);
X }
X
X /* no matches, failure return */
X return (FALSE);
X}
X
X/* db_update - update modified tuples */
Xint db_update(slptr)
X struct sel *slptr;
X{
X struct srel *srptr;
X
X /* check each selected relation for updates */
X for (srptr = slptr->sl_rels; srptr != NULL; srptr = srptr->sr_next)
X if (srptr->sr_update)
X if (!db_rupdate(srptr->sr_scan))
X return (FALSE);
X
X /* return successfully */
X return (TRUE);
X}
X
X/* db_store - store tuples */
Xint db_store(slptr)
X struct sel *slptr;
X{
X struct srel *srptr;
X
X /* check each selected relation for stores */
X for (srptr = slptr->sl_rels; srptr != NULL; srptr = srptr->sr_next)
X if (srptr->sr_update)
X if (!db_rstore(srptr->sr_scan))
X return (FALSE);
X
X /* return successfully */
X return (TRUE);
X}
X
X/* db_bind - bind a user buffer to the value of an attribute */
Xint db_bind(slptr,rname,aname,avalue)
X struct sel *slptr; char *rname,*aname,*avalue;
X{
X struct binding *newbd;
X struct srel *srptr;
X
X /* allocate and initialize a binding structure */
X if ((newbd = malloc(sizeof(struct binding))) == NULL)
X return (db_ferror(INSMEM));
X newbd->bd_vuser = avalue;
X
X /* find the attribute */
X if (!find_attr(slptr,rname,aname,&newbd->bd_vtuple,&srptr,&newbd->bd_attr))
X return (FALSE);
X
X /* link the new binding into the binding list */
X newbd->bd_next = slptr->sl_bindings;
X slptr->sl_bindings = newbd;
X
X /* return successfully */
X return (TRUE);
X}
X
X/* db_get - get the value of an attribute */
Xint db_get(slptr,rname,aname,avalue)
X struct sel *slptr; char *rname,*aname,*avalue;
X{
X struct srel *srptr;
X struct attribute *aptr;
X char *vptr;
X
X /* find the attribute */
X if (!find_attr(slptr,rname,aname,&vptr,&srptr,&aptr))
X return (FALSE);
X
X /* get the attribute value */
X db_aget(aptr,vptr,avalue);
X
X /* return successfully */
X return (TRUE);
X}
X
X/* db_put - put the value of an attribute */
Xint db_put(slptr,rname,aname,avalue)
X struct sel *slptr; char *rname,*aname,*avalue;
X{
X struct srel *srptr;
X struct attribute *aptr;
X char *vptr;
X
X /* find the attribute */
X if (!find_attr(slptr,rname,aname,&vptr,&srptr,&aptr))
X return (FALSE);
X
X /* put the attribute value */
X db_aput(aptr,vptr,avalue);
X
X /* mark the tuple as updated */
X srptr->sr_update = TRUE;
X
X /* return successfully */
X return (TRUE);
X}
X
X/* db_sattr - get selected attribute type, pointer, and length */
Xint db_sattr(slptr,rname,aname,ptype,pptr,plen)
X struct sel *slptr; char *rname,*aname;
X int *ptype; char **pptr; int *plen;
X{
X struct srel *srptr;
X struct attribute *aptr;
X
X if (!find_attr(slptr,rname,aname,pptr,&srptr,&aptr))
X return (FALSE);
X *ptype = aptr->at_type;
X *plen = aptr->at_size;
X return (TRUE);
X}
X
X/* get_sattrs(slptr) - get selected attributes */
Xstatic get_sattrs(slptr)
X struct sel *slptr;
X{
X struct sattr *newsattr,*lastsattr;
X
X /* check for "*" or blank field meaning all attributes are selected */
X if (db_token() == '*') {
X db_ntoken();
X return (TRUE);
X }
X else if (db_token() != ID)
X return (TRUE);
X
X /* parse a list of attribute names */
X lastsattr = NULL;
X while (TRUE) {
X
X /* get attribute name */
X if (db_ntoken() != ID)
X return (db_ferror(SYNTAX));
X
X /* allocate a selected attribute structure */
X if ((newsattr = malloc(sizeof(struct sattr))) == NULL)
X return (db_ferror(INSMEM));
X
X /* initialize the selected attribute structure */
X newsattr->sa_next = NULL;
X
X /* save the attribute name */
X if ((newsattr->sa_aname = malloc(strlen(dbv_tstring)+1)) == NULL) {
X free(newsattr);
X return (db_ferror(INSMEM));
X }
X strcpy(newsattr->sa_aname,dbv_tstring);
X
X /* check for "." meaning "<rel-name>.<att-name>" */
X if (db_token() == '.') {
X db_ntoken();
X
X /* the previous ID was really the relation name */
X newsattr->sa_rname = newsattr->sa_aname;
X
X /* check for attribute name */
X if (db_ntoken() != ID) {
X free(newsattr->sa_aname); free(newsattr);
X return (db_ferror(SYNTAX));
X }
X
X /* save the attribute name */
X if ((newsattr->sa_aname = malloc(strlen(dbv_tstring)+1)) == NULL) {
X free(newsattr->sa_aname); free(newsattr);
X return (db_ferror(INSMEM));
X }
X strcpy(newsattr->sa_aname,dbv_tstring);
X }
X else
X newsattr->sa_rname = NULL;
X
X /* check for alternate attribute name */
X if (db_token() == ID) {
X db_ntoken();
X
X /* allocate space for the alternate name */
X if ((newsattr->sa_name = malloc(strlen(dbv_tstring)+1)) == NULL) {
X if (newsattr->sa_rname != NULL)
X free(newsattr->sa_rname);
X free(newsattr->sa_aname);
X free(newsattr);
X return (db_ferror(INSMEM));
X }
X strcpy(newsattr->sa_name,dbv_tstring);
X }
X else
X newsattr->sa_name = NULL;
X
X /* link the selected attribute structure into the list */
X if (lastsattr == NULL)
X slptr->sl_attrs = newsattr;
X else
X lastsattr->sa_next = newsattr;
X lastsattr = newsattr;
X
X /* check for more attributes */
X if (db_token() != ',')
X break;
X db_ntoken();
X }
X
X /* return successfully */
X return (TRUE);
X}
X
X/* get_srels(slptr) - get selected relations */
Xstatic get_srels(slptr)
X struct sel *slptr;
X{
X char rname[KEYWORDMAX+1],*aname;
X
X /* get the list of selected relations */
X while (TRUE) {
X
X /* check for relation name */
X if (db_ntoken() != ID)
X return (db_ferror(SYNTAX));
X strcpy(rname,dbv_tstring);
X
X /* check for alternate relation name */
X if (db_token() == ID) {
X db_ntoken();
X aname = dbv_tstring;
X }
X else
X aname = NULL;
X
X /* add the relation name to the list */
X if (!srelation(slptr,rname,aname))
X return (FALSE);
X
X /* check for more selected relations */
X if (db_token() != ',')
X break;
X db_ntoken();
X }
X
X /* return successfully */
X return (TRUE);
X}
X
X/* srelation - select a relation */
Xstatic srelation(slptr,rname,aname)
X struct sel *slptr; char *rname,*aname;
X{
X struct srel *srptr,*newsrel;
X
X /* allocate a new selected relation structure */
X if ((newsrel = malloc(sizeof(struct srel))) == NULL)
X return (db_ferror(INSMEM));
X
X /* initialize the new selected relation structure */
X newsrel->sr_ctuple = FALSE;
X newsrel->sr_update = FALSE;
X newsrel->sr_next = NULL;
X
X /* open the relation */
X if ((newsrel->sr_scan = db_ropen(rname)) == NULL) {
X free(newsrel);
X return (FALSE);
X }
X
X /* check for alternate relation name */
X if (aname != NULL) {
X
X /* allocate space for the alternate name */
X if ((newsrel->sr_name = malloc(strlen(aname)+1)) == NULL) {
X free(newsrel);
X return (db_ferror(INSMEM));
X }
X strcpy(newsrel->sr_name,aname);
X }
X else
X newsrel->sr_name = NULL;
X
X /* find the end of the list of relation names */
X for (srptr = slptr->sl_rels; srptr != NULL; srptr = srptr->sr_next)
X if (srptr->sr_next == NULL)
X break;
X
X /* link the new selected relation structure into the list */
X if (srptr == NULL)
X slptr->sl_rels = newsrel;
X else
X srptr->sr_next = newsrel;
X
X /* return successfully */
X return (TRUE);
X}
X
X/* check_attrs(slptr) - check the list of selected attributes */
Xstatic int check_attrs(slptr)
X struct sel *slptr;
X{
X struct sattr *saptr;
X
X /* check for all attributes selected */
X if (slptr->sl_attrs == NULL)
X return (all_attrs(slptr));
X
X /* check each selected attribute */
X for (saptr = slptr->sl_attrs; saptr != NULL; saptr = saptr->sa_next)
X if (!find_attr(slptr,saptr->sa_rname,saptr->sa_aname,
X &saptr->sa_aptr,&saptr->sa_srel,&saptr->sa_attr))
X return (FALSE);
X
X /* return successfully */
X return (TRUE);
X}
X
X/* all_attrs(slptr) - create a list of all attributes */
Xstatic int all_attrs(slptr)
X struct sel *slptr;
X{
X struct sattr *newsattr,*lastsattr;
X struct srel *srptr;
X struct attribute *aptr;
X int i,astart;
X
X /* loop through each selected relation */
X lastsattr = NULL;
X for (srptr = slptr->sl_rels; srptr != NULL; srptr = srptr->sr_next) {
X
X /* loop through each attribute within the relation */
X astart = 1;
X for (i = 0; i < NATTRS; i++) {
X
X /* get a pointer to the current attribute */
X aptr = &srptr->sr_scan->sc_relation->rl_header.hd_attrs[i];
X
X /* check for last attribute */
X if (aptr->at_name[0] == 0)
X break;
X
X /* allocate a new selected attribute structure */
X if ((newsattr = malloc(sizeof(struct sattr))) == NULL)
X return (db_ferror(INSMEM));
X
X /* initialize the new selected attribute structure */
X newsattr->sa_name = NULL;
X newsattr->sa_srel = srptr;
X newsattr->sa_aptr = srptr->sr_scan->sc_tuple + astart;
X newsattr->sa_attr = aptr;
X newsattr->sa_next = NULL;
X
X /* save the relation name */
X if ((newsattr->sa_rname = malloc(RNSIZE+1)) == NULL) {
X free(newsattr);
X return (db_ferror(INSMEM));
X }
X strncpy(newsattr->sa_rname,
X srptr->sr_scan->sc_relation->rl_name,
X RNSIZE);
X newsattr->sa_rname[RNSIZE] = 0;
X
X /* save the attribute name */
X if ((newsattr->sa_aname = malloc(ANSIZE+1)) == NULL) {
X free(newsattr->sa_rname);
X free(newsattr);
X return (db_ferror(INSMEM));
X }
X strncpy(newsattr->sa_aname,
X srptr->sr_scan->sc_relation->rl_header.hd_attrs[i].at_name,
X ANSIZE);
X newsattr->sa_aname[ANSIZE] = 0;
X
X /* link the selected attribute into the list */
X if (lastsattr == NULL)
X slptr->sl_attrs = newsattr;
X else
X lastsattr->sa_next = newsattr;
X lastsattr = newsattr;
X
X /* update the attribute start */
X astart += aptr->at_size;
X }
X }
X
X /* return successfully */
X return (TRUE);
X}
X
X/* find_attr - find a named attribute */
Xstatic int find_attr(slptr,rname,aname,paptr,psrel,pattr)
X struct sel *slptr; char *rname,*aname;
X char **paptr; struct attribute **pattr;
X{
X /* check for unqualified or qualified attribute names */
X if (rname == NULL)
X return (uattr(slptr,aname,paptr,psrel,pattr));
X else
X return (qattr(slptr,rname,aname,paptr,psrel,pattr));
X}
X
X/* uattr - find an unqualified attribute name */
Xstatic int uattr(slptr,aname,paptr,psrel,pattr)
X struct sel *slptr; char *aname;
X char **paptr; struct srel **psrel; struct attribute **pattr;
X{
X struct srel *srptr;
X struct attribute *aptr;
X int i,astart;
X
X /* loop through each selected relation */
X *pattr = NULL;
X for (srptr = slptr->sl_rels; srptr != NULL; srptr = srptr->sr_next) {
X
X /* loop through each attribute within the relation */
X astart = 1;
X for (i = 0; i < NATTRS; i++) {
X
X /* get a pointer to the current attribute */
X aptr = &srptr->sr_scan->sc_relation->rl_header.hd_attrs[i];
X
X /* check for last attribute */
X if (aptr->at_name[0] == 0)
X break;
X
X /* check for attribute name match */
X if (db_sncmp(aname,aptr->at_name,ANSIZE) == 0) {
X if (*pattr != NULL)
X return (db_ferror(ATAMBG));
X *paptr = srptr->sr_scan->sc_tuple + astart;
X *psrel = srptr;
X *pattr = aptr;
X }
X
X /* update the attribute start */
X astart += aptr->at_size;
X }
X }
X
X /* check whether attribute was found */
X if (*pattr == NULL)
X return (db_ferror(ATUNDF));
X
X /* return successfully */
X return (TRUE);
X}
X
X/* qattr - find a qualified attribute name */
Xstatic int qattr(slptr,rname,aname,paptr,psrel,pattr)
X struct sel *slptr; char *rname,*aname;
X char **paptr; struct srel **psrel; struct attribute **pattr;
X{
X struct srel *srptr;
X struct attribute *aptr;
X char *crname;
X int i,astart;
X
X /* loop through each selected relation */
X for (srptr = slptr->sl_rels; srptr != NULL; srptr = srptr->sr_next) {
X
X /* get relation name */
X if ((crname = srptr->sr_name) == NULL)
X crname = srptr->sr_scan->sc_relation->rl_name;
X
X /* check for relation name match */
X if (db_sncmp(rname,crname,RNSIZE) == 0) {
X
X /* loop through each attribute within the relation */
X astart = 1;
X for (i = 0; i < NATTRS; i++) {
X
X /* get a pointer to the current attribute */
X aptr = &srptr->sr_scan->sc_relation->rl_header.hd_attrs[i];
X
X /* check for last attribute */
X if (aptr->at_name[0] == 0)
X break;
X
X /* check for attribute name match */
X if (db_sncmp(aname,aptr->at_name,ANSIZE) == 0) {
X *paptr = srptr->sr_scan->sc_tuple + astart;
X *psrel = srptr;
X *pattr = aptr;
X return (TRUE);
X }
X
X /* update the attribute start */
X astart += aptr->at_size;
X }
X
X /* attribute name not found */
X return (db_ferror(ATUNDF));
X }
X }
X
X /* relation name not found */
X return (db_ferror(RLUNDF));
X}
X
X/* process(srptr) - process each tuple in a relation cross-product */
Xstatic int process(srptr)
X struct srel *srptr;
X{
X /* always get a new tuple if this is the last relation in the list */
X if (srptr->sr_next == NULL) {
X
X /* check for beginning of new scan */
X if (!srptr->sr_ctuple)
X db_rbegin(srptr->sr_scan);
X
X /* return the next tuple in the relation */
X return (srptr->sr_ctuple = db_rfetch(srptr->sr_scan));
X }
X
X /* check for beginning of new scan */
X if (!srptr->sr_ctuple) {
X db_rbegin(srptr->sr_scan);
X
X /* get the first tuple */
X if (!db_rfetch(srptr->sr_scan))
X return (FALSE);
X }
X
X /* look for a match with the remaining relations in list */
X while (!process(srptr->sr_next))
X
X /* get the next tuple in the scan */
X if (!db_rfetch(srptr->sr_scan))
X return (srptr->sr_ctuple = FALSE);
X
X /* found a match at this level */
X return (srptr->sr_ctuple = TRUE);
X}
X
X/* db_aget - get the value of an attribute */
Xdb_aget(aptr,vptr,avalue)
X struct attribute *aptr; char *vptr,*avalue;
X{
X int i;
X
X /* get the attribute value */
X for (i = 0; i < aptr->at_size; i++)
X *avalue++ = vptr[i];
X *avalue = EOS;
X}
X
X/* db_aput - put the value of an attribute */
Xdb_aput(aptr,vptr,avalue)
X struct attribute *aptr; char *vptr,*avalue;
X{
X int i;
X
X /* initialize counter */
X i = 0;
X
X /* right justify numbers */
X if (aptr->at_type == TNUM)
X for (; i < aptr->at_size - strlen(avalue); i++)
X vptr[i] = ' ';
X
X /* put the attribute value */
X for (; i < aptr->at_size; i++)
X if (*avalue == 0)
X vptr[i] = 0;
X else
X vptr[i] = *avalue++;
X}
X
SHAR_EOF
if test 20482 -ne "`wc -c 'sel.c'`"
then
echo shar: error transmitting "'sel.c'" '(should have been 20482 characters)'
fi
echo shar: extracting "'srt.c'" '(8289 characters)'
if test -f 'srt.c'
then
echo shar: over-writing existing file "'srt.c'"
fi
sed 's/^X//' << \SHAR_EOF > 'srt.c'
X/* SDB - sort routines */
X
X#include "stdio.h"
X#include "sdbio.h"
X
Xextern int dbv_token;
Xextern char dbv_tstring[];
Xextern int dbv_tvalue;
X
X/* get_skeys - get sort key list */
Xstatic struct skey *get_skeys(sptr)
X struct scan *sptr;
X{
X struct skey *skeys,*newskey,*lastskey;
X
X /* parse a list of attribute names */
X skeys = lastskey = NULL;
X while (TRUE) {
X
X /* get attribute name */
X if (db_ntoken() != ID)
X return (db_nerror(SYNTAX));
X
X /* allocate a sort key structure */
X if ((newskey = malloc(sizeof(struct skey))) == NULL)
X return (db_nerror(INSMEM));
X
X /* initialize the sort key structure */
X newskey->sk_next = NULL;
X
X /* lookup the attribute name */
X if (!find_attr(sptr,newskey,dbv_tstring)) {
X free(newskey);
X return (NULL);
X }
X
X /* check for ascending or descending */
X if (db_token() == ASCENDING || dbv_token == DESCENDING) {
X newskey->sk_type = dbv_token;
X db_ntoken();
X }
X else
X newskey->sk_type = ASCENDING;
X
X /* link the sort key structure into the list */
X if (lastskey == NULL)
X skeys = newskey;
X else
X lastskey->sk_next = newskey;
X lastskey = newskey;
X
X /* check for more attributes */
X if (db_token() != ',')
X break;
X db_ntoken();
X }
X
X /* return successfully */
X return (skeys);
X}
X
X/* db_sort - sort tuples in a relation */
Xint *db_sort(fmt,a1,a2,a3,a4,a5,a6,a7,a8,a9)
X char *fmt;
X{
X struct scan *sptr1,*sptr2,*sptr3; /*dns*/
X struct skey *skeys;
X int result;
X
X /* check for a command line */
X if (fmt != NULL)
X db_scan(fmt,a1,a2,a3,a4,a5,a6,a7,a8,a9);
X
X /* checks for relation name */
X if (db_token() == ID)
X db_ntoken();
X else
X strcpy(dbv_tstring,"sdbcur");
X
X /* open the relation */
X if ((sptr1 = db_ropen(dbv_tstring)) == NULL)
X return (FALSE);
X if ((sptr2 = db_ropen(dbv_tstring)) == NULL) {
X db_rclose(sptr1);
X return (FALSE);
X }
X if ((sptr3 = db_ropen(dbv_tstring)) == NULL) { /*dns*/
X db_rclose(sptr1); /*dns*/
X db_rclose(sptr2); /*dns*/
X return (FALSE); /*dns*/
X }
X
X /* checks for "<relation-name> by <sort-list>" */
X if (db_ntoken() != BY)
X return (db_ferror(SYNTAX));
X if ((skeys = get_skeys(sptr1)) == NULL) {
X db_rclose(sptr1);
X db_rclose(sptr2);
X db_rclose(sptr3); /*dns*/
X return (FALSE);
X }
X
X /* do the sort */
X result = sort(skeys,sptr1,sptr2,sptr3); /*dns*/
X
X /* close the relation */
X db_rclose(sptr1);
X db_rclose(sptr2);
X db_rclose(sptr3); /*dns*/
X
X /* free the sort keys */
X free_skeys(skeys);
X
X return (result);
X}
X
X/* free_skeys - free a list of sort keys */
Xstatic free_skeys(skeys)
X struct skey *skeys;
X{
X struct skey *thisskey;
X
X for (thisskey = skeys; skeys != NULL; thisskey = skeys) {
X skeys = skeys->sk_next;
X free(thisskey);
X }
X}
X
X/* find_attr - find an attribute */
Xstatic int find_attr(sptr,newskey,aname)
X struct scan *sptr; struct skey *newskey; char *aname;
X{
X struct attribute *aptr;
X int i,astart;
X
X /* loop through each attribute within the relation */
X astart = 1;
X for (i = 0; i < NATTRS; i++) {
X
X /* get a pointer to the current attribute */
X aptr = &sptr->sc_relation->rl_header.hd_attrs[i];
X
X /* check for last attribute */
X if (aptr->at_name[0] == 0)
X break;
X
X /* check for attribute name match */
X if (db_sncmp(aname,aptr->at_name,ANSIZE) == 0) {
X newskey->sk_start = astart;
X newskey->sk_aptr = aptr;
X return (TRUE);
X }
X
X /* update the attribute start */
X astart += aptr->at_size;
X }
X
X /* attribute name not found */
X return (db_ferror(ATUNDF));
X}
X
X/* sort - sort the relation */
Xstatic int sort(skeys,sptr1,sptr2,sptr3)
X struct skey *skeys; struct scan *sptr1,*sptr2,*sptr3;
X{
X/* unsigned int j,k,l,r; dns */
X long int passes,swaps; /*dns*/
X int i, j, m, n; /*dns*/
X int rec1 = 0; /*dns*/
X int rec2 = 0; /*dns*/
X int rec3 = 0; /*dns*/
X int dns = 0; /*dns*/
X FILE *test; /*dns*/
X
X passes = 0L;
X swaps = 0L;
X
X /*dns ---> */
X test = fopen("sort.dat", "w");
X n = sptr1->sc_relation->rl_tcnt;
X m = n;
X
X while( m>1 ) {
X passes++;
X if ((m/=3.14159) < 1) m = 1;
X for ( j=1; j<=n-m; j++ ) {
X if( rec1 != j+m ) {
X if(dns) fprintf(test,"Read1: %d\n", j+m);
X if (!db_rget(sptr1, rec1=j+m)) return (FALSE);
X }
X for ( i=j; i>=1; i-=m ) {
X if( rec2 != i ) {
X if(dns) fprintf(test,"Read2: %d\n", i);
X if (!db_rget(sptr2, rec2=i)) return (FALSE);
X }
X if (compare(skeys,sptr1,sptr2) > 0)
X break;
X if(rec3 != i+m) {
X if(dns) fprintf(test,"Read3: %d\n", i+m);
X if (!db_rget(sptr3, rec3=i+m)) return (FALSE);
X }
X if(dns) fprintf(test,"Write 3,2: %d from %d\n", i+m, i);
X assign( sptr3, sptr2 );
X swaps++;
X }
X if(rec1 != i+m) {
X if(rec3 != i+m) {
X if(dns) fprintf(test,"Read 3: %d\n", i+m);
X if (!db_rget(sptr3, rec3=i+m)) return (FALSE);
X }
X if(dns) fprintf(test,"Write 3,1: %d from %d\n", i+m, j+m);
X assign( sptr3, sptr1 );
X swaps++;
X }
X }
X }
X fclose(test);
X
X/*
X l = 2;
X r = sptr1->sc_relation->rl_tcnt;
X k = r;
X
X do {
X for (j = r; j >= l; j--) {
X if (!db_rget(sptr1,j-1))
X return (FALSE);
X if (!db_rget(sptr2,j))
X return (FALSE);
X if (compare(skeys,sptr1,sptr2) > 0) {
X swap(sptr1,sptr2);
X k = j;
X swaps++;
X }
X }
X l = k + 1;
X for (j = l; j <= r; j++) {
X if (!db_rget(sptr1,j-1))
X return (FALSE);
X if (!db_rget(sptr2,j))
X return (FALSE);
X if (compare(skeys,sptr1,sptr2) > 0) {
X swap(sptr1,sptr2);
X k = j;
X swaps++;
X }
X }
X r = k - 1;
X passes++;
X } while (l <= r);
X*/
X
X printf("[ Passes: %ld Swaps: %ld ]\n",passes,swaps);
X
X return (TRUE);
X}
X
X/* compare - compare two tuples */
Xstatic int compare(skeys,sptr1,sptr2)
X struct skey *skeys; struct scan *sptr1,*sptr2;
X{
X struct skey *cskey;
X int result;
X
X for (cskey = skeys; cskey != NULL; cskey = cskey->sk_next)
X if ((result = cattr(cskey,sptr1,sptr2)) != 0)
X break;
X
X return (result);
X}
X
X/* cattr - compare two attributes */
Xstatic int cattr(cskey,sptr1,sptr2)
X struct skey *cskey; struct scan *sptr1,*sptr2;
X{
X int astart,aend,i;
X
X astart = cskey->sk_start;
X aend = astart + cskey->sk_aptr->at_size;
X
X for (i = astart; i < aend; i++)
X if (sptr1->sc_tuple[i] != sptr2->sc_tuple[i])
X break;
X
X if (i == aend)
X return (0);
X
X if (sptr1->sc_tuple[i] < sptr2->sc_tuple[i])
X if (cskey->sk_type == ASCENDING)
X return (-1);
X else
X return (1);
X else
X if (cskey->sk_type == ASCENDING)
X return (1);
X else
X return (-1);
X}
X
X/* swap - swap two tuples */
X/* dns
Xstatic int swap(sptr1,sptr2)
X struct scan *sptr1,*sptr2;
X{
X unsigned int tnum1,tnum2;
X
X tnum1 = sptr1->sc_atnum;
X tnum2 = sptr2->sc_atnum;
X
X if (!db_rput(sptr1,tnum2))
X return (FALSE);
X if (!db_rput(sptr2,tnum1))
X return (FALSE);
X
X return (TRUE);
X}
X dns */
X
X
X/* assign - assign one tupple to another */
Xstatic int assign(sptr1,sptr2)
X struct scan *sptr1,*sptr2;
X{
X unsigned int tnum1,tnum2;
X
X tnum1 = sptr1->sc_atnum;
X
X if (!db_rput(sptr2,tnum1))
X return (FALSE);
X
X return (TRUE);
X}
X
SHAR_EOF
if test 8289 -ne "`wc -c 'srt.c'`"
then
echo shar: error transmitting "'srt.c'" '(should have been 8289 characters)'
fi
echo shar: extracting "'tbl.c'" '(2554 characters)'
if test -f 'tbl.c'
then
echo shar: over-writing existing file "'tbl.c'"
fi
sed 's/^X//' << \SHAR_EOF > 'tbl.c'
X/* SDB - table output routines */
X
X#include "stdio.h"
X#include "sdbio.h"
X
Xstatic char buffer[TABLEMAX+1];
Xint bndx;
X
X/* db_thead - print a table header */
Xdb_thead(fp,slptr)
X FILE *fp; struct sel *slptr;
X{
X struct sattr *saptr;
X int twidth,fwidth,i;
X char *aname;
X
X /* compute the table width */
X twidth = 1;
X for (saptr = slptr->sl_attrs; saptr != NULL; saptr = saptr->sa_next)
X twidth += saptr->sa_attr->at_size + 3;
X
X /* print the top line of the table */
X bstart();
X for (i = 0; i < twidth; i++)
X binsert('-');
X bprint(fp);
X
X /* print the label line of the table */
X bstart();
X for (saptr = slptr->sl_attrs; saptr != NULL; saptr = saptr->sa_next) {
X fwidth = saptr->sa_attr->at_size;
X binsert('|'); binsert(' ');
X if ((aname = saptr->sa_name) == NULL)
X aname = saptr->sa_aname;
X for (i = 0; i < fwidth; i++)
X if (*aname != 0)
X binsert(*aname++);
X else
X binsert(' ');
X binsert(' ');
X }
X binsert('|');
X bprint(fp);
X
X /* print the line under the labels */
X bstart();
X for (i = 0; i < twidth; i++)
X binsert('-');
X bprint(fp);
X}
X
X/* db_tfoot - print a table foot */
Xdb_tfoot(fp,slptr)
X FILE *fp; struct sel *slptr;
X{
X struct sattr *saptr;
X int twidth,i;
X
X /* compute the table width */
X twidth = 1;
X for (saptr = slptr->sl_attrs; saptr != NULL; saptr = saptr->sa_next)
X twidth += saptr->sa_attr->at_size + 3;
X
X /* print the line at the foot of the table */
X bstart();
X for (i = 0; i < twidth; i++)
X binsert('-');
X bprint(fp);
X}
X
X/* db_tentry - print a table entry */
Xdb_tentry(fp,slptr)
X FILE *fp; struct sel *slptr;
X{
X struct sattr *saptr;
X int fwidth,i;
X
X /* print a table entry */
X bstart();
X for (saptr = slptr->sl_attrs; saptr != NULL; saptr = saptr->sa_next) {
X fwidth = saptr->sa_attr->at_size;
X binsert('|'); binsert(' ');
X for (i = 0; i < fwidth; i++)
X if (saptr->sa_aptr[i] != 0)
X binsert(saptr->sa_aptr[i]);
X else
X binsert(' ');
X binsert(' ');
X }
X binsert('|');
X bprint(fp);
X}
X
X/* bstart - start building a line */
Xstatic bstart()
X{
X bndx = 0;
X}
X
X/* binsert - insert a character into the buffer */
Xstatic binsert(ch)
X int ch;
X{
X if (bndx < TABLEMAX)
X buffer[bndx++] = ch;
X}
X
X/* bprint - print the current line */
Xstatic bprint(fp)
X FILE *fp;
X{
X buffer[bndx] = EOS;
X fprintf(fp,"%s\n",buffer);
X}
X
SHAR_EOF
if test 2554 -ne "`wc -c 'tbl.c'`"
then
echo shar: error transmitting "'tbl.c'" '(should have been 2554 characters)'
fi
echo shar: extracting "'sdbio.h'" '(7764 characters)'
if test -f 'sdbio.h'
then
echo shar: over-writing existing file "'sdbio.h'"
fi
sed 's/^X//' << \SHAR_EOF > 'sdbio.h'
X/* SDB - definition file */
X
X#include "ctype.h" /*dns*/
X
X/* compiler specific stuff (dns) */
X#define Lattice
X
X/* useful definitions */
X#define TRUE 1
X#define FALSE 0
X#ifndef NULL
X#define NULL 0
X#endif
X
X/* Character definitions (dns) */
X#define BS 0x8 /*dns*/
X#define CR 0xD /*dns*/
X#define FF 0xC /*dns*/
X#define ESC 0x1B /*dns*/
X
X/* program limits */
X#define LINEMAX 132 /* maximum input line length */
X#define TABLEMAX 132 /* maximum table output line */
X#define KEYWORDMAX 10 /* maximum keyword length */
X#define NUMBERMAX 20 /* maximum number length */
X#define STRINGMAX 132 /* maximum string length */
X#define CODEMAX 100 /* maximum length of code array */
X#define STACKMAX 20 /* maximum interpreter stack size */
X
X/* token definitions */
X#define EOS 0
X#define LSS -1
X#define LEQ -2
X#define EQL -3
X#define NEQ -4
X#define GEQ -5
X#define GTR -6
X#define SELECT -7
X#define FROM -8
X#define WHERE -9
X#define CREATE -10
X#define DELETE -11
X#define INSERT -12
X#define EXIT -13
X#define CHAR -14
X#define NUM -15
X#define ID -16
X#define STRING -17
X#define NUMBER -18
X#define UPDATE -19
X#define PRINT -20
X#define IMPORT -21
X#define EXPORT -22
X#define INTO -23
X#define HELP -24
X#define COMPRESS -25
X#define EXTRACT -26
X#define DEFINE -27
X#define SHOW -28
X#define USING -29
X#define SORT -30
X#define BY -31
X#define ASCENDING -32
X#define DESCENDING -33
X#define SET -34
X
X/* operand types */
X#define LITERAL 1
X#define ATTR 2
X#define TEMP 3
X
X/* attribute data types */
X#define TCHAR 1
X#define TNUM 2
X
X/* tuple status codes */
X#define UNUSED 0
X#define ACTIVE 1
X#define DELETED 2
X
X/* relation header page format definitions */
X#define RNSIZE 10 /* size of a relation name */
X#define HSIZE 16 /* size of a relation entry */
X#define ASIZE 16 /* size of a attribute entry */
X#define ANSIZE 10 /* size of a attribute name */
X#define NATTRS 31 /* number of attributes in header block */
X
X/* error code definitions */
X#define END 0 /* end of retrieval set */
X#define INSMEM 1 /* insufficient memory */
X#define RELFNF 2 /* relation file not found */
X#define BADHDR 3 /* bad relation file header */
X#define TUPINP 4 /* tuple input error */
X#define TUPOUT 5 /* tuple output error */
X#define RELFUL 6 /* relation file full */
X#define RELCRE 7 /* error creating relation file */
X#define DUPATT 8 /* duplicate attribute on relation create */
X#define MAXATT 9 /* too many attributes on relation create */
X#define INSBLK 10 /* insufficient disk blocks */
X#define SYNTAX 11 /* command syntax error */
X#define ATUNDF 12 /* attribute name undefined */
X#define ATAMBG 13 /* attribute name ambiguous */
X#define RLUNDF 14 /* relation name undefined */
X#define CDSIZE 15 /* boolean expression code too big */
X#define INPFNF 16 /* input file not found */
X#define OUTCRE 17 /* output file creation error */
X#define INDFNF 18 /* indirect command file not found */
X#define BADSET 19 /* bad set parameter */
X
Xstruct attribute {
X char at_name[ANSIZE]; /* attribute name */
X char at_type; /* attribute type */
X char at_size; /* attribute size in bytes */
X char at_scale; /* attribute scale factor (for numeric only) */
X char at_unused[ASIZE-ANSIZE-3]; /* unused space */
X};
X
Xstruct header { /* sizeof(struct header) must be 512 bytes */
X char hd_tcnt[2]; /* # of tuples in relation */
X char hd_tmax[2]; /* maximum # of tuples */
X char hd_data[2]; /* offset to first data byte */
X char hd_size[2]; /* size of each tuple in bytes */
X char hd_unused[HSIZE-8]; /* unused space */
X struct attribute hd_attrs[NATTRS]; /* table of attributes */
X};
X
Xstruct relation {
X char rl_name[RNSIZE]; /* relation name */
X unsigned int rl_tcnt; /* # of tuples in relation (from hd_tcnt) */
X unsigned int rl_tmax; /* maximum # of tuples (from hd_tmax) */
X int rl_data; /* offset to first data byte (from hd_data) */
X int rl_size; /* size of eachtuple in bytes (from hd_size) */
X int rl_store; /* flag indicating a store happened */
X int rl_fd; /* file descriptor for relation file */
X int rl_scnref; /* number of scans referencing this relation */
X struct header rl_header; /* the relation file header block */
X struct relation *rl_next; /* pointer to next relation */
X};
X
Xstruct scan {
X struct relation *sc_relation; /* pointer to relation definition */
X unsigned int sc_dtnum; /* desired tuple number */
X unsigned int sc_atnum; /* actual tuple number */
X int sc_store; /* flag indicating a store happened */
X char *sc_tuple; /* tuple buffer */
X};
X
Xstruct srel {
X char *sr_name; /* alternate relation name */
X struct scan *sr_scan; /* relation scan structure ptr */
X int sr_ctuple; /* current tuple flag */
X int sr_update; /* updated tuple flag */
X struct srel *sr_next; /* next selected relation in list */
X};
X
Xstruct sattr {
X char *sa_rname; /* relation name */
X char *sa_aname; /* attribute name */
X char *sa_name; /* alternate attribute name */
X char *sa_aptr; /* pointer to attr in tuple buffer */
X struct srel *sa_srel; /* pointer to the selected relation */
X struct attribute *sa_attr; /* attribute structure ptr */
X struct sattr *sa_next; /* next selected attribute in list */
X};
X
Xstruct operand {
X int o_type;
X union {
X struct {
X int ovc_type;
X char *ovc_string;
X int ovc_length;
X } ov_char;
X int ov_boolean;
X } o_value;
X};
X
Xunion codecell {
X int (*c_operator)();
X struct operand *c_operand;
X};
X
Xstruct binding {
X struct attribute *bd_attr; /* bound attribute */
X char *bd_vtuple; /* pointer to value in tuple */
X char *bd_vuser; /* pointer to user buffer */
X struct binding *bd_next; /* next binding */
X};
X
Xstruct sel {
X struct srel *sl_rels; /* selected relations */
X struct sattr *sl_attrs; /* selected attributes */
X union codecell *sl_where; /* where clause */
X struct binding *sl_bindings; /* user variable bindings */
X};
X
Xstruct mtext {
X char *mt_text;
X struct mtext *mt_next;
X};
X
Xstruct macro {
X char *mc_name;
X struct mtext *mc_mtext;
X struct macro *mc_next;
X};
X
Xstruct ifile {
X char *if_fp;
X struct mtext *if_mtext;
X char *if_cmdline;
X int if_savech;
X char *if_lptr;
X struct ifile *if_next;
X};
X
Xstruct skey {
X int sk_type;
X struct attribute *sk_aptr;
X int sk_start;
X struct skey *sk_next;
X};
X
SHAR_EOF
if test 7764 -ne "`wc -c 'sdbio.h'`"
then
echo shar: error transmitting "'sdbio.h'" '(should have been 7764 characters)'
fi
# End of shell archive
exit 0
--
Usenet: [decvax|allegra|linus|ihnp4]!utzoo!yetti!oz
Bitnet: oz@[yusol|yuyetti]
You see things; and you say "WHY?"
But I dream things that never were;
and say "WHY NOT?"
G. Bernard Shaw (Back to Methuselah)
More information about the Comp.sources.unix
mailing list