// BDE - (C) Copyright 1995 by Borland International // idxexpr.c #include "snipit.h" #define NAMELEN 30 // Length of the name field. static const char szTblName[] = "order"; static const char szMasterTblName[] = "cust"; static const char szTblType[] = szDBASE; // Key expression used to link the detail table. static SNIPFAR char szMstrExp[] = "TRIM(CITY) + \", \" + STATE_PROV"; // Field descriptor used in creating a table. static SNIPFAR FLDDesc fldDesc[] = { { // Field 1 - Customer Number 1, // Field number "CITY_STATE", // Field name fldZSTRING, // Field type fldUNKNOWN, // Field subtype 35, // 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, // Validity checks ( 0 ) fldrREADWRITE // Rights }, { // Field 2 - Name 2, "NAME", fldZSTRING, fldUNKNOWN, NAMELEN, 0, 0, 0, 0, fldvNOCHECKS, fldrREADWRITE }, { // Field 3 - Phone 3, "Phone", fldZSTRING, fldUNKNOWN, 15, 0, 0, 0, 0, fldvNOCHECKS, fldrREADWRITE } }; // Array of field descriptors. // Index descriptor - describes the Index associated with the // detail table. static SNIPFAR IDXDesc idxDesc[] = { { // Production Index - expression index. "order.mdx", // Name NULL, // Number {"CITY_STATE"}, // Tag name ( for dBASE ) { NULL }, // Optional format ( BTREE, // HASH, etc ) FALSE, // Primary? FALSE, // Unique? FALSE, // Descending? TRUE, // Maintained? FALSE, // Subset? FALSE, // Expression index? NULL, // For QBE only 1, // Fields in key 1, // Length in bytes FALSE, // Index out of date? 0, // Key type of expression { 1 }, // Array of field numbers { NULL}, // Key expression { NULL }, // Key condition FALSE, // Case insensitive 0, // Block size in bytes 0 // Restructure number } }; static DBIResult InitTable(phDBIDb phDb); static DBIResult AddRecord(phDBICur phCur, pCHAR pszCityState, pCHAR pszName, pCHAR pszPhone); //===================================================================== // Function: // IndexExpr(); // // Description: // This example shows how to create expression indexes and // link two tables together based upon the expression index // (which is similar to Set Relation to... in the dBASE language). // When the link is established, you will only be able to see a // subset of the records in the Detail table which correspond // to the current record of the Master table. //===================================================================== void IndexExpr (void) { hDBIDb hDb; // Database handle hDBICur hCur; // Cursor handle to the detail table hDBICur hMCur; // Cursor handle to the master table UINT16 i; // For looping. DBIResult rslt; // Return value from IDAPI functions Screen("*** dBASE Expression Index 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"); // Create the table and insert four records. if (InitTable(&hDb)) { CloseDbAndExit(&hDb); Screen("\r\n*** End of Example ***"); return; } Screen(" Open the %s table as the detail table (must be opened in" " shared mode)...", szTblName); rslt = DbiOpenTable(hDb, (pCHAR) szTblName, (pCHAR) szTblType, idxDesc[0].szName, idxDesc[0].szTagName, NULL, dbiREADWRITE, dbiOPENSHARED, xltFIELD, FALSE, NULL, &hCur); if (ChkRslt(rslt, "OpenTable") != DBIERR_NONE) { CloseDbAndExit(&hDb); Screen("\r\n*** End of Example ***"); return; } Screen(" Open the %s table, which is used as the master table...", szMasterTblName); rslt = DbiOpenTable(hDb, (pCHAR) szMasterTblName, (pCHAR) szTblType, NULL, NULL, NULL, dbiREADWRITE, dbiOPENSHARED, xltFIELD, FALSE, NULL, &hMCur); if (ChkRslt(rslt, "OpenTable") != DBIERR_NONE) { CloseDbAndExit(&hDb); Screen("\r\n*** End of Example ***"); return; } // Go to the top of the master table which is ordered by cust_no. rslt = DbiSetToBegin(hMCur); ChkRslt(rslt, "SetToBegin"); // Put the Cust table into link mode. rslt = DbiBeginLinkMode(&hMCur); ChkRslt(rslt, "BeginLinkMode"); // Put the Orders table into link mode. rslt = DbiBeginLinkMode(&hCur); ChkRslt(rslt, "BeginLinkMode"); // Now link the two cursors/tables together. Screen(" Link the two tables togther"); rslt = DbiLinkDetailToExp(hMCur, hCur, 0, (pCHAR) szMstrExp); ChkRslt(rslt, "LinkDetailToExp"); // The detail table has matching data only for the first two records // of the master table. for (i = 0; i < 3; i++) { // Display the master record. Screen("\r\n This is the master record"); DisplayTable(hMCur, 1); // Display all the detail records. Screen("\r\n This is the detail record(s)"); DisplayTable(hCur, 0); } Screen("\r\n There are no records in the detail table for the" "\r\n third record in the master table. Therefore, it" "\r\n should come up blank."); Screen("\r\n End the link..."); rslt = DbiUnlinkDetail(hCur); ChkRslt(rslt, "EndLinkMode"); // Take the Customer table out of link mode. rslt = DbiEndLinkMode(&hMCur); ChkRslt(rslt, "EndLinkMode"); // Take the Orders table out of link mode. rslt = DbiEndLinkMode(&hCur); ChkRslt(rslt, "EndLinkMode"); Screen(" Close the %s table...", szMasterTblName); rslt = DbiCloseCursor(&hMCur); ChkRslt(rslt, "CloseCursor"); Screen(" Close the %s table...", szTblName); rslt = DbiCloseCursor(&hCur); ChkRslt(rslt, "CloseCursor"); Screen(" Delete the %s table...", szTblName); 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: // InitTable(phDb); // // Input: phDb - Pointer to the database handle // // Return: Result of the table initialization // // Desc: This function will create a table and fill the table // with a number of records. The function uses // another function called AddRecord which adds records to // the table. //===================================================================== DBIResult InitTable (phDBIDb phDb) { DBIResult rslt; // Value returned from IDAPI functions hDBICur hCur; // Cursor handle for the table that is // created CRTblDesc crTblDsc; // Table descriptor BOOL bOverWrite = TRUE; // Overwrite, yes/no flag // The number of fields in the table. const unsigned uNumFields = sizeof(fldDesc) / sizeof (fldDesc[0]); // Number of indexes to be created when the table is created. const unsigned uNumIndexes = sizeof(idxDesc) / sizeof(idxDesc[0]); // Initialize the Table Create descriptor. memset(&crTblDsc, 0, sizeof(CRTblDesc)); strcpy(crTblDsc.szTblName, szTblName); strcpy(crTblDsc.szTblType, szTblType); crTblDsc.iFldCount = uNumFields; crTblDsc.pfldDesc = fldDesc; crTblDsc.iIdxCount = uNumIndexes; crTblDsc.pidxDesc = idxDesc; Screen(" Creating the table and indexes..."); rslt = DbiCreateTable(*phDb, bOverWrite, &crTblDsc); if (ChkRslt(rslt, "CreateTable") != DBIERR_NONE) { return rslt; } rslt = DbiOpenTable(*phDb, (pCHAR) szTblName, (pCHAR) szTblType, NULL, NULL, 0, dbiREADWRITE, dbiOPENSHARED, xltFIELD, FALSE, NULL, &hCur); ChkRslt(rslt, "OpenTable"); Screen(" Adding records to the table..."); rslt = AddRecord(&hCur, "Kapaa Kauai, HI", "Kapaa Dive Shoppe", "(408)-321-1729"); rslt = AddRecord(&hCur, "Kapaa Kauai, HI", "Kapaa Dive Shoppe", "(408)-321-1729"); rslt = AddRecord(&hCur, "Freeport, ", "Unisco", "(415)-567-1799"); rslt = AddRecord(&hCur, "Freeport, ", "Divers", "(415)-365-6159"); rslt = DbiCloseCursor(&hCur); ChkRslt(rslt, "CloseCursor"); return rslt; } //===================================================================== // Function: // AddRecord(phCur, pszCityState, pszName, pszPhone); // // Input: phCur - Pointer to the cursor handle // pszCityState - City and state // pszName - Customer name // pszPhone - Customer phone number // // Return: Result of adding the record to the table // // Desc: This function will add a record to the given table. //===================================================================== DBIResult AddRecord (phDBICur hCur, pCHAR pszCityState, pCHAR pszName, pCHAR pszPhone) { DBIResult rslt; // Value returned from IDAPI functions CURProps TblProps; // Table Properties pBYTE pRecBuf; // Record Buffer // Allocate a record buffer. rslt = DbiGetCursorProps(*hCur, &TblProps); ChkRslt(rslt, "GetCursorProps"); pRecBuf = (pBYTE) malloc(TblProps.iRecBufSize * sizeof(BYTE)); if (pRecBuf == NULL) { return DBIERR_NOMEMORY; } // Start with a clean record buffer. rslt = DbiInitRecord(*hCur, pRecBuf); ChkRslt(rslt, "InitRecord"); // City_state. rslt = DbiPutField(*hCur, 1, pRecBuf, (pBYTE)pszCityState); ChkRslt(rslt, "PutField"); // Customer name. rslt = DbiPutField(*hCur, 2, pRecBuf, (pBYTE) pszName); ChkRslt(rslt, "PutField"); // Customer phone number. rslt = DbiPutField(*hCur, 3, pRecBuf, (pBYTE) pszPhone); ChkRslt(rslt, "PutField"); // Now insert the record. rslt = DbiInsertRecord(*hCur, dbiNOLOCK, pRecBuf); ChkRslt(rslt, "InsertRecord"); free(pRecBuf); return rslt; }