home *** CD-ROM | disk | FTP | other *** search
- #include "datapriv.hpp"
-
- /*************** DATABASE ACCESSOR FUNCTIONS ***************/
-
- // Get pointer to index by name, return 0 if not found
-
- index *database::getindex(char *name)
- {
- if (!findex) return 0;
-
- index *ip=findex;
- while(ip && strcmpl(ip->name,name)) ip=ip->next;
-
- return ip;
- }
-
- char *database::getindkey(char *name)
- {
- index *ip;
-
- if (ip=getindex(name)) return(ip->indexp);
- return 0;
- }
-
- int database::getindtype(char *name)
- {
- index *ip;
-
- if (ip=getindex(name)) return(ip->indtype);
- return 0;
- }
-
- /*************** DATABASE FUNCTIONS ************************/
-
-
- // This is the constructor for a database
- // it opens the file and initialises the database variables.
-
- /*************** CONSTRUCTOR *******************************/
-
-
- // This is the constructor for a new database
-
- database::database()
- {
- valid=-1;
- ex=0;
- exwork=0;
- dbtp=0;
- memowl=0;
- memow=0;
- firstrec=0;
- change=1;
- findex=0;
- dbfp=0;
- nrec=0;
- nfield=0;
- maxfieldl=0;
- reclen=1;
- findex=0;
- dateformat=USDATE;
- if (!(fielda=new field*[MAXFLD])) {dbfer(NODBSP); valid=NOMEM;}
- }
-
- // This is the constructor for an existing database
-
- database::database(char *name,char *index)
- {
- char n[128],ws[128],*wsp;
- int i;
- int recpos=1;
-
- valid=0;
- ex=0; // Start with no expression evaluator
- exwork=0;
- dbtp=0;
- memowl=0;
- memow=0;
- firstrec=0;
- change=0;
- findex=0;
- dateformat=USDATE;
- if (!(fielda=new field*[MAXFLD])) {dbfer(NODBSP); valid=NOMEM; return;}
-
-
- strcpy(n,name);
- if (!strchr(n,'.')) strcat(n,".dbf");
-
- if (!(dbfp=fopen(n,"r+b"))) {valid=NOFILE; return;}
-
- Fread(ws,DBSIZE,1,dbfp); // Get database file statistics
-
- if (*ws&0x80)
- {
- *(strchr(n,'.'))=0; strcat(n,".dbt");
- dbtp=fopen(n,"r+b");
- if (!dbtp) {valid=MEMOERR; return;}
- }
- nrec=*(long *)(ws+4); // Now get the file parameters
- recstart=*(int *)(ws+8);
- reclen=*(int *)(ws+10);
-
- nfield=0; maxfieldl=0;
-
- do // Count number of fields
- {
- fielda[nfield]=0;
- Fread(ws,DBSIZE,1,dbfp);
- if (*ws==0x0d) break;
- nfield++;
- }
- while(!feof(dbfp));
-
- Fseek(dbfp,0L,SEEK_SET);
- Fread(ws,DBSIZE,1,dbfp);
-
- for(i=0; i<nfield; i++) // Read all field information
- {
- int flen; // Field length
-
- Fread(ws,DBSIZE,1,dbfp);
- flen=(unsigned char)ws[16];
- if (!(fielda[i]=new field(i+1,ws,ws[11],flen,
- (unsigned char)ws[17],recpos)))
- {dbfer(NODBSP); valid=NOMEM; return;}
- recpos=recpos+flen;
- if (flen>maxfieldl) maxfieldl=flen;
- }
- // Now open the index file
-
- if (!index || !(*index)) return;
- valid=addindex(index);
- }
-
- /*************** DESTRUCTOR ********************************/
-
- // This is the destructor for a database object.
-
- database::~database(void)
- {
- int i;
- class field *temp;
-
- if (dbfp)
- {
- if (change)
- {
- struct tm *t;
- time_t ltime;
-
- time(<ime); t=localtime(<ime);
- Fseek(dbfp,1L,SEEK_SET);
- Fputc(t->tm_year,dbfp);
- Fputc(t->tm_mon+1,dbfp);
- Fputc(t->tm_mday,dbfp);
- fputl(nrec,dbfp);
- }
- fclose(dbfp);
- for(i=0; i<nfield; i++) if (fielda[i]) delete fielda[i];
- }
-
- index *ip=findex;
- index *nip;
- while(ip) {nip=ip; ip=ip->next; delete nip;} // Close all the indexes
-
- if (fielda) delete fielda;
- if (ex) delete ex;
- if (exwork) delete exwork;
- if (memow) delete memow;
- if (dbtp) fclose(dbtp);
- if (firstrec) dber(DELREC); // Cannot delete database with attached rec.s
- }
-
- /*************** GETFIELD *******************************/
-
-
- // This function searches for a field by name and returns a pointer
-
- field *database::getfield(char *fname)
- {
- for (int i=0; i<nfield; i++)
- {
- if (!strcmpl(fielda[i]->name,fname)) return(fielda[i]);
- }
-
- return(0);
- }
-
- /*************** Add a field to a fresh database ********/
-
- // This version copies a field from elsewhere
-
- int database::addfield(field *fp)
- {
- if (valid>=0) return INVFIELD;
-
- int i;
-
- for(i=0; i<nfield; i++)
- if (!strcmpi(fielda[i]->name,fp->name)) return DUPFIELD;
-
- nfield++;
- fielda[nfield-1]=new field(nfield,fp->name,fp->type,fp->len,fp->rdp,reclen);
- reclen+=fp->len;
- if (fp->len>maxfieldl) maxfieldl=fp->len;
- if (fp->type) valid=-2;
- return 0;
- }
-
-
- // This version adds a completely new field
-
- int database::addfield(char *name,int type,int len,int rdp)
- {
- if (valid>=0) return INVFIELD;
-
- int i;
-
- for(i=0; i<nfield; i++)
- if (!strcmpi(fielda[i]->name,name)) return DUPFIELD;
-
- int ln=len;
- if (ln<1) return INVFIELD;
- switch(type&0xdf)
- {
- case 'C' : break;
- case 'D' : ln=8; break;
- case 'L' : ln=1; break;
- case 'M' : valid=-2; ln=10; break;
- case 'N' : if (rdp<0 || rdp>len-2) return INVFIELD; break;
- default : return INVFIELD;
- }
-
- nfield++;
- fielda[nfield-1]=new field(nfield,name,type,ln,rdp,reclen);
- reclen+=ln;
- if (ln>maxfieldl) maxfieldl=ln;
- return 0;
- }
-
- /*************** Write a database to disk ****************/
-
- int database::write(char *name)
- {
- if (valid>=0 || !nfield) return NOFILE;
-
- char n[128],ws[512],*wsp;
- int i;
-
- strcpy(n,name); if (!strchr(n,'.')) strcat(n,".dbf");
- if (!(dbfp=fopen(n,"w+b"))) {valid=NOFILE; return NOFILE;}
-
- if (valid==-2)
- {
- *(strchr(n,'.'))=0; strcat(n,".dbt");
- dbtp=fopen(n,"w+b");
- if (!dbtp) {valid=MEMOERR; return MEMOERR;}
- memset(ws,0,512);
- *ws=1;
- sprintf(ws+16,"Memo File written by dBase Library, Robin Abbott, %s",name);
- Fwrite(ws,512,1,dbtp);
- }
-
- memset(ws,0,32);
- *ws=(dbtp) ? 0x83 : 0x03;
- recstart=32*(nfield+1)+1;
- *(int *)(ws+8)=recstart;
- *(int *)(ws+10)=reclen;
- Fwrite(ws,32,1,dbfp);
-
- for(i=0; i<nfield; i++)
- {
- memset(ws,0,32);
- strcpy(ws,fielda[i]->name);
- ws[11]=fielda[i]->type;
- ws[16]=fielda[i]->len;
- ws[17]=fielda[i]->rdp;
- Fwrite(ws,32,1,dbfp);
- }
- Fputc(0x0d,dbfp);
-
- valid=0;
- return 0;
- }
-
- /*****************************************
-
- Here come a number of utility routines
-
- ******************************************/
-
-
- void fputl(long l,FILE *fp)
- {
- fputc(l&0xff,fp);
- fputc((l>>8) & 0xff,fp);
- fputc((l>>16) & 0xff,fp);
- fputc((l>>24) & 0xff,fp);
- }
-