// BDE - (C) Copyright 1995 by Borland International // refinteg.c #include "snipit.h" static DBIResult AddRecord(hDBICur hCur, DFLOAT fStatus, DFLOAT fOrder, CHAR *szDateSent, CHAR *szDateDelivered); static const char szTblName[] = "RefInteg"; static const char szTblType[] = szPARADOX; // Field descriptor used in creating a table. static SNIPFAR FLDDesc fldDesc[] = { { // Field 1 - AUTOINC 1, // Field number "Status ID", // Field name fldFLOAT, // Field type fldUNKNOWN, // Field subtype 0, // 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 - ALPHA 2, "Order No", fldFLOAT, fldUNKNOWN, 0, 0, 0, 0, 0, fldvNOCHECKS, fldrREADWRITE }, { // Field 4 - DATE 3, "Date Sent", fldDATE, fldUNKNOWN, 0, 0, 0, 0, 0, fldvNOCHECKS, fldrREADWRITE }, { // Field 4 - DATE 4, "Date Received", fldDATE, fldUNKNOWN, 0, 0, 0, 0, 0, fldvNOCHECKS, fldrREADWRITE } }; // Array of field descriptors. // The number of fields in the table. static const UINT16 uNumFields = sizeof(fldDesc) / sizeof(fldDesc[0]); // Array of referential integrity rules. static SNIPFAR RINTDesc rintDesc[] = { { 1, // Referential integrity number "Order No", // Name for this integrity rintDEPENDENT, // Whether master or dependent "orders.db", // Other table name rintCASCADE, // Modify qualifier rintRESTRICT, // Delete modifier 1, // Fields in foreign key {2}, // Fields in this table {1} // Fields in other table } }; // Number of referential integrity rules. static const INT16 iRintCount = sizeof(rintDesc) / sizeof(rintDesc[0]); // Index Descriptor - describes the indexes associated with the // table. This index is going to be added to the table when the // table is created. static SNIPFAR IDXDesc idxDesc[] = { { // Primary Index "", // 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 2, // Fields in key 1, // Length in bytes FALSE, // Index out of date? 0, // Key type of expression { 1,2 }, // 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. "Order No", 2, { NULL }, { NULL }, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, NULL, 1, 1, FALSE, 0, { 2 }, { 0 }, { 0 }, FALSE, 0, 0 } }; // Number of indexes to be created when the table is created. static const unsigned uNumIndexes = sizeof(idxDesc) / sizeof(idxDesc[0]); //===================================================================== // Function: // RefInteg(); // // Description: // This function shows how to create and use referential // integrity. //===================================================================== void RefInteg (void) { DBIResult rslt; // Return value from IDAPI functions 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 CROpType crOpType[] = { crADD }; // Define the operation on the table. Screen("*** Referential Integrity Example ***\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"); Screen(" Initializing the table descriptor..."); memset((void *)&TblDesc, 0, sizeof(CRTblDesc)); lstrcpy(TblDesc.szTblName, szTblName); lstrcpy(TblDesc.szTblType, szTblType); TblDesc.iFldCount = uNumFields; TblDesc.pfldDesc = fldDesc; TblDesc.iIdxCount = uNumIndexes; TblDesc.pidxDesc = idxDesc; TblDesc.iRintCount = iRintCount; TblDesc.pecrRintOp = crOpType; TblDesc.printDesc = rintDesc; Screen(" Creating the %s table...", szTblName); rslt = DbiCreateTable(hDb, TRUE, &TblDesc); if (ChkRslt(rslt, "CreateTable") != DBIERR_NONE) { CloseDbAndExit(&hDb); Screen("\r\n*** End of Example ***"); return; } 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) { rslt = DbiDeleteTable(hDb, (pCHAR) szTblName, (pCHAR) szTblType); ChkRslt(rslt, "DeleteTable"); CloseDbAndExit(&hDb); Screen("\r\n*** End of Example ***"); return; } // This add will fail. Order ID 900 does not exist within the // Orders table. Screen(" Add a record to the table."); Screen(" Error Expected - no record in the orders table has an" " ID of 900..."); AddRecord(hCur, 1, 900, "07/28/1994", "08/12/1994"); // This add will succeed. Order ID 1004 exists within the Orders // table. Screen("\r\n Add a record to the table with a valid Order ID..."); AddRecord(hCur, 1, 1004, "07/28/1994", "08/12/1994"); rslt = DbiSetToBegin(hCur); ChkRslt(rslt, "SetToBegin"); Screen(" Display the \"%s\" table...", szTblName); DisplayTable(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: // AddRecord(hCur, fStatus, fOrder, *DateSent, *DateDelivered) // // Input: hCur - Cursor to which the record will be added // fStatus - Value to write to the Status ID field // fOrder - Value to write to the Order ID field // DateSent - Value to write to the Date Sent field // DateDelivered - Value to write to the Date Received field // // Return: Success of the function. // // Description: // This function is used to add a record to the table. //===================================================================== DBIResult AddRecord (hDBICur hCur, DFLOAT fStatus, DFLOAT fOrder, CHAR *szDateSent, CHAR *szDateDelivered) { DBIResult rslt; // Return value from IDAPI functions pBYTE pRecBuf; // Record buffer CURProps TblProps; // The properties of the table UINT16 uMonth; // Contains the month portion of the // date UINT16 uDay; // Contains the day portion of the // date INT16 iYear; // Contains the year portion of the // date CHAR szDate[30]; // Pointer to be allocated off the // heap CHAR *pszTemp; // Temporary string used in parsing // the date DBIDATE Date; // Date structure, used in // DbiPutField // Allocate a record buffer. rslt = DbiGetCursorProps(hCur, &TblProps); ChkRslt(rslt, "GetCursorProps"); pRecBuf = (pBYTE) malloc(TblProps.iRecBufSize * sizeof(pBYTE)); if (pRecBuf == NULL) { Screen(" Error - Out of Memory"); return DBIERR_NOMEMORY; } // Make sure we're starting with a clean record buffer rslt = DbiInitRecord(hCur, pRecBuf); ChkRslt(rslt, "InitRecord"); // Add the Status ID to the record buffer rslt = DbiPutField(hCur, 1, pRecBuf, (pBYTE) &fStatus); ChkRslt(rslt, "PutField"); // Add the Order ID to the record buffer. rslt = DbiPutField(hCur, 2, pRecBuf, (pBYTE) &fOrder); ChkRslt(rslt, "PutField"); strcpy(szDate, szDateSent); // Need to convert the string to a Date structure. pszTemp = strtok(szDate, "/"); if (pszTemp) { uMonth = atoi(pszTemp); // uMonth set to 0 if invalid date. pszTemp = strtok(NULL, "/"); if (pszTemp) { uDay = atoi(pszTemp); // uDay set to 0 if invalid date. pszTemp = strtok(NULL, "/"); if (pszTemp) { iYear = atoi(pszTemp); // iYear set to 0 if // invalid date. } } } // Encode the date. rslt = DbiDateEncode(uMonth, uDay, iYear, &Date); ChkRslt(rslt, "DateEncode"); // Put the data into the record buffer. rslt = DbiPutField(hCur, 3, pRecBuf, (pBYTE) &Date); strcpy(szDate, szDateDelivered); // Need to convert the string to a Date structure. pszTemp = strtok(szDate, "/"); if (pszTemp) { uMonth = atoi(pszTemp); // uMonth set to 0 if invalid date. pszTemp = strtok(NULL, "/"); if (pszTemp) { uDay = atoi(pszTemp); // uDay set to 0 if invalid date. pszTemp = strtok(NULL, "/"); if (pszTemp) { iYear = atoi(pszTemp); // iYear set to 0 if // invalid date. } } } // Encode the date. rslt = DbiDateEncode(uMonth, uDay, iYear, &Date); ChkRslt(rslt, "DateEncode"); // Put the data into the record buffer. rslt = DbiPutField(hCur, 4, pRecBuf, (pBYTE) &Date); ChkRslt(rslt, "PutField"); // Insert the record into the table. rslt = DbiInsertRecord(hCur, dbiNOLOCK, pRecBuf); ChkRslt(rslt, "InsertRecord"); free(pRecBuf); return rslt; }