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

  • With JRebel, developers get to see their code changes immediately, fine-tune their code with incremental changes, debug, explore and deploy their code with ease (both locally and remotely), and ultimately spend more time coding instead of waiting for the dreaded application redeploy to finish. Every time a developer tests a code change it takes minutes to build and deploy the application. JRebel keeps the app server running at all times, so testing is instantaneous and interactive.

  • You probably have several goals for your patient portal of choice. Is "community" one of them? With a bevy of vendors offering portal solutions, it can be challenging for a hospital to know where to start. Fortunately, YourCareCommunity helps ease the decision-making process. Read this white paper to learn more. "3 Ways Clinicians can Leverage a Patient Portal to Craft a Healthcare Community" is a published document owned by www.medhost.com

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds