home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (c) 1990 by Borland International, Inc. */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include "pxengine.h"
-
- /*
- * SORT.C
- * Simple example of using Paradox Engine to sort a database
- *
- * Description:
- * Reorders records in a Paradox database. The user has the option
- * to specify ascending or descending order and the field number on
- * which to sort.
- *
- * Compilation:
- * To compile and link the example program, make sure that your C compiler
- * has been correctly installed. Compile the program using the large
- * memory model specification:
- * Turbo C: Option -ml
- * Microsoft C: Option /AL
- *
- * Execution:
- * To run the example program enter the following command:
- * sort <Table Name> <Field To Sort Upon> <Non-0 For Ascending Sort>
- */
-
- #define SUCCESS 0
- #define FAIL -1
- #define SORTMAIN
-
- /* Function prototypes */
- char *TempTable(void);
- void Error(int rc);
- int DoSort(char *tblName,FIELDHANDLE fldHandle,int ascending);
- int CopyTableStruct(char *Src,char *Dest);
- int CheckKeyViol(char *tbl1,char *tbl2);
-
- /*
- ** DoSort(tblName,fldHandle,ascending);
- **
- ** Description:
- **
- ** Sorts records in a table on a given field in ascending
- ** or descending order.
- **
- ** Parameters:
- **
- ** tblName Table to be sorted
- **
- ** fldHandle Field on which table is to be sorted
- **
- ** ascending Non-zero if to be sorted in ascending order
- ** Zero if to be sorted in descending order
- **
- ** Return Value:
- **
- ** Returns SUCCESS if sort is completed with no errors
- ** Exits via call to Error() if sort is unsuccessful
- */
- int DoSort(char *tblName,FIELDHANDLE f,int ascending)
- {
- TABLEHANDLE src,dest;
- RECORDHANDLE rh1,rh2;
- char tempNameSrc[9],tempNameDest[9];
- int (pascal *NextElement)(TABLEHANDLE tblHandle);
- int (pascal *FirstElement)(TABLEHANDLE tblHandle);
-
- if (ascending)
- {
- NextElement = PXRecNext;
- FirstElement = PXRecFirst;
- }
- else
- {
- NextElement = PXRecPrev;
- FirstElement = PXRecLast;
- }
-
- /* Create temporary tables */
- strcpy(tempNameSrc,TempTable());
- strcpy(tempNameDest,TempTable());
- Error(PXTblCopy(tblName,tempNameSrc));
- Error(CopyTableStruct(tblName,tempNameDest));
-
- /* Sort source table and check for key violation */
- Error(PXKeyAdd(tempNameSrc,1,&f,PRIMARY));
- Error(PXKeyAdd(tempNameSrc,1,&f,SECONDARY));
- Error(CheckKeyViol(tempNameSrc,tblName));
-
- /* Copy KEYED source to HEAP dest table */
- Error(PXTblOpen(tempNameSrc,&src,f,0));
- Error(PXTblOpen(tempNameDest,&dest,0,0));
- Error(PXRecBufOpen(src,&rh1));
- Error(PXRecBufOpen(dest,&rh2));
-
- /* This loop does the actual sort */
- if (!FirstElement(src))
- {
- do
- {
- PXRecGet(src,rh1);
- PXRecBufCopy(rh1,rh2);
- PXRecAppend(dest,rh2);
- }
- while (!NextElement(src));
- Error(PXTblClose(dest));
- Error(PXTblRename(tempNameDest,tblName));
- }
-
- /* Free the buffers */
- PXRecBufClose(rh1);
- PXRecBufClose(rh2);
- PXTblClose(src);
- PXTblClose(dest);
-
- /* Clean up temporary tables */
- PXTblDelete(tempNameSrc);
- PXTblDelete(tempNameDest);
- return(SUCCESS);
- }
-
- /*
- ** int CheckKeyViol(char *tbl1,char *tbl2);
- **
- ** Description:
- **
- ** Compares the number of records in two tables
- **
- ** Parameters:
- **
- ** tbl1 and tbl2 are strings containing the names of two tables
- **
- ** Return Value:
- **
- ** Returns PXSUCCESS if number of records are equal
- ** Returns PXERR_KEYVIOL if number of records are unequal
- **
- */
-
- CheckKeyViol(char *tbl1,char *tbl2)
- {
- TABLEHANDLE tblHandle1, tblHandle2;
- RECORDNUMBER recNum1, recNum2;
-
- Error(PXTblOpen(tbl1,&tblHandle1,0,0));
- Error(PXTblOpen(tbl2,&tblHandle2,0,0));
- Error(PXTblNRecs(tblHandle1,&recNum1));
- Error(PXTblNRecs(tblHandle2,&recNum2));
- Error(PXTblClose(tblHandle1));
- Error(PXTblClose(tblHandle2));
- if (recNum1 != recNum2)
- return PXERR_KEYVIOL;
- else
- return PXSUCCESS;
- }
-
- /*
- ** int CopyTableStruct(char *Src,char *Dest);
- **
- ** Description:
- **
- ** Copies the structure of one table to another
- **
- ** Parameters:
- **
- ** Src Table name from which to get structure
- **
- ** Dest Table name to receive Src structure
- **
- ** Return Value:
- **
- ** Returns SUCCESS if structure is copied with no errors
- ** Exits via call to Error() copy is unsuccessful
- **
- */
- int CopyTableStruct(char *Src,char *Dest)
- {
- TABLEHANDLE tblHandle;
- char **types,**fields;
- int i,NFlds;
- char buf[BUFSIZ];
-
- Error(PXTblOpen(Src,&tblHandle,0,0));
- Error(PXRecNFlds(tblHandle,&NFlds));
- types = (char **) malloc(NFlds * sizeof(char*));
- fields = (char **) malloc(NFlds * sizeof(char*));
- if (types == NULL || fields == NULL)
- {
- printf("Not enough memory\n");
- PXExit();
- exit(FAIL);
- }
-
- for (i=0;i<NFlds;++i)
- {
- PXFldName(tblHandle,i+1,BUFSIZ,buf);
- fields[i] = strdup(buf);
- PXFldType(tblHandle,i+1,BUFSIZ,buf);
- types[i] = strdup(buf);
- }
- Error(PXTblCreate(Dest,NFlds,fields,types));
- for (i=0;i<NFlds;++i)
- {
- free(fields[i]);
- free(types[i]);
- }
- free(fields);
- free(types);
- Error(PXTblClose(tblHandle));
- return(SUCCESS);
- }
-
-
-
- /*
- ** void Error(int rc);
- **
- ** Description:
- **
- ** Checks given return code from a PX function to see if
- ** an error has occurred. On error, a message is printed
- ** and the program terminates. On success, Error returns.
- **
- ** Parameters:
- **
- ** rc Return code from PX function
- **
- ** Return Value:
- **
- ** Returns nothing
- **
- */
- void Error(int rc)
- {
- if (rc != PXSUCCESS) {
- printf("Error: %s\n",PXErrMsg(rc));
- PXExit();
- exit(FAIL);
- }
- }
-
- /*
- ** char *TempTable(void);
- **
- ** Description:
- **
- ** Generates a unique table name
- **
- ** Parameters:
- **
- ** None
- **
- ** Return Value:
- **
- ** Character pointer to a unique table name
- **
- */
- char *TempTable()
- {
- static int i = 0;
- int exist = 1;
- static char buf[9];
-
- while (exist && i++ < 10000)
- {
- sprintf(buf,"t%d",i);
- PXTblExist(buf,&exist);
- }
- return(buf);
- }
-
- #ifdef SORTMAIN
- #define TABLE argv[1]
- #define FLDHANDLE atoi(argv[2])
- #define ASCENDING atoi(argv[3])
- int main(int argc,char *argv[])
- {
-
- if (argc != 4)
- {
- printf("Usage: Sort <Table Name> <Field To Sort Upon> <Non-0 For Ascending Sort>\n");
- exit(SUCCESS);
- }
- Error(PXInit());
- DoSort(TABLE,FLDHANDLE,ASCENDING);
- Error(PXExit());
- return(SUCCESS);
- }
-
- #endif
-
-
-