// BDE - (C) Copyright 1994 by Borland International #include "query.h" static DBIResult SetupFields(CURProps TblProps, pFLDDesc pFldDescs, CHAR** pszField, UINT16 uDefLength); static DBIResult GetFields(hDBICur hCur, pFLDDesc pFldDescs, pBYTE pRecBuf, CHAR** pszField, UINT16 uDefLength); static DBIResult FormatDate(DATE Date, pCHAR szDate); static DBIResult FormatTime(TIME Time, pCHAR szDate); static DBIResult FormatTimeStamp(TIMESTAMP TimeStamp, pCHAR szTime); #define MAXLEN 50 //=============================================================== // Name: Cls(pStr); // // Input: None // // Return: None // // Description: // Clears the Result Edit control. //================================================================ void Cls (void) { SendDlgItemMessage(hMainWnd, IDC_RESULT_EDIT, WM_SETTEXT, 0, (LPARAM)(LPCSTR)""); } //=============================================================== // Function: // Screen(pszMsg); // // Input: pszMsg - String to display // // Return: None // // Description: // Echo a message. //=============================================================== void Screen (pCHAR pszMsg) { pCHAR pszBuf; if (pszMsg) { // Dump the string and output a CR+LF. pszBuf = (pCHAR) malloc(lstrlen(pszMsg) + 3); wsprintf(pszBuf, "%s\r\n", pszMsg); SendDlgItemMessage(hMainWnd, IDC_RESULT_EDIT, EM_REPLACESEL, 0, (LPARAM)(LPCSTR)pszBuf); free(pszBuf); } } //============================================================== // Function: // ChkRslt(rslt, pMsg); // // Input: rslt - Return code from IDAPI // pMsg - Null terminated message // // Return: IDAPI return code passed in // // Description: // This will echo an error message if the expected // result does not equal the actual result. The output will be // echoed to the screen. //=============================================================== DBIResult ChkRslt (DBIResult rslt, pCHAR pMsg) { static CHAR szOutputErrorString[(DBIMAXMSGLEN * 6) + 81]; // Echo only if actual result doesn't equal expected result. if (rslt != DBIERR_NONE) { // Get as much error information as possible. GetErrorInformation(szOutputErrorString); Screen(szOutputErrorString); sprintf(szOutputErrorString, " Function: %s", pMsg); } return rslt; } //===================================================================== // Function: // DisplayTable(); // // Input: The cursor handle - which table to access // DisplayNRecs - How many records to display // - 0 = all records in the table // // Return: Result of displaying the records in the table // // Descrption: // This function will display all records in the table referenced // by the cursor. This function is used to display // in-memory and scema tables which do not support // the use of ReadBlock ( which is used in DislpayTable ) // // Note: This function will only display the columns // correctly when using a fixed pitch font. //===================================================================== DBIResult DisplayTable (hDBICur hCur, UINT32 uDisplayNRecs) { DBIResult rslt; // IDAPI function return value CURProps TblProps; // Table Properties pFLDDesc pFldDescs; // List of fields pBYTE pRecBuf; // Record Buffer CHAR** pszField; // Array to contain the fields of the // table. CHAR szFormat[1600] =""; // Contains an entire record (row) CHAR szTemp[MAXLEN] =""; // Temporary variable for reading data UINT16 uFldNum; // Loop variable UINT32 uCurCountRec=0; // Counter to keep track of how many // records have been displayed const UINT16 uDefLength = 15; // Default size of a field if ((rslt = DBIErr(DbiGetCursorProps(hCur, &TblProps))) != DBIERR_NONE) { return rslt; } // Allocate space for the Record Buffer. if((pRecBuf = (pBYTE) malloc(TblProps.iRecBufSize * sizeof(BYTE))) == NULL) { return DBIERR_NOMEMORY; } // Allocate enough space to contain information (Field Descriptors) // about all the fields in the answer table. if ((pFldDescs = (pFLDDesc)malloc(TblProps.iFields * sizeof(FLDDesc))) == NULL) { free(pRecBuf); return DBIERR_NOMEMORY; } // Get information about the fields. DBIErr(DbiGetFieldDescs(hCur, pFldDescs)); // Allocate enough buffers to contain data from the fields in the // answer table. Also sets the width of non-fldZSTRING fields // (all data will be converted to Strings for display ). if ((pszField = (CHAR**)malloc(TblProps.iFields * sizeof(CHAR*))) == NULL) { free(pRecBuf); free(pFldDescs); return DBIERR_NOMEMORY; } // Set up formatting for the fields. SetupFields(TblProps, pFldDescs, pszField, uDefLength); // Display the names of the fields, aligned by column. strcpy(szFormat,"\r\n "); for (uFldNum = 0; uFldNum < TblProps.iFields; uFldNum++) { sprintf(szTemp, "%-*s\t", pFldDescs[uFldNum].iUnits1 + 1, pFldDescs[uFldNum].szName); strcat(szFormat, szTemp); } // Display the header. Screen(szFormat); // Get records from the table until the end of the table is reached // or the maximum number of records is reached. // Note that not all field types are supported. All supported field // types are displayed as Strings. if (uDisplayNRecs == 0) { uDisplayNRecs = (UINT16)-1; // uDisplayNRecs is unsigned, so // -1 maximizes the value. } while ((uCurCountRec < uDisplayNRecs) && ((rslt = DbiGetNextRecord(hCur, dbiNOLOCK, pRecBuf, NULL)) == DBIERR_NONE)) { uCurCountRec++; // Fill the Record buffer with the field values. GetFields(hCur, pFldDescs, pRecBuf, pszField, uDefLength); // Initialize szFormat to all zero's. memset(szFormat, 0, sizeof(szFormat)); // Add leading blank space to the record. strcpy(szFormat," "); // Add each field to be displayed, making certain that the // columns line up. for (uFldNum = 0; uFldNum < TblProps.iFields; uFldNum++) { sprintf(szTemp, " %-*s\t", pFldDescs[uFldNum].iUnits1, pszField[uFldNum]); strcat(szFormat, szTemp); } // Display the record. Screen(szFormat); } // Expect the End-Of-File error - just means that there // aren't any more records in the table. if (rslt == DBIERR_EOF) { rslt = DBIERR_NONE; } // Clean up. for (uFldNum = 0; uFldNum < TblProps.iFields; uFldNum++) { free(pszField[uFldNum]); } free(pszField); free(pFldDescs); free(pRecBuf); return rslt; } //===================================================================== // Function: // GetFields(hCur, pFldDescs, pRecBuf, pszField, uDefLength) // // Input: hCur - Handle to the Cursor // pFldDescs - Field Descriptor // pRecBuf - Record buffer - contains the record from // which the field values are to be retrieved. // pszField - Fields in the table // uDefLength - Default length of a field // // Return: Success of the operation. // // Description: // This function is used to extract all field values from // a record and place them into an array of Strings. //===================================================================== DBIResult GetFields (hDBICur hCur, pFLDDesc pFldDescs, pBYTE pRecBuf, CHAR **pszField, UINT16 uDefLength) { DBIResult rslt; // Return value from IDAPI functions CURProps TblProps; // Properties of the table UINT16 uFldNum; // Loop Counter - used to determine the // current field. CHAR szTemp[MAXLEN] =""; // Temporary variable for reading data UINT32 ulBlobSize; // Size of the BLOB FLOAT lfFloat; // Float variable BOOL bIsBlank; // Check if the field is blank UINT16 uTmpLen; if ((rslt = DBIErr(DbiGetCursorProps(hCur, &TblProps))) != DBIERR_NONE) { return rslt; } // Get the field values from the record. Gets each field from // the table, placing the results in the pszField variable. for (uFldNum = 0; uFldNum < TblProps.iFields; uFldNum++) { switch (pFldDescs[uFldNum].iFldType) { case fldBYTES: case fldZSTRING: DBIErr(DbiGetField(hCur, uFldNum+1, pRecBuf, (pBYTE)pszField[uFldNum], &bIsBlank)); uTmpLen = pFldDescs[uFldNum].iLen - 1; pszField[uFldNum][uTmpLen] = 0; break; case fldFLOAT: DBIErr(DbiGetField(hCur, uFldNum+1, pRecBuf, (pBYTE)szTemp, &bIsBlank)); if (!bIsBlank) { if (pFldDescs[uFldNum].iSubType == fldstMONEY) { sprintf(pszField[uFldNum], "$%.2lf", *(FLOAT *)szTemp); } else { sprintf(pszField[uFldNum], "%.1lf", *(FLOAT *)szTemp); } } break; case fldBCD: DBIErr(DbiGetField(hCur, uFldNum+1, pRecBuf, (pBYTE)szTemp, &bIsBlank)); if (!bIsBlank) { DBIErr(DbiBcdToFloat((FMTBcd *)szTemp, &lfFloat)); sprintf(pszField[uFldNum], "%.*lf", pFldDescs[uFldNum].iUnits2, lfFloat); } break; case fldDATE: DBIErr(DbiGetField(hCur, uFldNum+1, pRecBuf, (pBYTE)szTemp, &bIsBlank)); if (!bIsBlank) { // Format the date. FormatDate defined in // SNIPTOOL.C. FormatDate(*(DATE *)szTemp, pszField[uFldNum]); } break; case fldTIME: DBIErr(DbiGetField(hCur, uFldNum+1, pRecBuf, (pBYTE)&szTemp, &bIsBlank)); if (!bIsBlank) { FormatTime(*(TIME *)szTemp, pszField[uFldNum]); } break; case fldTIMESTAMP: DBIErr(DbiGetField(hCur, uFldNum+1, pRecBuf, (pBYTE)szTemp, &bIsBlank)); if (!bIsBlank) { FormatTimeStamp(*(TIMESTAMP *)szTemp, pszField[uFldNum]); } break; case fldINT16: DBIErr(DbiGetField(hCur, uFldNum+1, pRecBuf, (pBYTE)szTemp, &bIsBlank)); if (!bIsBlank) { sprintf(pszField[uFldNum], "%d", *(FLOAT *)szTemp); } break; case fldUINT16: DBIErr(DbiGetField(hCur, uFldNum+1, pRecBuf, (pBYTE)szTemp, &bIsBlank)); if (!bIsBlank) { sprintf(pszField[uFldNum], "%u", *(FLOAT *)szTemp); } break; case fldINT32: DBIErr(DbiGetField(hCur, uFldNum+1, pRecBuf, (pBYTE)szTemp, &bIsBlank)); if (!bIsBlank) { sprintf(pszField[uFldNum], "%ld", *(INT32 *)szTemp); } break; case fldUINT32: DBIErr(DbiGetField(hCur, uFldNum+1, pRecBuf, (pBYTE)szTemp, &bIsBlank)); if (!bIsBlank) { sprintf(pszField[uFldNum], "%lu", *(UINT32 *)szTemp); } break; case fldBOOL: DBIErr(DbiGetField(hCur, uFldNum+1, pRecBuf, (pBYTE)szTemp, &bIsBlank)); if (!bIsBlank) { if (*(BOOL*)szTemp == 0) { strcpy(pszField[uFldNum], "No"); } else { strcpy(pszField[uFldNum], "Yes"); } } break; case fldBLOB: // Display the first uDefLength characters of // Memo BLOB fields. if (pFldDescs[uFldNum].iSubType == fldstMEMO) { DBIErr(DbiOpenBlob(hCur, pRecBuf, uFldNum + 1, dbiREADONLY)); // Determine the size of the BLOB. DBIErr(DbiGetBlobSize(hCur, pRecBuf, uFldNum + 1, &ulBlobSize)); // Determine the maximum amount to read. ulBlobSize = min(ulBlobSize, (UINT32)uDefLength-2); // Get the BLOB from the table. DBIErr(DbiGetBlob(hCur, pRecBuf, uFldNum + 1, 0, ulBlobSize, (pBYTE)pszField[uFldNum], &ulBlobSize)); // Add the NULL terminator to the string. pszField[uFldNum][(UINT16)ulBlobSize] = 0; // Free the blob from memory. DBIErr(DbiFreeBlob(hCur, pRecBuf, uFldNum + 1)); } else { strcpy(pszField[uFldNum], "Can't Display"); } break; default: strcpy(pszField[uFldNum], "Can't Display"); break; } // Initialize the string in case the field was blank. if (bIsBlank) { strcpy(pszField[uFldNum], ""); bIsBlank = FALSE; } } return DBIERR_NONE; } //===================================================================== // Function: // SetupFields(TblProps, pFldDescs, pszField, uDefLength) // // Input: TblProps - Properties of the Table // pFldDescs - Field Descriptor // pszField - Fields in the table // uDefLength - Default length of a field // // Return: Success of the operation. // // Description: // This function sets up the formatting of the fields. //===================================================================== DBIResult SetupFields (CURProps TblProps, pFLDDesc pFldDescs, CHAR** pszField, UINT16 uDefLength) { UINT16 uFldNum; // Loop variable for (uFldNum = 0; uFldNum < TblProps.iFields; uFldNum++) { // Allocate enough space to contain the data in each field. switch (pFldDescs[uFldNum].iFldType) { case fldBYTES: case fldZSTRING: pszField[uFldNum] = (CHAR*)malloc(((pFldDescs[uFldNum].iLen +1) * sizeof(CHAR))); if (MAXLEN - 4 < pFldDescs[uFldNum].iLen) { pFldDescs[uFldNum].iUnits1 = MAXLEN-4; pFldDescs[uFldNum].iLen = MAXLEN-3; } // Adjust if the field is smaller than it's description. if (pFldDescs[uFldNum].iLen < strlen(pFldDescs[uFldNum].szName)) { pFldDescs[uFldNum].iUnits1 = strlen(pFldDescs[uFldNum].szName); pFldDescs[uFldNum].iLen = pFldDescs[uFldNum].iUnits1 + 1; } break; case fldFLOAT: case fldDATE: case fldINT16: case fldUINT16: case fldINT32: case fldUINT32: case fldBOOL: case fldBLOB: case fldBCD: pszField[uFldNum] = (CHAR*)malloc(((uDefLength + 1)* sizeof(CHAR))); // Set the Width of the field as it will be displayed. pFldDescs[uFldNum].iUnits1 = uDefLength; pFldDescs[uFldNum].iLen = uDefLength + 1; // Adjust if the field is smaller than it's description. if (pFldDescs[uFldNum].iLen < strlen(pFldDescs[uFldNum].szName)) { pFldDescs[uFldNum].iUnits1 = strlen(pFldDescs[uFldNum].szName); pFldDescs[uFldNum].iLen = pFldDescs[uFldNum].iUnits1 + 1; } break; case fldTIMESTAMP: pszField[uFldNum] = (CHAR*)malloc((37 * sizeof(CHAR))); // Set the Width of the field as it will be displayed. pFldDescs[uFldNum].iUnits1 = 36; pFldDescs[uFldNum].iLen = 37; // Adjust if the field is smaller than it's description. if (pFldDescs[uFldNum].iLen < strlen(pFldDescs[uFldNum].szName)) { pFldDescs[uFldNum].iUnits1 = strlen(pFldDescs[uFldNum].szName); pFldDescs[uFldNum].iLen = pFldDescs[uFldNum].iUnits1 + 1; } break; case fldTIME: pszField[uFldNum] = (CHAR*)malloc((21 * sizeof(CHAR))); // Set the Width of the field as it will be displayed. pFldDescs[uFldNum].iUnits1 = 20; pFldDescs[uFldNum].iLen = 21; // Adjust if the field is smaller than it's description. if (pFldDescs[uFldNum].iLen < strlen(pFldDescs[uFldNum].szName)) { pFldDescs[uFldNum].iUnits1 = strlen(pFldDescs[uFldNum].szName); pFldDescs[uFldNum].iLen = pFldDescs[uFldNum].iUnits1 + 1; } break; default: // This field size will hold the 'Not Supported' // message. pszField[uFldNum] = (CHAR*)malloc(((uDefLength + 1) * sizeof(CHAR))); // Set the width of the field as it will be displayed. pFldDescs[uFldNum].iUnits1 = uDefLength; pFldDescs[uFldNum].iLen = uDefLength + 1; break; } } return DBIERR_NONE; } //===================================================================== // Function: // FormatDate(Date, szDate) // // Input: Date - Date which needs to be formatted // szDate - String to contain the formatted date // // Return: Result returned from DbiPutField(). // // Description: // This function is used to format date fields //===================================================================== DBIResult FormatDate (DATE Date, pCHAR szDate) { DBIResult rslt; // Return Value from IDAPI FMTDate fmtDate; // Date Format UINT16 uDay; // Day portion of date UINT16 uMonth; // Month portion of date INT16 iYear; // Year portion of date // Get the formatting of the Date. DBIErr(DbiGetDateFormat(&fmtDate)); // Decode the date. rslt = DBIErr(DbiDateDecode(Date, &uMonth, &uDay, &iYear)); // Determine if date should be displayed year based. if (!(fmtDate.bFourDigitYear) && (fmtDate.bYearBiased)) { iYear = iYear + 1900; } if (!(fmtDate.bFourDigitYear)) { iYear = iYear - 1900; } // Make certain the seperator is not the // escape character. if (!strcmp(fmtDate.szDateSeparator, "\\")) { strcpy(fmtDate.szDateSeparator, "/"); } // Format the date. switch(fmtDate.iDateMode) { // MM/DD/YY - Month, Day, Year. case 0: sprintf(szDate, "%0*d%s%0*d%s%0*d", 1 + fmtDate.bMonthLeadingZero, uMonth, fmtDate.szDateSeparator, 1 + fmtDate.bDayLeadingZero, uDay, fmtDate.szDateSeparator, 2, iYear); break; // DD/MM/YY - Day, Month, Year case 1: sprintf(szDate, "%0*d%s%0*d%s%0*d", 1 + fmtDate.bDayLeadingZero, uDay, fmtDate.szDateSeparator, 1 + fmtDate.bMonthLeadingZero, uMonth, fmtDate.szDateSeparator, 2, iYear); break; // YY/MM/DD - Year, Month, Day case 2: sprintf(szDate, "%0*d%s%0*d%s%0*d", 2, iYear, fmtDate.szDateSeparator, 1 + fmtDate.bMonthLeadingZero, uMonth, fmtDate.szDateSeparator, 1 + fmtDate.bDayLeadingZero, uDay); break; } return rslt; } //===================================================================== // Function: // FormatTime(Time, szTime) // // Input: Time - Time which needs to be formatted // szTime - String to contain the formatted time // // Return: Result returned from DbiPutField(). + // // Description: // This function is used to format Time fields. //===================================================================== DBIResult FormatTime (TIME Time, pCHAR szTime) { DBIResult rslt; // Return value from IDAPI functions FMTTime fmtTime; // Time format UINT16 uHour; // Hour portion of the time UINT16 uMinute; // Minute portion of the time UINT16 uMilSec; // Second portion (in ms) of the time UINT16 uIsAm; // Is Time AM? CHAR szTemp[10]; // Temp buffer, used for AM, PM string // Get the formatting of the Time. DBIErr(DbiGetTimeFormat(&fmtTime)); // Decode the time. rslt = DBIErr(DbiTimeDecode(Time, &uHour, &uMinute, &uMilSec)); // Make certain the seperator is not the // escape character. if (fmtTime.cTimeSeparator == '\\') { fmtTime.cTimeSeparator = '/'; } // Check if time should be displayed in 12 or 24 hour format. if (fmtTime.bTwelveHour) { // Temporary variable used to determine if the time is AM or PM. uIsAm = uHour; uHour = uHour % 12; if (uHour == 0) { uHour = 12; } // If AM, set uIsAm to TRUE, else set uIsAm to 0. if (uIsAm == uHour) { uIsAm = 1; } else { uIsAm = 0; } } // Format the hour and minute of the time. wsprintf(szTime, "%2u%c%02u", uHour, fmtTime.cTimeSeparator, uMinute); // Determine if seconds are to be displayed. if (fmtTime.bSeconds) { wsprintf(szTemp, "%c%02u", fmtTime.cTimeSeparator, (uMilSec / 1000)); strcat(szTime, szTemp); // Determine if milliseconds are to be displayed. if (fmtTime.bMilSeconds) { wsprintf(szTemp, "%c%03u", fmtTime.cTimeSeparator, (uMilSec % 1000)); strcat(szTime, szTemp); } } // Add a string to the time if the time is 12-hour. if (fmtTime.bTwelveHour) { strcat(szTime, " "); if (uIsAm) { strcat(szTime, fmtTime.szAmString); } else // otherwise it's PM { strcat(szTime, fmtTime.szPmString); } } return rslt; } //===================================================================== // Function: // FormatTimeStamp(TimeStamp, szTimeStamp) // // Input: TimeStamp - Time which needs to be formatted // szTimeStamp - String to contain the formatted time // // Return: Result returned from DbiPutField(). // // Description: // This function is used to format TimeStamp fields. //===================================================================== DBIResult FormatTimeStamp (TIMESTAMP TimeStamp, pCHAR szTimeStamp) { DBIResult rslt; // Return value from IDAPI functions TIME Time; // Time portion of the TimeStamp DATE Date; // Date portion of the TimeStamp CHAR szDate[15]; // Date string CHAR szTime[20]; // Time String // Get the date and time components rslt = DBIErr(DbiTimeStampDecode(TimeStamp, &Date, &Time)); // Get the Date format FormatDate(Date, szDate); // Get the Time format FormatTime(Time, szTime); // Format the TimeStamp wsprintf(szTimeStamp, "%s, %s", szTime, szDate); return rslt; } //====================================================================== // Function: // DisplayProgress(szProgress) // // Input: szProgress - String to display // // Return: None // // Description: // Displays progress information in the progress static control // of the main dialog. //====================================================================== void DisplayProgress (char *szProgress) { SendDlgItemMessage(hMainWnd, IDS_PROGRESS, WM_SETTEXT, 0, (LPARAM) szProgress); }