www.pudn.com > jpeg1.zip > DBF.C


/**************************************************/ 
/*           DBMS Engine source File              */ 
/*Copyright:WangHaiyun,HiSoft                     */ 
/*Date:1996/08/01                                 */ 
/*Last Modified:                                  */ 
/**************************************************/ 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
 
/*Open database*/ 
DBF *_Cdecl use(char* dbfname) 
{ 
DBF *dbf; 
unsigned char byte_buf; 
int i; 
dbf=(DBF *)malloc(sizeof(DBF)); 
if((dbf->handle=open(dbf_name,O_RDWR|O_DENYNONE|O_BINARY)) 
      ==-1) 
{ 
free(dbf); 
return NULL; 
} 
read(dbf->handle,&byte_buf,1); 
if(byte_buf!=0x03&&byte_buf!=0x83) 
{ 
  close(dbf->handle); 
  free(dbf); 
  return NULL; 
} 
read(dbf->handle,&byte_buf,1); 
dbf->modify_date.da_year=byte_buf+1900; 
read(dbf->handle,&byte_buf,1); 
dbf->modify_date.da_mon=byte_buf; 
read(dbf->handle,&byte_buf,1); 
dbf->modify_date.da_day=byte_buf; 
read(dbf->handle,&(dbf->rec_count),4); 
read(dbf->handle,&(dbf->stru_len),2); 
dbf->fld_count=(dbf->stru_len-33)/32; 
read(dbf->handle,&(dbf->rec_len),2); 
dbf->dbf_stru=(DBF_STRU*)malloc(dbf->fld_count*sizeof(DBF_STRU)); 
lseek(dbf->handle,32L,SEEK_SET); 
for(i=0;ifld_count;i++) 
{ 
  read(dbf->handle,dbf->stru[i].field_name,11); 
  read(dbf->handle,&(dbf->dbf_stru[i].field_type),1); 
  read(dbf->handle,&(dbf->dbf_stru[i].field_pos),2); 
  lseek(dbf->handle,2L,SEEK_CUR); 
  read(dbf->handle,&(dbf->dbf_stru[i].field_len),1); 
  read(dbf->handle,&(dbf->dbf_stru[i].field_dec),1); 
  lseek(dbf->handle,14L,SEEK_CUR); 
} 
lseek(dbf->handle,1L,SEEK_CUR); 
dbf->curr_rec=(char*)malloc(dbf->rec_len+1); 
if(dbf->rec_count>0) 
{ 
  dbf->rec_no=1; 
  read(dbf->handle,dbf->curr_rec,dbf->rec_len); 
  dbf->curr_rec[dbf->rec_len]=0; 
  dbf->eof=NO; 
} 
else 
{ 
  for(i=0;irec_len;i++) 
    dbf->curr_rec[i]=' '; 
    dbf->curr_rec[dbf->rec_len]=0; 
    dbf->rec_no=0; 
    dbf->eof=YES; 
} 
dbf->update_tag=NO; 
return(dbf); 
} 
/*     Close database   */ 
int _Cdecl close_DBF(DBF* dbf) 
{ 
char temp[3]; 
if(dbf==NULL) 
  return 0; 
if(dbf->update_tag==YES) 
{ 
   getdate(&(dbf->modify_date)); 
   lseek(dbf->handle,1L,SEEK_SET); 
   tmp[0]=dbf->modify_date.da_year-1900; 
   tmp[1]=dbf->modify_date.da_mon; 
   tmp[2]=dbf->modify_date.da_day; 
   write(dbf->handle,tmp,3); 
   write(dbf->handle,&(dbf->rec_count),4); 
} 
free(dbf->curr_rec); 
free(dbf->dbf_stru); 
close(dbf->handle); 
free(dbf); 
return 1; 
} 
 
/*Database file pointer relative moving function */ 
long _Cdecl skip(DBF *dbf,int step) 
{ 
 if(dbf==NULL||dbf->rec_no==0) 
    return 0; 
 if(dbf->rec_no+step<1) 
    step=1-dbf->rec_no; 
 else if(dbf->rec_no+step>dbf->rec_count) 
 { 
  step=dbf->rec_count-dbf->rec_no; 
  dbf->eof=YES; 
 } 
 dbf->rec_no+=step; 
 if(step!=1) 
   lseek(dbf->handle,dbf->rec_len*(step-1),SEEK_CUR); 
 read(dbf->handle,dbf->curr_rec,dbf->rec_len); 
 return(dbf->rec_no); 
} 
 
