home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 5 / 05.iso / a / a006 / 1.ddi / CSAMP.ZIP / SORT.C < prev   
Encoding:
C/C++ Source or Header  |  1991-03-11  |  6.8 KB  |  295 lines

  1. /*       Copyright (c) 1990 by Borland International, Inc.        */
  2.  
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include "pxengine.h"
  7.  
  8. /*
  9.  * SORT.C
  10.  *   Simple example of using Paradox Engine to sort a database
  11.  *
  12.  * Description:
  13.  *   Reorders records in a Paradox database.  The user has the option
  14.  *   to specify ascending or descending order and the field number on
  15.  *   which to sort.
  16.  *
  17.  * Compilation:
  18.  *   To compile and link the example program, make sure that your C compiler
  19.  *   has been correctly installed.  Compile the program using the large
  20.  *   memory model specification:
  21.  *     Turbo C:     Option -ml
  22.  *     Microsoft C: Option /AL
  23.  *
  24.  * Execution:
  25.  *   To run the example program enter the following command:
  26.  *     sort <Table Name> <Field To Sort Upon> <Non-0 For Ascending Sort>
  27.  */
  28.  
  29. #define SUCCESS         0
  30. #define FAIL           -1
  31. #define SORTMAIN
  32.  
  33. /* Function prototypes */
  34. char *TempTable(void);
  35. void Error(int rc);
  36. int DoSort(char *tblName,FIELDHANDLE fldHandle,int ascending);
  37. int CopyTableStruct(char *Src,char *Dest);
  38. int CheckKeyViol(char *tbl1,char *tbl2);
  39.  
  40. /*
  41. **    DoSort(tblName,fldHandle,ascending);
  42. **
  43. **    Description:
  44. **
  45. **        Sorts records in a table on a given field in ascending
  46. **        or descending order.
  47. **
  48. **    Parameters:
  49. **
  50. **        tblName                 Table to be sorted
  51. **
  52. **        fldHandle               Field on which table is to be sorted
  53. **
  54. **        ascending               Non-zero if to be sorted in ascending order
  55. **                                Zero if to be sorted in descending order
  56. **
  57. **    Return Value:
  58. **
  59. **        Returns SUCCESS if sort is completed with no errors
  60. **        Exits via call to Error() if sort is unsuccessful
  61. */
  62. int DoSort(char *tblName,FIELDHANDLE f,int ascending)
  63. {
  64.   TABLEHANDLE src,dest;
  65.   RECORDHANDLE rh1,rh2;
  66.   char tempNameSrc[9],tempNameDest[9];
  67.   int (pascal *NextElement)(TABLEHANDLE tblHandle);
  68.   int (pascal *FirstElement)(TABLEHANDLE tblHandle);
  69.  
  70.   if (ascending)
  71.   {
  72.     NextElement = PXRecNext;
  73.     FirstElement = PXRecFirst;
  74.   }
  75.   else
  76.   {
  77.     NextElement = PXRecPrev;
  78.     FirstElement = PXRecLast;
  79.   }
  80.  
  81.   /* Create temporary tables */
  82.   strcpy(tempNameSrc,TempTable());
  83.   strcpy(tempNameDest,TempTable());
  84.   Error(PXTblCopy(tblName,tempNameSrc));
  85.   Error(CopyTableStruct(tblName,tempNameDest));
  86.  
  87.   /* Sort source table and check for key violation */
  88.   Error(PXKeyAdd(tempNameSrc,1,&f,PRIMARY));
  89.   Error(PXKeyAdd(tempNameSrc,1,&f,SECONDARY));
  90.   Error(CheckKeyViol(tempNameSrc,tblName));
  91.  
  92.   /* Copy KEYED source to HEAP dest table */
  93.   Error(PXTblOpen(tempNameSrc,&src,f,0));
  94.   Error(PXTblOpen(tempNameDest,&dest,0,0));
  95.   Error(PXRecBufOpen(src,&rh1));
  96.   Error(PXRecBufOpen(dest,&rh2));
  97.  
  98.   /* This loop does the actual sort */
  99.   if (!FirstElement(src))
  100.   {
  101.     do
  102.     {
  103.       PXRecGet(src,rh1);
  104.       PXRecBufCopy(rh1,rh2);
  105.       PXRecAppend(dest,rh2);
  106.     }
  107.     while (!NextElement(src));
  108.     Error(PXTblClose(dest));
  109.     Error(PXTblRename(tempNameDest,tblName));
  110.   }
  111.  
  112. /* Free the buffers */
  113.   PXRecBufClose(rh1);
  114.   PXRecBufClose(rh2);
  115.   PXTblClose(src);
  116.   PXTblClose(dest);
  117.  
  118. /* Clean up temporary tables */
  119.   PXTblDelete(tempNameSrc);
  120.   PXTblDelete(tempNameDest);
  121.   return(SUCCESS);
  122. }
  123.  
  124. /*
  125. **    int CheckKeyViol(char *tbl1,char *tbl2);
  126. **
  127. **    Description:
  128. **
  129. **        Compares the number of records in two tables
  130. **
  131. **    Parameters:
  132. **
  133. **        tbl1 and tbl2 are strings containing the names of two tables
  134. **
  135. **    Return Value:
  136. **
  137. **        Returns PXSUCCESS if number of records are equal
  138. **        Returns PXERR_KEYVIOL if number of records are unequal
  139. **
  140. */
  141.  
  142. CheckKeyViol(char *tbl1,char *tbl2)
  143. {
  144.     TABLEHANDLE tblHandle1, tblHandle2;
  145.     RECORDNUMBER recNum1, recNum2;
  146.  
  147.     Error(PXTblOpen(tbl1,&tblHandle1,0,0));
  148.     Error(PXTblOpen(tbl2,&tblHandle2,0,0));
  149.     Error(PXTblNRecs(tblHandle1,&recNum1));
  150.     Error(PXTblNRecs(tblHandle2,&recNum2));
  151.     Error(PXTblClose(tblHandle1));
  152.     Error(PXTblClose(tblHandle2));
  153.     if (recNum1 != recNum2)
  154.       return PXERR_KEYVIOL;
  155.     else
  156.       return PXSUCCESS;
  157. }
  158.  
  159. /*
  160. **    int CopyTableStruct(char *Src,char *Dest);
  161. **
  162. **    Description:
  163. **
  164. **        Copies the structure of one table to another
  165. **
  166. **    Parameters:
  167. **
  168. **        Src                   Table name from which to get structure
  169. **
  170. **        Dest                  Table name to receive Src structure
  171. **
  172. **    Return Value:
  173. **
  174. **        Returns SUCCESS if structure is copied with no errors
  175. **        Exits via call to Error() copy is unsuccessful
  176. **
  177. */
  178. int CopyTableStruct(char *Src,char *Dest)
  179. {
  180.   TABLEHANDLE tblHandle;
  181.   char **types,**fields;
  182.   int i,NFlds;
  183.   char buf[BUFSIZ];
  184.  
  185.   Error(PXTblOpen(Src,&tblHandle,0,0));
  186.   Error(PXRecNFlds(tblHandle,&NFlds));
  187.   types = (char **) malloc(NFlds * sizeof(char*));
  188.   fields = (char **) malloc(NFlds * sizeof(char*));
  189.   if (types == NULL || fields == NULL)
  190.       {
  191.         printf("Not enough memory\n");
  192.         PXExit();
  193.         exit(FAIL);
  194.       }
  195.  
  196.   for (i=0;i<NFlds;++i)
  197.       {
  198.         PXFldName(tblHandle,i+1,BUFSIZ,buf);
  199.         fields[i] = strdup(buf);
  200.         PXFldType(tblHandle,i+1,BUFSIZ,buf);
  201.         types[i] = strdup(buf);
  202.       }
  203.   Error(PXTblCreate(Dest,NFlds,fields,types));
  204.   for (i=0;i<NFlds;++i)
  205.       {
  206.         free(fields[i]);
  207.         free(types[i]);
  208.       }
  209.   free(fields);
  210.   free(types);
  211.   Error(PXTblClose(tblHandle));
  212.   return(SUCCESS);
  213. }
  214.  
  215.  
  216.  
  217. /*
  218. **    void Error(int rc);
  219. **
  220. **    Description:
  221. **
  222. **        Checks given return code from a PX function to see if
  223. **        an error has occurred.  On error, a message is printed
  224. **        and the program terminates.  On success, Error returns.
  225. **
  226. **    Parameters:
  227. **
  228. **        rc                      Return code from PX function
  229. **
  230. **    Return Value:
  231. **
  232. **        Returns nothing
  233. **
  234. */
  235. void Error(int rc)
  236. {
  237.   if (rc != PXSUCCESS) {
  238.     printf("Error: %s\n",PXErrMsg(rc));
  239.     PXExit();
  240.     exit(FAIL);
  241.   }
  242. }
  243.  
  244. /*
  245. **    char *TempTable(void);
  246. **
  247. **    Description:
  248. **
  249. **        Generates a unique table name
  250. **
  251. **    Parameters:
  252. **
  253. **        None
  254. **
  255. **    Return Value:
  256. **
  257. **        Character pointer to a unique table name
  258. **
  259. */
  260. char *TempTable()
  261. {
  262.   static int i = 0;
  263.   int exist = 1;
  264.   static char buf[9];
  265.  
  266.   while (exist && i++ < 10000)
  267.   {
  268.     sprintf(buf,"t%d",i);
  269.     PXTblExist(buf,&exist);
  270.   }
  271.   return(buf);
  272. }
  273.  
  274. #ifdef SORTMAIN
  275. #define TABLE argv[1]
  276. #define FLDHANDLE atoi(argv[2])
  277. #define ASCENDING atoi(argv[3])
  278. int main(int argc,char *argv[])
  279. {
  280.  
  281.   if (argc != 4)
  282.   {
  283.     printf("Usage:  Sort <Table Name> <Field To Sort Upon> <Non-0 For Ascending Sort>\n");
  284.     exit(SUCCESS);
  285.   }
  286.   Error(PXInit());
  287.   DoSort(TABLE,FLDHANDLE,ASCENDING);
  288.   Error(PXExit());
  289.   return(SUCCESS);
  290. }
  291.  
  292. #endif
  293.  
  294.  
  295.