home *** CD-ROM | disk | FTP | other *** search
- // ------------------------------- //
- // -------- Start of File -------- //
- // ------------------------------- //
- // ----------------------------------------------------------- //
- // C++ Source Code File Name: part.cpp
- // Compiler Used: MSVC40, DJGPP 2.7.2.1, GCC 2.7.2.1, HP CPP 10.24
- // Produced By: Doug Gaer
- // File Creation Date: 09/18/1997
- // Date Last Modified: 03/17/1999
- // Copyright (c) 1997 Douglas M. Gaer
- // ----------------------------------------------------------- //
- // ------------- Program Description and Details ------------- //
- // ----------------------------------------------------------- //
- /*
- This is a test program use to test the (P)ersistent base class.
-
- The VBD C++ classes are copyright (c) 1997, by Douglas M. Gaer.
- All those who put this code or its derivatives in a commercial
- product MUST mention this copyright in their documentation for
- users of the products in which this code or its derivative
- classes are used. Otherwise, you have the freedom to redistribute
- verbatim copies of this source code, adapt it to your specific
- needs, or improve the code and release your improvements to the
- public provided that the modified files carry prominent notices
- stating that you changed the files and the date of any change.
-
- THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND.
- THE ENTIRE RISK OF THE QUALITY AND PERFORMANCE OF THIS SOFTWARE
- IS WITH YOU. SHOULD ANY ELEMENT OF THIS SOFTWARE PROVE DEFECTIVE,
- YOU WILL ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR, OR
- CORRECTION.
- */
- // ----------------------------------------------------------- //
- #include "part.h"
-
- __UWORD__ Part::ObjectLength()
- {
- return sizeof(id) + sizeof(price) + StringFileLength(name);
- }
-
- FAU Part::Write()
- {
- ObjectHeader oh;
- FAU addr = pod->OpenDatabase()->Alloc(ObjectLength() + sizeof(ObjectHeader));
- if(!addr) return 0;
-
- oh.ClassID = GetClassID();
- oh.ObjectID = addr;
- WriteObjHeader(oh);
-
- pod->OpenDatabase()->Write(&id, sizeof(id));
- pod->OpenDatabase()->Write(&price, sizeof(price));
- WriteString(name);
- objectaddress = addr;
-
- // Write a 32-bit CRC checksum for the object
- pod->OpenDatabase()->WriteObjectChecksum(addr);
-
- // Add the entry to the Index file
- if (UsingIndex()) {
- EntryKey key(name.c_str(), oh.ObjectID, oh.ClassID);
- AddKey(key);
- }
- return addr;
- }
-
- void Part::Read(FAU Address)
- {
- ObjectHeader oh;
-
- // Optimize seeks during intervening reads
- pod->OpenDatabase()->SeekTo(Address);
-
- ReadObjHeader(oh, Address);
- if(oh.ClassID != GetClassID()) return; // Incorrect object type
- pod->OpenDatabase()->Read(&id, sizeof(id));
- pod->OpenDatabase()->Read(&price, sizeof(price));
- ReadString(name);
- objectaddress = Address;
-
- // Test the objects checksum
- int rv = pod->OpenDatabase()->ReadObjectChecksum(Address);
- if(!rv)
- #ifdef CPP_EXCEPTIONS
- throw CChecksumError();
- #else
- Error->SignalException(EHandler::ChecksumError, EHandler::DISPLAY);
- #endif
- }
-
- FAU Part::Find()
- {
- int rv; // Return value
-
- // Search the index file for this entry
- if(UsingIndex()) {
- EntryKey e(this->name.c_str());
- rv = FindKey(e);
- if(rv) // Found the object in the index file
- return e.object_address;
- }
-
- // If not using index file or entry not found, search the data file
- Part part;
- FAU oa; // Object Address
- VBHeader vb; // Variable Block Header
- ObjectHeader oh; // Object Header
-
- FAU vbdfileEOF = pod->OpenDatabase()->GetEOF();
- FAU addr = 0;
- addr = pod->OpenDatabase()->FindFirstVB(addr); // Search the entire file
-
- if(addr == 0) return 0; // No variable blocks found in file
-
- part.id = this->id;
- part.price = this->price;
- part.name = this->name;
-
- while(1) {
- if(addr >= vbdfileEOF) break;
- pod->OpenDatabase()->Read(&vb, sizeof(VBHeader), addr);
- if(vb.CkWord == CheckWord) {
- if((__SBYTE__)vb.Status == NormalVB) {
- oa = addr + sizeof(VBHeader);
- ReadObjHeader(oh, oa);
- if(oh.ClassID == GetClassID()) {
- Read(oa);
- if(name == part.name) {
- objectaddress = oa;
- return oa; // Found unique data member
- }
- }
- }
- addr = addr + vb.Length; // Goto the next variable block
- }
- else {
- addr = pod->OpenDatabase()->VBSearch(addr);
- if(!addr) break;
- }
- }
-
- // Reset the objects data
- this->id = part.id;
- this->price = part.price;
- this->name = part.name;
-
- return 0; // Could not find
- }
-
- FAU Part::Delete()
- {
- if(UsingIndex()) {
- EntryKey e(this->name.c_str());
- int rv = FindKey(e);
- if(rv) { // Found the object in the index file
- FAU addr = e.object_address;
- DeleteObject(e.object_address); // Delete from the data file
- RemoveKey(e); // Remove from the index file
- return addr;
- }
- else
- return 0; // Could not delete
- }
-
- FAU addr = Find();
- if(!addr) return 0; // Object does not exist
- DeleteObject(addr);
- return addr;
- }
-
- FAU Part::Remove()
- {
- if(UsingIndex()) {
- EntryKey e(this->name.c_str());
- int rv = FindKey(e);
- if(rv) { // Found the object in the index file
- FAU addr = e.object_address;
- RemoveObject(e.object_address); // Remove from the data file
- RemoveKey(e); // Remove from the index file
- return addr;
- }
- else
- return 0; // Could not remove
- }
-
- FAU addr = Find();
- if(!addr) return 0; // Object does not exist
- RemoveObject(addr);
- return addr;
- }
-
- int Part::CompareIndex()
- // Compares the data file to the index file.
- // Returns true if data and index file match.
- {
- if(!UsingIndex()) return 0;
-
- // Ensure that the in memory buffers and the file data
- // stay in sync during multiple file access.
- pod->Index()->TestTree();
-
- Part part(pod);
- EntryKey key;
-
- FAU oa; // Object Address
- VBHeader vb; // Variable Block Header
- ObjectHeader oh; // Object Header
-
- int objects = 0; // Keeps track of good variable blocks
- int matches = 0; // Keep track of matches
-
- FAU vbdfileEOF = pod->OpenDatabase()->GetEOF();
- FAU addr = 0;
- addr = pod->OpenDatabase()->FindFirstVB(addr); // Search the entire file
-
- if(addr == 0) // No variable blocks found in file
- #ifdef CPP_EXCEPTIONS
- throw CNoObjectsExist();
- #else
- Error->SignalException(EHandler::NoObjectsExist);
- #endif
-
- while(1) {
- if(addr >= vbdfileEOF) break;
- pod->OpenDatabase()->Read(&vb, sizeof(VBHeader), addr);
- if(vb.CkWord == CheckWord) {
- if((__SBYTE__)vb.Status == NormalVB) {
- oa = addr + sizeof(VBHeader);
- ReadObjHeader(oh);
- if(oh.ClassID == GetClassID()) {
- objects++; // Increment the object count
- part.Read(oa);
- key.SetStrKey(part.GetName());
- key.SetOA(oa);
- key.SetCID(oh.ClassID);
- int rv = FindKey(key, 1);
- if(rv) matches++; // Index and data file match
- }
- }
- addr = addr + vb.Length; // Goto the next variable block
- }
- else {
- addr = pod->OpenDatabase()->VBSearch(addr);
- if(!addr) break;
- }
- }
-
- return objects == matches;
- }
-
- int Part::RebuildIndexFile(const char *fname)
- {
- if(!UsingIndex()) return 0;
-
- int rv; // (R)eturn (V)alue
- int CacheSize = 15;
-
- VBDFilePtr f(new VBDFile);
- Btree btx(CacheSize);
- f->Create(fname, sizeof(BtreeHeader));
- btx.Connect(f, 1);
-
- Part part(pod);
- EntryKey key;
-
- FAU oa; // Object Address
- VBHeader vb; // Variable Block Header
- ObjectHeader oh; // Object Header
-
- int objects = 0; // Keeps track of good variable blocks
- int inserts = 0; // Keep track of inserts
-
- FAU vbdfileEOF = pod->OpenDatabase()->GetEOF();
- FAU addr = 0;
- addr = pod->OpenDatabase()->FindFirstVB(addr); // Search the entire file
-
- if(addr == 0) // No variable blocks found in file
- #ifdef CPP_EXCEPTIONS
- throw CNoObjectsExist();
- #else
- Error->SignalException(EHandler::NoObjectsExist);
- #endif
-
- while(1) {
- if(addr >= vbdfileEOF) break;
- pod->OpenDatabase()->Read(&vb, sizeof(VBHeader), addr);
- if(vb.CkWord == CheckWord) {
- if((__SBYTE__)vb.Status == NormalVB) {
- oa = addr + sizeof(VBHeader);
- ReadObjHeader(oh, oa);
- if(oh.ClassID == GetClassID()) {
- objects++; // Increment the object count
- part.Read(oa);
- key.SetStrKey(part.GetName());
- key.SetOA(oa);
- key.SetCID(oh.ClassID);
- rv = btx.Add(key);
- if(!rv) {
- #ifdef CPP_EXCEPTIONS
- throw CAssertError();
- #else
- Error->SignalException(EHandler::AssertError);
- #endif
- }
- else
- inserts++; // Index and data file match
- }
- }
- addr = addr + vb.Length; // Goto the next variable block
- }
- else {
- addr = pod->OpenDatabase()->VBSearch(addr);
- if(!addr) break;
- }
- }
-
- return objects == inserts;
- }
- // ----------------------------------------------------------- //
- // ------------------------------- //
- // --------- End of File --------- //
- // ------------------------------- //
-