/*get current record*/ 
long _Cdecl get_record(DBF *dbf,char *fmt,...) 
{ 
 va_list arglist; 
 int *ival; 
 long *lval; 
 char *sval; 
 double *fval; 
 GRAPH_TEXT *gval; 
 struct date *dval; 
 int no=1; 
 int tmp; 
 char *p; 
 char word[MAX_FIELD_LEN]; 
 if(dbf==NULL||dbf->eof==YES) 
 return 0; 
 va_start(arglist,fmt); 
 for(;*fmt;fmt++) 
 { 
   tmp=0; 
   while(*fmt&&isdigit(*fmt)) 
   { 
   tmp=tmp*10+*fmt-'0'; 
   fmt++; 
   } 
   no=tmp==0?no:tmp; 
   if(*fmt=='i'||*fmt=='l'||*fmt=='f'||*fmt=='d' 
       ||*fmt=='s'||*fmt=='c'||*fmt=='g'||*fmt=='m') 
   { 
   p=dbf->curr_rec+dbf->dbf_stru[no-1].field_pos; 
     strncpy(word,p,dbf->dbf_stru[no-1].field_len); 
     word[dbf->dbf_stru[no-1].field_len]=0; 
     switch(*fmt) 
     { 
      case 'i': 
        ival=va_arg(arglist,int*); 
        *ival=atoi(word); 
        break; 
      case 'l': 
        lval=va_arg(arglist,long*); 
        *lval=atol(word); 
        break; 
      case 'f': 
        fval=va_arg(arglist,double *); 
        *fval=atof(word); 
        break; 
      case 'd':/*note the 2000 year problem*/ 
        dval=va_arg(arglist,struct date *); 
        dval->da_day=atoi(word+6); 
        word[6]=0; 
        dval->da_mon=atoi(word+4); 
        word[4]=0; 
        dval->da_year=atoi(word); 
        break; 
      case 's': 
        sval=va_arg(arglist,char *); 
        strcpy(sval,word); 
        break; 
      case 'c': 
        ival=va_arg(arglist,int *); 
        *ival=word[0]; 
        break; 
      case 'g': 
        gval=va_arg(arglist,GRAPH_TEXT *); 
        memcpy(gval,word,10); 
        break; 
      case 'm': 
        lval=va_arg(arglist,long *); 
        *lval=atol(word); 
        break; 
    } 
       no++; 
   } 
  } 
 va_end(arglist); 
 return(dbf->rec_no); 
} 
 
/*write database file current record function*/ 
long _Cdecl put_record(DBF *dbf,char *fmt,...) 
{ 
va_list arglist; 
int ival; 
long lval; 
char *sval; 
double fval; 
struct date dval; 
GRAPH_TEXT gval; 
int no=1; 
int i; 
int tmp; 
char *p; 
char word[MAX_FIELD_LEN]; 
char format[20]; 
if(dbf==NULL||dbf->rec_no==0||dbf->eof==YES) 
  return 0; 
va_start(arglist,fmt); 
for(;*fmt;fmt++) 
{ 
        tmp=0; 
        while(*fmt&&isdigit(*fmt)) 
        { 
        tmp=tmp*10+*fmt-'0'; 
        fmt++; 
        } 
        no=tmp==0?no:tmp; 
        if(*fmt=='i'||*fmt='l'||*fmt=='f'||*fmt=='d'\ 
          ||*fmt=='s'||*fmt=='c'||*fmt=='m'||*fmt=='g') 
          { 
          strcpy(format,"%"); 
          switch(dbf->dbf_stru[no-1].field_type) 
            { 
            case 'N': 
              itoa(dbf->dbf_stru[no-1].field_len,word,10); 
              strcat(format,word); 
              if(dbf->dbf_stru[no-1].field_dec==0) 
                strcat(format,"d"); 
                else 
                { 
                itoa(dbf->dbf_stru[no-1].field_dec,word,10); 
                strcat(format,"."); 
                strcat(format,word); 
                strcat(format,"f"); 
                 } 
                 break; 
              case 'C': 
                strcat(format,"-"); 
                itoa(dbf->dbf_stru[no-1].field_len,word,10); 
                strcat(format,word); 
                strcat(format,"s"); 
                break; 
              case 'D': 
                strcat(format,"4d%02d%02d"); 
                break; 
              case 'L': 
                format[0]='l'; 
                break; 
              case 'M': 
                strcat(format,"010d"); 
           } 
          switch(*fmt) 
          { 
            case 'i': 
              ival=va_arg(arglist,int); 
              if(dbf->dbf_stru[no-1].field_dec==0) 
                sprintf(word,format,ival); 
              else 
              { 
               fval=ival; 
               sprintf(word,format,fval); 
               } 
               break; 
             case 'l': 
               lval=va_arg(arglist,long); 
               if(dbf->dbf_stru[no-1].field_dec==0) 
                sprintf(word,format,lval); 
              else 
              { 
               fval=lval; 
               sprintf(word,format,fval); 
               } 
               break; 
             case 'f': 
               fval=va_arg(arglist,double); 
               if(dbf->dbf_stru[no-1].field_dec!=0) 
                 sprintf(word,format,fval); 
              else 
              { 
               lval=fval; 
               sprintf(word,format,lval); 
               } 
               break; 
             case 'd': 
               dval=va_arg(arglist,struct date); 
               sprintf(word,format,dval.da_year,dval.da_mon,dval.da_day); 
               break; 
             case 's': 
               sval=va_arg(arglist,char *); 
               sprintf(word,format,sval); 
               break; 
             case 'c': 
               ival=va_arg(arglist,int); 
               word[0]=format[0]=='l'?((ival=='y'||ival=='Y'||\ 
                 ival=='t'||ival=='T')?'T':'F'):ival; 
               word[1]=0; 
               break; 
             case 'm': 
               lval=va_arg(arglist,long); 
               sprintf(word,format,lval); 
               break; 
             case 'g': 
               gval=va_arg(arglist,GRAPH_TEXT); 
               memcpy(word,&gval,10); 
              } 
              p=dbf->curr_rec+dbf->dbf_stru[no-1].field_pos; 
              for(i=0;idbf_stru[no-1].field_len;i++) 
                *p++=word[i]; 
              no++; 
              } 
          } 
        va_end(arglist); 
        lseek(dbf->handle,-dbf->rec_len,SEEK_CUR); 
        write(dbf->handle,dbf->curr_rec,dbf->rec_len); 
        dbf->update_tag=YES; 
        return(dbf->rec_no); 
} 
 
