/*程序中用到的结构体dbf_head.h*/ #include<stdio.h> #include<malloc.h> #include <string.h> #include "dbf_head.h" //#define p(t) printf("debug_int%d/t./n",t) //#define pc(c) printf("debug_char%c/t/n",c) /* *query the SQL string user input */ char * query(char[]); /* * equals "quit" ? if equals return 0 */ int isQuit(char[]); void pack(char *str); /*get where type*/ int getWhereType(char *tmp); /* *check the table file */ int check( Head_Table head, char attribute[][20],int *count_att, char *where1); int compare(char *w1,char *w2,int type,char c); /**dfdfd*/ //void whereDisplay(FILE *fp,Head_Table head,int count_att,int wType,char *w1,char *w2); /*display the result of select*/ void display(FILE *fp,Head_Table head,int count_att); /* * open file */ int openFile(char *name,FILE **fp) ; /* *get_fields */ void get_fields(FILE *fp, Head_Table *table); /* * main, later we'll set the parameters to set the path of table; */ void pack(char *str){ char *tmp,*p; int i=0,len=strlen(str); p=tmp=(char*)malloc(len); while(i<len){//跳过首部空格 if(str[i]==' ') i++; else break; } while(i<len){ if(str[i]!=' '&&str[i]!=','){ *p++=str[i++]; }else if(*(p-1)==' '||*(p-1)==',') i++; else *p++=str[i++]; } if(*(p-1)==' '||*(p-1)==',')*(p-1)=0; else*p=0; strcpy(str,tmp); //strupr(str); } int isDoSQL(char *str){ char doS[4]; doS[0]=*str; doS[1]=*(str+1); doS[2]=*(str+2); doS[3]=0; strupr(doS); return strcmp(doS,"DO "); } /*程序方式执行:执行一个文件内的命令语句*/ int doSQL(char *str){ FILE *fp; int i=2,j=0; int len; char name[80]; char c; len=strlen(str); while(i<len&&str[i]==' ')i++; while(i<len&&str[i]!=' '){ name[j++]=str[i++]; } name[j]=0; if((fp=fopen(name,"r"))==NULL){ printf("ERROR:Can not open the file %s/n",name); return 0; } j=0; c=fgetc(fp); while(c!=-1){ if(c=='/n') c=' '; name[j++]=c; c=fgetc(fp); } name[j]=0; puts(name); query(name); return 1; } void whereDisplay(FILE *fp,Head_Table head,int count_att,int wType,char *w1,char *w2){ Record_field *tmp; Data_tmp result[head.num_records][count_att]; char c; int i,j=0,k=0,cc=0; int pp=0,wlen; char *buffer; fseek(fp,head.num_header+1,0); /**************/ tmp=head.first; while(tmp){ if(tmp->isWhere){ buffer=(char *)malloc(tmp->len+1); c=tmp->type; break; } else{ pp+=tmp->len; tmp=tmp->next; } } wlen=tmp->len; /***************************/ while(k<head.num_records){ ++k; tmp=head.first; /*8888888888888888888******/ fseek(fp,pp,SEEK_CUR); fread(buffer,wlen,1,fp); i=wlen-1; buffer[wlen]=0; while(buffer[i]==0x20)buffer[i--]=0; //消除字符串后的空格 fseek(fp,(-pp-wlen),SEEK_CUR); if(compare(buffer,w2,wType,c)){ j=0; while(tmp){ if(tmp->isShow){ if((result[cc][j].data=(char*) malloc(tmp->len+1))==NULL){ puts("ERROR: momery empty"); exit(0); } result[cc][j].type=tmp->type; result[cc][j].len=tmp->len; fread(result[cc][j].data,tmp->len,1,fp); result[cc][j].data[tmp->len]=0; j++; }else{ fseek(fp,tmp->len,SEEK_CUR); } tmp=tmp->next; } fseek(fp,1L,SEEK_CUR); cc++; }else{ fseek(fp,head.num_record,SEEK_CUR); } } printf("--------------------------results of query(%d,%d)--------------------------------/n",cc,j); if(j==0)cc=0; tmp=head.first; while(tmp){ if(tmp->isShow) printf("%s/t",tmp->name); tmp=tmp->next; } printf("/n"); for(k=0;k<cc;k++){ for(i=0;i<j;i++){ if(result[k][i].type=='I'){ pp=0; pp=(int)result[k][i].data[0]; pp=pp|((int)result[k][i].data[1]<<8); pp=pp|((int)result[k][i].data[2]<<16); pp=pp|((int)result[k][i].data[3]<<16) ; printf("%d/t",pp); } else printf("%s/t",(result[k][i].data)); } puts(""); } puts("----------------------------------query ended----------------------------------"); } int compare(char w1[],char w2[],int type,char c){ int p1,p2=0; int i; if(c=='I'){ p1=(int)w1[0]; p1=p1|((int)w1[1]<<8); p1=p1|((int)w1[2]<<16); p1=p1|((int)w1[3]<<16) ; i=0; while(w2[i]){ p2=(p2+(w2[i]-0x30))*10; i++; } p2=p2/10; switch(type){ case 1: return (p1<=p2); case 2:return (p1>=p2); case 3:return (p1!=p2); case 4:return (p1!=p2); case 5:return (p1>=p2); case 6:return (p1<=p2); case 7:return (p1==p2); case 8:return (p1<p2); case 9:return (p1 > p2); default : return 0; } }else{ i=strcmp(w1,w2); switch(type){ case 1: i=(i<=0?1:0); break; case 2: i=(i>=0?1:0); break; case 3: i;break; case 4: i; break; case 5:i= (i>=0?1:0); break; case 6: i= (i<=0?1:0); break; case 7: i=!i; break; case 8: i=(i<0?1:0); break; case 9: i=(i>0?1:0); break; default : i=-1; } return i; } } void main(void){ char para[100]={0}; char c; int i=0; while(1){ c = getchar(); if(c ==';'){ c = getchar(); if(c=='/n') c =' '; else{ para[i++]=' '; } } if(c =='/n'){ para[i]=0; pack(para); if(isQuit(para)==0) exit(0); if(isDoSQL(para)==0){ doSQL(para); i=0; continue; } query(para); i=0; continue; } para[i++]=c; } } char * query(char* string){/*要求string为“紧缩”格式*/ int len_str = strlen(string); char tmp[30]={0}; char attribute[20][20]={0}; char table[10]={0}; char where1[20]={0}; char where2[20]={0}; int whereType=0; FILE *file=NULL; int i,j,count_att; Head_Table head = {0,0,0,NULL}; //puts("********Here is query ********"); i=0; while(i<6&&i<len_str){ tmp[i]=string[i]; i++; } tmp[6]=0; strlwr(tmp); if(strcmp(tmp,"select")==0){ /*将select之后的属性读入数组***********************************/ count_att=0; ++i; while(1){ j=0; while(string[i]!=','&&string[i]!=' '&&i<len_str){ tmp[j++]=string[i++]; } if(i>=len_str){puts("Error: bad command!");return NULL;} i++; tmp[j]=0; if(strcmp(tmp,"from")!=0){ strcpy(attribute[count_att],tmp); count_att++; }else break; }/*end while*/ /*将from之后的表名读入数组*/ j=0; while(string[i]==' ')i++; while(string[i]!=','&&string[i]!=' '&&i<len_str){ tmp[j++]=string[i++]; } tmp[j]=0; strcpy(table,tmp); /***读取where子句**************************************/ j=0; while(string[i]==' ')i++; while(string[i]!=','&&string[i]!=' '&&i<len_str){ tmp[j++]=string[i++]; } tmp[j]=0; if(strcmp(tmp,"where")==0){ /***********************/ j=0; while(string[i]==' ')i++; while(string[i]!='='&&string[i]!='<'&&string[i]!='>'&&string[i]!='!'&&string[i]!=' '&&i<len_str) where1[j++]=string[i++]; where1[j]=0; j=0; tmp[j++]=string[i++]; if(string[i]=='='||string[i]=='>'||string[i]=='<'){ tmp[j++]=string[i++]; } tmp[j]=0; whereType=getWhereType(tmp); /***********************/ j=0; while(string[i]==' ')i++; while(string[i]!='='&&string[i]!='<'&&string[i]!='>'&&string[i]!='!'&&string[i]!=' '&&i<len_str) where2[j++]=string[i++]; where2[j]=0; }else if(strlen(tmp)!=0){ puts("ERROR: Unknow command!"); return NULL; } /***open table ******************************************/ if(openFile(table,&file)==0){ puts("/nError: can not open the table!"); return NULL; } /**********读取表文件的字段******************/ rewind(file); get_fields(file,&head); if(!check(head,attribute,&count_att,where1)){puts("Error:check");return NULL;} /************开始查询了***************/ if(whereType==0){ display(file,head,count_att); }else{ whereDisplay(file,head,count_att,whereType,where1,where2); } }else{ puts("no select command/n"); } if(file!=NULL) fclose(file); return string; } int openFile(char *name,FILE **fp){ char *filename; int len = strlen(name)+5; filename = (char*)malloc(sizeof(char)*len); strcpy(filename,name); filename[len-1]=0; filename[len-2]='f'; filename[len-3]='b'; filename[len-4]='d'; filename[len-5]='.'; *fp = fopen( filename,"rb"); if(*fp ==NULL)return 0; /*Head_Table head={0,0,0,NULL};*/ /*get_fields(fp,&head);*/ free(filename); return 1; } void get_fields(FILE *fp, Head_Table *table){ FILE *ff=fp; struct Record_field *next,*tmp; int c; int i,j; fseek(fp,4,0); fread(&table->num_records,4,1,fp); fread(&table->num_header,2,1,fp); fread(&table->num_record,2,1,fp); if(!(next = (Record_field*)malloc(sizeof(Record_field))))exit(0); table->first = next; fseek(fp,32,0); c= fgetc(fp); /* printf("____: %d/n",ftell(fp)); */ while(c!=13&&c!=-1){ if(!(tmp = (Record_field*)malloc(sizeof(Record_field))))exit(0); tmp->name[0]=c; for(i=1;i<11;i++){ /* get the name of field */ c= fgetc(fp); tmp->name[i]=c; } tmp->name[i]=0; c= fgetc(fp); /* get the type of field */ tmp->type=(char)c; fseek(fp,4,SEEK_CUR); c= fgetc(fp); /* get the length of field */ tmp->len=c; fseek(fp,14,SEEK_CUR); c= fgetc(fp); /* field is part of production index - 0x01 else 0x00 */ tmp->isIndex=c; next->next=tmp; next = tmp; c= fgetc(fp); } next = table->first; table->first=next->next; free(next); /*display the fields*/ tmp = table->first; /* while(tmp){ printf("%s/t%c/t%d/t%d/n",tmp->name,tmp->type,tmp->len,tmp->isIndex); tmp=tmp->next; } */ } int getWhereType(char *tmp){ if(strcmp(tmp,"<=")==0) return 1; if(strcmp(tmp,">=")==0) return 2; if(strcmp(tmp,"!=")==0) return 3; if(strcmp(tmp,"<>")==0) return 4; if(strcmp(tmp,"!<")==0) return 5; if(strcmp(tmp,"!>")==0) return 6; if(strcmp(tmp,"=")==0) return 7; if(strcmp(tmp,"<")==0) return 8; if(strcmp(tmp,">")==0) return 9; } /*查询并显示数据*/ void display(FILE *fp,Head_Table head,int count_att){ Record_field *tmp; Data_tmp result[head.num_records][count_att]; char c; int i,j=0,k=0,cc=0; int pp; fseek(fp,head.num_header+1,0); while(k<head.num_records){ ++k; tmp=head.first; j=0; while(tmp){ if(tmp->isShow){ if((result[cc][j].data=(char*) malloc(tmp->len+1))==NULL){ puts("ERROR: momery empty"); exit(0); } result[cc][j].type=tmp->type; result[cc][j].len=tmp->len; /*读取数据*/ fread(result[cc][j].data,tmp->len,1,fp); result[cc][j].data[tmp->len]=0; j++; }else{ fseek(fp,tmp->len,SEEK_CUR); } tmp=tmp->next; } fseek(fp,1L,SEEK_CUR); cc++; } printf("--------------------------results of query(%d,%d)--------------------------------/n",cc,j); if(j==0)cc=0; tmp=head.first; while(tmp){ if(tmp->isShow) printf("%s/t",tmp->name); tmp=tmp->next; } printf("/n"); for(k=0;k<cc;k++){ for(i=0;i<j;i++) if(result[k][i].type=='I'){ pp=0; pp=(int)result[k][i].data[0]; pp=pp|((int)result[k][i].data[1]<<8); pp=pp|((int)result[k][i].data[2]<<16); pp=pp|((int)result[k][i].data[3]<<16) ; printf("%d/t",pp); } else printf("%s/t",(result[k][i].data)); puts(""); } puts("----------------------------------query ended----------------------------------"); } int check(Head_Table head, char (*attribute)[20],int *count_att, char* where1){ int i=0; Record_field *tmp=head.first; /*检测是否含有ALL或* */ if(((strcmp(attribute[0],"*")==0)||(strcmp(attribute[0],"ALL")==0))&&attribute[1][0]==0){ tmp=head.first; while((tmp!=NULL)){ tmp->isShow=1; //strcpy(attribute[i++],tmp->name); tmp=tmp->next; } *count_att=head.num_records; }else{ i=0; for(;i<*count_att;i++){ tmp=head.first; while((tmp!=NULL)&&strcmp(attribute[i],tmp->name))tmp=tmp->next; if(tmp==NULL)continue; tmp->isShow=1; } } tmp=head.first; while((tmp!=NULL)&&strcmp(where1,tmp->name))tmp=tmp->next; if(tmp) tmp->isWhere=1; return 1; } int isQuit(char* str){ char qS[5]; qS[0]=*str; qS[1]=*(str+1); qS[2]=*(str+2); qS[3]=*(str+3); qS[4]=0; strupr(qS); return strcmp(qS,"QUIT"); } |