home *** CD-ROM | disk | FTP | other *** search
/ Borland Programmer's Resource / Borland_Programmers_Resource_CD_1995.iso / code / kdbf / example / abrest.cpp next >
Encoding:
C/C++ Source or Header  |  1995-05-19  |  15.3 KB  |  571 lines

  1. /***************************************************************************
  2. *                                                                           
  3. * FILE: ABREST.CPP
  4. *
  5. * DESCRIPTION:  This file contains the member functions for the class
  6. *               AbstractRestaurant used in the sample program for the   
  7. *               C++ Database Framework.
  8. *               
  9. *
  10. ****************************************************************************/
  11.  
  12. #include <string.h>
  13. #include "demo.h"
  14.  
  15. /****************************************************************************
  16. *          
  17. * CLASS: AbstractRestaurant
  18. *                                                                
  19. * MEMBER FUNCTION: AbstractRestaurant (constructor)
  20. *
  21. * DESCRIPTION:  This is the constructor for the Abstract restaurant class.
  22. *               It creates a class of this type and associates it with
  23. *               a database.  
  24. *               
  25. * RETURNS: NONE              
  26. *
  27. ****************************************************************************/
  28.  
  29. AbstractRestaurant::AbstractRestaurant(BDatabase *db)
  30. {
  31.   //
  32.   // Create a cursor for the table to be opened later. 
  33.   //
  34.   cursorPtr = new BCursor();
  35.   //
  36.   //
  37.   // Set all the data members to their initial condition.
  38.   //
  39.   isOpen = FALSE;
  40.   lastError = PXSUCCESS;
  41.   //
  42.   //
  43.   // Set a pointer to the database object.
  44.   //
  45.   dataBase = db;
  46. }
  47.  
  48. /****************************************************************************
  49. *          
  50. * CLASS: AbstractRestaurant
  51. *                                                                
  52. * MEMBER FUNCTION: ~AbstractRestaurant (destructor)
  53. *
  54. * DESCRIPTION:  This is the destructor for the Abstract restaurant class.
  55. *               It will properly close a class of this type.
  56. *               
  57. * RETURNS: NONE              
  58. *
  59. ****************************************************************************/
  60.  
  61. AbstractRestaurant::~AbstractRestaurant()
  62. {
  63.   //
  64.   // Determine if the database was ever opened.
  65.   //
  66.   if(isOpen == TRUE)
  67.   {
  68.     //
  69.     // Call the close() member function to free up any memory storage
  70.     // and resources the class instance is using.
  71.     //
  72.     close();
  73.   }
  74.   //
  75.   // Delete the BCursor object in the class.
  76.   //
  77.   delete cursorPtr;
  78. }
  79.  
  80. /****************************************************************************
  81. *          
  82. * CLASS: AbstractRestaurant
  83. *                                                                
  84. * MEMBER FUNCTION: up
  85. *
  86. * DESCRIPTION: This function moves to the previous record in the database. 
  87. *              This is similiar to the C Engine PXRecPrev() function call.
  88. *               
  89. * RETURNS: PXERR_, if one occurs.
  90. *
  91. ****************************************************************************/
  92.  
  93. Retcode AbstractRestaurant::up()
  94. {
  95.   //
  96.   // Check to see that the database has been opened before moving to  
  97.   // a different record. 
  98.   //
  99.   if(isOpen != TRUE)
  100.   {
  101.     //
  102.     // It was not open, so return one of the special restaurant errors.
  103.     //
  104.     lastError = ERROR_TABLENOTOPEN;
  105.   }
  106.   else
  107.   {
  108.     //
  109.     // Call the gotoPrev member function of the open cursor for the database
  110.     // and save its error condition.
  111.     //
  112.     lastError = cursorPtr->gotoPrev();
  113.   }
  114.   //
  115.   // Return any error.
  116.   //
  117.   return(lastError);
  118. }
  119.  
  120. /****************************************************************************
  121. *          
  122. * CLASS: AbstractRestaurant
  123. *                                                                
  124. * MEMBER FUNCTION: down
  125. *
  126. * DESCRIPTION: This function moves to the next record in the database. 
  127. *              This is similiar to C Engine PXRecNext() function. 
  128. *               
  129. * RETURNS: PXERR_, if one occurs.
  130. *
  131. ****************************************************************************/
  132.  
  133. Retcode AbstractRestaurant::down()
  134. {
  135.   //
  136.   // Check to see that the database has been opened before moving to 
  137.   // another record. 
  138.   //
  139.   if(isOpen != TRUE)
  140.   {
  141.     //
  142.     // It was not open, so return one of the special restaurant errors.
  143.     //
  144.     lastError = ERROR_TABLENOTOPEN;
  145.   }
  146.   else
  147.   {
  148.     //
  149.     // Call the gotoNext member function of the open cursor for the database
  150.     // and save its error condition.
  151.     //
  152.     lastError = cursorPtr->gotoNext();
  153.   }
  154.   //
  155.   // Return any error.
  156.   //
  157.   return(lastError);
  158. }
  159.  
  160. /****************************************************************************
  161. *          
  162. * CLASS: AbstractRestaurant
  163. *                                                                
  164. * MEMBER FUNCTION: home
  165. *
  166. * DESCRIPTION: This function moves to the first record in the database. This
  167. *              is similiar to C Engine PXRecFirst() function.
  168. *
  169. * NOTE: The Database Framework does not have a function that moves to the
  170. *       first record in the table. This function must use the BCursor
  171. *       functions gotoBegin() and gotoNext() to move the record pointer to 
  172. *       the first record in the database.
  173. *               
  174. * RETURNS: PXERR_, if one occurs.
  175. *
  176. ****************************************************************************/
  177.  
  178. Retcode AbstractRestaurant::home()
  179. {
  180.   //
  181.   // Check to see that the database has been opened before moving to 
  182.   // another record. 
  183.   //
  184.   if(isOpen != TRUE)
  185.   {
  186.     //
  187.     // It was not open, so return one of the special restaurant errors.
  188.     //
  189.     lastError = ERROR_TABLENOTOPEN;
  190.   }
  191.   else
  192.   {
  193.     //
  194.     // Call the gotoBegin member function to move the current record pointer
  195.     // to a position in front of the first record.
  196.     //
  197.     lastError = cursorPtr->gotoBegin();
  198.     //
  199.     // Check if an error occurred.
  200.     //
  201.     if(lastError == PXSUCCESS)
  202.     {
  203.       //
  204.       // Move to the first record in the table.
  205.       //
  206.       lastError = cursorPtr->gotoNext();
  207.     }
  208.   }
  209.   //
  210.   // Return any error that occurred.
  211.   //
  212.   return(lastError);
  213. }
  214.  
  215. /****************************************************************************
  216. *          
  217. * CLASS: AbstractRestaurant
  218. *                                                                
  219. * MEMBER FUNCTION: end
  220. *
  221. * DESCRIPTION: This function moves to the last record in the database. This
  222. *              is similiar to C Engine PXRecLast() function. 
  223. *               
  224. * NOTE: The Database Framework does not have a function that moves to the
  225. *       last record in the table. This function must use the BCursor 
  226. *       functions gotoEnd() and gotoPrev() to move the record pointer to
  227. *       the last record in the database.
  228. *               
  229. * RETURNS: PXERR_, if one occurs.
  230. *
  231. ****************************************************************************/
  232.  
  233. Retcode AbstractRestaurant::end()
  234. {
  235.   //
  236.   // Check to see that the database has been opened before moving to 
  237.   // another record. 
  238.   //
  239.   if(isOpen != TRUE)
  240.   {
  241.     //
  242.     // It was not open, so return one of the special restaurant errors.
  243.     //
  244.     lastError = ERROR_TABLENOTOPEN;
  245.   }
  246.   else
  247.   {
  248.     //
  249.     // Call the gotoEnd member function of the open cursor for the database
  250.     // and save its error condition.
  251.     //
  252.     lastError = cursorPtr->gotoEnd();
  253.     //
  254.     // Check if an error occurred. 
  255.     //
  256.     if(lastError == PXSUCCESS)
  257.     {
  258.       //
  259.       // Moving to the previous record places the record pointer at the
  260.       // first record in the table.
  261.       //
  262.       lastError = cursorPtr->gotoPrev();
  263.     }
  264.   }
  265.   //
  266.   // Return any error.
  267.   //
  268.   return(lastError);
  269. }
  270.  
  271. /****************************************************************************
  272. *          
  273. * CLASS:  AbstractRestaurant
  274. *                                                                
  275. * MEMBER FUNCTION: open
  276. *
  277. * DESCRIPTION:  This function opens a given table name and assigns it
  278. *               to the BCursor data member in the class.
  279. *               
  280. * RETURNS: PXERR_, if one occurs.
  281. *
  282. ****************************************************************************/
  283.  
  284. Retcode AbstractRestaurant::open(char *tableName)
  285. {
  286.   //
  287.   // Check to see if the table is already open.
  288.   //
  289.   if (isOpen == TRUE)
  290.   {
  291.     return(lastError = PXERR_TABLEOPEN);
  292.   }
  293.   //
  294.   // Try to open the table.
  295.   //
  296.   lastError = cursorPtr->open(dataBase, tableName, 0, 0);
  297.   //
  298.   // Check if the table was successfully opened.
  299.   //
  300.   if (lastError == PXSUCCESS) 
  301.   {
  302.     //
  303.     // Table successfully opened.
  304.     //
  305.     isOpen = TRUE;
  306.   }
  307.  
  308.   return(lastError);
  309. }
  310.  
  311. /****************************************************************************
  312. *          
  313. * CLASS:  AbstractRestaurant
  314. *                                                                
  315. * MEMBER FUNCTION:  close
  316. *
  317. * DESCRIPTION:  This function closes an open restaurant table.
  318. *               
  319. * RETURNS:  PXERR_, if one occurs.
  320. *
  321. ****************************************************************************/
  322.  
  323. Retcode AbstractRestaurant::close()
  324. {
  325.   //
  326.   // Check to see if the table has been opened.
  327.   //
  328.   if (!isOpen) 
  329.   {
  330.      return(lastError = ERROR_TABLENOTOPEN);
  331.   }
  332.   //
  333.   // Flush and close the table.
  334.   //
  335.   lastError = cursorPtr->close();
  336.   if(lastError == PXSUCCESS)
  337.   {
  338.      isOpen = FALSE;
  339.   }
  340.   return(lastError);
  341. }
  342.  
  343. /****************************************************************************
  344. *          
  345. * CLASS:  AbstractRestaurant
  346. *                                                                
  347. * MEMBER FUNCTION: getRecord
  348. *
  349. * DESCRIPTION:  This function retrieves the current record from a table
  350. *               and places it in the generic record associated with
  351. *               th BCursor object.
  352. *               
  353. * RETURNS: PXERR_, if one occurs.
  354. *
  355. ****************************************************************************/
  356.  
  357. Retcode AbstractRestaurant::getRecord()
  358. {
  359.   //
  360.   // Retrieve a record using the member function getRecord() in
  361.   // the BCursor class.
  362.   //
  363.   lastError = cursorPtr->getRecord();
  364.   return(lastError);
  365. }
  366.  
  367. /****************************************************************************
  368. *          
  369. * CLASS:  AbstractRestaurant
  370. *                                                                
  371. * MEMBER FUNCTION: getBlobField
  372. *
  373. * DESCRIPTION:  This function retrieves part of the contents of a memo
  374. *               field and places it in buffer. sizeOfBuffer is the size
  375. *               of this buffer in bytes, including the NULL terminator.
  376. *               The function will read up to sizeOfBuffer - 1 bytes from
  377. *               the BLOB field.
  378. *               
  379. * RETURNS: PXERR_, if one occurs.
  380. *
  381. ****************************************************************************/
  382.  
  383. Retcode AbstractRestaurant::getBlobField(FIELDNUMBER blobField, char *buffer, 
  384.   unsigned int sizeOfBuffer, long offset, unsigned int &bytesRead)
  385. {
  386.   BRecord *curRecord;
  387.   //
  388.   // To be safe, set the buffer to ensure it is NULL terminated.
  389.   // When dealing with memo fields, the buffer is filled with the length 
  390.   // requested, without regard for a NULL terminator.
  391.   //  
  392.   //
  393.   memset(buffer, 0, sizeOfBuffer);
  394.  
  395.   //
  396.   // Determine if the table was opened.
  397.   //
  398.   if(!isOpen)
  399.   {
  400.      return(lastError = ERROR_TABLENOTOPEN);
  401.   }
  402.   //
  403.   // Used to reduce pointer dereference.
  404.   //
  405.   curRecord = cursorPtr->genericRec;
  406.  
  407.   //
  408.   // Set the length to read from the memo field. 
  409.   //
  410.   lastError = fixReadLength(blobField, sizeOfBuffer, offset, bytesRead);
  411.  
  412.   if(lastError == PXSUCCESS)
  413.   {
  414.     //
  415.     // Get string, but leave room for the null terminator <bytesRead>.
  416.     //
  417.     lastError = curRecord->getBlob(blobField, bytesRead, offset, buffer);
  418.   }
  419.   return(lastError);
  420. }
  421.  
  422. /****************************************************************************
  423. *          
  424. * CLASS: AbstractRestaurant
  425. *                                                                
  426. * MEMBER FUNCTION: getQuickBlob
  427. *
  428. * DESCRIPTION: This function retrieves a header from a BLOB field. 
  429. *               
  430. * RETURNS: PXERR_, if one occurs. 
  431. *
  432. ****************************************************************************/
  433.  
  434. Retcode AbstractRestaurant::getQuickBlob(FIELDNUMBER blobField, char *buffer, 
  435.   int length, int &bytesRead)
  436. {
  437.   BRecord *curRecord;
  438.   //
  439.   // To be safe, set the buffer to ensure it is NULL-terminated.
  440.   // When dealing with memo fields, the buffer is filled with the length 
  441.   // requested, without regard for a NULL terminator.
  442.   //  
  443.   memset(buffer, 0, length);
  444.   //
  445.   // Determine if the table was opened.
  446.   //
  447.   if(!isOpen)
  448.   {
  449.      return(lastError = ERROR_TABLENOTOPEN);
  450.   }
  451.   //
  452.   // Reduce pointer dereference. 
  453.   //
  454.   curRecord = cursorPtr->genericRec;
  455.  
  456.   //
  457.   // Call the Paradox Engine to get the header of the memo field.
  458.   //
  459.   lastError = curRecord->getBlobHeader(blobField, length, buffer, bytesRead);
  460.  
  461.   return(lastError);
  462. }
  463.  
  464. /****************************************************************************
  465. *          
  466. * CLASS:  AbstractRestaurant
  467. *                                                                
  468. * MEMBER FUNCTION: fixReadLength
  469. *
  470. * DESCRIPTION:  This function adjusts the length of the read request
  471. *               of a BLOB field if the current position is less than 
  472. *               sizeOfBuffer bytes from the end of the memo field.
  473. *               
  474. * RETURNS: PXERR_, if one occurs.
  475. *
  476. ****************************************************************************/
  477.  
  478. Retcode AbstractRestaurant::fixReadLength(FIELDNUMBER blobField, 
  479.   unsigned int sizeOfBuffer, long offset, unsigned int &readLength)
  480. {
  481.   BRecord *curRecord;
  482.   long lengthOfBlob;
  483.  
  484.   //
  485.   // Reduce pointer dereference.
  486.   //
  487.   curRecord = cursorPtr->genericRec;
  488.  
  489.   //
  490.   // Get the length of the memo field.
  491.   //
  492.   lengthOfBlob = curRecord->getBlobSize(blobField);
  493.  
  494.   //
  495.   // Determine if current length will read past the end of the BLOB data.
  496.   //
  497.   if(offset > lengthOfBlob)
  498.   { 
  499.     //
  500.     // Sufficient BLOB data remains. 
  501.     //
  502.     readLength = 0L;
  503.     return(PXERR_BLOBINVOFFSET);
  504.   }
  505.   //
  506.   // Determine if read will occur past the end of the BLOB data.
  507.   //
  508.   if((offset + sizeOfBuffer - 1) > lengthOfBlob)
  509.   {
  510.     //
  511.     // Adjust the amount of data to read.
  512.     //
  513.     readLength = (unsigned int)(lengthOfBlob - offset);
  514.   }
  515.   else
  516.   {
  517.     //
  518.     // Read is not attempting to read past the length of the BLOB data.
  519.     //
  520.     readLength = sizeOfBuffer - 1;
  521.   }
  522.   return(PXSUCCESS);
  523. }
  524.  
  525. /****************************************************************************
  526. *          
  527. * CLASS: AbstractRestaurant
  528. *                                                                
  529. * MEMBER FUNCTION: getBlobSize
  530. *
  531. * DESCRIPTION: This function returns the size of the memo BLOB field. 
  532. *               
  533. * RETURNS: Number of bytes in the memo field.
  534. *
  535. ****************************************************************************/
  536.  
  537. long AbstractRestaurant::getBlobSize(FIELDNUMBER blobField)
  538. {    
  539.   BRecord *curRecord;
  540.   long lengthOfBlob;
  541.  
  542.   lengthOfBlob = 0;
  543.   //
  544.   // Determine if the table was opened.
  545.   //
  546.   if(!isOpen)
  547.   {
  548.      lastError = ERROR_TABLENOTOPEN;
  549.      return(lengthOfBlob);
  550.   }
  551.   //
  552.   // Reduce pointer dereference. 
  553.   //
  554.   curRecord = cursorPtr->genericRec;
  555.   //
  556.   // Call member function getBlobSize of class BRecord.
  557.   //
  558.   lengthOfBlob = curRecord->getBlobSize(blobField);
  559.   //
  560.   // Get the error code from the cursor.
  561.   //
  562.   lastError = curRecord->lastError;
  563.  
  564.   return(lengthOfBlob);
  565.  
  566. }
  567.  
  568.  
  569.  
  570.  
  571.