/*append blank record at the end of database file*/ 
long _Cdecl append_blank(DBF *dbf) 
{ 
        if(dbf==NULL) 
        return 0; 
        lseek(dbf->handle,-1L,SEEK_END); 
        strset(dbf->curr_rec,''); 
        dbf->curr_rec[dbf->rec_len]=0x1a; 
        write(dbf->handle,dbf->curr_rec,dbf->rec_len+1); 
        lseek(dbf->handle,-1L,SEEK_END); 
        dbf->curr_rec[dbf->rec_len]=0; 
        dbf->update_tag=YES; 
        dbf->rec_no=++(dbf->rec_count); 
        dbf->eof=NO; 
        return(dbf->rec_no); 
} 
/*create new database sub_rountine*/ 
DBF *_Cdecl create_DBF(char *dbf_name,int fld_count,DBF_STRU *dbf_stru) 
{ 
        DBF *dbf; 
        unsigned char byte_buf; 
        int i,j; 
        int pos; 
        char *p; 
        dbf=(DBF*)malloc(sizeof(DBF)); 
        _create(dbf_name,0); 
        if((dbf->handle)=open(dbf_name,O_RDWR|O_DENYNONE|O_BINARY))==\ 
        -1) 
        { 
          free(dbf); 
          return NULL; 
        } 
        byte_buf=0x03; 
        write(dbf->handle,&byte_buf,1); 
        getdate(&(dbf->modify_date)); 
        byte_buf=dbf->modify_date.da_year-1900; 
        write(dbf->handle,&byte_buf,1); 
        byte_buf=dbf->modify_date.da_mon; 
        write(dbf->handle,&byte_buf,1); 
        byte_buf=dbf->modify_date.da_day; 
        write(dbf->handle,&byte_buf,1); 
        dbf->rec_count=0; 
        write(dbf->handle,&(dbf->rec_count),4); 
        dbf->stru_len=fld_count*32+33; 
        write(dbf->handle,&(dbf->stru_len),2); 
        dbf->fld_count=fld_count; 
        pos=1; 
        dbf->rec_len=1; 
        for(i=0;irec_len+=dbf_stru[i].field_len; 
        } 
        write(dbf->handle,&(dbf->rec_len),2); 
        dbf->dbf_stru=(DBF_STRU *)malloc(dbf->fld_count*sizeof(DBF_STRU)); 
        memcpy((void *)(dbf->dbf_stru),(void*)dbf_stru,\ 
           fld_count*sizeof(DBF_STRU)); 
        byte_buf=0; 
        for(i=0;i<20;i++) 
           write(dbf->handle,&byte_buf,1); 
        for(i=0;ihandle,dbf->dbf_stru[i].field_name,11); 
          write(dbf->handle,&(dbf->dbf_stru[i].field_type),1); 
          write(dbf->handle,&(dbf->dbf_stru[i].field_pos),2); 
          write(dbf->handle,&byte_buf,1); 
          write(dbf->handle,&byte_buf,1); 
          write(dbf->handle,&(dbf->dbf_stru[i].field_len),1); 
          write(dbf->handle,&(dbf->dbf_stru[i].field_dec),1); 
          for(j=0;j<14;j++) 
             write(dbf->handle,&byte_buf,1); 
        } 
        byte_buf=0x0d; 
        write(dbf->handle,&byte_buf,1); 
        byte_buf=0x1a; 
        write(dbf->handle,&byte_buf,1); 
        lseek(dbf->handle,-1L,SEEK_CUR); 
        dbf->curr_rec=(char*)malloc(dbf->rec_len+1); 
        for(i=0;irec_len;i++) 
           dbf->curr_rec[i]=''; 
        dbf->curr_rec[dbf->rec_len]=0; 
        dbf->rec_no=0; 
        dbf->eof=YES; 
        dbf->update_tag=NO; 
        return(dbf); 
} 
/*delete all the records in the database file*/ 
int _Cdecl zap(DBF *dbf) 
{ 
    char eof_tag=0x1a; 
    if(dbf==NULL) 
        return 0; 
    dbf->update_tag=YES; 
    dbf->rec_count=0; 
    dbf->rec_no=0; 
    dbf->eof=YES; 
    strset(dbf->curr_rec,''); 
    lseek(dbf->handle,4L,SEEK_SET); 
    write(dbf->handle,&(dbf->rec_count),4); 
    lseek(dbf->handle,dbf->stru_len,SEEK_SET); 
    write(dbf->handle,&eof_tag,1); 
    lseek(dbf->handle,-1L,SEEK_END); 
    chsize(dbf->handle,dbf->stru_len+1); 
    return 1; 
} 
 
