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

More by Author

Get the Free Newsletter!

Subscribe to Data Insider for top news, trends & analysis

Must Read