home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
cslio205.zip
/
EXAMPLES
/
2
/
DEMODB.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1996-10-09
|
20KB
|
771 lines
/////////////////////////////////////////////////////////
// Implementation file of database class: DEMO.
//
// Source generated by: CSDBGEN version 1.6.b.
// Date of generation: Wednesday, 9 October 1996.
// Time of generation: 10:19:28.
//
//
// The next lines represent the database definition
// file used as input for CSDBGEN.
//
//
////////////// Start of the .def file //////////////////
/*
class: DEMO
record: Record
file: DBdemo
field: name s 50 Y
field: data s 32 Y
*/
/////////////// End of .def file //////////////////////////////////////////////
/*
█████ █ █
██ ██ ██ ██
███ ████ ███ ██ ███ ████
███ ██ ██ ███ ██ ██
███ ██ █████ ██ ██
██ ██ ██ █ ██ ██ ██ ██ █
█████ ██ ███ ██ ██ ██
████ ████ ██ ██ ██ ███ █████ ████
██ ██ ██ ██ ██ ███ ██ ██ █ ██ ██
████ ██ ██ ██ ██ ██ ██ ██████
██ ██ ██ ██ ██ ██ ██ █ ██
████ ████ ███ ██ ██ █████ █████
*/
//////////////////////////////////////////////////////////////////////////////
#include "csmess.h"
#include "csendian.h"
#include "demodb.h"
#ifdef _CP_010
extern unsigned _stklen=7000; // Under DOS, a large stack is needed.
#endif
Record *record_p;
///////////////////////////////// Constructor ////////////////////////////////
DEMO::DEMO(void)
{
static_rec=(Record *)malloc(sizeof(Record));
if(!static_rec) { csmess_p(" Out of memory "); exit(12); }
is_open=FALSE;
current=1;
NeedSync=TRUE;
errnr=0;;
e_name="DEMO-class";
use_lock_file(TRUE);
}
///////////////////////////////// Destructor /////////////////////////////////
DEMO::~DEMO(void)
{
close();
free(static_rec);
}
///////////////////////////////// Errors /////////////////////////////////////
int DEMO::error_nr(void)
{
int RC=0;
int RCT;
RCT=in1.error_nr(); if(RCT) RC=RCT;
RCT=in2.error_nr(); if(RCT) RC=RCT;
RCT=db.error_nr(); if(RCT) RC=RCT;
if(errnr) { RC=errnr; errnr=0; }
return RC;
}
///////////////////////////////// Display Error //////////////////////////////
U16 DEMO::display_error(void)
{
int RC;
RC=db.display_error();
if(!RC) RC=in1.display_error();
if(!RC) RC=in2.display_error();
if(!RC && errnr) { RC=errnr; csmess_p(RC,e_name); }
error_nr(); // Just to reset all error variables.
return RC;
}
///////////////////////////////// Messages ///////////////////////////////////
void DEMO::visible_error(int ErrorNr,char *Parm)
{
csmess_p(ErrorNr,e_name,Parm);
error_nr(ErrorNr);
}
///////////////////////////////// Test for Empty DB //////////////////////////
void DEMO::te(void)
{
if(numrec()) return;
visible_error(30010);
close();
exit(8);
}
///////////////////////////////// test Begin Of File /////////////////////////
int DEMO::tBOF(void)
{
if(!numrec()) return TRUE;
if(NeedSync) synch_index();
return (this->*bof_fun)();
}
///////////////////////////////// test End Of File /////////////////////////
int DEMO::tEOF(void)
{
if(!numrec()) return TRUE;
if(NeedSync) synch_index();
return (this->*eof_fun)();
}
///////////////////////////////// Read Only //////////////////////////////////
int DEMO::read_only(int ToF)
{
if(already_open()) { visible_error(30063); return FALSE; }
db.read_only(ToF);
in1.read_only(ToF);
in2.read_only(ToF);
return TRUE;
}
///////////////////////////////// Use lock files /////////////////////////////
int DEMO::use_lock_file(int ToF)
{
db.use_lock_file(ToF);
in1.use_lock_file(FALSE);
in2.use_lock_file(FALSE);
return TRUE;
}
///////////////////////////////// Lock file exist/////////////////////////////
int DEMO::lock_file_exist(void)
{
if(db.lock_file_exist("DBdemo.dbf")) return TRUE;
return FALSE;
}
///////////////////////////////// remove lock file ///////////////////////////
int DEMO::remove_lock_file(void)
{
db.remove_lock_file("DBdemo.dbf");
return TRUE;
}
///////////////////////////////// Sync Index /////////////////////////////////
void DEMO::synch_index(void)
{
switch(order())
{
case UNSORTED:
break;
case DEMO_NAME_INDEX:
find1(static_rec->_name);
break;
case DEMO_DATA_INDEX:
find2(static_rec->_data);
break;
}
NeedSync=FALSE;
}
///////////////////////////////// reindex ////////////////////////////////////
int DEMO::reindex(void)
{
if(!already_open()) { visible_error(30051); return FALSE; }
write_rec();
U32 l=current;
Record *rp;
in1.empty();
in2.empty();
for(current=numrec(); current>0; current--)
{
rp=locate_curr();
in1.insert(rp->_name,¤t);
in2.insert(rp->_data,¤t);
}
current=l;
NeedSync=TRUE;
return TRUE;
}
///////////////////////////////// skip ///////////////////////////////////////
int DEMO::skip0(int delta)
{
long old_current=current;
current=pMax(pMin(current+delta,db.numrec()),1);
return (int)(current-old_current);
}
int DEMO::skip(int delta)
{
int rc;
if(numrec()==0) return 0;
if(NeedSync) synch_index();
write_rec();
rc=(this->*skip_fun)(delta);
read_rec();
return rc;
}
/////////////// go_to ////////////////////////////////////////////
int DEMO::go_to(long n)
{
if(n<1 || n>numrec()) return FALSE;
write_rec();
current=n;
read_rec();
NeedSync=(order()!=UNSORTED);
return TRUE;
}
/////////////// bottom() /////////////////////////////////////////
int DEMO::bottom(void )
{
if(numrec()==0) return FALSE;
write_rec();
(this->*bottom_fun)();
read_rec();
NeedSync=FALSE;
return TRUE;
}
/////////////// top() ////////////////////////////////////////////
int DEMO::top(void )
{
if(numrec()==0) return FALSE;
write_rec();
(this->*top_fun)();
read_rec();
NeedSync=FALSE;
return TRUE;
}
/////////////// search() /////////////////////////////////////////
int DEMO::search(void *k)
{
if(numrec()==0) return FALSE;
int RC;
write_rec();
if(0==(RC=(this->*search_fun)(k))) bottom();
read_rec();
NeedSync=FALSE;
return RC;
}
/////////////// append blank//////////////////////////////////////
void DEMO::append_blank(void)
{
append();
in1.insert(static_rec->_name,¤t);
in2.insert(static_rec->_data,¤t);
NeedSync=FALSE;
}
///////////////////////////////// append /////////////////////////////////////
// This function doesn't update the indexes, which can save some
// disk I/O because you are likely to alter the fields
// immediately after you have appended the record.
// However, if you have an index on a field you don't update, this
// record will NOT appear in that particular index!
// The 'append_blank' function does update all indexes, which
// makes it a safer, but slower option.
//
void DEMO::append(void)
{
write_rec();
memset(static_rec,0,sizeof(Record));
current=db.append_rec(static_rec);
dirty=TRUE;
NeedSync=TRUE;
}
///////////////////////////////// open ///////////////////////////////////////
int DEMO::open(int kBbuf)
{
if(already_open()) { visible_error(30061); return FALSE; }
int needs_reindex=FALSE;
char *iname;
dirty=FALSE;
current=1;
int fre=kBbuf/5; //kBbuf default = 100 Kb.
if(!db.open("DBdemo.dbf",fre))
{
visible_error(30020,"DBdemo.dbf");
error_nr(db.error_nr());
return FALSE;
}
if(db.lengthrec()!=sizeof(Record))
{
visible_error(30030);
db.close();
exit(1);
}
iname="DBdemo01.idx";
if(!file_exist(iname))
{
in1.multiple_keys(TRUE);
in1.define(iname,DEMO_NAME_LENGTH+1,sizeof(long));
needs_reindex=TRUE;
}
if(!in1.open(iname,fre*2))
{
visible_error(30040,iname);
error_nr(in1.error_nr());
goto OnOpenError;
}
iname="DBdemo02.idx";
if(!file_exist(iname))
{
in2.multiple_keys(TRUE);
in2.define(iname,DEMO_DATA_LENGTH+1,sizeof(long));
needs_reindex=TRUE;
}
if(!in2.open(iname,fre*2))
{
visible_error(30040,iname);
error_nr(in2.error_nr());
goto OnOpenError;
}
is_open=TRUE;
if(needs_reindex) reindex();
read_rec();
order(UNSORTED);
return TRUE;
OnOpenError:
close2();
return FALSE;
}
///////////////////////////////// close //////////////////////////////////////
int DEMO::close2(void)
{
db.close();
in1.close();
in2.close();
return TRUE;
}
int DEMO::close(void)
{
if(!already_open()) return TRUE;
int RC=close2();
is_open=FALSE;
return RC;
}
///////////////////////////////// define /////////////////////////////////////
int DEMO::define(void)
{
if(already_open()) { visible_error(30062); return FALSE; }
int RC;
RC=db.define("DBdemo.dbf",sizeof(Record));
in1.multiple_keys(TRUE);
RC&=in1.define("DBdemo01.idx",DEMO_NAME_LENGTH+1,sizeof(long));
in2.multiple_keys(TRUE);
RC&=in2.define("DBdemo02.idx",DEMO_DATA_LENGTH+1,sizeof(long));
if(!RC) visible_error(30070);
return RC;
}
///////////////////////////////// pack ///////////////////////////////////////
int DEMO::pack(void)
{
if(!is_open) { visible_error(30052); return FALSE; }
write_rec();
db.pack();
reindex();
top();
return TRUE;
}
///////////////////////////////// order //////////////////////////////////////
int DEMO::order(int nr)
{
if(!is_open) { visible_error(30053); return FALSE; }
switch(nr)
{
case UNSORTED: //Unsorted
bof_fun =&DEMO::bof0;
eof_fun =&DEMO::eof0;
skip_fun =&DEMO::skip0;
top_fun =&DEMO::top0;
bottom_fun=&DEMO::bottom0;
search_fun=&DEMO::search0;
NeedSync=FALSE;
break;
case DEMO_NAME_INDEX: //Index on field name
bof_fun =&DEMO::bof1;
eof_fun =&DEMO::eof1;
skip_fun =&DEMO::skip1;
top_fun =&DEMO::top1;
bottom_fun=&DEMO::bottom1;
search_fun=&DEMO::search1;
NeedSync=TRUE;
break;
case DEMO_DATA_INDEX: //Index on field data
bof_fun =&DEMO::bof2;
eof_fun =&DEMO::eof2;
skip_fun =&DEMO::skip2;
top_fun =&DEMO::top2;
bottom_fun=&DEMO::bottom2;
search_fun=&DEMO::search2;
NeedSync=TRUE;
break;
default: { visible_error(30080); return FALSE; }
}
iOrder=nr;
return TRUE;
}
/////////////////////////////reading record ///////////////////////////////
void DEMO::read_rec(void)
{
if(numrec()==0) return;
*static_rec=*locate_curr();
}
/////////////////////////////writing record ///////////////////////////////
void DEMO::write_rec2(void)
{
Record *recp=locate_curr();
if(strcmp(recp->_name,static_rec->_name))
{
in1.delet(recp->_name,¤t);
in1.insert(static_rec->_name,¤t);
}
if(strcmp(recp->_data,static_rec->_data))
{
in2.delet(recp->_data,¤t);
in2.insert(static_rec->_data,¤t);
}
db.write_rec(current,static_rec);
dirty=FALSE;
}
///////////////////////////////// export /////////////////////////////////////
int DEMO::export(char *s)
{
if(!is_open) { visible_error(30054,s); return FALSE; }
write_rec();
FILE *fo=fopen(s,"w");
if(fo==NULL) { visible_error(30071,s); return FALSE; }
fprintf(fo,"class: DEMO");
fprintf(fo,"\nrecord: Record");
fprintf(fo,"\nfile: DBdemo");
fprintf(fo,"\nfield: name s 50 Y ");
fprintf(fo,"\nfield: data s 32 Y ");
if(ferror(fo)) { fclose(fo); visible_error(30072,s); return FALSE; }
Record *rp;
U32 lmax=numrec();
U32 l;
for(l=1;l<=lmax;l++)
{
rp=( Record * )db.locate_rec(l);
fprintf(fo,"\n%c",12);
fprintf(fo,"\n%s",rp->_name);
fprintf(fo,"\n%s",rp->_data);
fprintf(fo,"\n"); //Additional linefeed
if(ferror(fo)) { fclose(fo); visible_error(30072,s); return FALSE; }
}
if(fclose(fo)) { visible_error(30072,s); return FALSE; }
return TRUE;
}
///////////////////////////////// import /////////////////////////////////////
int DEMO::import(char *s)
{
if(!is_open) { visible_error(30055,s); return FALSE; }
FILE *fr=fopen(s,"r");
if(fr==NULL) { visible_error(30091,s); return FALSE; }
const MAX_NUM_FIELDS= 100; //Increase this to allow more fields
const MAX_FIELD_LEN = 500; //Increase this to allow longer fields
int *finu;
finu=(int *)malloc(MAX_NUM_FIELDS*sizeof(int));
if(finu==NULL) { fclose(fr); visible_error(30092); return FALSE; }
char *fibu;
fibu=(char *)malloc(MAX_FIELD_LEN);
if(fibu==NULL)
{
fclose(fr);
free(finu);
visible_error(30092);
return FALSE;
}
*fibu=0;
char *fipo=fibu+strlen("field:");
char *cp;
int ifieldnr=0;
int ofieldnr;
int RC=TRUE;
int InDef=TRUE;
memset(finu,0,MAX_NUM_FIELDS*sizeof(int));
fgets(fibu,MAX_FIELD_LEN,fr);
while(!strchr(fibu,12))
{
if(feof(fr))
{
if(!InDef)
visible_error(30093,s);
RC=FALSE;
break;
}
pStrlwr(fibu); //Converting to lower case.
notabs(fibu); //Removing tabs.
trim_string(fibu); //Removing heading & trailing spaces.
if(!strchr(fibu,':') && *fibu) InDef=FALSE;
if(strstr(fibu,"field:"))
{
ifieldnr++;
trim_string(fipo);
if((cp=strchr(fipo,' '))!=NULL) *cp=0;
if (!strcmp(fipo,"name")) ofieldnr=1;
else if(!strcmp(fipo,"data")) ofieldnr=2;
else ofieldnr=0;
finu[ifieldnr]=ofieldnr;
}
fgets(fibu,MAX_FIELD_LEN,fr);
}
if(RC)
for(;;)
{
if(!strchr(fibu,12))
{
ifieldnr++;
if(ifieldnr<MAX_NUM_FIELDS)
switch(finu[ifieldnr])
{
case 0: break;
case 1:
fibu[DEMO_NAME_LENGTH]=0;
name(fibu);
break;
case 2:
fibu[DEMO_DATA_LENGTH]=0;
data(fibu);
break;
}
}
else
{
ifieldnr=0;
append_blank();
}
if(feof(fr)) break;
fgets(fibu,MAX_FIELD_LEN,fr);
cp=fibu+(pMax(1,strlen(fibu))-1);
if(*cp=='\n') *cp=0; //removing the line feed
}
fclose(fr);
free(fibu);
free(finu);
return RC;
}
///////////////////////////////// export to dBASE compatible file. ///////////
int DEMO::to_DBASE(char *s)
{
if(!is_open) { visible_error(30056,s); return FALSE; }
char bufje[12];
write_rec();
FILE *fo=fopen(s,"wb");
if(fo==NULL) { visible_error(30095,s); return FALSE; }
int i;
csDATE d_upda;
d_upda.sem_jul(db.sj_updated());
fputc(03,fo);
fputc(d_upda.year()%100,fo);
fputc(d_upda.month(),fo);
fputc(d_upda.day(),fo);
long nr_record=numrec();
fwrite(&nr_record,sizeof(long),1,fo);
WriteU16l(fo,98); //Header length
WriteU16l(fo,83); //Length of data record
for(i=0;i<20;i++) fputc(0,fo); // 20 dummy bytes
// Writing definition of field name to dbase file header.
memset(bufje,0,11);
strcpy(bufje,"NAME");
fwrite(bufje,11,1,fo);
fputc('C',fo);
for(i=0;i<4;i++) fputc(0,fo); // 4 dummy bytes
fputc(50,fo);
fputc(0,fo);
for(i=0;i<14;i++) fputc(0,fo); // 14 dummy bytes
// Writing definition of field data to dbase file header.
memset(bufje,0,11);
strcpy(bufje,"DATA");
fwrite(bufje,11,1,fo);
fputc('C',fo);
for(i=0;i<4;i++) fputc(0,fo); // 4 dummy bytes
fputc(32,fo);
fputc(0,fo);
for(i=0;i<14;i++) fputc(0,fo); // 14 dummy bytes
fputc(13,fo); //Field terminator
fputc(0,fo);
// By now we have written the definition of the
// record structure to the file header.
// From here on we will export the records.
Record *rp;
U32 lmax=numrec();
U32 l;
for(l=1;l<=lmax;l++)
{
if(ferror(fo))
{
fclose(fo);
visible_error(30096,s);
return FALSE;
}
rp=(Record *)db.locate_rec(l);
if(db.is_delet(l)) fputc(42,fo);
else fputc(32,fo);
/////////////////////// writing field name /////////////
fprintf(fo,"%-50s",rp->_name);
/////////////////////// writing field data /////////////
fprintf(fo,"%-32s",rp->_data);
}
fputc(26,fo); //End of File
fclose(fo);
if(ferror(fo))
{
visible_error(30096,s);
return FALSE;
}
return TRUE;
}