/*make delete tag for the current record in the database*/ 
long _Cdecl delete(DBF *dbf) 
{ 
    if(dbf==NULL||dbf->eof==YES||dbf->rec_no==0) 
      return 0; 
    *(dbf->curr_rec)='*'; 
    lseek(dbf->handle,-dbf->rec_len,SEEK_CUR); 
    write(dbf->handle,dbf->curr_rec,dbf->rec_len); 
    dbf->update_tag=YES; 
    return(dbf->rec_no); 
} 
 
/*recall current deleted record in the database*/ 
long _Cdecl recall(DBF *dbf) 
{ 
    if(dbf==NULL||dbf->eof==YES||dbf->rec_no==0) 
      return 0; 
    if(*(dbf->curr_rec)=='*') 
    { 
    *(dbf->curr_rec)=='' 
    lseek(dbf->handle,-dbf->rec_len,SEEK_CUR); 
    write(dbf->handle,dbf->curr_rec,dbf->rec_len); 
    dbf->update_tag=YES; 
    } 
    return(dbf->rec_no); 
} 
 
/*pack database:delete all delete-tagged records*/ 
long _Cdecl pack(DBF *dbf) 
{ 
    long i; 
    char eof_tag=0x1a; 
    if(dbf==NULL||dbf->rec_no==0) 
      return 0; 
    dbf->rec_no=0; 
    for(i=0;irec_count;i++) 
    { 
        lseek(dbf->handle,dbf->stru_len+i*dbf->rec_len,SEEK_SET); 
        read(dbf->handle,dbf->curr_rec,dbf->rec_len); 
        if(*dbf->curr_rec)!='*' 
        { 
            lseek(dbf->handle,dbf->stru_len+dbf->rec_no*dbf->rec_len,\ 
                SEEK_SET); 
            write(dbf->handle,dbf->curr_rec,dbf->rec_len); 
            dbf->rec_no++; 
        } 
    } 
    dbf->rec_count=dbf->rec_no; 
    chsize(dbf->handle,dbf->stru_len+dbf->rec_count*dbf->rec_len+1); 
    lseek(dbf->handle,-1L,SEEK_END); 
    write(dbf->handle,&eof_tag,1); 
    lseek(dbf->handle,dbf->stru_len,SEEK_SET); 
    if(dbf->rec_count!=0) 
    { 
        read(dbf->handle,dbf->curr_rec,dbf->rec_len); 
        dbf->rec_no=1; 
        dbf->eof=NO; 
    } 
    else 
        dbf->eof=YES; 
        dbf->update_tag=YES; 
        return(dbf->rec_count); 
} 
 
