Creating a Custom Database Class That Uses IStorage

Environment: MSVC++ 6.0, Windows 2000 Server

Introduction

When writing an application that keeps data in the database, the possibilities of the usual wrappers of the DAO or ADO types cannot always satisfy the requirements of the developer, the speed of data exchange, or the size of additional files that are required to be included in the distribution kit, or of something else. In that case, if the usual standard, cheap solution to find it fails, a solution can be the organization of the database.

I want to offer a variant of the implementation of such a class, which can be used for storage in the structured storage of any objects derivative from CObject. Thus, the speed of data exchange increases considerably, and to avoid memory leaks the mechanism of redefinition of the new and delete operators allows, at which we control selection and clearing of memory from a heap (Jeffrey Richter, Programming Applications for Microsoft Windows, fourth edition). I've used it since 1999, and I think that the similar idea will be useful to the visitors of this site.

Using the Class

  1. First of all, we must have a class, derived from CObject, with its own implementation of serialization.
  2. We also need a database file to store our data. The database file may be created, for example, with InitInstance(). One possible way of implementation follows:
  3. CFileFind file;
      CString str;
      USES_CONVERSION;
      IStorage*pStgStorage=NULL;IStorage*pSub=NULL;
      const char*path=(LPCSTR)str;
        str=m_myCoolDatabasePath+"\\general.db";
        path=(LPCSTR)str;
      if(file.FindFile(str))
      {
    
    
      }
      else
      {
    
    
      VERIFY(::StgCreateDocfile(T2OLE(path),
               STGM_READWRITE|STGM_SHARE_EXCLUSIVE|
               STGM_CREATE,0,&pStgStorage)==S_OK);
      VERIFY(pStgStorage->CreateStorage(L"RootStorage",
               STGM_READWRITE|
               STGM_SHARE_EXCLUSIVE|
               STGM_CREATE,0,0,&pSub)==S_OK);
      pSub->Release();pStgStorage->Release();
      }
    
  4. Then, we can manipulate our data: add objects to storage, enumerate, edit, and delete them.
    Here's how you add an object:
  5. CStoreClass*m_storage=new CStoreClass("employees","
                              \\bizdatas.db");
    CMyCoolSerializableObject*m_object=new
                              CMyCoolSerializableObject;
    m_object->code=m_storage->GetCounter();
    
    
    .....
    .....
    .....
    
    
    m_storage->AddObject((CObject*)m_object);
    delete m_storage;
    delete m_object;
    
    Here's how to enumerate, edit, and delete objects:
    CStoreClass*m_storage=new CStoreClass("employees","
                              \\bizdatas.db");
    m_storage->GetObjects();
    while(m_storage->ReceiveObject())
    {
    if(((CMyCoolSerializableObject*)m_storage->
         CurrentObject())->code==10) {
         m_storage->DeleteObject();
    }
    if(((CMyCoolSerializableObject*)m_storage->
         CurrentObject())->paramX==20)
    {
    CMyCoolSerializableObject*m_object=(CMyCoolSerializableObject*)
                              m_storage->CurrentObject();
    m_object->paramX=100;
    m_object->paramZ="Don't panic";
    m_storage->StoreObject((CObject*)m_object);
    }
    
    
    }
    delete m_storage;
    

Remarks and Notes

If you include StoredClass.h, you must comment these lines in yourclass.cpp file:

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

As the direct access to the database file occurs only in the constructor and destructor, you can create some objects simultaneously, like this:

CStoreClass*m_storage1=new CStoreClass
                           ("employees","\\bizdatas.db");
CStoreClass*m_storage2=new CStoreClass
                           ("categories","\\bizdatas.db");
CStoreClass*m_storage3=new CStoreClass
                           ("merchant","\\bizdatas.db");
CStoreClass*m_storage4=new CStoreClass
                           ("towns","\\common.db");


....
....
....


delete m_storage1;
delete m_storage2;
delete m_storage4;
delete m_storage3;

You can organize multiple users working in the network by creating a database folder in the server. Then, just write the constructor:

CStoreClass*m_storage1=new CStoreClass
      ("employees","server\\commonbases\\mybase1\\bizdatas.db");

Downloads

Download source - 4 Kb


Comments

  • Everything works perfect...

    Posted by Legacy on 09/12/2003 12:00am

    Originally posted by: Daniel Semushin

    It's a good idea, everything works perfect...

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Is your sales and operations planning helping or hurting your bottom line? Here are 5 useful tips from the experts at Quintiq to guide you to a better S&OP strategy.

  • Live Event Date: August 14, 2014 @ 2:00 p.m. ET / 11:00 a.m. PT Data protection has long been considered "overhead" by many organizations in the past, many chalking it up to an insurance policy or an extended warranty you may never use. The realities of today make data protection a must-have, as we live in a data driven society. The digital assets we create, share, and collaborate with others on must be managed and protected for many purposes. Check out this upcoming eSeminar and join eVault Chief Technology …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds