// BDE - (C) Copyright 1995 by Borland International // prdxsort.c #include "snipit.h" // Default length of the mapped fields #define NAMELEN 30 static const char szTblName[] = "vendors"; static const char szSortedTblName[] = "SortVend"; static const char szTblType[] = "PARADOX"; // Field descriptor used in mapping the fields of the table. // Used in order to display the fields in the order that they // are sorted: 'State/Prov' and 'Street'. The 'Vendor Name' is // included as additional information. // See the fieldmap.c file for a description of field mapping static SNIPFAR FLDDesc FldDescs1[] = { { 1, // Field number "State/Prov", // Field name fldZSTRING, // Field type fldUNKNOWN, // Field subtype NAMELEN, // Field size (1 or 0, except // BLOB or CHAR field) 0, // Decimal places ( 0 ) // computed 0, // Offset in record ( 0 ) 0, // Length in bytes ( 0 ) 0, // For NULL Bits ( 0 ) fldvNOCHECKS, // Validiy checks ( 0 ) fldrREADWRITE // Rights }, { 2, "Street", fldZSTRING, fldUNKNOWN, NAMELEN, 0, 0, 0, 0, fldvNOCHECKS, fldrREADWRITE }, { 3, "Vendor Name", fldZSTRING, fldUNKNOWN, NAMELEN, 0, 0, 0, 0, fldvNOCHECKS, fldrREADWRITE } }; // FldDescs1. INT16 DBIFN StreetCompare(pVOID pLdObj, pVOID pValue1, pVOID pValue2, INT16 iLen); pCHAR DBIFN FindFirstChar(const char *pszString); //===================================================================== // Function: // ParadoxSort(); // // Description: // This example shows how to sort on a field in a PARADOX // table. The example will use the DbiSortTable() function. //===================================================================== void ParadoxSort (void) { hDBIDb hDb; // Handle to the database hDBICur hCur; // Handle to the table hDBICur hSortCur; // Handle to the sorted table UINT16 uSortFields[] = { 5, 3 }; // Which fields to sort BOOL bCaseIns[] = { FALSE, FALSE}; SORTOrder SortOrder[] = { sortASCEND, sortASCEND }; pfSORTCompFn pfSortFn[] = { NULL, StreetCompare }; UINT16 NOSRTFLDS; // Number of fields to sort UINT32 uNumToSort = 10;// Number of record to display UINT16 uNumFields; // Number of fields in the table DBIResult rslt; // Return value from IDAPI functions Screen("*** Sorting Example ***\r\n"); BREAK_IN_DEBUGGER(); Screen(" Initializing IDAPI..."); if (InitAndConnect(&hDb) != DBIERR_NONE) { Screen("\r\n*** End of Example ***"); return; } Screen(" Setting the database directory..."); rslt = DbiSetDirectory(hDb, (pCHAR) szTblDirectory); ChkRslt(rslt, "SetDirectory"); Screen(" Open the %s table...", szTblName); rslt = DbiOpenTable(hDb, (pCHAR) szTblName, (pCHAR) szTblType, NULL, NULL, 0, dbiREADWRITE, dbiOPENSHARED, xltFIELD, FALSE, NULL, &hCur); if (ChkRslt(rslt, "OpenTable") != DBIERR_NONE) { CloseDbAndExit(&hDb); Screen("\r\n*** End of Example ***"); return; } rslt = DbiSetToBegin(hCur); ChkRslt(rslt, "SetToBegin"); Screen(" Display the unsorted %s table...", szTblName); DisplayTable(hCur, uNumToSort); Screen("\r\n Sort the %s table, using first the 'State/Prov'" " field,", szTblName); Screen(" and then the 'Street' field. The sorted" " records are saved in the %s table", szSortedTblName); // Number of sort fields on which to sort the table. NOSRTFLDS = sizeof(uSortFields) / sizeof(uSortFields[0]); rslt = DbiSortTable(hDb, (pCHAR) szTblName, (pCHAR) szTblType, 0, (pCHAR) szSortedTblName, NULL, 0, NOSRTFLDS, uSortFields, bCaseIns, SortOrder, pfSortFn, FALSE, NULL, &uNumToSort); if (ChkRslt(rslt, "SortTable") != DBIERR_NONE) { rslt = DbiDeleteTable(hDb, (pCHAR) szSortedTblName, (pCHAR) szTblType); ChkRslt(rslt, "DeleteTable"); CloseDbAndExit(&hDb); Screen("\r\n*** End of Example ***"); return; } Screen(" Open the %s sorted table...", szSortedTblName); rslt = DbiOpenTable(hDb, (pCHAR) szSortedTblName, (pCHAR) szTblType, NULL, NULL, 0, dbiREADWRITE, dbiOPENSHARED, xltFIELD, FALSE, NULL, &hSortCur); if (ChkRslt(rslt, "OpenTable") != DBIERR_NONE) { rslt = DbiDeleteTable(hDb, (pCHAR) szSortedTblName, (pCHAR) szTblType); ChkRslt(rslt, "DeleteTable"); CloseDbAndExit(&hDb); Screen("\r\n*** End of Example ***"); return; } Screen(" Change which fields of the table are displayed:" "\r\n 'State/Prov', 'Street', and 'Vendor Name'"); // Determine the number of fields that are part of the descriptor. uNumFields = sizeof(FldDescs1) / sizeof (FldDescs1[0]); // Set the field mapping. rslt = DbiSetFieldMap(hSortCur, uNumFields, FldDescs1); ChkRslt(rslt, "SetFieldMap"); rslt = DbiSetToBegin(hSortCur); ChkRslt(rslt, "SetToBegin"); Screen(" Display the %s sorted table...", szSortedTblName); DisplayTable(hSortCur, uNumToSort); Screen("\r\n Close the %s original table...", szTblName); rslt = DbiCloseCursor(&hCur); ChkRslt(rslt, "CloseCursor"); Screen(" Close the %s sorted table...", szSortedTblName); rslt = DbiCloseCursor(&hSortCur); ChkRslt(rslt, "CloseCursor"); Screen(" Delete the %s sorted table...", szSortedTblName); rslt = DbiDeleteTable(hDb, (pCHAR) szSortedTblName, (pCHAR) szTblType); ChkRslt(rslt, "DeleteTable"); Screen(" Close the database and exit IDAPI..."); CloseDbAndExit(&hDb); Screen("\r\n*** End of Example ***"); } //===================================================================== // Function: // StreetCompare(pLdObj, pValue1, pValue2, iLen); // // Input: // pLdObj - Language driver, not used // pValue1 - First value to compare // pValue2 - Second value to compare // iLen - Length, not used // // Return: -1 if (pValue1 < pValue2) // 0 if (pValue1 == pValue2) // 1 if (pValue1 > pValue2) // // Description: // This function is used in comparing the 'Street' // field of the vendor table. This function will // sort according to the street name, not the address. //===================================================================== INT16 DBIFN StreetCompare (pVOID pLdObj, pVOID pValue1, pVOID pValue2, INT16 iLen) { INT16 rslt; // Value returned from IDAPI functions pCHAR szOne; // First value to compare pCHAR szTwo; // Second value to compare // Dummy assignments to avoid warnings. iLen = iLen; pLdObj = pLdObj; // Skip leading numeric values - used to skip the house number // portion of the street address. szOne = FindFirstChar((const char *)pValue1); szTwo = FindFirstChar((const char *)pValue2); // Compare the values in the 'Street' field, starting the // strings at the first non-numeric character - sort on // Street name, not the house number on a given street. rslt = strcmp(szOne, szTwo); // If on the same street (pValue1 == pValue2), // compare House Number on the street. if (rslt == DBIERR_NONE) { rslt = strcmp((pCHAR)pValue1, (pCHAR)pValue2); } if (0 < rslt) { rslt = 1; } if (rslt < 0) { rslt = -1; } return rslt; } //===================================================================== // Code: FindFirstChar(pszString); // // Input: pszString - String to search // // Return: Pointer to the location in the string after the house // number // // Description: // This function is used to skip the house number part // of the street address when sorting the table. This // allows the 'Street' field to be sorted according to // the street name. //===================================================================== pCHAR DBIFN FindFirstChar (const char *pszString) { UINT16 uWhere = 0; // Counter to keep track of the current character // within the string // Search for the first blank as part of the string - // this should be the start of the street name. while ((pszString[uWhere] != 0) && (pszString[uWhere] != ' ')) { uWhere++; } // Return the character after the space return (pCHAR)&(pszString[uWhere+1]); }