home *** CD-ROM | disk | FTP | other *** search
/ Prima Shareware 3 / DuCom_Prima-Shareware-3_cd1.bin / PROGRAMO / C / TPXCLS / TPXCLASS.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1991-12-11  |  37.5 KB  |  1,747 lines

  1.  
  2. // tpxclass.cpp
  3. //--------------------------------------------------------------------------
  4. //    TPXCLASS.CPP & TPXCLASS.HPP are the sole proporty of 
  5. //  Masterson Johnston, Inc. Feel free to modify and use this code in any
  6. //  way, but remember, though we wrote it, we are not responsibile for it's
  7. //  actions nor yours if anything goes wrong. 
  8. //
  9. //--------------------------------------------------------------------------
  10. #include "tpxclass.hpp"
  11. //----------------------------------------------------------------------------
  12.  
  13. /*
  14.     Clear totals.
  15. */
  16.  
  17. PX_Table :: PX_Table()
  18. {
  19.   field_count=0;
  20.   index_count=0;
  21.   secondary_index_count=0;
  22.   current_field_count=0;
  23.   current_index_count=0;
  24.   current_secondary_index_count=0;
  25.   memset(table_path,0,80);
  26. }
  27.  
  28. //----------------------------------------------------------------------------
  29.  
  30. /*
  31.     get the address of the data buffer to be associated with this object.
  32.     This is the address of a C struct which will hold 1 record from the DB file.
  33.     Note that char strings will have 1 more byte than length
  34.     specified in the DB definition to account for NULL.
  35.     PDX "A10" field will be moved into a C char str[11] field.
  36. */
  37.  
  38. void PX_Table :: set_data_buf(char *dbuf)
  39. {
  40.   data_buf=dbuf;    // get pointer to the C structure in which to load a record 
  41. }
  42.  
  43. //----------------------------------------------------------------------------
  44.  
  45. /*
  46.     Set master path, usually a subdir where the program file resides
  47. */
  48.  
  49. void PX_Table :: set_path(char *dpath)
  50. {
  51.   strcpy(table_path,dpath);    // path to the program files. see below for details
  52. }
  53.  
  54. //----------------------------------------------------------------------------
  55.  
  56. /*
  57.   Set file name to be associated with this object. For historical reasons
  58.     this routine was held seperate from the above function. The DB files
  59.     are expected to be in the DATA subdor off of table_path,
  60. */
  61.  
  62. void PX_Table :: set_name(char *fname)
  63. {
  64.   strcat(table_path,"DATA\\");                                                            
  65.   strncat(table_path,fname,8);
  66. }
  67.  
  68. //----------------------------------------------------------------------------
  69.  
  70. /*
  71.     This routine allocates the correct # of field & index pointers needed to
  72.     create the **list used by PXAPI to create files and indexes. It is a prime
  73.     candidate for recoding with operator overloading along with the associated
  74.     add_field & add_secondary_index functions. Note that there is no 
  75.     add_primary_index function, since promary keys start at field 1 and are
  76.     icount in length. The create_data_file automatically creates the primary
  77.     index when called.
  78. */
  79.  
  80. int PX_Table :: init_descriptors(char fcount, char icount, char sicount)
  81. {
  82.   register a;
  83.  
  84.   field_count=0;
  85.   index_count=0;
  86.   secondary_index_count=0;
  87.   current_field_count=0;
  88.   current_index_count=0;
  89.   current_secondary_index_count=0;
  90.  
  91.   if(fcount>0){
  92.  
  93.     (void *)field_name=malloc(fcount * sizeof(char *));
  94.     if(!(long)field_name)
  95.       return(-1);
  96.  
  97.     (void *)field_type=malloc(fcount * sizeof(char *));
  98.     if(!(long)field_type){
  99.       free(field_name);
  100.       return(-1);
  101.     }
  102.  
  103.     field_count=fcount;
  104.     current_field_count=0;
  105.  
  106.   }
  107.  
  108.   if(icount>0){
  109.  
  110.     (void *)index_field_handles=malloc(icount * sizeof(FIELDHANDLE));
  111.     if(!(long)index_field_handles){
  112.       free_descriptors();
  113.       return(-1);
  114.     }
  115.  
  116.     index_count=icount;
  117.  
  118.   }
  119.  
  120.   if(sicount>0){
  121.  
  122.     (void *)secondary_index_field_handles=malloc(sicount * sizeof(FIELDHANDLE));
  123.     if(!(long)secondary_index_field_handles){
  124.       free_descriptors();
  125.       return(-1);
  126.     }
  127.  
  128.     secondary_index_count=sicount;
  129.     current_secondary_index_count=0;
  130.  
  131.   }
  132.  
  133.   return(0);
  134.  
  135. }
  136.  
  137. //----------------------------------------------------------------------------
  138.  
  139. /*
  140.     Clean up when done with the descriptors. Note that the loop for free each
  141.     list member (descriptor) is limited by the current_xxx_xxx count so if an
  142.     error occurs during init_descriptor or add_xxx, a simple call to this
  143.     fuinction clears up the proper number of pointers.    
  144. */
  145.  
  146. void PX_Table :: free_descriptors()
  147. {
  148.   register a;
  149.  
  150.   if(field_count){
  151.     for(a=0;a<current_field_count;a++){
  152.       free(field_name[a]);
  153.       free(field_type[a]);
  154.     }
  155.     free(field_name);
  156.     free(field_type);
  157.   }
  158.  
  159.   if(index_count){
  160.     free(index_field_handles);
  161.     index_count=0;
  162.   }
  163.  
  164.   if(secondary_index_count){
  165.     free(secondary_index_field_handles);
  166.     secondary_index_count=0;
  167.   }
  168.  
  169. }
  170.  
  171. //----------------------------------------------------------------------------
  172.  
  173. /*
  174.     Add a field definition (descriptor) to the **list. Clip name if too long.
  175.     The *type is the "A10" or "S" component and the *name is the field name. 
  176. */
  177.  
  178. void PX_Table :: add_field(char *type, char *name)
  179. {    
  180.   if(current_field_count<field_count){
  181.     if(strlen(name)>25)
  182.       name[24]=0;
  183.     field_name[current_field_count]=strdup(name);
  184.     field_type[current_field_count]=strdup(type);
  185.     current_field_count++;
  186.   }
  187. }
  188.  
  189. //----------------------------------------------------------------------------
  190.  
  191. /*
  192.     Add a secondary index definition to file. fh is the field handle (number)
  193.     of the desired field to have an index.
  194. */
  195.  
  196. void PX_Table :: add_secondary_index(FIELDHANDLE fh)
  197. {
  198.   if(current_secondary_index_count<secondary_index_count){
  199.     (FIELDHANDLE)secondary_index_field_handles[current_secondary_index_count]=fh;
  200.     current_secondary_index_count++;
  201.   }
  202. }
  203.  
  204. //----------------------------------------------------------------------------
  205.  
  206. /*
  207.     Check the actual descriptior counts vs the initial counts and then make DB
  208.     file if they are equal. If there was a primary index count specified, load
  209.     that array and create that index. If secondary indexes were specified, 
  210.     create each one then free all descriptors.
  211. */
  212.  
  213. int PX_Table :: init_data_file()
  214. {
  215.   register a,b;
  216.   char temp[80];
  217.  
  218.   if(field_count!=current_field_count){
  219.     free_descriptors();
  220.     return(-1);
  221.   }
  222.  
  223.   if(secondary_index_count!=current_secondary_index_count){
  224.     free_descriptors();
  225.     return(-2);
  226.   }
  227.  
  228.   b=PXTblCreate(table_path, field_count, field_name, field_type);
  229.  
  230.   if(!b)
  231.     if(index_count){
  232.  
  233.       for(a=current_index_count;a<index_count;a++)
  234.         (FIELDHANDLE)index_field_handles[a]=a+1;
  235.  
  236.       b=PXKeyAdd(table_path,index_count,index_field_handles,PRIMARY);
  237.  
  238.   }
  239.  
  240.   if(!b)
  241.     if(secondary_index_count)
  242.       for(a=0;a<secondary_index_count;a++)
  243.         b=PXKeyAdd(table_path,(int)1,(FIELDHANDLE *)secondary_index_field_handles+a,INCSECONDARY);
  244.  
  245.   free_descriptors();
  246.  
  247.   return(b);
  248.  
  249. }
  250.  
  251. //----------------------------------------------------------------------------
  252. /*
  253.     From here on down to TPXFile, the PXENG functions are C plus-ized, with
  254.     the common variables taken out of the passed args. Usually this involves
  255.     the table path, field counts and data buffers shared among all the functions
  256. */
  257. //----------------------------------------------------------------------------
  258.  
  259. int PX_Table :: pxtbladd(char *tpath)
  260. {
  261.   register b;
  262.   b=PXTblAdd(table_path,tpath);
  263.   return(b);
  264. }
  265.  
  266. //----------------------------------------------------------------------------
  267.  
  268. int PX_Table :: pxtblclose()
  269. {
  270.   register b;
  271.   b=PXTblClose(table_handle);
  272.   return(b);
  273. }
  274.  
  275. //----------------------------------------------------------------------------
  276.  
  277. int PX_Table :: pxtblcopy(char *tpath)
  278. {
  279.   register b;
  280.   b=PXTblCopy(table_path, tpath);
  281.   return(b);
  282. }
  283.  
  284. //----------------------------------------------------------------------------
  285.  
  286. int PX_Table :: pxtbldecrypt()
  287. {
  288.   register b;
  289.   b=PXTblDecrypt(table_path);
  290.   return(b);
  291. }
  292.  
  293. //----------------------------------------------------------------------------
  294.  
  295. int PX_Table :: pxtbldelete()
  296. {
  297.   register b;
  298.   b=PXTblDelete(table_path);
  299.   return(b);
  300. }
  301.  
  302. //----------------------------------------------------------------------------
  303.  
  304. int PX_Table :: pxtblempty()
  305. {
  306.   register b;
  307.   b=PXTblEmpty(table_path);
  308.   return(b);
  309. }
  310.  
  311. //----------------------------------------------------------------------------
  312.  
  313. int PX_Table :: pxtblencrypt(char *psw)
  314. {
  315.   register b;
  316.   b=PXTblEncrypt(table_path, psw);
  317.   return(b);
  318. }
  319.  
  320. //----------------------------------------------------------------------------
  321.  
  322. int PX_Table :: pxtblexist(int *exist_flag)
  323. {
  324.   register b;
  325.   b=PXTblExist(table_path, exist_flag);
  326.   return(b);
  327. }
  328.  
  329. //----------------------------------------------------------------------------
  330.  
  331. int PX_Table :: pxtblname(int buflen, char *buf)
  332. {
  333.   register b;
  334.   b=PXTblName(table_handle, buflen, buf);
  335.   return(b);
  336. }
  337.  
  338. //----------------------------------------------------------------------------
  339.  
  340. int PX_Table :: pxtblnrecs()
  341. {
  342.   register b;
  343.   b=PXTblNRecs(table_handle, &total_records);
  344.   return(b);
  345. }
  346.  
  347. //----------------------------------------------------------------------------
  348.  
  349. int PX_Table :: pxtblopen()
  350. {
  351.   register b;
  352.   b=PXTblOpen(table_path,&table_handle,0,1);
  353.   return(b);
  354. }
  355.  
  356. //----------------------------------------------------------------------------
  357.  
  358. int PX_Table :: pxtblprotected(int *protect_flag)
  359. {
  360.   register b;
  361.   b=PXTblProtected(table_path,protect_flag);
  362.   return(b);
  363. }
  364.  
  365. //----------------------------------------------------------------------------
  366.  
  367. int PX_Table :: pxtblrename(char *tpath)
  368. {
  369.   register b;
  370.   b=PXTblRename(table_path,tpath);
  371.   return(b);
  372. }
  373.  
  374. //----------------------------------------------------------------------------
  375.  
  376. PX_File :: PX_File()
  377. {
  378.   record_handle=0;
  379.   record_number=0;
  380.   field_handle=0;
  381.   lock_handle=0;
  382. }
  383.  
  384. //----------------------------------------------------------------------------
  385.  
  386. int PX_File :: pxfldblank(int *blank_flag)
  387. {
  388.   register b;
  389.   b=PXFldBlank(record_handle,field_handle,blank_flag);
  390.   return(b);
  391. }
  392.  
  393. //----------------------------------------------------------------------------
  394.  
  395. int PX_File :: pxfldblank(char *field_name, int *blank_flag)
  396. {
  397.   register b;
  398.   b=pxfldhandle(field_name);
  399.   if(!b)
  400.     b=PXFldBlank(record_handle,field_handle,blank_flag);
  401.   return(b);
  402. }
  403.  
  404. //----------------------------------------------------------------------------
  405.  
  406. int PX_File :: pxfldhandle(char *field_name)
  407. {
  408.   register b;
  409.   b=PXFldHandle(table_handle,field_name,&field_handle);
  410.   return(b);
  411. }
  412.  
  413. //----------------------------------------------------------------------------
  414.  
  415. int PX_File :: pxfldname(char *field_name)
  416. {
  417.   register b;
  418.   b=PXFldName(table_handle,field_handle,24,field_name);
  419.   return(b);
  420. }
  421.  
  422. //----------------------------------------------------------------------------
  423.  
  424. int PX_File :: pxfldtype(char *field_type)
  425. {
  426.   register b;
  427.   b=PXFldType(table_handle,field_handle,4,field_type);
  428.   return(b);
  429. }
  430.  
  431. //----------------------------------------------------------------------------
  432.  
  433. int PX_File :: pxfldtype(char *field_name, char *field_type)
  434. {
  435.   register b;
  436.   b=pxfldhandle(field_name);
  437.   if(!b)
  438.     b=PXFldType(table_handle,field_handle,4,field_type);
  439.   return(b);
  440. }
  441.  
  442. //----------------------------------------------------------------------------
  443.  
  444. int PX_File :: pxgetalpha(int buf_size, char *buf)
  445. {
  446.   register b;
  447.   b=PXGetAlpha(record_handle,field_handle,buf_size,buf);
  448.   return(b);
  449. }
  450.  
  451. //----------------------------------------------------------------------------
  452.  
  453. int PX_File :: pxgetalpha(char *field_name, int buf_size, char *buf)
  454. {
  455.   register b;
  456.   b=pxfldhandle(field_name);
  457.   if(!b)
  458.     b=PXGetAlpha(record_handle,field_handle,buf_size,buf);
  459.   return(b);
  460. }
  461.  
  462. //----------------------------------------------------------------------------
  463.  
  464. int PX_File :: pxgetdate(DATE *buf)
  465. {
  466.   register b;
  467.   b=PXGetDate(record_handle,field_handle,buf);
  468.   return(b);
  469. }
  470.  
  471. //----------------------------------------------------------------------------
  472.  
  473. int PX_File :: pxgetdate(char *field_name, DATE *buf)
  474. {
  475.   register b;
  476.   b=pxfldhandle(field_name);
  477.   if(!b)
  478.     b=PXGetDate(record_handle,field_handle,buf);
  479.   return(b);
  480. }
  481.  
  482. //----------------------------------------------------------------------------
  483.  
  484. int PX_File :: pxgetdouble(double *buf)
  485. {
  486.   register b;
  487.   b=PXGetDoub(record_handle,field_handle,buf);
  488.   return(b);
  489. }
  490.  
  491. //----------------------------------------------------------------------------
  492.  
  493. int PX_File :: pxgetdouble(char *field_name, double *buf)
  494. {
  495.   register b;
  496.   b=pxfldhandle(field_name);
  497.   if(!b)
  498.     b=PXGetDoub(record_handle,field_handle,buf);
  499.   return(b);
  500. }
  501.  
  502. //----------------------------------------------------------------------------
  503.  
  504. int PX_File :: pxgetlong(long *buf)
  505. {
  506.   register b;
  507.   b=PXGetLong(record_handle,field_handle,buf);
  508.   return(b);
  509. }
  510.  
  511. //----------------------------------------------------------------------------
  512.  
  513. int PX_File :: pxgetlong(char *field_name, long *buf)
  514. {
  515.   register b;
  516.   b=pxfldhandle(field_name);
  517.   if(!b)
  518.     b=PXGetLong(record_handle,field_handle,buf);
  519.   return(b);
  520. }
  521.  
  522. //----------------------------------------------------------------------------
  523.  
  524. int PX_File :: pxgetshort(short *buf)
  525. {
  526.   register b;
  527.   b=PXGetShort(record_handle,field_handle,buf);
  528.   return(b);
  529. }
  530.  
  531. //----------------------------------------------------------------------------
  532.  
  533. int PX_File :: pxgetshort(char *field_name, short *buf)
  534. {
  535.   register b;
  536.   b=pxfldhandle(field_name);
  537.   if(!b)
  538.     b=PXGetShort(record_handle,field_handle,buf);
  539.   return(b);
  540. }
  541.  
  542. //----------------------------------------------------------------------------
  543.  
  544. int PX_File :: pxneterruser(char *user)
  545. {
  546.   register b;
  547.   b=PXNetErrUser(47,user);
  548.   return(b);
  549. }
  550.  
  551. //----------------------------------------------------------------------------
  552.  
  553. int PX_File :: pxnetfilelock(int lock_type)
  554. {
  555.   register b;
  556.   b=PXNetFileLock(table_path,lock_type);
  557.   return(b);
  558. }
  559.  
  560. //----------------------------------------------------------------------------
  561.  
  562. int PX_File :: pxnetfileunlock(int lock_type)
  563. {
  564.   register b;
  565.   b=PXNetFileUnlock(table_path,lock_type);
  566.   return(b);
  567. }
  568.  
  569. //----------------------------------------------------------------------------
  570.  
  571. int PX_File :: pxnetreclock()
  572. {
  573.   register b;
  574.   b=PXNetRecLock(table_handle,&lock_handle);
  575.   return(b);
  576. }
  577.  
  578. //----------------------------------------------------------------------------
  579.  
  580. int PX_File :: pxnetrecunlock()
  581. {
  582.   register b;
  583.   b=PXNetRecUnlock(table_handle,lock_handle);
  584.   return(b);
  585. }
  586.  
  587. //----------------------------------------------------------------------------
  588.  
  589. int PX_File :: pxnetreclocked(int *lock_flag)
  590. {
  591.   register b;
  592.   b=PXNetRecLocked(table_handle,lock_flag);
  593.   return(b);
  594. }
  595.  
  596. //----------------------------------------------------------------------------
  597.  
  598. int PX_File :: pxnetrecgotolock()
  599. {
  600.   register b;
  601.   b=PXNetRecGotoLock(table_handle,lock_handle);
  602.   return(b);
  603. }
  604.  
  605. //----------------------------------------------------------------------------
  606.  
  607. int PX_File :: pxnettblchanged(int *change_flag)
  608. {
  609.   register b;
  610.   b=PXNetTblChanged(table_handle,change_flag);
  611.   return(b);
  612. }
  613.  
  614. //----------------------------------------------------------------------------
  615.  
  616. int PX_File :: pxnettbllock(int lock_type)
  617. {
  618.   register b;
  619.   b=PXNetTblLock(table_handle,lock_type);
  620.   return(b);
  621. }
  622.  
  623. //----------------------------------------------------------------------------
  624.  
  625. int PX_File :: pxnettblunlock(int lock_type)
  626. {
  627.   register b;
  628.   b=PXNetTblUnlock(table_handle,lock_type);
  629.   return(b);
  630. }
  631.  
  632. //----------------------------------------------------------------------------
  633.  
  634. int PX_File :: pxnettblrefresh()
  635. {
  636.   register b;
  637.   b=PXNetTblRefresh(table_handle);
  638.   return(b);
  639. }
  640.  
  641. //----------------------------------------------------------------------------
  642.  
  643. int PX_File :: pxnetusername(char *buf)
  644. {
  645.   register b;
  646.   b=PXNetUserName(47,buf);
  647.   return(b);
  648. }
  649.  
  650. //----------------------------------------------------------------------------
  651.  
  652. int PX_File :: pxputalpha(char *buf)
  653. {
  654.   register b;
  655.   b=PXPutAlpha(record_handle,field_handle,buf);
  656.   return(b);
  657. }
  658.  
  659. //----------------------------------------------------------------------------
  660.  
  661. int PX_File :: pxputalpha(char *field_name, char *buf)
  662. {
  663.   register b;
  664.   b=pxfldhandle(field_name);
  665.   if(!b)
  666.     b=PXPutAlpha(record_handle,field_handle,buf);
  667.   return(b);
  668. }
  669.  
  670. //----------------------------------------------------------------------------
  671.  
  672. int PX_File :: pxputblank()
  673. {
  674.   register b;
  675.   b=PXPutBlank(record_handle,field_handle);
  676.   return(b);
  677. }
  678.  
  679. //----------------------------------------------------------------------------
  680.  
  681. int PX_File :: pxputblank(char *field_name)
  682. {
  683.   register b;
  684.   b=pxfldhandle(field_name);
  685.   if(!b)
  686.     b=PXPutBlank(record_handle,field_handle);
  687.   return(b);
  688. }
  689.  
  690. //----------------------------------------------------------------------------
  691.  
  692. int PX_File :: pxputdate(DATE buf)
  693. {
  694.   register b;
  695.   b=PXPutDate(record_handle,field_handle,buf);
  696.   return(b);
  697. }
  698.  
  699. //----------------------------------------------------------------------------
  700.  
  701. int PX_File :: pxputdate(char *field_name, DATE buf)
  702. {
  703.   register b;
  704.   b=pxfldhandle(field_name);
  705.   if(!b)
  706.     b=PXPutDate(record_handle,field_handle,buf);
  707.   return(b);
  708. }
  709.  
  710. //----------------------------------------------------------------------------
  711.  
  712. int PX_File :: pxputdouble(double buf)
  713. {
  714.   register b;
  715.   b=PXPutDoub(record_handle,field_handle,buf);
  716.   return(b);
  717. }
  718.  
  719. //----------------------------------------------------------------------------
  720.  
  721. int PX_File :: pxputdouble(char *field_name, double buf)
  722. {
  723.   register b;
  724.   b=pxfldhandle(field_name);
  725.   if(!b)
  726.     b=PXPutDoub(record_handle,field_handle,buf);
  727.   return(b);
  728. }
  729.  
  730. //----------------------------------------------------------------------------
  731.  
  732. int PX_File :: pxputlong(long buf)
  733. {
  734.   register b;
  735.   b=PXPutLong(record_handle,field_handle,buf);
  736.   return(b);
  737. }
  738.  
  739. //----------------------------------------------------------------------------
  740.  
  741. int PX_File :: pxputlong(char *field_name, long buf)
  742. {
  743.   register b;
  744.   b=pxfldhandle(field_name);
  745.   if(!b)
  746.     b=PXPutLong(record_handle,field_handle,buf);
  747.   return(b);
  748. }
  749.  
  750. //----------------------------------------------------------------------------
  751.  
  752. int PX_File :: pxputshort(short buf)
  753. {
  754.   register b;
  755.   b=PXPutShort(record_handle,field_handle,buf);
  756.   return(b);
  757. }
  758.  
  759. //----------------------------------------------------------------------------
  760.  
  761. int PX_File :: pxputshort(char *field_name, short buf)
  762. {
  763.   register b;
  764.   b=pxfldhandle(field_name);
  765.   if(!b)
  766.     b=PXPutShort(record_handle,field_handle,buf);
  767.   return(b);
  768. }
  769.  
  770. //----------------------------------------------------------------------------
  771.  
  772. int PX_File :: pxrecappend()
  773. {
  774.   register b;
  775.   b=PXRecAppend(table_handle,record_handle);
  776.   return(b);
  777. }
  778.  
  779. //----------------------------------------------------------------------------
  780.  
  781. int PX_File :: pxrecbufclose()
  782. {
  783.   register b;
  784.   b=PXRecBufClose(record_handle);
  785.   return(b);
  786. }
  787.  
  788. //----------------------------------------------------------------------------
  789.  
  790. int PX_File :: pxrecbufcopy(RECORDHANDLE rhandle)
  791. {
  792.   register b;
  793.   b=PXRecBufCopy(record_handle,rhandle);
  794.   return(b);
  795. }
  796.  
  797. //----------------------------------------------------------------------------
  798.  
  799. int PX_File :: pxrecbufempty()
  800. {
  801.   register b;
  802.   b=PXRecBufEmpty(record_handle);
  803.   return(b);
  804. }
  805.  
  806. //----------------------------------------------------------------------------
  807.  
  808. int PX_File :: pxrecbufopen()
  809. {
  810.   register b;
  811.   b=PXRecBufOpen(table_handle,&record_handle);
  812.   return(b);
  813. }
  814.  
  815. //----------------------------------------------------------------------------
  816.  
  817. int PX_File :: pxrecdelete()
  818. {
  819.   register b;
  820.   b=PXRecDelete(table_handle);
  821.   return(b);
  822. }
  823.  
  824. //----------------------------------------------------------------------------
  825.  
  826. int PX_File :: pxrecfirst()
  827. {
  828.   register b;
  829.   b=PXRecFirst(table_handle);
  830.   return(b);
  831. }
  832.  
  833. //----------------------------------------------------------------------------
  834.  
  835. int PX_File :: pxrecget()
  836. {
  837.   register b;
  838.   b=PXRecGet(table_handle,record_handle);
  839.   return(b);
  840. }
  841.  
  842. //----------------------------------------------------------------------------
  843.  
  844. int PX_File :: pxrecgoto(RECORDNUMBER rnum)
  845. {
  846.   register b;
  847.   b=PXRecGoto(table_handle,rnum);
  848.   return(b);
  849. }
  850.  
  851. //----------------------------------------------------------------------------
  852.  
  853. int PX_File :: pxrecinsert()
  854. {
  855.   register b;
  856.   b=PXRecInsert(table_handle,record_handle);
  857.   return(b);
  858. }
  859.  
  860. //----------------------------------------------------------------------------
  861.  
  862. int PX_File :: pxreclast()
  863. {
  864.   register b;
  865.   b=PXRecLast(table_handle);
  866.   return(b);
  867. }
  868.  
  869. //----------------------------------------------------------------------------
  870.  
  871. int PX_File :: pxrecnext()
  872. {
  873.   register b;
  874.   b=PXRecNext(table_handle);
  875.   return(b);
  876. }
  877.  
  878. //----------------------------------------------------------------------------
  879.  
  880. int PX_File :: pxrecnflds()
  881. {
  882.   register b;
  883.   b=PXRecNFlds(table_handle,(int *)&total_fields);
  884.   return(b);
  885. }
  886.  
  887. //----------------------------------------------------------------------------
  888.  
  889. int PX_File :: pxrecnum()
  890. {
  891.   register b;
  892.   b=PXRecNum(table_handle,&record_number);
  893.   return(b);
  894. }
  895.  
  896. //----------------------------------------------------------------------------
  897.  
  898. int PX_File :: pxrecprev()
  899. {
  900.   register b;
  901.   b=PXRecPrev(table_handle);
  902.   return(b);
  903. }
  904.  
  905. //----------------------------------------------------------------------------
  906.  
  907. int PX_File :: pxrecupdate()
  908. {
  909.   register b;
  910.   b=PXRecUpdate(table_handle,record_handle);
  911.   return(b);
  912. }
  913.  
  914. //----------------------------------------------------------------------------
  915.  
  916. int PX_File :: pxsrchfld(int mode)
  917. {
  918.   register b;
  919.   b=PXSrchFld(table_handle,record_handle,field_handle,mode);
  920.   return(b);
  921. }
  922.  
  923. //----------------------------------------------------------------------------
  924.  
  925. int PX_File :: pxsrchfld(char *field_name, int mode)
  926. {
  927.   register b;
  928.   b=pxfldhandle(field_name);
  929.   if(!b)
  930.     b=PXSrchFld(table_handle,record_handle,field_handle,mode);
  931.   return(b);
  932. }
  933.  
  934. //----------------------------------------------------------------------------
  935.  
  936. int PX_File :: pxsrchkey(int num_key_fields, int mode)
  937. {
  938.     register b;
  939.     b=PXSrchKey(table_handle,record_handle,num_key_fields,mode);
  940.     return(b);
  941. }
  942.  
  943. //----------------------------------------------------------------------------
  944. /*
  945.     Here's wher the fun begins, all the above wrapper code is designed to make
  946.     these functions work smoothly. Managing expected errors (exceptions) as
  947.     well as unexpected errors, searching for records, loading them into C
  948.     structs (data_buf) without explicit coding and other useful functions
  949.     are all here.
  950. */
  951. //----------------------------------------------------------------------------
  952.  
  953. /*
  954.   Clear the exception list.
  955. */
  956.  
  957. TPXFile :: TPXFile()
  958. {
  959.   exception_list=NULL;
  960. }
  961.  
  962. //----------------------------------------------------------------------------
  963.  
  964. /*
  965.   Get a list of expected errors (exceptions) for use later. This is a simple
  966.     NULL terminated list int elist[]={PXERR_RECNOTFOUND,NULL};
  967. */
  968.  
  969. int TPXFile :: add_exceptions(int *list)
  970. {
  971.   register a;
  972.  
  973.   if(!(long)list)
  974.     return(0);
  975.  
  976.   for(a=0;list[a];a++);
  977.   a++;
  978.  
  979.   (void *)exception_list=malloc(a);
  980.   if(!(long)exception_list)
  981.     return(-1);
  982.  
  983.   for(a=0;list[a];a++)
  984.     exception_list[a]=list[a];
  985.  
  986.   exception_list[a]=0;
  987.  
  988.   return(0);
  989.  
  990. }
  991.  
  992. //----------------------------------------------------------------------------
  993.  
  994. /*
  995.     In an error has occured during a PXENG call, check the supplied elist,
  996.     if a list was given, for a matching entry to the actual error (code). If
  997.     the error was in the exception list, return a positive value of its numeric
  998.     position in the list, otherwise return a -1 after printing the error. This is
  999.     kept primitve intentionally in this code to allow other authors to handle 
  1000.     errors in their own manner.
  1001. */
  1002.  
  1003. int TPXFile :: check_exceptions(int code)
  1004. {
  1005.   register a;
  1006.   char found=0;
  1007.  
  1008.   if(!code){
  1009.     free_exceptions();
  1010.     return(0);
  1011.   }
  1012.  
  1013.   if((long)exception_list){
  1014.  
  1015.       for(a=0;exception_list[a];a++)
  1016.         if((int)exception_list[a]==code){
  1017.           found=1;
  1018.           break;
  1019.         }
  1020.  
  1021.       free_exceptions();
  1022.  
  1023.   }
  1024.  
  1025.   if(found)
  1026.     return(a+1);
  1027.  
  1028.     printf("\n%s\n",PXErrMsg(code));
  1029.     
  1030.   return(-1);
  1031.  
  1032. }
  1033.  
  1034. //----------------------------------------------------------------------------
  1035.  
  1036. /*
  1037.     Free the list when the operation is through
  1038. */
  1039.  
  1040. void TPXFile :: free_exceptions()
  1041. {
  1042.   if((long)exception_list){
  1043.     free(exception_list);
  1044.     exception_list=NULL;
  1045.   }
  1046. }
  1047.  
  1048. //----------------------------------------------------------------------------
  1049.  
  1050. /*
  1051.     When opening a table, open all associated indexes, assign a rec buffer,
  1052.     get the number of records and number of fields in each record. This is
  1053.     very handy information to have.
  1054. */
  1055.  
  1056. int TPXFile :: OpenTable()
  1057. {
  1058.   register b;
  1059.  
  1060.   b=pxtblopen();
  1061.   if(b)
  1062.     return(b);
  1063.  
  1064.   b=pxrecbufopen();
  1065.   if(b)
  1066.     return(b);
  1067.   
  1068.   b=pxtblnrecs();
  1069.   if(b)
  1070.     return(b);
  1071.   
  1072.   b=pxrecnflds();
  1073.   if(b)
  1074.     return(b);
  1075.  
  1076.   return(0);
  1077. }
  1078.  
  1079. //-----------------------------------------------------------------------------
  1080.  
  1081. /*
  1082.     Was this really necessary?
  1083. */
  1084.  
  1085. int TPXFile :: CloseTable()
  1086. {
  1087.   register b;
  1088.  
  1089.   b=pxtblclose();
  1090.  
  1091.   return(b);
  1092.  
  1093. }
  1094.  
  1095. //-----------------------------------------------------------------------------
  1096.  
  1097. /*
  1098.     This simple routine shows the power inherent in this class. The abilty to
  1099.     get a record, load its (current) record #, then load that record into
  1100.     the data_buf (C struct).    
  1101. */
  1102.  
  1103. int TPXFile :: GetFirstRecord()
  1104. {
  1105.   register b;
  1106.     
  1107.   b=pxrecfirst();
  1108.   if(b)
  1109.     return(b);
  1110.  
  1111.   b=pxrecget();
  1112.   if(b)
  1113.     return(b);
  1114.  
  1115.   b=pxrecnum();
  1116.   if(b)
  1117.     return(b);
  1118.  
  1119.   b=get_field_values();
  1120.   if(b)
  1121.     return(b);
  1122.  
  1123.   return(0);
  1124.  
  1125. }
  1126.  
  1127. //----------------------------------------------------------------------------
  1128.  
  1129. /*
  1130.     Step through the file
  1131. */
  1132.  
  1133. int TPXFile :: GetNextRecord()
  1134. {
  1135.   register b;
  1136.  
  1137.   b=pxrecnext();
  1138.   if(b)
  1139.     return(b);
  1140.  
  1141.   b=pxrecget();
  1142.   if(b)
  1143.     return(b);
  1144.  
  1145.   b=pxrecnum();
  1146.   if(b)
  1147.     return(b);
  1148.  
  1149.   b=get_field_values();
  1150.   if(b)
  1151.     return(b);
  1152.  
  1153.   return(0);
  1154.  
  1155. }
  1156.  
  1157. //----------------------------------------------------------------------------
  1158.  
  1159. /*
  1160.     Searching for a record combines alot of the techniques above with the abilty
  1161.     differentiate between a SEARCHFIRST, which loads the specified key fields into 
  1162.     the record buf so that the proper index is used and to selectively load the 
  1163.     matching records into the data_buf. The later is good for data validation
  1164.     without overlaying the data in the data_buf, but rather checking the exception
  1165.     code returned by the function.
  1166.   start_field is the statging index field to be used in the search.
  1167.     num_key_fields is the count, use 1 if using a secondary index.
  1168.     elist is the exception list.
  1169.     mode is SEARCHFIRST, SEARCHCLOSEST or SEARCHNEXT
  1170.     load_flag is LOAD_RECORDS or NO_LOAD_RECORDS depending on if you want to
  1171.     overlay the data in the data_buf.        
  1172. */
  1173.  
  1174. int TPXFile :: SearchRecord(char *fname, int num_key_fields, int *elist, int mode, char load_flag)
  1175. {
  1176.   register field_num, b;
  1177.  
  1178.   b=add_exceptions(elist);
  1179.   if(b)
  1180.     return(b);
  1181.  
  1182.     b=pxfldhandle(fname);
  1183.     if(b){
  1184.     free_exceptions();
  1185.     return(b);
  1186.   }
  1187.     
  1188.   if(mode!=SEARCHNEXT){
  1189.  
  1190.     b=put_field_values(field_handle,num_key_fields);
  1191.     if(b){
  1192.       free_exceptions();
  1193.       return(b);
  1194.     }
  1195.   }
  1196.  
  1197.   b=pxsrchkey(num_key_fields,mode);
  1198.   if(mode!=CLOSESTRECORD)
  1199.         if(b!=PXERR_RECNOTFOUND){
  1200.             b=check_exceptions(b);
  1201.             if(b){
  1202.                 free_exceptions();
  1203.                 return(b);
  1204.             }
  1205.         }
  1206.  
  1207.   if(load_flag==NO_LOAD_RECORDS){
  1208.     free_exceptions();
  1209.     return(0);
  1210.   }
  1211.  
  1212.   b=pxrecget();
  1213.   if(b){
  1214.     free_exceptions();
  1215.     return(b);
  1216.   }
  1217.  
  1218.   b=pxrecnum();
  1219.   if(b){
  1220.     free_exceptions();
  1221.     return(b);
  1222.   }
  1223.  
  1224.   b=get_field_values();
  1225.   if(b){
  1226.     free_exceptions();
  1227.     return(b);
  1228.   }
  1229.  
  1230.   return(0);
  1231.  
  1232. }
  1233.  
  1234. //----------------------------------------------------------------------------
  1235.  
  1236. /*
  1237.     What good is a file engine that cannot search for the last matching record?
  1238.     This function takes a subset of the SearchRecord args, since it can supply
  1239.     most of them itsself
  1240. */
  1241.  
  1242. int TPXFile :: SearchLastRecord(char *fname, int num_key_fields, char load_flag)
  1243. {
  1244.   register b;
  1245.   int list[]={PXERR_RECNOTFOUND,PXERR_TABLEEMPTY,NULL};
  1246.  
  1247.   b=SearchRecord(fname,num_key_fields,list,SEARCHFIRST,NO_LOAD_RECORDS);
  1248.   if(b)
  1249.     return(b);
  1250.  
  1251.   for(;;){
  1252.     b=pxsrchkey(num_key_fields,SEARCHNEXT);
  1253.     if(b)
  1254.       break;
  1255.   }
  1256.  
  1257.   if(b!=PXERR_RECNOTFOUND)
  1258.     return(b);
  1259.  
  1260.   b=pxrecnum();
  1261.   if(b)
  1262.     return(b);
  1263.  
  1264.   if(load_flag==NO_LOAD_RECORDS)
  1265.     return(0);
  1266.  
  1267.   b=pxrecget();
  1268.   if(b)
  1269.     return(b);
  1270.  
  1271.   b=get_field_values();
  1272.   if(b)
  1273.     return(b);
  1274.  
  1275.   return(0);
  1276. }
  1277.  
  1278. //----------------------------------------------------------------------------
  1279.  
  1280. /*
  1281.   Kind of like SearchRecord, but it uses no indexes. Insted you pass the
  1282.     name of the field you want to search on, the exception_list, a valid mode
  1283.   and a load flag, then wait...
  1284. */
  1285.  
  1286. int TPXFile :: FindRecord(char *fname, int *elist, int mode, char load_flag)
  1287. {
  1288.   register b;
  1289.     
  1290.   b=add_exceptions(elist);
  1291.   if(b)
  1292.     return(b);
  1293.  
  1294.     b=pxfldhandle(fname);
  1295.     if(b){
  1296.     free_exceptions();
  1297.     return(b);
  1298.   }
  1299.     
  1300.   if(mode!=SEARCHNEXT){
  1301.  
  1302.     b=put_field_values(field_handle,1);
  1303.     if(b){
  1304.       free_exceptions();
  1305.       return(b);
  1306.     }
  1307.   }
  1308.     
  1309.   b=pxsrchfld(mode);
  1310.   if(mode!=CLOSESTRECORD)
  1311.         if(b!=PXERR_RECNOTFOUND){
  1312.             b=check_exceptions(b);
  1313.             if(b){
  1314.                 free_exceptions();
  1315.                 return(b);
  1316.             }
  1317.         }
  1318.     
  1319.   b=pxrecnum();
  1320.   if(b){
  1321.     free_exceptions();
  1322.     return(b);
  1323.   }
  1324.  
  1325.   if(load_flag==NO_LOAD_RECORDS){
  1326.     free_exceptions();
  1327.     return(0);
  1328.   }
  1329.  
  1330.   b=pxrecget();
  1331.   if(b){
  1332.     free_exceptions();
  1333.     return(b);
  1334.   }
  1335.  
  1336.   b=pxrecnum();
  1337.   if(b){
  1338.     free_exceptions();
  1339.     return(b);
  1340.   }
  1341.  
  1342.   b=get_field_values();
  1343.   if(b){
  1344.     free_exceptions();
  1345.     return(b);
  1346.   }
  1347.  
  1348.   return(0);
  1349.  
  1350. }
  1351.  
  1352. //----------------------------------------------------------------------------
  1353.  
  1354. /*
  1355.     Like SearchLastRecord, but alot slower since it uses no index.
  1356. */
  1357.  
  1358. int TPXFile :: FindLastRecord(char *fname, char load_flag)
  1359. {
  1360.   register b;
  1361.   int list[]={PXERR_RECNOTFOUND,PXERR_TABLEEMPTY,NULL};
  1362.  
  1363.   b=FindRecord(fname,list,SEARCHFIRST,NO_LOAD_RECORDS);
  1364.   if(b)
  1365.     return(b);
  1366.  
  1367.   for(;;){
  1368.     b=pxsrchfld(fname,SEARCHNEXT);
  1369.     if(b)
  1370.       break;
  1371.   }
  1372.  
  1373.   if(b!=PXERR_RECNOTFOUND)
  1374.     return(b);
  1375.  
  1376.   b=pxrecnum();
  1377.   if(b)
  1378.     return(b);
  1379.  
  1380.   if(load_flag==NO_LOAD_RECORDS)
  1381.     return(0);
  1382.  
  1383.   b=pxrecget();
  1384.   if(b)
  1385.     return(b);
  1386.  
  1387.   b=get_field_values();
  1388.   if(b)
  1389.     return(b);
  1390.  
  1391.   return(0);
  1392. }
  1393.  
  1394. //----------------------------------------------------------------------------
  1395.  
  1396. /*
  1397.     Once you have loacted a record you can put the new values in the data_buf,
  1398.     your C struct, and call this func to write the new data. 
  1399. */
  1400.  
  1401. int TPXFile :: UpdateRecord()
  1402. {
  1403.   register b;
  1404.  
  1405.   b=put_field_values(1,0);
  1406.   if(b)
  1407.     return(b);
  1408.  
  1409.   b=pxrecupdate();
  1410.   if(b)
  1411.     return(b);
  1412.  
  1413.   return(0);
  1414.  
  1415. }
  1416.  
  1417. //----------------------------------------------------------------------------
  1418.  
  1419. /*
  1420.     Put the data into the data_bus, your C struct, and call this function.
  1421. */
  1422.  
  1423. int TPXFile :: InsertRecord()
  1424. {
  1425.   register b;
  1426.  
  1427.   b=put_field_values(1,0);
  1428.   if(b)
  1429.     return(b);
  1430.  
  1431.   b=pxrecinsert();
  1432.   if(b)
  1433.     return(b);
  1434.  
  1435.   b=pxrecnum();
  1436.   if(b)
  1437.     return(b);
  1438.  
  1439.   return(0);
  1440.  
  1441. }
  1442.  
  1443. //----------------------------------------------------------------------------
  1444.  
  1445. /*
  1446.     This is the driver for the automated functions used in this class. You
  1447.     pass this    function the starting field # to be moved from the data_buf 
  1448.     into the record buf and the number of fields from that point to follow.
  1449.     If nmu_fields is 0, then all fields will be moved from the data_buf,
  1450.     your C struct, into the PXAPI record buf.
  1451. */
  1452.  
  1453. int TPXFile :: put_field_values(int start_field, int num_fields)
  1454. {
  1455.   register a,b;
  1456.   int temp;
  1457.  
  1458.   if(!num_fields)
  1459.     num_fields=total_fields;
  1460.  
  1461.   for(a=1;a<start_field;a++){
  1462.     b=put_field_value(a-1,'N');
  1463.     if(b)
  1464.       return(b);        
  1465.   }
  1466.  
  1467.   for(;a<start_field+num_fields;a++){  
  1468.    b=put_field_value(a-1,'Y');
  1469.    if(b)
  1470.      return(b);
  1471.   }
  1472.  
  1473.   return(0);
  1474.  
  1475. }
  1476.  
  1477. //----------------------------------------------------------------------------
  1478.  
  1479. /*
  1480.     This private function actually parses the field type and decides how to 
  1481.     move the data from C structure to paradox record buffer, then updates
  1482.     internal pointers to the data_buf for the next read. The load flag is
  1483.     set to 'N' when the starting field is not the 1st field in the data_buf,
  1484.     and thusly the internal pointers need to be advanced to the proper point.
  1485.     The reason I mention this, is that this method cuold probably be rewritten
  1486.     to work alot better if I had time to think about it. Maybe you do...    
  1487. */
  1488.  
  1489. int TPXFile :: put_field_value(int field_number, char load_flag)
  1490. {
  1491.   register a,b;
  1492.   char field_type[6];
  1493.   int month, day, year;
  1494.   DATE date;
  1495.     short *sptr;
  1496.   double dval,
  1497.              *dptr;
  1498.   static int data_buf_offset;
  1499.  
  1500.   if(!field_number)
  1501.     data_buf_offset=0;
  1502.  
  1503.   field_handle=field_number+1;
  1504.  
  1505.   b=pxfldtype(field_type);
  1506.   if(b)
  1507.     return(b);
  1508.  
  1509.   a=field_type[0];
  1510.  
  1511.   b=0;
  1512.   switch(a){
  1513.     case 'A':
  1514.       a=atoi(field_type+1);
  1515.       if(!a)
  1516.         return(-1);
  1517.       if(load_flag=='Y')
  1518.         b=pxputalpha((char *)data_buf+data_buf_offset);
  1519.       data_buf_offset+=(a+1);
  1520.       break;
  1521.     case 'D':
  1522.       disassemble_date((char *)data_buf+data_buf_offset, &month, &day, &year);
  1523.       PXDateEncode(month, day, year, &date);
  1524.       if(load_flag=='Y')
  1525.         b=pxputdate(date);
  1526.       data_buf_offset+=9;
  1527.       break;
  1528.     case 'N':
  1529.     case '$':
  1530.       dptr=(double *)(data_buf+data_buf_offset);
  1531.             if(load_flag=='Y')
  1532.         b=pxputdouble(*dptr);
  1533.       data_buf_offset+=8;
  1534.       break;
  1535.     case 'S':
  1536.             sptr=(short *)data_buf+data_buf_offset;
  1537.       if(load_flag=='Y')
  1538.         b=pxputshort(*sptr);
  1539.       data_buf_offset+=2;
  1540.       break;
  1541.   }
  1542.  
  1543.   return(b);
  1544.  
  1545. }
  1546.  
  1547. //----------------------------------------------------------------------------
  1548.  
  1549. /*
  1550.   The reverse driver of the put functions
  1551. */
  1552.  
  1553. int TPXFile :: get_field_values()
  1554. {
  1555.   register a,b;
  1556.   int num_fields;
  1557.  
  1558.   for(a=0;a<total_fields;a++){
  1559.     b=get_field_value(a);
  1560.     if(b)
  1561.       return(b);
  1562.   }
  1563.  
  1564.   return(0);
  1565.  
  1566. }
  1567.  
  1568. //----------------------------------------------------------------------------
  1569.  
  1570. /*
  1571.     The reverse private function od the put function
  1572. */
  1573.  
  1574. int TPXFile :: get_field_value(int field_number)
  1575. {
  1576.   register a,b;
  1577.   char temp[80],
  1578.        field_type[6];
  1579.   int month, day, year;
  1580.     double *dptr;
  1581.   DATE date;
  1582.   static int data_buf_offset;
  1583.  
  1584.   if(!field_number)
  1585.     data_buf_offset=0;
  1586.  
  1587.   field_handle=field_number+1;
  1588.  
  1589.   b=pxfldtype(field_type);
  1590.   if(b)
  1591.     return(b);
  1592.  
  1593.   a=field_type[0];
  1594.  
  1595.   switch(a){
  1596.     case 'A':
  1597.       a=atoi(field_type+1);
  1598.       if(!a)
  1599.         return(-1);
  1600.       b=pxgetalpha(a+1,temp);
  1601.       setstrsz(temp,a);
  1602.       strcpy((char *)data_buf+data_buf_offset,temp);
  1603.       data_buf_offset+=(a+1);
  1604.       break;
  1605.     case 'D':
  1606.       b=pxgetdate(&date);
  1607.       b=PXDateDecode(date, &month, &day, &year);
  1608.       reassemble_date((char *)data_buf+data_buf_offset, month, day, year);
  1609.       data_buf_offset+=9;
  1610.       break;
  1611.     case 'N':
  1612.     case '$':
  1613.       dptr=(double *)(data_buf+data_buf_offset);
  1614.       b=pxgetdouble((double *)dptr);
  1615.       data_buf_offset+=8;
  1616.       break;
  1617.     case 'S':
  1618.       b=pxgetshort((short *)data_buf+data_buf_offset);
  1619.       data_buf_offset+=2;
  1620.       break;
  1621.   }
  1622.  
  1623.   return(b);
  1624.  
  1625. }
  1626.  
  1627. //----------------------------------------------------------------------------
  1628.  
  1629. /*
  1630.     Just point to a valid record and call this function.
  1631. */
  1632.  
  1633. int TPXFile :: DeleteRecord()
  1634. {
  1635.   register b;
  1636.  
  1637.   b=pxrecdelete();
  1638.   if(b)
  1639.     return(b);
  1640.  
  1641.   b=pxrecnum();
  1642.   if(b)
  1643.     return(b);
  1644.  
  1645.   b=get_field_values();
  1646.   if(b)
  1647.     return(b);
  1648.  
  1649.   return(0);
  1650.  
  1651. }
  1652.  
  1653. //----------------------------------------------------------------------------
  1654.  
  1655. /*
  1656.     Ok, this may or may not work. The idea is to delete all matching records
  1657.     based on a given key and its value. Nice in theory, easy to implement in
  1658.     this code. Haven't had the chance to test it out..
  1659. */
  1660.  
  1661. int TPXFile :: DeleteAllRecord(char *fname, int num_key_fields)
  1662. {
  1663.   register b;
  1664.   int list[]={PXERR_ENDOFTABLE,NULL};
  1665.  
  1666.   for(;;){
  1667.  
  1668.     b=pxrecdelete();
  1669.     if(b)
  1670.       return(b);
  1671.  
  1672.     SearchRecord(fname,num_key_fields,list,SEARCHNEXT,NO_LOAD_RECORDS);
  1673.     if(b)
  1674.       break;
  1675.  
  1676.   }
  1677.  
  1678.   b=pxrecnum();
  1679.   if(b)
  1680.     return(b);
  1681.  
  1682.   b=get_field_values();
  1683.   if(b)
  1684.     return(b);
  1685.  
  1686.   return(0);
  1687.  
  1688. }
  1689.  
  1690. //----------------------------------------------------------------------------
  1691.  
  1692. /*
  1693.   A quick function to get numeric vaues from a texttual date mm/dd/yyyy
  1694. */
  1695.  
  1696. void TPXFile :: disassemble_date(char *buf, int *month, int *day, int *year)
  1697. {
  1698.   char date[12];
  1699.  
  1700.   memset(date,0,12);
  1701.  
  1702.   strncpy(date,buf,2);
  1703.   strncpy(date+3,buf+2,2);
  1704.   strncpy(date+6,buf+4,2);
  1705.   strncpy(date+9,buf+6,2);
  1706.  
  1707.   *month=atoi(date);
  1708.   *day=atoi(date+3);
  1709.   *year=100*atoi(date+6);
  1710.   *year+=atoi(date+9);
  1711.  
  1712. }
  1713.  
  1714. //-----------------------------------------------------------------------------
  1715.  
  1716. /*
  1717.   And put it back together again, wee..
  1718. */
  1719.  
  1720. void TPXFile :: reassemble_date(char *buf, int month, int day, int year)
  1721. {
  1722.   sprintf(buf,"%2d/%2d/%2d",month,day,year);
  1723. }
  1724.  
  1725. //-----------------------------------------------------------------------------
  1726.  
  1727. /*
  1728.     There must be 100 better/faster ways to code this string padding routine, 
  1729.     but I'm not gonna do it..
  1730. */
  1731.  
  1732. void TPXFile :: setstrsz(char *buf, int size)
  1733. {
  1734.   register b;
  1735.     
  1736.     for(b=0;buf[b];b++);
  1737.     
  1738.     if(b<size)
  1739.         for(;b<size;b++)
  1740.             buf[b]=' ';
  1741.         
  1742.     buf[size]=0;
  1743.         
  1744. }
  1745.  
  1746. //-----------------------------------------------------------------------------
  1747.