home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************************
- *
- * FILE: REST.CPP
- *
- * DESCRIPTION: This file contains the member functions for the class
- * MainRestaurant used in the sample program for the
- * C++ Database Framework.
- *
- *
- ****************************************************************************/
- #include <string.h>
- #include "demo.h"
-
- //
- // Field arrays for the composite keys used in searches of the main table.
- //
- FIELDNUMBER ratingTypeFields[] = {MAIN_RATING_FIELD, MAIN_TYPE_FIELD};
- FIELDNUMBER cityTypeFields[] = {MAIN_CITY_FIELD, MAIN_TYPE_FIELD};
-
-
- /****************************************************************************
- *
- * CLASS: MainRestaurant
- *
- * MEMBER FUNCTION: MainRestaurant (constructor)
- *
- * DESCRIPTION: This function creates an instance of a MainRestaurant
- * class object.
- *
- * RETURNS: NONE
- *
- ****************************************************************************/
-
- MainRestaurant::MainRestaurant(BDatabase *db) : AbstractRestaurant(db)
- {
- //
- // Set the field data members to blank.
- //
-
- memset(name, 0, MAX_NAME_LEN + 1);
- memset(type, 0, MAX_TYPE_LEN + 1);
- memset(street, 0, MAX_STREET_LEN + 1);
- memset(city, 0, MAX_CITY_LEN + 1);
- memset(state, 0, MAX_STATE_LEN + 1);
- memset(zip, 0, MAX_ZIP_LEN + 1);
- memset(telephone,0, MAX_TELEPHONE_LEN + 1);
- rating = 0;
-
- //
- // Construct cursors for the composite secondary indexes.
- //
- ratingTypeIndex = new BCursor();
- cityTypeIndex = new BCursor();
-
- }
-
- /****************************************************************************
- *
- * CLASS: MainRestaurant
- *
- * MEMBER FUNCTION: ~MainRestaurant (destructor)
- *
- * DESCRIPTION: This is the destructor for the main restaurant class.
- * It will properly close a class of this type.
- *
- * RETURNS: NONE
- *
- ****************************************************************************/
-
- MainRestaurant::~MainRestaurant()
- {
- //
- // Delete the BCursor objects in the class for the secondary indexes.
- //
- delete ratingTypeIndex;
- delete cityTypeIndex;
- }
-
- /****************************************************************************
- *
- * CLASS: MainRestaurant
- *
- * MEMBER FUNCTION: getRecord
- *
- * DESCRIPTION: This function gets the current record from the database
- * and assigns the field values to the data members in the
- * class.
- *
- * NOTE:
- *
- * Since BLOB fields are not stored in the table's .DB file, getting the
- * record does not retrieve the BLOB field's contents. Two functions are
- * used to get a record and a BLOB field. First, one must get the record
- * and then the BLOB fields must be retrieved. Between the call to
- * getRecord() and open BlobRead(), the BLOBs record could be deleted, or
- * the BLOB could be changed. If this happens, openBlobRead() will return
- * PXERR_BLOBMODIFIED. To prevent BLOB updates while a record is being
- * read, you can lock the record prior to calling getRecord() and release
- * the lock after getting the BLOB fields.
- *
- * RETURNS: PXERR_, if one occurs.
- *
- ****************************************************************************/
-
- Retcode MainRestaurant::getRecord()
- {
- BRecord *currentRecord;
- LOCKHANDLE recordLockHandle;
- BOOL isBlank;
-
- //
- // See if the table was opened.
- //
- if(!isOpen)
- {
- return(lastError = ERROR_TABLENOTOPEN);
- }
-
- //
- // If the application is running in a multiuser environment, check to
- // see if another user has changed the table.
- //
- if(cursorPtr->hasChanged() == TRUE)
- {
- //
- // Refresh the table's buffers.
- //
- cursorPtr->refresh();
- }
- //
- // Reduce the amount of pointer dereference.
- //
- currentRecord = cursorPtr->genericRec;
- //
- // Close any open BLOB fields that might be open in this table.
- //
- currentRecord->closeBlob(MAIN_REVIEW_FIELD, FALSE);
- currentRecord->closeBlob(MAIN_MENU_FIELD, FALSE);
- //
- // Lock the record.
- //
- recordLockHandle = cursorPtr->lockRecord();
-
- //
- // Check if the record is locked and the network is initialized.
- //
- if((cursorPtr->lastError != PXSUCCESS) &&
- (cursorPtr->lastError != PXERR_NONETINIT))
- {
- //
- // Return any error that occurred.
- //
- return(lastError = cursorPtr->lastError);
- }
- //
- // Call the base class to get the record from the table.
- //
- lastError = AbstractRestaurant::getRecord();
- //
- // Check if successful.
- //
- if(lastError == PXSUCCESS)
- {
- //
- // Use the BCursor generic record to extract the fields from the record.
- //
- currentRecord->getField(MAIN_NAME_FIELD, name, MAX_NAME_LEN + 1, isBlank);
- currentRecord->getField(MAIN_STREET_FIELD, street, MAX_STREET_LEN + 1,
- isBlank);
- currentRecord->getField(MAIN_CITY_FIELD, city, MAX_CITY_LEN + 1, isBlank);
- currentRecord->getField(MAIN_STATE_FIELD, state, MAX_STATE_LEN + 1,
- isBlank);
- currentRecord->getField(MAIN_ZIP_FIELD, zip, MAX_ZIP_LEN + 1, isBlank);
- currentRecord->getField(MAIN_TELEPHONE_FIELD, telephone,
- MAX_TELEPHONE_LEN + 1, isBlank);
- currentRecord->getField(MAIN_TYPE_FIELD, type, MAX_TYPE_LEN + 1, isBlank);
- currentRecord->getField(MAIN_RATING_FIELD, rating, isBlank);
-
- //
- // Create private BLOBs for the two memo fields. This will prevent
- // other users from changing the BLOB or deleting the record with
- // which the BLOB is associated.
- //
- currentRecord->openBlobRead(MAIN_MENU_FIELD, TRUE);
- currentRecord->openBlobRead(MAIN_REVIEW_FIELD, TRUE);
- }
- //
- // Unlock the record.
- //
- cursorPtr->unlockRecord(recordLockHandle);
-
- return(lastError);
- }
-
- /****************************************************************************
- *
- * CLASS: MainRestaurant
- *
- * MEMBER FUNCTION: getQuickReview
- *
- * DESCRIPTION: This function gets the header (first 80 bytes) of the Review
- * field in the record.
- *
- * RETURNS: PXERR_, if one occurs.
- *
- ****************************************************************************/
-
- Retcode MainRestaurant::getQuickReview(char *buffer, int sizeOfBuffer,
- int &bytesRead)
- {
- //
- // Use a generic function to retrieve the BLOB header.
- //
- lastError = getQuickBlob(MAIN_REVIEW_FIELD, buffer, sizeOfBuffer,
- bytesRead);
-
- return(lastError);
-
- }
-
- /****************************************************************************
- *
- * CLASS: MainRestaurant
- *
- * MEMBER FUNCTION: getReview
- *
- * DESCRIPTION: This function gets the review field from the table.
- * It skips the first 80 bytes of the field which provides
- * a quick review of the field's contents.
- *
- * RETURNS: PXERR_, if one occurs.
- *
- ****************************************************************************/
-
- Retcode MainRestaurant::getReview(char *buffer, unsigned int sizeOfBuffer,
- long offset, unsigned int &bytesRead)
- {
- //
- // Specify particular field and use more generic getBlobField function.
- // Offset past the quick review size so the header is not duplicated when
- // getting the review.
- //
- lastError = getBlobField(MAIN_REVIEW_FIELD, buffer, sizeOfBuffer,
- offset + MAX_REVIEW_SIZE, bytesRead);
-
- return(lastError);
-
- }
-
- /****************************************************************************
- *
- * CLASS: MainRestaurant
- *
- * MEMBER FUNCTION: getMenu
- *
- * DESCRIPTION: This function gets the menu field from the table.
- *
- * RETURNS: PXERR_, if one occurs.
- *
- ****************************************************************************/
-
- Retcode MainRestaurant::getMenu(char *buffer, unsigned int sizeOfBuffer,
- long offset, unsigned int &bytesRead)
- {
- //
- // Specify a particular field and use the generic get BLOB field function.
- //
- lastError = getBlobField(MAIN_MENU_FIELD, buffer, sizeOfBuffer, offset,
- bytesRead);
-
- return(lastError);
- }
-
- /****************************************************************************
- *
- * CLASS: MainRestaurant
- *
- * MEMBER FUNCTION: sizeOfReviewBlob
- *
- * DESCRIPTION: This function returns the size of the REVIEW memo field.
- *
- * RETURNS: Number of bytes in the REVIEW memo field.
- *
- ****************************************************************************/
-
- long MainRestaurant::sizeOfReviewBlob()
- {
-
- //
- // Return the BLOB size. Error checking done in base function.
- //
- return(getBlobSize(MAIN_REVIEW_FIELD));
-
- }
-
- /****************************************************************************
- *
- * CLASS: MainRestaurant
- *
- * MEMBER FUNCTION: sizeOfMenuBlob
- *
- * DESCRIPTION: This function returns the size of the MENU memo field.
- *
- * RETURNS: Number of bytes in the MENU memo field.
- *
- ****************************************************************************/
-
- long MainRestaurant::sizeOfMenuBlob()
- {
- //
- // Return the BLOB size. Error checking done in base function.
- //
- return(getBlobSize(MAIN_MENU_FIELD));
-
- }
-
- /****************************************************************************
- *
- * CLASS: MainRestaurant
- *
- * MEMBER FUNCTION: open
- *
- * DESCRIPTION: This function opens the primary table and also opens the
- * secondary indexes needed for this table.
- *
- * RETURNS: PXERR_, if one occurs.
- *
- ****************************************************************************/
-
- Retcode MainRestaurant::open(char *tableName)
- {
- FIELDNUMBER ratingTypeIndexId;
- FIELDNUMBER cityTypeIndexId;
-
- //
- // Call the base class open() function to open the primary index.
- //
- lastError = AbstractRestaurant::open(tableName);
- //
- // Check if successful.
- //
- if(lastError == PXSUCCESS)
- {
- //
- // Create index ID for the rating-type index.
- //
- lastError = dataBase->defineCompoundKey(tableName, RATING_TYPE_FLDCOUNT,
- ratingTypeFields, RATING_TYPE_INDEX, FALSE, ratingTypeIndexId);
-
- //
- // Create index ID for the city-type index. This index is
- // case-sensititive.
- //
- lastError = dataBase->defineCompoundKey(tableName, CITY_TYPE_FLDCOUNT,
- cityTypeFields, CITY_TYPE_INDEX, TRUE, cityTypeIndexId);
- //
- // Open the cursor for the rating-type index.
- //
- ratingTypeIndex->open(dataBase, tableName, ratingTypeIndexId, FALSE);
- //
- // Open the cursor for the city-type index.
- //
- cityTypeIndex->open(dataBase, tableName, cityTypeIndexId, FALSE);
- }
- return(lastError);
- }
-
- /****************************************************************************
- *
- * CLASS: MainRestaurant
- *
- * MEMBER FUNCTION: close
- *
- * DESCRIPTION: This function closes the primary table and also closes the
- * secondary indexes used by this table.
- *
- * RETURNS: PXERR_, if one occurs.
- *
- ****************************************************************************/
-
- Retcode MainRestaurant::close()
- {
- //
- // Call the base class open() function to open the primary index.
- //
- lastError = AbstractRestaurant::close();
- //
- // Check if successful.
- //
- if(lastError == PXSUCCESS)
- {
- //
- // Close the secondary indexes.
- //
- ratingTypeIndex->close();
- cityTypeIndex->close();
- }
- return(lastError);
- }
-
- /****************************************************************************
- *
- * CLASS: MainRestaurant
- *
- * MEMBER FUNCTION: copyToFavorite
- *
- * DESCRIPTION: This function will copy the current record of the main
- * restaurant table to the favorite restuarant table.
- *
- * RETURNS: PXERR_, if one occurs.
- *
- ****************************************************************************/
-
- Retcode MainRestaurant::copyToFavorite(FavoriteRestaurant &placeHere)
- {
- BRecord favoriteRecord(placeHere.cursorPtr);
-
- char menuBuffer[BLOB_COPY_LEN + 1];
-
- unsigned int menuBytesRead;
-
- long menuOffset;
- long menuSize;
-
- //
- // Get the current record.
- //
- lastError = getRecord();
-
- //
- // Check if successful.
- //
- if(lastError == PXSUCCESS)
- {
- //
- // Determine if the favorite table is open.
- //
- if(placeHere.isOpen == FALSE)
- {
- lastError = ERROR_TABLENOTOPEN;
- }
- else
- {
- //
- // Place the field values (name and type) into the favorite table's
- // record buffer.
- //
- favoriteRecord.putField(FAV_NAME_FIELD, name);
- favoriteRecord.putField(FAV_TYPE_FIELD, type);
-
- //
- // Get the size of the menu memo.
- //
- menuSize = sizeOfMenuBlob();
-
- //
- // Determine if the menu field needs to be copied.
- //
- if(menuSize != 0)
- {
- //
- // Open the BLOB in the favorite record buffer in write mode and
- // allocate the size of the menu memo.
- //
- //favoriteRecord.openBlobWrite(FAV_MENU_FIELD, menuSize, TRUE);
- // ms changed PXBLOBCOPY to PXBLOBNEW
- favoriteRecord.openBlobWrite(FAV_MENU_FIELD, menuSize, FALSE);
-
- //
- // Read BLOB_COPY_LEN bytes of the menu field and write
- // it to the menu field in the favorite restaurant table.
- //
- for(menuOffset = 0; menuOffset < menuSize;
- menuOffset += BLOB_COPY_LEN)
- {
- //
- // Read the BLOB from the main table. Use the getMenu() member
- // function.
- //
- getMenu(menuBuffer, BLOB_COPY_LEN + 1, menuOffset, menuBytesRead);
-
- //
- // Write it to the favorite restaurant record buffer.
- //
- favoriteRecord.putBlob(FAV_MENU_FIELD, menuBytesRead, menuOffset,
- menuBuffer);
- }
- //
- // Close the BLOB and accept the changes.
- //
- favoriteRecord.closeBlob(FAV_MENU_FIELD, TRUE);
- }
- //
- // Append this record to the end of the favorite restaurant table.
- //
- lastError = placeHere.cursorPtr->appendRec(&favoriteRecord);
- }
- }
- return(lastError);
- }
-
- /****************************************************************************
- *
- * CLASS: MainRestaurant
- *
- * MEMBER FUNCTION: findRatingType
- *
- * DESCRIPTION: This function locates a restaurant by Rating and Type using
- * a composite index.
- *
- * RETURNS: PXERR_, if one occurs.
- *
- ****************************************************************************/
-
- Retcode MainRestaurant::findRatingType(int ratingToFind, char *typeToFind,
- PXSearchMode searchMode)
- {
- BRecord searchRecord(ratingTypeIndex);
- BRecord *currentRecord;
-
- if(!isOpen)
- {
- return(lastError = ERROR_TABLENOTOPEN);
- }
- //
- // Specify the rating you want to find in the Rating field.
- //
- searchRecord.putField(MAIN_RATING_FIELD, (short)ratingToFind);
-
- //
- // Specify the type you want to find in the Type field.
- //
- searchRecord.putField(MAIN_TYPE_FIELD, typeToFind);
-
- //
- // Search the rating-type index for the specified values.
- //
- lastError = ratingTypeIndex->searchIndex(&searchRecord, searchMode,
- RATING_TYPE_FLDCOUNT);
-
- //
- // Determine if the search located a record.
- //
- if(lastError == PXSUCCESS)
- {
- currentRecord = cursorPtr->genericRec;
-
- //
- // Close any open BLOB fields that might be open for this table. These
- // BLOB fields must be closed because the function setToCursor() in the
- // BCursor class uses the generic record to do the search.
- //
- currentRecord->closeBlob(MAIN_REVIEW_FIELD, FALSE);
- currentRecord->closeBlob(MAIN_MENU_FIELD, FALSE);
- //
- // Use setToCursor() to synchronize the main cursor with the
- // secondary index cursor.
- //
- lastError = cursorPtr->setToCursor(ratingTypeIndex);
- }
- //
- // Return any error that occurs.
- //
- return(lastError);
-
- }
-
- /****************************************************************************
- *
- * CLASS: MainRestaurant
- *
- * MEMBER FUNCTION: findCityType
- *
- * DESCRIPTION: This function locates a restaurant by City and Type using a
- * composite index
- *
- * RETURNS: PXERR_, if one occurs.
- *
- ****************************************************************************/
-
- Retcode MainRestaurant::findCityType(char *cityToFind, char *typeToFind,
- PXSearchMode searchMode)
- {
- BRecord searchRecord(cityTypeIndex);
- BRecord *currentRecord;
-
- if(!isOpen)
- {
- return(lastError = ERROR_TABLENOTOPEN);
- }
- //
- // Specify city to find in the City field.
- //
- searchRecord.putField(MAIN_CITY_FIELD, cityToFind);
-
- //
- // Specify the type to find in the Type field.
- //
- searchRecord.putField(MAIN_TYPE_FIELD, typeToFind);
-
- //
- // Search the city-type index for the specified values.
- //
- lastError = cityTypeIndex->searchIndex(&searchRecord, searchMode,
- CITY_TYPE_FLDCOUNT);
- //
- // Determine if the search located a record.
- //
- if(lastError == PXSUCCESS)
- {
- currentRecord = cursorPtr->genericRec;
- //
- // Close any open BLOB fields that might be open for this table. These
- // BLOB fields must be closed because the function setToCursor() in the
- // BCursor class uses the generic record to do the search.
- //
- currentRecord->closeBlob(MAIN_REVIEW_FIELD, FALSE);
- currentRecord->closeBlob(MAIN_MENU_FIELD, FALSE);
- //
- // Use setToCursor() to synchronize the main cursor with the
- // secondary index cursor.
- //
- lastError = cursorPtr->setToCursor(cityTypeIndex);
- }
- //
- // Return any error that occurred.
- //
- return(lastError);
- }
-