home *** CD-ROM | disk | FTP | other *** search
- // BDE - (C) Copyright 1995 by Borland International
-
- #include "dbfseek.h"
- #include "macro.h"
-
- #define szCURRENTMODULE "DBFSEEK"
-
- //=====================================================================
- // This BDE example provides Paradox for Windows ver. 5.0 ObjectPAL users
- // a means of doing a seek similar to the dBASE seek of MAINTAINED
- // expression indexes on dBASE tables for retrieving record numbers. The
- // ObjectPAL procedures created are: DbfIdxSeek and DbfGetIdxExpr.
- //
- // Expressions tested in an MDX file:
- //
- // LTRIM(STR(MONTH(DATES)))+"/"+LTRIM(STR(DAY(DATES)))+"/"
- // +SUBSTR(LTRIM(STR(YEAR(DATES))),3,2)
- // LTRIM(FIRST_NAME)
- // LTRIM(FIRST_NAME)-LTRIM(LAST_NAME)
- // FIRST_NAME (a character field)
- // FIRST_NAME-LAST_NAME
- // FLOATS (a float field)
- // NUMBERS (a number field)
- // RECNO()
- // RTRIM(FIRST_NAME) + DTOS(DATES)
- // Indexes on concatenation of character and date field. The date
- // field is converted to characters in format YYYYMMDD.
- // i.e. - Jerry19950518.
- // SQRT(NUMBERS)
- // LTRIM(STR(FLOATS))
- // SUBSTR(FIRST_NAME,2,3)
- //
- // Notes:
- //
- // DbfIdxSeek returns a record number. A return of 0 means that the record
- // was not found.
- //
- // DbfGetIdxExpr is just for viewing an expression string.
- //
- // The EXACT setting, when set to FALSE, will find records with partial
- // values in character expressions. EXACT set to TRUE sets NEAR to FALSE.
- //
- // EXACT: 0 = FALSE, 1 = TRUE
- //
- // The NEAR setting, after an unsuccessful dbfSEEK, positions the record
- // pointer at the record in the indexed table immediately after the position
- // at which the value searched for would have been found.
- //
- // NEAR: 0 = FALSE, 1 = TRUE
- //
- // Character expressions are case sensitive except for soundex which must
- // sound like the key value for a match to occur.
- //
- // Use no commas in values seeking NUMERIC expressions.
- //
- // "Sounds like" can be used if SOUNDEX is the only function used
- // and is at the beginning of the expression. All field names and
- // other words must be contained within its perentheses i.e. -
- // SOUNDEX(FIRST_NAME)
- // SOUNDEX(FIRST_NAME-LAST_NAME)
- //
- // DATE fields can be used directly if the field name is at the beginning
- // of the expression and is used alone i.e. -
- // DATES (a date field)
- //
- //
- // This is how the Paradox Uses block should appear:
- //
- // Uses dbfseek
- //
- // DbfIdxSeek(TableDir cptr, TableName cptr,
- // IndexFileNameWithExtension cptr,
- // IndexTagName cptr, KeyValue cptr,
- // Exact cword, Near cword,
- // returnStringBuffer cptr)cdouble
- // DbfGetIdxExpr(TableDir cptr, TableName cptr,
- // IndexFileNameWithExtension cptr,
- // IndexTagName cptr, ReturnValue cptr)
- //
- // endUses
- //
- //
- // And some typical methods:
- //
- // Var
- // returnStringBuffer String
- // endVar
- //
- //
- // method open(var eventInfo Event)
- //
- // if eventInfo.isPreFilter() then
- // ;// This code executes for each object on the form:
- //
- // else
- // ;// This code executes only for the form:
- //
- // ; requires a 129 byte buffer:
- // returnStringBuffer = space(129) ; VERY IMPORTANT! or GPF
- //
- // endif
- //
- // endmethod
- //
- //
- // method pushButton(var eventInfo Event)
- //
- // var exact, near smallint endvar
- // exact = 0
- // near = 0
- // RecNoReturn = DbfIdxSeek(workingdir(), "test.dbf",
- // "test.mdx", "sometag",
- // "somevalue", exact, near, returnStringBuffer)
- // if RecNoReturn > 0 then
- // TableFrameName.moveToRecNo(RecNoReturn)
- // else
- // TableFrameName.moveToRecNo(1)
- // endif
- // message(returnStringBuffer) ; for errors
- //
- // endmethod
- //
- //
- // method pushButton(var eventInfo Event)
- //
- // DbfGetIdxExpr(workingdir(), "test.dbf", "test.mdx",
- // "sometag", returnStringBuffer)
- // view(returnStringBuffer)
- //
- // endmethod
- //
- //=====================================================================
-
- //=====================================================================
- // Function:
- // DbfIdxSeek(pCHAR pTblDir, pCHAR pTblName, pCHAR pIdxName,
- // pCHAR pIdxTag, pCHAR pKeyVal, pCHAR pszRetBuffer)
- //
- // Description:
- // This example shows how to seek for a key value in a dBASE
- // maintained key expression.
- //
- //=====================================================================
- DFLOAT FAR WINAPI _export
- DbfIdxSeek (pCHAR pTblDir, pCHAR pTblName, pCHAR pIdxName,
- pCHAR pIdxTag, pCHAR pKeyVal, int bExact, int bNear,
- pCHAR pszRetBuffer)
- {
- CHAR szTblType[] = szDBASE; // table type (dBASE)
- UINT16 i = 0; // for loops
- UINT16 iKeyValLen = 0; // for total key bytes received
- UINT16 iKeyValEven = 1; // for total used key bytes
- div_t x; // for calcing total used key bytes
- FMTBcd Bcd;
- CURProps TblProps;
- IDXDesc *pIdxDesc = NULL;
- DBIResult rslt = NULL;
- UINT32 retVal = 0;
- hDBIDb hDb = NULL;
- hDBICur hCur = NULL;
- pRECProps precProps = NULL;
- char *ptok = NULL;
- UINT16 iFldNum = 0;
- DFLOAT fKeyVal = 0;
- pFLDDesc pFldDesc = NULL;
- char *ptrFunc, c = '(';
- UINT16 iIndexSeqNumber = 0;
- pBYTE pBuf = NULL; // Pointer to the record buffer
- pBYTE pKeyBuf = NULL; // Pointer to the key buffer
- BOOL bIsNegative = 0;
- BOOL bExpFunc = 0;
- BOOL bHasNoFld = 0;
- BOOL bBlank = 0;
- BOOL bBlankDate = 0;
- UINT16 ptr = 0;
- UINT16 iFldType = 0;
- DBIDATE dateD = NULL;
- UINT16 uDay = NULL; // Day portion of date
- UINT16 uMon = NULL; // Month portion of date
- INT16 iYear = NULL; // Year portion of date
- char szYear[5]; // buffer for year
- char szPlaces[2] = "4";
- char *szKeyBuf1 = NULL;
- char *szKeyBuf2 = NULL;
- char *szKeyBuf3 = NULL;
- char *szKeyBuf4 = NULL;
- char *szFField = NULL; // buffer for first exp. field name
- UINT16 uDecLen = 0; // Decimal length
-
- if (bExact == 1)
- {
- bNear = 0;
- }
-
- // initialize buffer for error string
- memset(pszRetBuffer, 0, (DBIMAXMSGLEN + 1) * sizeof(char));
-
- // do nothing if a key value is not sent
- CHKERR_NODISPLAY(!strcmp(pKeyVal, ""))
-
- iKeyValLen = strlen(&pKeyVal[0]);
-
- if (pKeyVal[0] == '-') // for negative numbers
- {
- bIsNegative = TRUE;
- }
-
- precProps = ((pRECProps) malloc (sizeof(RECProps)));
- if (precProps == NULL)
- {
- GetString(1, pszRetBuffer); //"Out of Memory."
- CLEANUP_NODISPLAY;
- }
-
- // open a database in the current session and get a database handle
- CHKERR_CLEANUP(DbiOpenDatabase(NULL, NULL, dbiREADONLY, dbiOPENSHARED,
- NULL, 0, NULL, NULL, &hDb));
-
- // set the current directory
- CHKERR_CLEANUP(DbiSetDirectory(hDb, pTblDir));
-
- // associate a cursor handle with an opened table
- CHKERR_CLEANUP(DbiOpenTable(hDb, pTblName, NULL, pIdxName, pIdxTag,
- 0, dbiREADONLY, dbiOPENSHARED, xltFIELD,
- FALSE, NULL, &hCur));
-
- CHKERR_CLEANUP(DbiGetCursorProps(hCur, &TblProps));
-
- if (strcmp(szTblType, TblProps.szTableType))
- {
- GetString(7, pszRetBuffer); //"Only dBASE tables are supported."
- CLEANUP_NODISPLAY;
- }
-
- pFldDesc = (pFLDDesc) malloc (sizeof(FLDDesc) * TblProps.iFields);
- if (pFldDesc == NULL)
- {
- GetString(1, pszRetBuffer); //"Out of Memory."
- CLEANUP_NODISPLAY;
- }
-
- CHKERR_CLEANUP(DbiGetFieldDescs(hCur, pFldDesc));
-
- pIdxDesc = (IDXDesc*) malloc (TblProps.iIndexes * sizeof(IDXDesc));
- if (pIdxDesc == NULL)
- {
- GetString(1, pszRetBuffer); //"Out of Memory."
- CLEANUP_NODISPLAY;
- }
-
- CHKERR_CLEANUP(DbiGetIndexDescs(hCur, pIdxDesc));
-
- pBuf = (pBYTE) malloc (TblProps.iRecBufSize);
- if (pBuf == NULL)
- {
- GetString(1, pszRetBuffer); //"Out of Memory."
- CLEANUP_NODISPLAY;
- }
-
- CHKERR_CLEANUP(DbiInitRecord(hCur, pBuf));
-
- CHKERR_CLEANUP(DbiGetIndexSeqNo(hCur, pIdxName, pIdxTag, NULL,
- &iIndexSeqNumber));
-
- if (pIdxDesc[iIndexSeqNumber - 1].bMaintained == 0)
- {
- GetString(3, pszRetBuffer); //"Only maintained indexes are supported."
- CLEANUP_NODISPLAY;
- }
-
- pKeyBuf = (pBYTE) malloc((pIdxDesc[iIndexSeqNumber - 1].iKeyLen + 1) *
- sizeof (BYTE));
- szKeyBuf1 = (char*) malloc((pIdxDesc[iIndexSeqNumber - 1].iKeyLen + 1) *
- sizeof (char));
- szKeyBuf2 = (char*) malloc((pIdxDesc[iIndexSeqNumber - 1].iKeyLen + 1) *
- sizeof (char));
- szKeyBuf3 = (char*) malloc((pIdxDesc[iIndexSeqNumber - 1].iKeyLen + 1) *
- sizeof (char));
- szKeyBuf4 = (char*) malloc((pIdxDesc[iIndexSeqNumber - 1].iKeyLen + 1) *
- sizeof (char));
- // initialize buffer for first exp. field name
- szFField = (char*) malloc((strlen(pIdxDesc[iIndexSeqNumber - 1].szKeyExp)
- + 1) * sizeof (char));
- if ((szFField == NULL) ||
- (pKeyBuf == NULL) ||
- (szKeyBuf1 == NULL) ||
- (szKeyBuf2 == NULL) ||
- (szKeyBuf3 == NULL) ||
- (szKeyBuf4 == NULL))
- {
- GetString(1, pszRetBuffer); //"Out of Memory."
- CLEANUP_NODISPLAY;
- }
-
- // does the expression contain soundex
- ptrFunc = strchr(pIdxDesc[iIndexSeqNumber - 1].szKeyExp, c);
- if (ptrFunc)
- {
- ptr = strncmpi("soundex", pIdxDesc[iIndexSeqNumber - 1].szKeyExp, 7);
- if (ptr == 0)
- {
- bExpFunc = 1;
- }
-
- // get first field name and type disregarding function
- ptok = strtok(pIdxDesc[iIndexSeqNumber - 1].szKeyExp, "(");
- ptok = strtok('\0', " ()-+/*");
- if (ptok)
- {
- strcpy(szFField, ptok);
- }
- else
- {
- // has no field name in the expression
- bHasNoFld = 1;
- }
- }
- else
- {
- // has no function, then assuming expression has a field name
- ptok = strtok(pIdxDesc[iIndexSeqNumber - 1].szKeyExp, " -+/*");
- if (ptok)
- {
- strcpy(szFField, ptok);
- }
- else
- {
- bHasNoFld = 1;
- }
- }
-
- if (bHasNoFld == 0)
- {
- for (i = 0; i < TblProps.iFields; i++)
- {
- if (!strcmp(pFldDesc[i].szName, ptok))
- {
- iFldType = pFldDesc[i].iFldType;
- iFldNum = pFldDesc[i].iFldNum;
- break;
- }
- }
- }
-
- if (iFldType == fldDATE)
- {
- // set max input to key buffer
- if (iKeyValLen > pIdxDesc[iIndexSeqNumber - 1].iKeyLen + 3)
- {
- GetString(4, pszRetBuffer); //"Key length exceeded."
- MessageBeep(-1);
- CLEANUP_NODISPLAY;
- }
-
- if (pKeyVal[0] == ' ')
- {
- uMon = 12;
- uDay = 31;
- iYear = 9999;
- bBlankDate = 1;
- bNear = 1;
- }
- else
- {
- ptok = strtok(pKeyVal, " /");
- if (ptok)
- {
- uMon = atoi(ptok);
- }
-
- for (i = 0; i < 2; i++)
- {
- ptok = strtok('\0', "/");
- if ((i == 0)&&(ptok))
- {
- uDay = atoi(ptok);
- }
-
- if ((i == 1)&&(ptok))
- {
- // assumption: dates entered > 51 and <100 = 1950 otherwise
- // it = 2050 unless 4 digit year is entered
- if (atoi(ptok) > 50 && atoi(ptok) < 100)
- {
- if (atoi(ptok) > 50)
- {
- strcpy(szYear, "19");
- strcat(szYear, ptok);
- iYear = atoi(szYear);
- }
- else
- {
- strcpy(szYear, "20");
- strcat(szYear, ptok);
- iYear = atoi(szYear);
- }
- }
- else
- {
- strcpy(szYear, ptok);
- iYear = atoi(szYear);
- }
- }
- }
- }
-
- CHKERR_CLEANUP(DbiDateEncode(uMon, uDay, iYear, &dateD));
-
- CHKERR_CLEANUP(DbiPutField(hCur, iFldNum, pBuf, (pBYTE) &dateD));
-
- CHKERR_CLEANUP(DbiExtractKey(hCur, pBuf, (pBYTE) pKeyBuf));
-
- if (bNear == 1)
- {
- CHKERR_CLEANUP(DbiSetToKey(hCur, keySEARCHGEQ, TRUE, 0, 0,
- pKeyBuf));
- }
- else
- {
- CHKERR_CLEANUP(DbiSetToKey(hCur, keySEARCHEQ, TRUE, 0, 0,
- pKeyBuf));
- }
-
- CHKERR_CLEANUP(DbiGetNextRecord(hCur, dbiNOLOCK, pBuf, precProps));
-
- CHKERR_CLEANUP(DbiGetField(hCur, iFldNum, pBuf, NULL, &bBlank));
-
- if (bBlank)
- {
- // if set to near and the indate is larger than any key value,
- // force an end of table (message only), otherwise a blank
- // record gets found.
- if (bNear == 1 && bBlankDate == 0)
- {
- GetString(9, pszRetBuffer); //"At end of table."
- CLEANUP_NODISPLAY;
- }
- }
-
- retVal = precProps[0].iPhyRecNum;
- }
- else
- {
- if (pIdxDesc[iIndexSeqNumber - 1].iKeyExpType == fldDBCHAR)
- {
- // set key buffer for char expression type
- memset(pKeyBuf, ' ', pIdxDesc[iIndexSeqNumber - 1].
- iKeyLen + 1 * sizeof (BYTE));
-
- if (bExpFunc == 0)
- {
- // set max input to key buffer
- if (iKeyValLen > pIdxDesc[iIndexSeqNumber - 1].iKeyLen)
- {
- GetString(4, pszRetBuffer); //"Key length exceeded."
- MessageBeep(-1);
- CLEANUP_NODISPLAY;
- }
-
- memcpy((pCHAR)pKeyBuf, pKeyVal, iKeyValLen);
- if (bExact == 0 && bNear == 0)
- {
- CHKERR_CLEANUP(DbiGetRecordForKey(hCur, TRUE, 0,
- iKeyValLen, (pBYTE)
- pKeyBuf, NULL));
-
- CHKERR_CLEANUP(DbiGetRecord(hCur, dbiNOLOCK, NULL,
- precProps));
-
- }
- if (bExact == 1)
- {
- CHKERR_CLEANUP(DbiGetRecordForKey(hCur, TRUE, 0,
- 0, (pBYTE) pKeyBuf,
- NULL));
-
- CHKERR_CLEANUP(DbiGetRecord(hCur, dbiNOLOCK, NULL,
- precProps));
- }
-
- if (bNear == 1)
- {
- CHKERR_CLEANUP(DbiSetToKey(hCur, keySEARCHGEQ, TRUE, 0,
- 0, pKeyBuf));
-
- CHKERR_CLEANUP(DbiGetNextRecord(hCur, dbiNOLOCK, pBuf,
- precProps));
- }
- }
-
- if (bExpFunc == 1) // for soundex
- {
- // if first char in pKeyVal is not a letter, fail
- // (because DbiGetRecordForKey won't).
- if (!((pKeyVal[0] > '@') && (pKeyVal[0] < '[')) &&
- !((pKeyVal[0] > '`') && (pKeyVal[0] < '{')))
- {
- GetString(5, pszRetBuffer); //"Invalid character."
- MessageBeep(-1);
- CLEANUP_NODISPLAY;
- }
-
- CHKERR_CLEANUP(DbiPutField(hCur, iFldNum, pBuf,
- (pBYTE) pKeyVal));
-
- CHKERR_CLEANUP(DbiExtractKey(hCur, pBuf, (pBYTE) pKeyBuf));
-
- CHKERR_CLEANUP(DbiGetRecordForKey(hCur, TRUE, 0, 0,
- (pBYTE) pKeyBuf, NULL));
-
- CHKERR_CLEANUP(DbiGetRecord(hCur, dbiNOLOCK, NULL, precProps));
- }
-
- retVal = precProps[0].iPhyRecNum;
- }
-
- if (pIdxDesc[iIndexSeqNumber - 1].iKeyExpType == fldDBKEYBCD)
- {
- // can't start with a space
- if (pKeyVal[0] == ' ')
- {
- CLEANUP_NODISPLAY;
- }
-
- if (strchr(&pKeyVal[0], ','))
- {
- GetString(6, pszRetBuffer); //"Use no commas."
- MessageBeep(-1);
- CLEANUP_NODISPLAY;
- }
-
- // set max for input to key buffer
- if (iKeyValLen > (pIdxDesc[iIndexSeqNumber - 1].iKeyLen) + 3)
- {
- GetString(4, pszRetBuffer); //"Key length exceeded."
- MessageBeep(-1);
- CLEANUP_NODISPLAY;
- }
-
- memset(pKeyBuf, '\0', pIdxDesc[iIndexSeqNumber - 1].
- iKeyLen * sizeof (BYTE));
- memset(szKeyBuf1, '\0', pIdxDesc[iIndexSeqNumber - 1].
- iKeyLen * sizeof (char));
-
- // OK, now for some decimal and negative number control...
- if (pKeyVal[0] == '.' || (pKeyVal[0] == '-' && pKeyVal[1] == '.'))
- {
- GetString(8, pszRetBuffer); //"Enter 0 or -0 first."
- MessageBeep(-1);
- CLEANUP_NODISPLAY;
- }
-
- ptok = strtok(pKeyVal, " .");
- strcpy(szKeyBuf4, ptok);
- iKeyValLen = strlen(szKeyBuf4);
- if (ptok)
- {
- ptok = strtok(NULL, ".");
- if (ptok)
- {
- uDecLen = strlen(&ptok[0]);
- strcat(szKeyBuf4, ptok);
- i = 0;
- if (szKeyBuf4[0] == '0')
- {
- while (szKeyBuf4[i] == '0')
- {
- i++;
- }
- strcpy(szKeyBuf2, &szKeyBuf4[i]);
- }
- else
- {
- szKeyBuf2 = strdup(szKeyBuf4);
- iKeyValLen = strlen(szKeyBuf2);
- }
- }
- else
- {
- szKeyBuf2 = strdup(szKeyBuf4);
- }
- }
-
- if (bIsNegative)
- {
- if (strlen(&pKeyVal[0]) > 1)
- {
- ptok = strtok(szKeyBuf2, " -");
- strcpy(szKeyBuf3, ptok);
- iKeyValLen = strlen(szKeyBuf3);
- fKeyVal = atof(szKeyBuf3);
- }
- else
- {
- CLEANUP_NODISPLAY;
- }
- }
- else
- {
- fKeyVal = atof(szKeyBuf2);
- }
-
- if (fKeyVal == 0)
- {
- CLEANUP_NODISPLAY;
- }
-
- // make total key bytes used an even number.
- x = div(iKeyValLen, 2);
- if (iKeyValLen > 1)
- {
- iKeyValEven = iKeyValLen;
- }
-
- if (x.rem == 1)
- {
- iKeyValEven = iKeyValLen + 1;
- }
-
- // setup first key buffer byte
- szPlaces[0] = szPlaces[0] + (char)(iKeyValLen - uDecLen);
- memmove(szKeyBuf1, szPlaces, 1);
-
- // setup second key buffer byte
- if (bIsNegative)
- {
- szPlaces[0] = (((iKeyValLen - 1) * 4) + 129);
- }
- else
- {
- szPlaces[0] = ((iKeyValLen * 4) + 1);
- }
-
- memmove(&szKeyBuf1[1], &szPlaces[0], 1);
-
- CHKERR_CLEANUP(DbiBcdFromFloat(&fKeyVal, iKeyValLen + 2,
- 2, &Bcd));
-
- if (iKeyValLen > 1)
- {
- iKeyValLen--;
- }
-
- for (i = 0; i < iKeyValLen; i++)
- {
- memmove(&szKeyBuf1[i + 2], &Bcd.iFraction[i], 1);
- }
-
- memcpy((pCHAR)pKeyBuf, szKeyBuf1, (iKeyValEven / 2) + 2);
-
- if (bNear == 1)
- {
- CHKERR_CLEANUP(DbiSetToKey(hCur, keySEARCHGEQ, TRUE, 0, 0,
- pKeyBuf));
- }
- else
- {
- CHKERR_CLEANUP(DbiSetToKey(hCur, keySEARCHEQ, TRUE, 0, 0,
- pKeyBuf));
- }
-
- CHKERR_CLEANUP(DbiGetNextRecord(hCur, dbiNOLOCK, pBuf, precProps));
-
- retVal = precProps[0].iPhyRecNum;
- }
- }
-
- CleanUp:
- if (hCur)
- {
- DbiCloseCursor(&hCur);
- }
- if (hDb)
- {
- DbiCloseDatabase(&hDb);
- }
- if (precProps)
- {
- free(precProps);
- }
- if (pBuf)
- {
- free(pBuf);
- }
- if (pKeyBuf)
- {
- free(pKeyBuf);
- }
- if (pIdxDesc)
- {
- free(pIdxDesc);
- }
- if (pFldDesc)
- {
- free(pFldDesc);
- }
- if (szKeyBuf1)
- {
- free(szKeyBuf1);
- }
- if (szKeyBuf2)
- {
- free(szKeyBuf2);
- }
- if (szKeyBuf3)
- {
- free(szKeyBuf3);
- }
- if (szKeyBuf4)
- {
- free(szKeyBuf4);
- }
- if (szFField)
- {
- free(szFField);
- }
-
- return retVal;
- }
-
- //=====================================================================
- // Function:
- // DbfGetIdxExpr(pCHAR pTblDir, pCHAR pTblName, pCHAR pIdxName,
- // pCHAR pIdxTag, pCHAR pszRetBuffer)
- //
- // Description:
- // This example shows how to return an expression string and
- // other information about an MDX file.
- //
- //=====================================================================
- void FAR WINAPI _export
- DbfGetIdxExpr (pCHAR pTblDir, pCHAR pTblName, pCHAR pIdxName,
- pCHAR pIdxTag, pCHAR pszRetBuffer)
- {
- CHAR szTblType[] = szDBASE;
- DBIResult rslt;
- CURProps TblProps;
- UINT16 iIndexSeqNumber;
- hDBIDb hDb = NULL;
- hDBICur hCur = NULL;
- IDXDesc *pIdxDesc = NULL;
-
- // initialize buffer for error string
- memset(pszRetBuffer, 0, (DBIMAXMSGLEN + 1) * sizeof(char));
-
- // open a database in the current session and get a database handle
- CHKERR_CLEANUP(DbiOpenDatabase(NULL, NULL, dbiREADONLY, dbiOPENSHARED,
- NULL, 0, NULL, NULL, &hDb));
-
- // set the current directory
- CHKERR_CLEANUP(DbiSetDirectory(hDb, pTblDir));
-
- // associate a cursor handle with an opened table
- CHKERR_CLEANUP(DbiOpenTable(hDb, pTblName, NULL, pIdxName, pIdxTag,
- 0, dbiREADONLY, dbiOPENSHARED, xltFIELD,
- FALSE, NULL, &hCur));
-
- CHKERR_CLEANUP(DbiGetCursorProps(hCur, &TblProps));
-
- if (strcmp(szTblType, TblProps.szTableType))
- {
- GetString(7, pszRetBuffer); //"Only dBASE tables are supported."
- CLEANUP_NODISPLAY;
- }
-
- pIdxDesc = (IDXDesc*) malloc (TblProps.iIndexes * sizeof(IDXDesc));
- if (pIdxDesc == NULL)
- {
- GetString(1, pszRetBuffer); //"Out of Memory."
- CLEANUP_NODISPLAY;
- }
-
- CHKERR_CLEANUP(DbiGetIndexDescs(hCur, pIdxDesc));
-
- CHKERR_CLEANUP(DbiGetIndexSeqNo(hCur, pIdxName, pIdxTag, NULL,
- &iIndexSeqNumber));
-
- if (pIdxDesc[iIndexSeqNumber - 1].bMaintained == 0)
- {
- GetString(3, pszRetBuffer); //"Only maintained indexes are supported."
- CLEANUP_NODISPLAY;
- }
-
- strcpy(pszRetBuffer, pIdxDesc[iIndexSeqNumber - 1].szKeyExp);
-
- CleanUp:
- if (hCur)
- {
- DbiCloseCursor(&hCur);
- }
- if (hDb)
- {
- DbiCloseDatabase(&hDb);
- }
- if (pIdxDesc)
- {
- free(pIdxDesc);
- }
- }
-
- //=====================================================================
- // Function:
- // DBIError(DBIResult retVal, pCHAR pszRetBuffer)
- //
- // Input:
- // retVal - BDE return
- // pszRetBuffer - Buffer to contain the error string
- //
- // Return: a DBIResult value.
- //
- // Description:
- // This function gets information of where an error occurred.
- //=====================================================================
- DBIResult
- DBIError (DBIResult retVal, pCHAR pszRetBuffer)
- {
- if (retVal == DBIERR_NONE)
- {
- return retVal;
- }
-
- if (retVal == DBIERR_CANTFINDODAPI)
- {
- GetString(2, pszRetBuffer); //"Cannot find IDAPI files: Check path."
- CLEANUP_DISPLAYERR(pszRetBuffer);
- }
- else
- {
- DbiGetErrorString(retVal, pszRetBuffer);
- }
-
- CleanUp:
- return retVal;
- }
-
- //=====================================================================
- // Function:
- // GetString(WORD iStringID, pCHAR pszRetBuffer)
- //
- // Input:
- // iStringID - Identifier for the string
- // pszRetBuffer - Buffer to contain the error string.
- // (Allocated by the calling function)
- //
- // Description:
- // Load a string from DBFSEEK.DLL.
- //=====================================================================
- void
- GetString (WORD iStringID, pCHAR pszRetBuffer)
- {
- if (pszRetBuffer)
- {
- LoadString(GetModuleHandle(szCURRENTMODULE), iStringID, pszRetBuffer,
- DBIMAXMSGLEN - 1);
- }
- }
-
-
- #pragma argsused
- BOOL WINAPI
- LibMain (HINSTANCE hInstance, WORD wDataSeg,
- WORD cbHeapSize, LPSTR lpCmdLine)
- {
- if (cbHeapSize != 0)
- {
- UnlockData(0);
- }
-
- return TRUE;
- }
-
- int WINAPI
- WEP (int nSystemExit)
- {
- switch (nSystemExit)
- {
- case WEP_SYSTEM_EXIT:
- break;
- case WEP_FREE_DLL:
- break;
- }
-
- return 1;
- }
-
-
-