/*get the field number of a certain field*/ 
int _Cdecl field_no(DBF *dbf,char *field_name) 
{ 
  int i=1; 
  while(ifld_count&&stricmp(dbf->dbf_stru[i].field_name,field_name)) 
    i++; 
  i=i>dbf->fld_count?i=0:i; 
  return(i); 
} 
 
/*database project function*/ 
DBF *_Cdecl project(char *dest_name,DBF *sour,int para_num,...) 
{ 
    int i,k; 
    int *no; 
    DBF *dest; 
    DBF_STRU *d_stru; 
    va_list arglist; 
    char *p,*q; 
    d_stru=(DBF_STRU *)malloc(para_num*sizeof(DBF_STRU)); 
    no=(int *)malloc(para_num*sizeof(int)); 
    va_start(arglist,para_num); 
    for(i=0;idbf_stru[no[i]].field_name); 
        d_stru[i].field_type=sour->dbf_stru[no[i]].field_type; 
        d_stru[i].field_len =sour->dbf_stru[no[i]].field_len; 
        d_stru[i].field_dec =sour->dbf_stru[no[i]].field_dec; 
    } 
    va_end(arglist); 
    if((dest=create_DBF(dest_name,para_num,d_stru))=NULL) 
        return NULL; 
    go_record(sour,1); 
    while(!eof_DBF(sour)) 
    { 
        append_blank(dest); 
        if(isdeleted(sour)) 
          *(dest->curr_rec)='*'; 
          for(i=0;icurr_rec+dest->dbf_stru[i].field_pos; 
            q=sour->curr_rec+sour->dbf_stru[no[i]].field_pos; 
            for(k=0;kdbf_stru[i].field_len;k++) 
                    *p++=*q++; 
            lseek(dest->handle,-(dest->rec_len),SEEK_CUR); 
            write(dest->handle,dest->curr_rec,dest->rec_len); 
 
          } 
          skip(sour,1); 
    } 
    return(dest); 
} 
/*join function*/ 
DBF *_Cdecl join(char *dest_name,DBF *sour1,DBF *sour2,\ 
   int field_no1,int field_no2) 
{ 
    int i,d_f_count,no,key_len; 
    DBF *dest; 
    DBF_STRU *d_stru; 
    char *p,*q,*r,*s; 
    d_f_count=sour1->fld_count+sour2->fld_count-1; 
    d_stru=(DBF_STRU *)malloc(d_f_count*sizeof(DBF_STRU)); 
    for(i=0;ifld_count;i++) 
    { 
      strcpy(d_stru[i].field_name,sour1->dbf_stru[i].field_name); 
      d_stru[i].field_type=sour1->dbf_stru[i].field_type; 
      d_stru[i].field_len =sour1->dbf_stru[i].field_len; 
      d_stru[i].field_dec =sour1->dbf_stru[i].field_dec; 
       
    } 
    for(i=0;ifld_count;i++) 
    { 
      if(i!=field_no2) 
      { 
        no=idbf_stru[no].field_name); 
        d_stru[i].field_type=sour2->dbf_stru[no].field_type; 
        d_stru[i].field_len =sour2->dbf_stru[no].field_len; 
        d_stru[i].field_dec =sour2->dbf_stru[no].field_dec; 
      } 
    } 
    if((dest=create_DBF(dest_name,d_f_count,d_stru))=NULL) 
        return NULL; 
        key_len=min(sour1->dbf_stru[field_no1].field_len,\ 
          sour2->dbf_stru[field_no2].field_len); 
    go_record(sour1,1); 
    while(!eof_DBF(sour1)) 
    { 
        p=sour1->curr_rec+field_no1; 
        go_record(sour2,1); 
        while(!eof_DBF(sour2)) 
        { 
            q=sour2->curr_rec+field_no2; 
            if(strncmp(p,q,key_len)==0) 
            { 
                append_blank(dest); 
                r=dest->curr_rec+1; 
                s=sour1->curr_rec+1; 
                while(*s) 
                  *r++=*s++; 
                s=sour2->curr_rec+1; 
                while(sdbf_stru[field_no2].field_len; 
                while(*s) 
                  *r++=*s++; 
                lseek(dest->handle,-dest->rec_len,SEEK_END); 
                write(dest->handle,dest->curr_rec,dest->rec_len); 
            } 
            skip(sour2,1); 
         } 
         skip(sour1,1); 
        } 
        return(dest); 
}