Category : C Source Code
Archive   : SQLVER1.ZIP
Filename : COMMAND.C
Output of file : COMMAND.C contained in archive : SQLVER1.ZIP
#include "C:\LANGUAGE\C\TURBO.C\40.570\DEFS.H"
#endif
extern struct LIST *garbage;
/* */
/****************************************************************************/
/* SQL functions */
/****************************************************************************/
/*
int create( );
- This routine is used to create a table. Moreover, this routine writes
a header into each table storing the table's attributes. When every
table is created, an attribute is added "DEL" to mark deleted tuples.
A check is made to insure that duplicate attributes cannot be entered
into the header of a table.
Calls:
------
-createview( );
-insertlist( );
-maketable ( );
-recycle ( );
-scanner ( );
Called by:
----------
-parse ( );
*/
int create(table)
char *table;
{
char string[128] = "";
struct LIST *list = NULL;
if (command(table) == 14) return(createview(table));
if (scanner(table) == 99) return(-8);
if (scanner(string) != -3) return(-10); /* left paren expected */
while(TRUE)
{
int value = 0;
struct LIST *pointer = list;
struct DATA data;
getc(stdin);
if (scanner(string) != 0)
{
if (list) recycle(list);
return(-12); /* must be identifier */
}
while(pointer) /* insure that there are no duplicate fields */
{
if (strcmp(pointer->data.attribute,string) == 0)
{
recycle(list);
return(-21); /* duplicate field */
}
pointer = pointer->rlist;
}
strcpy(data.attribute,string);
value = scanner(string);
if (value != 20 && value != 21)
{
if (list) recycle(list);
return(-13); /* TYPE expected */
}
if (value == 20)
data.type = 1; /* number */
else
data.type = 0; /* character(s) */
if ((scanf("%d*",&value) == 0) || (value < 1))
{
if (list) recycle(list);
return(-14);
}
data.length = value; /* size of the attribute */
list = insertlist(list,data);
value = scanner(string);
if (value == -2) continue; /* comma ? */
if (value == -4) /* must be right paren */
{
getc(stdin);
break;
}
recycle(list);
return(-11);
}
if (scanner(string) != -1) /* Semicolon Expected */
{
recycle(list);
return(-6);
}
maketable(table,list);
recycle(list);
puts("\n TABLE created.");
return(0);
}
/* */
/*****************************************************************************/
/*
int createview( )
-This routine is used to create a view.
Calls:
------
-attributelist( );
-fields ( );
-maketable ( );
-recycle ( );
-scanner ( );
-select ( );
Called by:
----------
-create ( );
*/
int createview(table)
char *table;
{
int value = 0;
FILE *source,
*destination;
struct LIST *list = NULL,
*columns = NULL,
*pointer = NULL;
char *ch = NULL,
*dh = NULL,
string[128] = "";
if (scanner(table) == 99) return( -8); /* does file already exist ? */
value = scanner(string);
if (value == -3) /* '(' ? */
{
getc(stdin);
columns = attributelist(columns);
if ((value = columns->data.type) != -1)
{
recycle(columns);
return(value);
}
value = scanner(string);
}
if (value != 16)
{
recycle(columns);
return(-26); /* AS expected */
}
if (scanner(string) != 9)
{
recycle(columns);
return(-27); /* SELECT expected */
}
/* create the view file */
maketable(table,NULL);
value = select(string,1,columns);
unlink(table);
if (value != 0)
{
recycle(columns);
return(value);
}
list = fields(source = fopen(string,"r"));
ch = strchr(table,'.');
if (*ch == '.') *ch = NULL;
/*
if a list of columns was provided, then copy the data type's and size's
from the old table.
*/
if (columns)
{
struct LIST *columnlist = columns;
pointer = list->rlist;
while(pointer)
{
columnlist->data.type = pointer->data.type;
columnlist->data.length = pointer->data.length;
columnlist = columnlist->rlist;
pointer = pointer->rlist;
}
maketable(table,columns);
}
else
{
pointer = list->rlist;
/* remove all qualified attribute names */
while(pointer)
{
char temp[128] = "";
ch = strchr(pointer->data.attribute,'.');
dh = ch++;
while((dh = strchr(dh,'.'))) ch = ++dh;
strcpy(temp,ch);
strcpy(pointer->data.attribute,temp);
pointer = pointer->rlist;
}
maketable(table,list->rlist);
}
destination = fopen(table,"a");
/* copy the old table to the new one */
while((*ch = fgetc(source)) != EOF) fputc(*ch,destination);
fclose(source);
fclose(destination);
recycle(list);
recycle(columns);
unlink(string); /* delete the temporary old table */
return(0);
}
/* */
/*****************************************************************************/
/*
int delete( );
-This routine does the required parsing and determines if a tuple(s) is
to be deleted from a table. Two possibilities can occur: 1) the user
wants to delete all of the tuples in a table regardless of the value
of any of the attributes, or 2) the user wants to delete a tuple(s)
based on certain constant values contained in the table's attributes
and a conditional expression.
Calls:
------
-checktuple ( );
-command ( );
-deletetuple ( );
-fields ( );
-getspredicate( );
-makelist ( );
-readtuple ( );
-recycle ( );
-scanner ( );
Called By:
----------
-parse ( );
*/
int delete(table)
char *table;
{
FILE *fp;
int value = 0,
deleted = 0;
char string[128],
predicate[1024];
struct LIST *list = NULL, /* storage for table's attributes */
*tuplelist = NULL; /* storage for tuple */
if (scanner(table) != 99) return(-5); /* table name expected */
strcat(table,TAB);
strcpy(predicate,"");
list = fields(fp = fopen(table,"r+")); /* get table's attributes */
if (scanner(string) == 12) /* WHERE provided ? */
{
if ((value = getspredicate(predicate,list,NULL)) != 0)
{
recycle(list);
fclose(fp);
return(value);
}
}
else
if (command(string) != -1)
{
recycle(list);
fclose(fp);
return(-6);
}
if (scanner(string) != -1)
{
recycle(list);
fclose(fp);
return(-6);
}
tuplelist = makelist(list);
/* read entire file */
while (feof(fp) == 0)
{
unsigned long tuplepos = ftell(fp);
readtuple(tuplelist,fp);
if (tuplelist->data.attribute[0] == '0') /* is tuple deleted ? */
if (checktuple(tuplelist,list,predicate))
{
fseek(fp,tuplepos,SEEK_SET);
deleted++;
deletetuple(fp);
}
}
recycle(list);
recycle(tuplelist);
fclose(fp);
printf("\n%4d Tuples Deleted\n",deleted);
return(0);
}
/* */
/*****************************************************************************/
/*
int insert( );
-This routine is used to insert a tuple to the end of a table. The user
can enter the tuple in one of two fashions: 1) enter the constants
in left to right order where there is a one two one correspondence
between each constant entered and the attribute in the table, or 2)
enter any (1 or more) attributes to the table in any desired order.
The routine does the necessary checking to insure that all values
entered by the user are of the correct data type.
Calls:
------
-attributelist ( );
-checkfields ( );
-fields ( );
-makelist ( );
-nfields ( );
-readconstant ( );
-recycle ( );
-scanner ( );
-sequencelist ( );
-writetuple ( );
Called By:
----------
-parse ( );
*/
int insert(table)
char *table;
{
int ffields = 0, /* number of fields in specified field list */
value = 0;
char string[128];
FILE *fp;
struct LIST *constantlist = NULL, /* data to be inserted into the table */
*list = NULL, /* list of fields in table */
*fieldlist = NULL, /* fields that are to be inserted */
*tlist = NULL, /* temporary pointer */
*tfieldlist = NULL, /* temporary pointer */
*pointer = NULL; /* temporary pointer */
if (scanner(table) != 99) return(-5); /* table name expected */
if ((value = scanner(string)) != 17) /* VALUES ? */
{
getc(stdin);
if (value != -3) /* '(' expected */
{
if (fieldlist) recycle(fieldlist);
return(-10);
}
tfieldlist = fieldlist = attributelist(fieldlist);
if ((value = fieldlist->data.type) != -1)
{
recycle(fieldlist);
return(value);
}
if (scanner(string) != 17)
{
recycle(fieldlist);
return(-16); /* VALUES expected */
}
}
if (scanner(string) != -3)
{
if (fieldlist) recycle(fieldlist);
return(-10); /* left paren expected */
}
getc(stdin);
/* get table's attributes */
tlist = list = fields(fp = fopen(strcat(table,TAB),"r"));
fclose(fp);
if (nfields(list) < (ffields = nfields(fieldlist)))
{
recycle(list);
if (fieldlist) recycle(fieldlist);
return(-19);
}
if ((ffields > 0) && ((value = checkfields(list,fieldlist)) != 0))
{
recycle(list);
if (fieldlist) recycle(fieldlist);
return(value);
}
list = list->rlist; /* move beyond deletion flag */
pointer = constantlist = makelist(list); /* set up storage for data */
if (fieldlist) fieldlist = sequencelist(list,fieldlist);
/* read the constants from the command line */
if (fieldlist == NULL)
/* user did not specify any particular attributes to read. just VALUES */
{
while (list)
{
if ((value = readconstant(constantlist,list->data.type,list->data.length)) != 0)
{
recycle(tlist);
recycle(pointer);
return(value);
}
value = scanner(string);
if (value != -2 && value != -4) /* ',' or ')' expected */
{
recycle(tlist);
recycle(pointer);
return(-18);
}
getc(stdin);
constantlist = constantlist->rlist;
list = list->rlist;
if (value == -4) break; /* ')' encountered */
}
if (list) /* make sure that all attributes have been entered */
{
recycle(tlist);
recycle(pointer);
return(-23);
}
}
else
while(fieldlist) /* insert specific attributes. in any order */
{
struct LIST *templist = constantlist,
*temp2list = list;
int i = 0;
/* position pointer to the correct place in the constantlist to store
data into, and position pointer to the correct place in the
file attribute list to insure that the data corresponds to the
correct data type.
*/
for (i = 1 ; i != fieldlist->data.order;i++)
{
templist = templist->rlist;
temp2list = temp2list->rlist;
}
if ((value = readconstant(templist,temp2list->data.type,temp2list->data.length)) != 0)
{
recycle(constantlist);
recycle(tlist);
recycle(tfieldlist);
return(value);
}
fieldlist = fieldlist->rlist;
value = scanner(string);
if (value != -2 && value != -4) /* ',' or ')' expected */
{
recycle(constantlist);
recycle(tlist);
recycle(tfieldlist);
return(-18);
}
getc(stdin);
if (value == -4) break; /* ')' encountered */
}
if (scanner(string) != -1) /* semicolon expected */
{
recycle(constantlist);
recycle(tlist);
recycle(tfieldlist);
return(-6);
}
fp = fopen(table,"a+");
writetuple(pointer,fp);
fputc(RECORD,fp); /* add delimiter between tuples */
fclose(fp);
recycle(tlist);
recycle(pointer);
recycle(tfieldlist);
return(0);
}
/* */
/*****************************************************************************/
/*
int select( )
Calls:
------
-checkfields ( );
-command ( );
-insertlist ( );
-join ( );
-makedistinct ( );
-makeview ( );
-nfields ( );
-readselect ( );
-recycle ( );
-reordertable ( );
-printfile ( );
-scanner ( );
-tablelistfields ( );
Called By:
----------
-createview ( );
-parse ( );
*/
int select(string,viewfile,columns)
char *string;
int viewfile;
struct LIST *columns;
{
char predicate[1024] = "",
table[128] = "",
temptable[15] = "";
int distinct = 0,
star = 0,
value = 0;
struct LIST *selectlist = NULL,
*tablelist = NULL,
*fieldlist = NULL;
if (scanner(string) == 15) /* DISTINCT ? */
{
distinct = 1;
scanner(string);
}
if (command(string) == 19) /* "*" ? */
{
star = 1;
getc(stdin);
if (scanner(string) != 6) return(-2); /* FROM expected */
}
else /* read attributes from command line into a list. */
{
selectlist = readselect(string);
if ((value = selectlist->data.type) != -1)
{
recycle(selectlist);
return(value);
}
if ((viewfile) && (columns))
if (nfields(selectlist) != nfields(columns))
{
recycle(selectlist);
return(-31);
}
}
if (scanner(table) != 99) /* table name expected */
{
recycle(selectlist);
return(-5);
}
while (TRUE)
{
struct DATA data;
struct LIST *pointer = tablelist;
data.type = 0;
strcat(table,TAB);
strcpy(data.attribute,table);
/* insure that the user is not trying to join the same table w/ itself */
while(pointer)
{
if (strcmp(data.attribute,pointer->data.attribute) == 0)
{
recycle(selectlist);
recycle(tablelist);
return(-30);
}
pointer= pointer->rlist;
}
tablelist = insertlist(tablelist,data);
value = scanner(table);
if (value == -1) break; /* ";" */
if (value == 12) break; /* WHERE ? */
if (value == -2) /* "," ? */
{
getc(stdin);
if (scanner(table) != 99) /* is it a table ? */
{
recycle(selectlist);
recycle(tablelist);
return(-5); /* TABLE name not found */
}
continue;
}
recycle(selectlist);
recycle(tablelist);
return(-18); /* COMMA expected */
}
if ((value != -1) && (value != 12))
{
recycle(selectlist);
recycle(tablelist);
return(-5);
}
fieldlist = tablelistfields(tablelist); /* retrieve fields from all tables */
if ((star) && (viewfile) && (columns))
if(nfields(columns) != nfields(fieldlist))
{
recycle(tablelist);
recycle(fieldlist);
return(-31);
}
if (value == 12)
{
if((value = getspredicate(predicate,fieldlist,tablelist)) != 0)
{
recycle(fieldlist);
recycle(tablelist);
recycle(selectlist);
return(value);
}
if (scanner(string) != -1) /* semicolon expected */
{
recycle(selectlist);
recycle(tablelist);
recycle(fieldlist);
return(-5);
}
}
/* determine which table each attribute is from. */
if (selectlist) selectlist = fixattributes(selectlist,fieldlist,tablelist);
value = checkfields(fieldlist,selectlist);
recycle(fieldlist);
if (value) /* legal list of fields given on command line ? */
{
recycle(selectlist);
recycle(tablelist);
return(value);
}
if (tablelist->rlist)
join(tablelist,selectlist,distinct,temptable,predicate);
else
if (distinct && star)
makedistinct(tablelist->data.attribute,temptable,predicate);
else
if (selectlist)
reordertable(selectlist,tablelist,distinct,temptable,predicate);
if (!(viewfile))
/* just SELECT was desired print it and delete it if necessary */
if (tablelist->rlist || (distinct && star) || selectlist)
{
printfile(temptable,predicate);
unlink(temptable);
}
else
printfile(tablelist->data.attribute,predicate);
else
{
/* view was desired. determine if it has been created yet. */
if ((tablelist->rlist) || (selectlist) || (distinct && star))
strcpy(string,temptable);
else
makeview(string,tablelist->data.attribute,predicate);
}
recycle(selectlist);
recycle(tablelist);
return(0);
}
/* */
/****************************************************************************/
/*
int update( );
-This routine is used to update a tuple(s) in a table.
Calls:
------
-copytuple ( );
-fields ( );
-getspredicate( );
-makelist ( );
-readconstant ( );
-readtuple ( );
-recycle ( );
-scanner ( );
-writetuple ( );
Called By:
----------
-parse ( );
*/
int update(table)
char *table;
{
int value = 0,
updated = 0;
char string[128],
predicate[1024];
FILE *fp;
struct LIST *list = NULL, /* table's attributes */
*constantlist = NULL, /* constants to use in update */
*fieldlist = NULL, /* attribute to update */
*tuplelist = NULL, /* one tuple read from a table */
*tconstantlist = NULL, /* temporary pointer */
*tfieldlist = NULL, /* temporary pointer */
*tlist = NULL; /* temporary pointer */
if (scanner(table) != 99) return(-5); /* table name expected */
if (scanner(string) != 18) return(-9); /* SET expected */
/* get table's attributes */
tlist = list = fields(fp = fopen(strcat(table,TAB),"r+"));
/* set up storage for parsing */
constantlist = makelist(list);
fieldlist = makelist(list);
strcpy(predicate,"");
/* read attributes & expressions off commandline */
while(TRUE)
{
tlist = list->rlist; /* can't have access to deletion flag */
tconstantlist = constantlist->rlist;
tfieldlist = fieldlist->rlist;
value = scanner(string);
while(tlist)
{
if (strcmp(tlist->data.attribute,string) == 0) break;
tlist = tlist->rlist;
tconstantlist = tconstantlist->rlist;
tfieldlist = tfieldlist->rlist;
}
if (tlist == NULL) /* attribute expected and not found */
{
recycle(list);
recycle(constantlist);
recycle(fieldlist);
fclose(fp);
return(-12);
}
strcpy(tfieldlist->data.attribute,string);
value = scanner(string);
if (value != 1)
{
recycle(list);
recycle(constantlist);
recycle(fieldlist);
fclose(fp);
return(-24);
}
/* legal constant expected */
if ((value = readconstant(tconstantlist,tlist->data.type,tlist->data.length)) != 0)
{
recycle(list);
recycle(constantlist);
recycle(fieldlist);
fclose(fp);
return(value);
}
value = scanner(string);
if (value == -2)
{
getc(stdin);
continue; /* comma */
}
if (value == -1) break; /* semicolon */
if (value == 12) break; /* WHERE */
recycle(list);
recycle(constantlist);
recycle(fieldlist);
fclose(fp);
return(-18);
}
/* storage for each tuple */
tuplelist = makelist(list);
if (value == 12) /* should a predicate bw included ? */
if ((value = getspredicate(predicate,list,NULL)) != 0)
{
recycle(list);
recycle(tuplelist);
recycle(constantlist);
recycle(fieldlist);
fclose(fp);
return(value);
}
/* read entire file and update necessary attributes */
while (feof(fp) == 0)
{
unsigned long tuplepos = ftell(fp);
readtuple(tuplelist,fp);
if (tuplelist->data.attribute[0] == '0') /* is tuple deleted ? */
if (checktuple(tuplelist,list,predicate))
{
copytuple(tuplelist->rlist,constantlist->rlist,fieldlist->rlist,list->rlist);
fseek(fp,tuplepos,SEEK_SET);
writetuple(tuplelist->rlist,fp);
fseek(fp,ftell(fp)+1,SEEK_SET);
updated++;
}
}
recycle(list);
recycle(tuplelist);
recycle(constantlist);
recycle(fieldlist);
fclose(fp);
printf("\n%4d Tuples Updated\n",updated);
return(0);
}
/* */
/****************************************************************************/
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/