// BDE - (C) Copyright 1995 by Borland International // idxpdox.c #include "snipit.h" #define NAMELEN 10 // The length of the name fields. #define PLACELEN 20 // The length of the POB field. #define DATELEN 11 // The display length of a date field: mm\dd\yyyy. static const char szTblName[] = "People"; static const char szTblType[] = szPARADOX; // Field descriptor used in creating a table. static SNIPFAR FLDDesc fldDesc[] = { { // Field 1 - First Name 1, // Field number "First Name", // 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, // Validity checks ( 0 ) fldrREADWRITE // Rights }, { // Field 2 - Middle Name 2, "Middle Name", fldZSTRING, fldUNKNOWN, NAMELEN, 0, 0, 0, 0, fldvNOCHECKS, fldrREADWRITE }, { // Field 3 - Last Name 3, "Last Name", fldZSTRING, fldUNKNOWN, NAMELEN, 0, 0, 0, 0, fldvNOCHECKS, fldrREADWRITE }, { // Field 4 - Date of Birth 4, "DOB", fldDATE, fldUNKNOWN, 0, 0, 0, 0, 0, fldvNOCHECKS, fldrREADWRITE }, { // Field 5 - Place of Birth 5, "POB", fldZSTRING, fldUNKNOWN, PLACELEN, 0, 0, 0, 0, fldvNOCHECKS, fldrREADWRITE } }; // Array of field descriptors. // Index descriptor - describes the index associated with the // table. static SNIPFAR IDXDesc idxDesc[] = { { // Primary Index - Full Name. "Full Name", // Name 1, // Number { NULL }, // Tag name ( for dBase ) { NULL }, // Optional format ( BTREE, // HASH, etc ) TRUE, // Primary? TRUE, // Unique? FALSE, // Descending? TRUE, // Maintained? FALSE, // Subset? FALSE, // Expression index? NULL, // For QBE only 3, // Fields in key 1, // Length in bytes FALSE, // Index out of date? 0, // Key type of expression { 1,2,3 }, // Array of field numbers { 0 }, // Key expression { 0 }, // Key condition FALSE, // Case insensitive 0, // Block size in bytes 0 // Restructure number }, { // Secondary Index 1 - single-field - maintained, // Case insensitive. "Last Name", 2, { NULL }, { NULL }, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, NULL, 1, 1, FALSE, 0, { 3 }, { 0 }, { 0 }, TRUE, 0, 0 }, { // Secondary Index 2 - multi-field - maintained. "Name", 3, { NULL }, { NULL }, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, NULL, 2, 1, FALSE, 0, { 3,1 }, { 0 }, { 0 }, FALSE, 0, 0 } }; // Index descriptor - Describes the indexes associated with the // table. This index will be added to the table after the table // has been created. static SNIPFAR IDXDesc idxDesc1[] = { { // Secondary Index 3 - single-field - not maintained. "POB", 4, { NULL }, { NULL }, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL, 1, 1, FALSE, 0, { 5 }, { 0 }, { 0 }, FALSE, 0, 0 } }; // Number of fields in the table. static const unsigned uNumFields = sizeof(fldDesc) / sizeof (fldDesc[0]); // Number of indexes to be created when the table is created. static const unsigned uNumIndexes = sizeof(idxDesc) / sizeof(idxDesc[0]); static DBIResult InitTable(phDBIDb phDb); static DBIResult AddRecord(phDBICur hCur, pCHAR pszFirst, pCHAR pszMiddle, pCHAR pszLast, UINT16 iMonth, UINT16 iDay, UINT16 iYear, pCHAR pszPOB); //===================================================================== // Function: // IndexPDox(); // // Description: // This example shows how to create and add Paradox indexes. // This includes creating primary indexes and managing // non-maintained secondary indexes. //===================================================================== void IndexPDox (void) { hDBIDb hDb; // Database handle hDBICur hCur; // Cursor handle CURProps TblProps; // Table properties IDXDesc *MyDesc; // Index descriptor UINT16 i; // Loop variable DBIResult rslt; // Return value from IDAPI functions Screen("*** Paradox Index Manipulation 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 fill with data. if (InitTable(&hDb)) { CloseDbAndExit(&hDb); Screen("\r\n*** End of Example ***"); return; } // Add an index to the table. Note that the index is added to the // table before the table is opened - the table must either be closed // or be opened in exclusive mode to add an index. Screen(" Add an index to the table..."); rslt = DbiAddIndex(hDb, NULL, (pCHAR) szTblName, (pCHAR) szTblType, idxDesc1, NULL); ChkRslt(rslt, "AddIndex"); 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; } Screen(" Get the number of indexes on the %s table...", szTblName); rslt = DbiGetCursorProps(hCur, &TblProps); ChkRslt(rslt, "GetCursorProps"); Screen(" There are %d indexes on the table", TblProps.iIndexes); // Allocate space for the index descriptor. MyDesc = (IDXDesc *) malloc(sizeof(IDXDesc) * TblProps.iIndexes); if (MyDesc == NULL) { Screen(" Error - Out of memory"); CloseDbAndExit(&hDb); Screen("\r\n*** End of Example ***"); return; } Screen(" Get and display information about the indexes"); Screen("\r\n Name\t\t ID\tPrimary Maintained " "Fields Case_Insensitive"); Screen(" ==================================================" "=========="); for (i = 0;i < TblProps.iIndexes; i++) { rslt = DbiGetIndexDesc(hCur, (i+1), &(MyDesc[i])); ChkRslt(rslt, "GetIndexDesc"); Screen(" %-15s\t%5d \t%s\t%2s\t %4d\t %2s", (strcmp(MyDesc[i].szName, "") ? MyDesc[i].szName : "*Primary Index*"), // Primary indexes don't have a name. MyDesc[i].iIndexId, // The ID of the Index. // Display "TRUE" or "FALSE" as opposed to 1 or 0.... (MyDesc[i].bPrimary ? "TRUE" : "FALSE"), (MyDesc[i].bMaintained ? "TRUE" : "FALSE"), MyDesc[i].iFldsInKey, (MyDesc[i].bCaseInsensitive ? "TRUE" : "FALSE")); } rslt = DbiSetToBegin(hCur); ChkRslt(rslt, "SetToBegin"); // Display the records in the table. The order of the records depends // on the active index - in this case, it is the primary index. Screen("\r\n Display the records in the table in the order of the" " primary \r\n index - First, Middle, Last"); DisplayTable(hCur, 0); // Switch the index that the table is opened on - only need to // provide one of the following: IndexName, TagName, or IndexId. Screen("\r\n Change the table to be opened on the \"Last Name\"" " index..."); rslt = DbiSwitchToIndex(&hCur, idxDesc[1].szName, NULL, NULL, FALSE); ChkRslt(rslt, "SwitchToIndex"); // Go to the beginning of the table. rslt = DbiSetToBegin(hCur); ChkRslt(rslt, "SetToBegin"); Screen(" Display the records in the table in the order of the" " \"Last Name\" index..."); DisplayTable(hCur, 0); Screen("\r\n Add a record to the table in order to invalidate" " non-maintained indexes..."); AddRecord(&hCur, "Jerry", "Joel", "Raccah", 5, 22, 1958, "Lake Tahoe"); // Switch the index that the table is opened on - only need to // provide one of the following: IndexName, TagName, or IndexId. // This function is passed an ID of 5 which is the id of the // single field that it is indexing on. Screen("\r\n Change the table to be opened on the \"POB\"" " index (which is non-maintained)..."); Screen("\r\n Error expected - the \"POB\" index is" " not maintained"); rslt = DbiSwitchToIndex(&hCur, NULL, NULL, MyDesc[1].iIndexId, FALSE); ChkRslt(rslt, "SwitchToIndex"); Screen("\r\n Steps to regenerate the \"POB\" index..."); Screen(" Close the table - the table must be open in" " exclusive mode to regenerate \r\n the indexes..."); rslt = DbiCloseCursor(&hCur); ChkRslt(rslt, "CloseCursor"); Screen(" Open the table in exclusive mode..."); rslt = DbiOpenTable(hDb, (pCHAR) szTblName, (pCHAR) szTblType, NULL, NULL, 0, dbiREADWRITE, dbiOPENEXCL, xltFIELD, FALSE, NULL, &hCur); if (ChkRslt(rslt, "OpenTable") != DBIERR_NONE) { CloseDbAndExit(&hDb); Screen("\r\n*** End of Example ***"); return; } Screen(" Regenerate the index..."); rslt = DbiRegenIndex(hDb, hCur, (pCHAR) szTblName, (pCHAR) szTblType, MyDesc[1].szName, NULL, NULL); ChkRslt(rslt, "RegenIndexes"); // Switch the index that the table is opened on - only need to // provide one of the following: IndexName, TagName, or IndexId // (parameter 2, 3, or 4 to DbiSwitchToIndex). Screen("\r\n Change the table to be opened on the \"POB\"" " index (which is non-maintained)..."); rslt = DbiSwitchToIndex(&hCur, MyDesc[1].szName, NULL, NULL, FALSE); ChkRslt(rslt, "SwitchToIndex"); rslt = DbiSetToBegin(hCur); ChkRslt(rslt, "SetToBegin"); Screen(" Display the records in the table in the order of the" " \"POB\" (Place of Birth)\r\n index..."); DisplayTable(hCur, 0); // Note that the table has to be opened in exclusive mode or closed // to delete an index. Screen("\r\n Delete the \"Last Name\" index..."); rslt = DbiDeleteIndex(hDb, NULL, (pCHAR) szTblName, (pCHAR) szTblType, "Last Name", "", NULL); ChkRslt(rslt, "DeleteIndex"); Screen(" Close the %s table...", szTblName); rslt = DbiCloseCursor(&hCur); ChkRslt(rslt, "CloseCursor"); Screen(" Delete the %s table and remaining indexes...", szTblName); rslt = DbiDeleteTable(hDb, (pCHAR) szTblName, (pCHAR) szTblType); ChkRslt(rslt, "DeleteTable"); free(MyDesc); 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 // // Description: // This function will create a table and fill it // with a number of records. //===================================================================== 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 // 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 %s table...", szTblName); 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); if (ChkRslt(rslt, "OpenTable") != DBIERR_NONE) { return rslt; } // Add records to the table. Screen(" Add records to the table..."); AddRecord(&hCur, "Klaus", "John", "Lockwood", 7, 28, 1968, "Chicago"); AddRecord(&hCur, "Tracy", "Dunvan", "Aoki", 12, 27, 1969, "Hermosa Beach"); AddRecord(&hCur, "John", "David", "Krull", 2, 7, 1954, "Ohmaha"); AddRecord(&hCur, "Goliath", "Joel", "Raccah", 4, 13, 1966, "Tel Aviv"); rslt = DbiCloseCursor(&hCur); ChkRslt(rslt, "CloseCursor"); return rslt; } //===================================================================== // Function: // AddRecord(hCur, pszFirst, pszMiddle, pszLast, iMonth, // iDay, iYear, pszPOB); // // Input: hCur - Pointer to the cursor handle // pszFirst - First name // pszMiddle - Middle name // pszLast - Last name // iMonth - Month of birth // iDay - Day of birth // iYear - Year of birth // pszPOB - Place of birth // // Return: Result of adding the record to the table // // Description: // This function will add a record to the given table. //===================================================================== DBIResult AddRecord (phDBICur hCur, pCHAR pszFirst, pCHAR pszMiddle, pCHAR pszLast, UINT16 iMonth, UINT16 iDay, UINT16 iYear, pCHAR pszPOB) { DATE Date; // Date structure 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; } // Make sure we're starting with a clean record buffer. rslt = DbiInitRecord(*hCur, pRecBuf); ChkRslt(rslt, "InitRecord"); // First name. rslt = DbiPutField(*hCur, 1, pRecBuf, (pBYTE) pszFirst); ChkRslt(rslt, "PutField"); // Middle name. rslt = DbiPutField(*hCur, 2, pRecBuf, (pBYTE) pszMiddle); ChkRslt(rslt, "PutField"); // Last name. rslt = DbiPutField(*hCur, 3, pRecBuf, (pBYTE) pszLast); ChkRslt(rslt, "PutField"); // Date of birth. rslt = DbiDateEncode(iMonth, iDay, iYear, &Date); ChkRslt(rslt, "DateEncode"); rslt = DbiPutField(*hCur, 4, pRecBuf, (pBYTE) &Date); ChkRslt(rslt, "PutField"); // Place of Birth. rslt = DbiPutField(*hCur, 5, pRecBuf, (pBYTE) pszPOB); ChkRslt(rslt, "PutField"); rslt = DbiInsertRecord(*hCur, dbiNOLOCK, pRecBuf), ChkRslt(rslt, "InsertRecord"); free(pRecBuf); return rslt; }