home *** CD-ROM | disk | FTP | other *** search
- // BDE - (C) Copyright 1995 by Borland International
-
- // Langdrv.C
- #include "snipit.h"
-
- #define MAXLEN 50
-
- static DBIResult GetLdObjectFromLdName(hDBIDb hDb, pCHAR pLdName,
- ppVOID ppLdObj);
- static DBIResult IntlFillTable(hDBIDb hDb, pCHAR szTblName, pCHAR szTblType,
- DFLOAT NumRecs);
- static DBIResult IntlPutFieldSample(hDBICur hCur, pBYTE pRecBuf,
- UINT16 FldNum, pFLDDesc pfldDesc);
- static DBIResult IntlDisplayTable(hDBICur hCur, UINT32 uDisplayNRecs);
-
- static const char szTblType[] = szPARADOX;
-
- // Field descriptor used in creating the temporary table.
- static SNIPFAR FLDDesc tmpFldDesc[] = {
- { // Field 1 - NUMERIC
- 1, "XNUM", fldFLOAT, fldUNKNOWN,
- 0, 0, 0, 0, 0, fldvNOCHECKS, fldrREADWRITE
- }
- }; // Array of field descriptors
-
- static SNIPFAR FLDDesc OptFldDesc[] = {
- { 1, "LANGDRIVER", fldZSTRING, fldUNKNOWN,
- DBIMAXTBLNAMELEN, 0, 0, DBIMAXSCFLDLEN, 0,
- fldvNOCHECKS, fldrREADWRITE
- }
- }; // Array of field descriptors
-
- //=====================================================================
- // Function:
- // LangDriver();
- //
- // Description:
- // This sample code will create a Paradox table with the default
- // Paradox language driver (as defined in the IDAPI configuration
- // file), append 10 records to the table, and then delete the
- // table. Field names, table names, and field data need to be
- // converted when using non-ASCII characters. This code
- // demonstrates how to do international support in IDAPI
- // functions DbiGetLdName, DbiGetLdObj, DbiAnsiToNative and
- // DbiNativeToAnsi.
- //=====================================================================
- void
- LangDriver (void)
- {
- hDBIDb hDb; // Handle to the database
- hDBICur hCur; // Handle to the table
- CRTblDesc TblDesc; // Create table descriptor
- UINT16 uDispNumRecs = 10 ; // Number of records to add
- // and display
- CHAR pDefLdName[DBIMAXNAMELEN]; // Default language driver
- // name
- pVOID pLdObj = NULL; // Language driver object
- CHAR szDspTblName[DBIMAXNAMELEN]; // Buffer to hold table name
- // for display (in ANSI
- // character set)
- UINT16 i; // Loop counter
- BOOL bDataLoss; // Contains if data loss
- // occured durring
- // conversion
- DBIResult rslt; // Return value from IDAPI
- // functions
- // Variables are declared local because they are changed within
- // this example and need to be reset each time the example is run.
- char szTblName[] = "╟R8PXT▀L";
-
- // Field descriptor used in creating a table.
- FLDDesc fldDesc[] = {
- { // Field 1 - ALPHA
- 1, // Field number
- "─LPH┼", // Field name
- fldZSTRING, // Field type
- fldUNKNOWN, // Field subtype
- 10, // Field size
- 0, // Decimal places ( 0 )
- // computed
- 0, // Offset in record ( 0 )
- 0, // Length in bytes ( 0 )
- 0, // For Null bits ( 0 )
- fldvNOCHECKS, // Validity checks ( 0 )
- fldrREADWRITE // Rights
- },
- { // Field 2 - NUMERIC
- 2, "╤▄MERIC", fldFLOAT, fldUNKNOWN,
- 0, 0, 0, 0, 0, fldvNOCHECKS, fldrREADWRITE
- },
- { // Field 3 - MONEY
- 3, "M╓NEY", fldFLOAT, fldstMONEY,
- 0, 0, 0, 0, 0, fldvNOCHECKS, fldrREADWRITE
- },
- { // Field 4 - DATE
- 4, "DAT╔", fldDATE, fldUNKNOWN,
- 0, 0, 0, 0, 0, fldvNOCHECKS, fldrREADWRITE
- },
- { // Field 5 - MEMO
- 5, "M╔MO", fldBLOB, fldstMEMO,
- 20, 0, 0, 0, 0, fldvNOCHECKS, fldrREADWRITE
- }
- }; // Array of field descriptors.
-
- // The number of fields in the table.
- const unsigned uNumFields = sizeof(fldDesc) / sizeof (fldDesc[0]);
-
- Screen("*** Creating language independent applications ***\r\n");
-
- BREAK_IN_DEBUGGER();
-
- Screen(" Initializing IDAPI...");
- if (InitAndConnect(&hDb) != DBIERR_NONE)
- {
- Screen("\r\n*** End of Example ***");
- return;
- }
-
- Screen(" Setting the default database directory...");
- rslt = DbiSetDirectory(hDb, (pCHAR)szTblDirectory);
- ChkRslt(rslt, "SetDirectory");
-
- // Table name is received from users in ANSI character set, but IDAPI
- // expects it in OEM.
- AnsiToOem((pCHAR)szTblName, (pCHAR)szTblName);
-
- Screen(" Initializing the table descriptor...");
- memset((void *) &TblDesc , 0, sizeof(CRTblDesc));
- lstrcpy(TblDesc.szTblName, szTblName);
- lstrcpy(TblDesc.szTblType, szTblType);
- TblDesc.iFldCount = uNumFields;
-
- // Translate field names in field descriptor from ANSI (as received
- // from users) to the table's character set using table's language
- // driver.
- // Get default language driver name for specified table type. This
- // will also be the language driver of the new table.
- rslt = DbiGetLdName((pCHAR)szTblType, NULL, pDefLdName);
- if (ChkRslt(rslt, "GetLdName") == DBIERR_NONE)
- {
- if (GetLdObjectFromLdName(hDb, pDefLdName, &pLdObj) == DBIERR_NONE)
- {
- for (i=0; i<uNumFields; i++)
- {
- rslt = DbiAnsiToNative(pLdObj, fldDesc[i].szName,
- fldDesc[i].szName, NULL, &bDataLoss);
- ChkRslt(rslt, "AnsiToNative");
- }
- }
- else
- {
- CloseDbAndExit(&hDb);
- Screen("\r\n*** End of Example ***");
- return;
- }
- }
- else
- {
- CloseDbAndExit(&hDb);
- Screen("\r\n*** End of Example ***");
- return;
- }
-
- TblDesc.pfldDesc = fldDesc;
-
- // Create and overwrite the table using the default language driver
- // defined in the IDAPI configuration file.
- Screen(" Creating the Paradox table...");
- rslt = DbiCreateTable(hDb, TRUE, &TblDesc);
- if (ChkRslt(rslt, "CreateTable") != DBIERR_NONE)
- {
- CloseDbAndExit(&hDb);
- Screen("\r\n*** End of Example ***");
- return;
- }
-
- Screen(" Fill the table with random data...");
- IntlFillTable(hDb, (pCHAR)szTblName, (pCHAR)szTblType, uDispNumRecs);
-
- // Open the table which we just created. The table name should be
- // translated from the DOS character set to ANSI for display.
- OemToAnsi(szTblName, szDspTblName);
- Screen(" Open the \"%s\" table...", szDspTblName);
- rslt = DbiOpenTable(hDb, (pCHAR)szTblName, (pCHAR)szTblType,
- NULL, NULL, 0, dbiREADWRITE, dbiOPENSHARED,
- xltFIELD, FALSE, NULL, &hCur);
- if (ChkRslt(rslt, "OpenTable") != DBIERR_NONE)
- {
- rslt = DbiDeleteTable(hDb, (pCHAR)szTblName, (pCHAR)szTblType);
- ChkRslt(rslt, "DeleteTable");
- CloseDbAndExit(&hDb);
- Screen("\r\n*** End of Example ***");
- return;
- }
-
- Screen(" Display the \"%s\" table which we just created...",
- szDspTblName);
- IntlDisplayTable(hCur, uDispNumRecs);
-
- Screen("\r\n Close the table...");
- rslt = DbiCloseCursor(&hCur);
- ChkRslt(rslt, "CloseCursor");
-
- Screen(" Deleting the table...");
- rslt = DbiDeleteTable(hDb, (pCHAR)szTblName, (pCHAR)szTblType);
- ChkRslt(rslt, "DeleteTable");
-
- Screen(" Close the database and exit IDAPI...");
- CloseDbAndExit(&hDb);
-
- Screen("\r\n*** End of Example ***");
- }
-
- //=====================================================================
- // Function:
- // GetLdObjectFromLdName(hDb, pLdName, ppLdObj)
- //
- // Input: hDb - Database handle
- // pLdName - Language driver name
- //
- // Return: DBIResult - Success of the opperation
- //
- // Description:
- // This function is used to get the language driver (LD) object from
- // an LD name rather than from a table cursor (as in DbiGetLdObj).
- // This allows us to get the LD object before a table is created.
- // If a table exists, you may use DbiGetLdObj to get the LD object.
- // The function creates a temporary table "__X123" (using optional
- // parameters to specify the language driver name) and gets the LD
- // object from the table. The temporary table will be deleted upon
- // exiting IDAPI.
- //=====================================================================
- DBIResult
- GetLdObjectFromLdName (hDBIDb hDb, pCHAR pLdName, ppVOID ppLdObj)
- {
- hDBICur hTmpCur; // Handle to the table
- pCRTblDesc pTmpTblDesc; // Create table descriptor
- DBIResult rslt; // Return value
- DBIResult rslt2; // Return value to use during cleanup
-
- CHAR szTmpTblName[] = "__X123";
-
- pTmpTblDesc = (pCRTblDesc)malloc(sizeof(CRTblDesc));
-
- // Initialize the Table create descriptor.
- memset((void *) pTmpTblDesc , 0, sizeof(CRTblDesc));
- lstrcpy(pTmpTblDesc->szTblName, szTmpTblName);
- lstrcpy(pTmpTblDesc->szTblType, szPARADOX);
- pTmpTblDesc->iFldCount = 1;
- pTmpTblDesc->pfldDesc = tmpFldDesc;
- pTmpTblDesc->iOptParams = 1;
- pTmpTblDesc->pfldOptParams = OptFldDesc;
- pTmpTblDesc->pOptData = (pBYTE)pLdName;
-
- // Create and overwrite the table using specific language driver
- // passed to the function.
- rslt = DbiCreateTable(hDb, TRUE, pTmpTblDesc);
- ChkRslt(rslt, "CreateTable");
- if (rslt != DBIERR_NONE)
- {
- free(pTmpTblDesc);
- Screen("\r\n GetLdObjectFromLdName\r\n");
- return rslt;
- }
-
- rslt = DbiOpenTable(hDb, szTmpTblName, szPARADOX, NULL, NULL,
- NULL, dbiREADONLY, dbiOPENSHARED, xltNONE,
- FALSE, NULL, &hTmpCur);
- ChkRslt(rslt, "OpenTable");
- if (rslt != DBIERR_NONE)
- {
- free(pTmpTblDesc);
- return rslt;
- }
-
- // Get LD object.
- rslt = DbiGetLdObj(hTmpCur, ppLdObj);
- ChkRslt(rslt, "GetLdObj");
- if (rslt != DBIERR_NONE)
- {
- rslt2 = DbiCloseCursor(&hTmpCur);
- ChkRslt(rslt2, "CloseCursor");
- rslt2 = DbiDeleteTable(hDb, (pCHAR)szTmpTblName, (pCHAR)szTblType);
- ChkRslt(rslt2, "DeleteTable");
- free(pTmpTblDesc);
- return rslt;
- }
-
- free(pTmpTblDesc);
- rslt = DbiCloseCursor(&hTmpCur);
- ChkRslt(rslt, "CloseCursor");
-
- rslt = DbiDeleteTable(hDb, (pCHAR)szTmpTblName, (pCHAR)szTblType);
- ChkRslt(rslt, "DeleteTable");
-
- return rslt;
- }
-
- //=====================================================================
- // Function:
- // IntlFillTable(hDb, szTblName, szTblType, NumRecs);
- //
- // Input: hDb - The database handle
- // szTblName - Name of the table to fill
- // szTblTyps - Type of the table to fill
- // NumRecs - The number of records to insert
- //
- // Return: DBIResult - Success of the operation
- //
- // Description:
- // This function adds the specified number of records to
- // the table containing random data.
- //=====================================================================
- DBIResult
- IntlFillTable (hDBIDb hDb, pCHAR szTblName, pCHAR szTblType, DFLOAT NumRecs)
- {
- DBIResult rslt; // Return value from IDAPI functions
- DFLOAT fRecCount; // Loop variable = count of records
- UINT16 FldCntr; // Field counter
- pBYTE pRecBuf = NULL; // Pointer to the record buffer
- FLDDesc fldDesc; // Field descriptor
- CURProps TblProps; // Table descriptor
- hDBICur hCur; // Handle to the table
- hDBICur hFldList; // Handle to the field list table
-
- rslt = DbiOpenTable(hDb, szTblName, szTblType, NULL, NULL, 0,
- dbiREADWRITE, dbiOPENSHARED, xltFIELD, FALSE,
- NULL, &hCur);
- if (ChkRslt(rslt,"OpenTable") != DBIERR_NONE)
- {
- return rslt;
- }
-
- // Create an in-memory table that contains a list of fields. Note
- // that logical (i.e. IDAPI types), are being requested instead of
- // driver types.
- rslt = DbiOpenFieldList(hDb, szTblName, szTblType, FALSE, &hFldList);
- if (ChkRslt(rslt,"OpenFieldList")!= DBIERR_NONE)
- {
- rslt = DbiCloseCursor(&hCur);
- ChkRslt(rslt, "CloseCursor");
- return rslt;
- }
-
- // Append the records if the list and table are available.
- if (hCur && hFldList)
- {
- ChkRslt(DbiGetCursorProps(hCur, &TblProps),
- "GetCursorProps");
-
- pRecBuf = (pBYTE) malloc(TblProps.iRecBufSize);
- if (!pRecBuf)
- {
- Screen("Out of Memory");
- rslt = DbiCloseCursor(&hCur);
- ChkRslt(rslt, "CloseCursor");
- rslt = DbiCloseCursor(&hFldList);
- ChkRslt(rslt, "CloseCursor");
- return DBIERR_NOMEMORY;
- }
-
- // Loop until the specified number of records have been written
- // to the table.
- for (fRecCount = 0; fRecCount < NumRecs; fRecCount++)
- {
- // Make sure we're starting with a clean record buffer.
- rslt = DbiInitRecord(hCur, pRecBuf);
- ChkRslt(rslt, "InitRecord");
-
- FldCntr = 1;
- rslt = DbiSetToBegin(hFldList);
- ChkRslt(rslt, "SetToBegin");
-
- // This loop will use the previously opened field list to
- // determine what type of data is inserted into the table.
- while (DbiGetNextRecord(hFldList, dbiNOLOCK, (pBYTE) &fldDesc,
- NULL) == DBIERR_NONE)
- {
- // Put field data into the record buffer.
- IntlPutFieldSample(hCur, pRecBuf, FldCntr, &fldDesc);
- FldCntr++;
- }
-
- // All fields have been inserted into the record buffer. Now
- // we need to append the record to the table.
- rslt = DbiAppendRecord(hCur, pRecBuf);
- ChkRslt(rslt, "AppendRecord") ;
-
- // Make sure to close all BLOBs (opened when data was put into
- // the record buffer).
- FldCntr = 1;
- rslt = DbiSetToBegin(hFldList);
- ChkRslt(rslt, "SetToBegin");
- while (DbiGetNextRecord(hFldList, dbiNOLOCK, (pBYTE) &fldDesc,
- NULL) == DBIERR_NONE)
- {
- if (fldDesc.iFldType == fldBLOB)
- {
- rslt = DbiFreeBlob(hCur, pRecBuf, FldCntr);
- ChkRslt(rslt, "FreeBlob");
- }
- FldCntr++;
- }
- }
-
- // Free allocated record buffer.
- free((pCHAR) pRecBuf);
- }
-
- // Clean up and return.
- rslt = DbiCloseCursor(&hFldList);
- ChkRslt(rslt, "CloseCursor");
-
- rslt = DbiCloseCursor(&hCur);
- ChkRslt(rslt, "CloseCursor");
-
- return DBIERR_NONE;
- }
-
- //=====================================================================
- // Function:
- // IntlPutFieldSample(hCur, pRecBuf, FldNum, pfldDesc);
- //
- // Input: hCur - The handle for the table to fill
- // pRecBuf - The record buffer to insert data into
- // FldNum - The field we are generating
- // pfldDesc - A descriptor that describes the field to generate
- //
- // Return: Result returned from DbiPutField()
- //
- // Description:
- // This routine is used to put field data into a record
- // buffer. Note that all logical field types are covered. You
- // will need to refer to documentation, or run the DRVCAPS.C
- // example for physical to logical field mappings.
- //=====================================================================
- DBIResult
- IntlPutFieldSample (hDBICur hCur, pBYTE pRecBuf, UINT16 FldNum,
- pFLDDesc pfldDesc)
- {
- pBYTE pBuf; // Buffer which contains the record data
- DBIResult rslt; // Return value from IDAPI functions
- INT16 i; // Loop counter
- INT16 BlobSize; // Size of the BLOB
- BOOL bDataLoss; // If any data is lost in translation
- BOOL Bool; // Used for fldBOOL
- INT16 Int16; // Used for fldINT16
- UINT16 uInt16; // Used for fldUINT16
- INT32 Int32; // Used for fldINT32
- UINT32 uInt32; // Used for fldUINT32
- DFLOAT Float; // Used for fldFLOAT
- FMTBcd fmtBcd; // Used for fldBCD
- DBIDATE Date; // Used for fldDATE
- TIME Time; // Used for fldTIME
- TIMESTAMP tStamp; // Used for fldTIMESTAMP
- UINT16 month; // Used in generating the date
- UINT16 day; // Used in generating the date
- UINT16 year; // Used in generating the date
- UINT16 hour; // Used in generating the time
- UINT16 min; // Used in generating the time
- UINT16 sec; // Used in generating the time
- pVOID pLdObj = NULL; // Table's language driver object
-
- // Allocate a generic buffer (used for string & blob fields).
- pBuf = (pBYTE) malloc(4096);
- if (!pBuf)
- {
- Screen(" Error - Out of memory.");
- return DBIERR_NOMEMORY;
- }
-
- // This section contains sample code demonstrating how to
- // insert a field of any type into a record buffer. Random data
- // is used by this example. Field data is assumed to be in the ANSI
- // character set, and needs to be translated into the table's
- // character set before being inserted in the table.
-
- // Get tables language driver.
- rslt = DbiGetLdObj(hCur, &pLdObj);
- ChkRslt(rslt, "GetLdObj");
-
- switch (pfldDesc->iFldType)
- {
- case fldBYTES:
- case fldZSTRING:
- sprintf((pCHAR)pBuf, "F∩Θld #%d", FldNum);
- // Translate the character string. If table's language
- // driver is based on the ANSI character set, no translation
- // is performed.
- rslt = DbiAnsiToNative(pLdObj, (pCHAR)pBuf, (pCHAR)pBuf, NULL,
- &bDataLoss);
- ChkRslt(rslt, "AnsiToNative");
-
- // Put the data into the record buffer.
- rslt = DbiPutField(hCur, FldNum, pRecBuf, pBuf);
- break;
- case fldDATE:
- // Randomly generate and encode a date.
- month = (rand() % 12) + 1;
- day = (rand() % 20) + 1;
- year = (rand() % 99) + 1900;
- rslt = DbiDateEncode(month, day, year, &Date);
- ChkRslt(rslt, "DateEncode");
-
- // Put the data into the record buffer.
- rslt = DbiPutField(hCur, FldNum, pRecBuf, (pBYTE) &Date);
- break;
- case fldBLOB:
- // Generate a blob with length from 10-4010 bytes.
- BlobSize = (rand() % 4000) + 11;
-
- strcpy((pCHAR)pBuf, "BL╓B Θxßmple ");
-
- // Write data to the BLOB field.
- for (i = 0; i < (BlobSize % 11); i++)
- {
- strcat((pCHAR)pBuf, "BL╓B tΦst ");
- }
-
- // Translate character data. If table's language
- // driver is based on ANSI character set, no translation
- // is performed.
- rslt = DbiAnsiToNative(pLdObj, (pCHAR)pBuf, (pCHAR)pBuf, NULL,
- &bDataLoss);
- ChkRslt(rslt, "AnsiToNative");
-
- // Init the BLOB header (contents defined by IDAPI client).
- if ((pfldDesc->iSubType == fldstFMTMEMO) ||
- (pfldDesc->iSubType == fldstOLEOBJ) ||
- (pfldDesc->iSubType == fldstGRAPHIC))
- {
- memset(pBuf, 8, '\0');
- }
-
- // Open the BLOB prior to putting.
- ChkRslt(DbiOpenBlob(hCur, pRecBuf, FldNum, dbiREADWRITE), "OpenBlob");
-
- // Put the BLOB. Note that DbiFreeBlob() will be
- // called after the record is inserted!
- rslt = DbiPutBlob(hCur, pRecBuf, FldNum, 0, BlobSize,
- pBuf);
- break;
- case fldBOOL:
- // Boolean fields are either TRUE or FALSE.
- if ((rand() % 100) < 50)
- Bool = 1;
- else
- Bool = 0;
- // Put the data into the record buffer.
- rslt = DbiPutField(hCur, FldNum, pRecBuf, (pBYTE)&Bool);
- break;
- case fldINT16:
- Int16 = (rand() % 255);
- // Put the data into the record buffer.
- rslt = DbiPutField(hCur, FldNum, pRecBuf, (pBYTE)&Int16);
- break;
- case fldBCD:
- Float = (rand() / 1.21324);
- rslt = DbiBcdFromFloat(&Float, pfldDesc->iUnits1,
- pfldDesc->iUnits2, &fmtBcd);
- ChkRslt(rslt, "BcdFromFloat");
-
- // Put the data into the record buffer.
- rslt = DbiPutField(hCur, FldNum, pRecBuf, (pBYTE)&fmtBcd);
- break;
- case fldLOCKINFO:
- rslt = 0;
- break;
- case fldUINT16:
- uInt16 = (rand() % 255);
- // Put the data into the record buffer.
- rslt = DbiPutField(hCur, FldNum, pRecBuf, (pBYTE)&uInt16);
- break;
- case fldINT32:
- // Put the data into the record buffer if it is not an
- // auto-increment field.
- if (pfldDesc->iSubType != fldstAUTOINC)
- {
- Int32 = (rand() % 10000);
- rslt = DbiPutField(hCur, FldNum, pRecBuf, (pBYTE)&Int32);
- }
- else
- {
- // Don't have to put a value into an auto-increment field,
- // but make certain not to return an error.
- rslt = 0;
- }
- break;
- case fldUINT32:
- uInt32 = (rand() % 10000);
- // Put the data into the record buffer.
- rslt = DbiPutField(hCur, FldNum, pRecBuf, (pBYTE)&uInt32);
- break;
- case fldFLOAT:
- Float = (rand() % 128000L);
- // Put the data into the record buffer.
- rslt = DbiPutField(hCur, FldNum, pRecBuf, (pBYTE)&Float);
- break;
- case fldTIME:
- // Randomize and encode a time value.
- hour = (rand() % 23) + 1;
- min = (rand() % 59) + 1;
- sec = ((rand() * 2) % 59999U) + 1;
- rslt = DbiTimeEncode( hour, min, sec, &Time);
- ChkRslt(rslt, "TimeEncode");
-
- // Put the data into the record buffer.
- rslt = DbiPutField(hCur, FldNum, pRecBuf, (pBYTE)&Time);
- break;
- case fldTIMESTAMP:
- // Encode a date and a time.
- month = (rand() % 12) + 1;
- day = (rand() % 20) + 1;
- year = (rand() % 99) + 1900;
- rslt = DbiDateEncode(month, day, year, &Date);
- ChkRslt(rslt, "DateEncode");
- hour = (rand() % 23) + 1;
- min = (rand() % 59) + 1;
- sec = ((rand() * 2) % 59999U) + 1;
- rslt = DbiTimeEncode(hour, min, sec, &Time);
- ChkRslt(rslt, "TimeEncode");
-
- // Now encode and put the time stamp.
- rslt = DbiTimeStampEncode(Date, Time, &tStamp);
- ChkRslt(rslt, "TimeStampEncode");
- // Put the data into the record buffer.
- rslt = DbiPutField(hCur, FldNum, pRecBuf, (pBYTE)&tStamp);
- break;
- case fldVARBYTES:
- // Init the size (1st two bytes) and contents.
- *((int *) pBuf) = (pfldDesc->iUnits1 - 2);
- for (i = 2; i < pfldDesc->iUnits1; i++)
- {
- pBuf[i] = (rand() % 90) + 32;
- }
- pBuf[i] = '\0';
-
- // Put the data into the record buffer.
- rslt = DbiPutField(hCur, FldNum, pRecBuf, (pBYTE)pBuf);
- break;
- default:
- rslt = DBIERR_INVALIDFLDTYPE;
- break;
- }
- // Determine if any of the previous DbiPutField functions failed.
- ChkRslt(rslt, "PutField");
-
- // Clean up and return.
- free((pCHAR) pBuf);
- return rslt;
- }
-
- //=====================================================================
- // Function:
- // DisplayTable(hCur, uDisplayNRecs);
- //
- // Input: The cursor handle - Which table to access
- // DisplayNRecs - How many records to display
- // (0 means display 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. Records are read from the table in blocks,
- // making this function faster than the DisplayInMemoryTable()
- // function.
- //
- // Note: This function will only display the columns
- // correctly when using a fixed pitch font.
- //=====================================================================
- DBIResult
- IntlDisplayTable (hDBICur hCur, UINT32 uDisplayNRecs)
- {
- DBIResult rslt = DBIERR_NONE; // Return value from IDAPI functions
- CURProps TblProps; // Table properties
- pFLDDesc pFldDescs; // List of fields
- pBYTE pRecBuf; // Record buffer
- CHAR** ppszField; // Array to contain the fields of the
- // table
- pCHAR szFormat; // Contains an entire record (row)
- CHAR szTemp[MAXLEN] =""; // Temporary variable for reading data
- UINT16 uFldNum; // Loop variable
- UINT16 uMaxNumRecs = 30; // Maximum number of record to read
- // from the table at a time
- UINT32 uNumRecs; // Number of records Read in from the
- // table
- UINT16 uCount; // 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
- pVOID pLdObj = NULL; // Language driver object
- BOOL bDataLoss; // Data loss parameter for character
- // translation
-
- rslt = DbiGetCursorProps(hCur, &TblProps);
- if ((ChkRslt(rslt, "GetCursorProps")) != DBIERR_NONE)
- {
- return rslt;
- }
-
- // Allocate memory for the format string.
- szFormat = (pCHAR)malloc(1400);
- // Allocate space for the record buffer.
- pRecBuf = (pBYTE)malloc(TblProps.iRecBufSize * sizeof(BYTE) *
- uMaxNumRecs);
- // Allocate enough space to contain information (field descriptors)
- // about all the fields in the answer table.
- pFldDescs = (pFLDDesc)malloc(TblProps.iFields * sizeof(FLDDesc));
- if ((!pFldDescs) || (!pRecBuf) || (!szFormat))
- {
- if (szFormat) free(szFormat);
- if (pRecBuf) free(pRecBuf);
- if (pFldDescs) free(pFldDescs);
- return DBIERR_NOMEMORY;
- }
-
- szFormat[0] = 0;
-
- // Get information about the fields.
- rslt = DbiGetFieldDescs(hCur, pFldDescs);
- ChkRslt(rslt, "GetFieldDescs");
-
- // Allocate enough buffers to contain data from the fields in the
- // answer table. Also set the width of non-fldZSTRING fields
- // (all data will be converted to strings for display.)
- ppszField = (CHAR**)malloc(TblProps.iFields * sizeof(CHAR*));
- if (!ppszField)
- {
- free(szFormat);
- free(pRecBuf);
- free(pFldDescs);
- return DBIERR_NOMEMORY;
- }
-
- SetupFields(TblProps, pFldDescs, ppszField, uDefLength);
- // Get table language driver to translate field names from table's
- // character set to ANSI for display.
- rslt = DbiGetLdObj(hCur, &pLdObj);
- if ((ChkRslt(rslt, "GetLdObj")) != DBIERR_NONE)
- {
- free(szFormat);
- free(pRecBuf);
- free(pFldDescs);
- return rslt;
- }
-
- // Format 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);
- }
-
- // Translate field names from table's character set to ANSI for display.
- rslt = DbiNativeToAnsi(pLdObj, szFormat, szFormat, NULL,
- &bDataLoss);
- if ((ChkRslt(rslt, "NativeToAnsi")) != DBIERR_NONE)
- {
- free(szFormat);
- free(pRecBuf);
- free(pFldDescs);
- return rslt;
- }
-
- // Display the header information (field names).
- Screen(szFormat);
-
- // Get records from the table until the end of the table is reached
- // Note that not all field types are supported. All supported field
- // types are displayed as strings.
- // The DbiReadBlock function is used in case field mapping
- // is taking place - the GetNextRec, GetPriorRec, and GetRelativeRec
- // functions do not take field mapping into consideration.
- uNumRecs = uMaxNumRecs; // Set the number of records to read from the
- // table as a block
- // If uCurCoutRec == 0, display all the records in the table.
- if (uDisplayNRecs == 0)
- {
- uDisplayNRecs = (UINT16)-1; // uDisplayNRecs is unsigned, so
- // -1 maximizes the value.
- }
- // Get the records from the table and display.
- do
- {
- // Limit the number of records to be read from the table -
- // do not want to display more than uDisplayNRecs records.
- if ((uNumRecs + uCurCountRec) > uDisplayNRecs)
- {
- uNumRecs = uDisplayNRecs - uCurCountRec;
- }
- // Read a block of records - this is more efficient than reading
- // records one at a time from the table.
- rslt = DbiReadBlock(hCur, &uNumRecs, pRecBuf);
- if ((rslt != DBIERR_EOF) && // DBIERR_EOF is an expected return
- (rslt != DBIERR_NONE)) // code - means cannot read more records.
- {
- free(szFormat);
- for (uFldNum = 0; uFldNum < TblProps.iFields; uFldNum++)
- {
- free(ppszField[uFldNum]);
- }
- free(ppszField);
- free(pFldDescs);
- free(pRecBuf);
- return rslt;
- }
- for (uCount=0; uCount < uNumRecs; uCount++)
- {
- uCurCountRec++;
-
- // Fill the record buffer with the field values.
- GetFields(hCur, pFldDescs,
- &pRecBuf[uCount * TblProps.iRecBufSize],
- ppszField, uDefLength);
-
- // 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,
- ppszField[uFldNum]);
- strcat(szFormat, szTemp);
- }
- // Translate table data from table's character set to ANSI for
- // display.
- rslt = DbiNativeToAnsi(pLdObj, szFormat, szFormat, NULL,
- &bDataLoss);
- if ((ChkRslt(rslt, "NativeToAnsi")) != DBIERR_NONE)
- {
- // Clean up.
- for (uFldNum = 0; uFldNum < TblProps.iFields; uFldNum++)
- {
- free(ppszField[uFldNum]);
- }
- free(szFormat);
- free(ppszField);
- free(pFldDescs);
- free(pRecBuf);
- }
-
- // Display the record.
- Screen(szFormat);
- } // For ... uCount.
- // While ReadBlock reads as many records as are supposed to be
- // batched (uMaxNumRecs) and the maximum number of records have not
- // been read from the table. Reading a smaller number of records than
- // that specified in uMaxNumRecs indicates that the end of the table has
- // been reached.
- } while((uNumRecs == uMaxNumRecs) &&
- (uCurCountRec < uDisplayNRecs));
-
- // 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(ppszField[uFldNum]);
- }
- free(szFormat);
- free(ppszField);
- free(pFldDescs);
- free(pRecBuf);
-
- return DBIERR_NONE;
- }
-
-