Saving an ADO Recordset to an IStream

ID: Q242249


The information in this article applies to:
  • ActiveX Data Objects (ADO), versions 1.5, 2.0, 2.1


SUMMARY

ADOPERSIST.exe is a Visual C++ sample that shows you how to save an ADO recordset to an IStream object and then reload another ADO recordset from it.

ADO 1.5x and 2.x Recordset implementation offers two functions for data persistance to a disk file:

  1. ADORecordset.Save() to save the recordset object to a file.


  2. ADORecordset.Open() to reload a recordset from a file.


For performance or other reasons it may sometimes be desired to save an ADO recordset to the memory only as a stream of data. To accomplish that you can use the ADO recordset's IPersistStream interface implementation.


MORE INFORMATION

Saving an ADO Recordset Object

This sample uses the following steps to save an ADO recordset:
  1. Calls QueryInterface() on the given ADO recordset to get a pointer to the IPersistStream object.


  2. Uses CreateStreamOnHGlobal() to create a standard, COM, IStream object.


  3. Calls the COM function OleSaveToStream() to save the IPersistStream object into the IStream object.


Recreating the ADO Recordset

Given the IStream object, the sample then recreates another ADO recordset from it. It does this using the IStream pointer that holds the data stream and calls OleLoadFromStream().

Below is the key code from the sample:

int main(int argc, char* argv[])
{
	InitOle oleinit;

	HRESULT hr=S_OK;
	_RecordsetPtr rs; //Recordset for Saving Data
	_RecordsetPtr rs2; //Recordset for Loading Data
	IStreamPtr pStream;

//----------------------------------------
//	Create a recordset for testing
//----------------------------------------
	if (FAILED(CreateTestRS(&rs)))
	{
		printf("Couldn't create the first recordset\n");
		goto exit;
	}

//----------------------------------------
//	Create IStream
//----------------------------------------
	if (FAILED(SaveRS(rs, (IStream**)&pStream)))
	{
		printf("Couldn't save the recordset\n");
		goto exit;
	}

//----------------------------------------
//	Load another recordset from IStream
//----------------------------------------
	if (FAILED(LoadRS(&rs2, pStream)))
	{
		printf("Couldn't save the recordset\n");
		goto exit;
	}
	//Now display the names of the fields of the rs that we just recreated
	{
		for (short i =0;i<rs2->Fields->Count;i++)
		printf("Name of field %d is %s\n", i, (LPCTSTR) rs2->Fields->GetItem(i)->Name);
	}



//----------------------------------------
//	Pause and then exit so that the user
//	Can  
//----------------------------------------

exit:
	printf("Press any key to end program\n");
	_getch();
	return 0;
}


//----------------------------------------
//	Create a recordset from scratch
//----------------------------------------

HRESULT CreateTestRS(_Recordset** prs/*OUT*/)
{
    try
    {
	* prs=NULL;
	_RecordsetPtr pRS;
	pRS.CreateInstance( __uuidof(Recordset));
	pRS->CursorLocation = adUseClient;
	pRS->CursorType = adOpenStatic;
	pRS->LockType = adLockBatchOptimistic;
	// append fields
	pRS->Fields->Append(_bstr_t("ADOField1"), adVarChar, 45,adFldFixed);
	pRS->Fields->Append(_bstr_t("ADOField2"), adBoolean, 0,adFldFixed);
	pRS->Fields->Append(_bstr_t("ADOField3"), adCurrency, 0,adFldFixed);
	pRS->Fields->Append(_bstr_t("ADOField4"), adDate, 0,adFldFixed);
	pRS->Open(vtMissing, vtMissing, adOpenStatic,adLockBatchOptimistic,-1);
	*prs= pRS.Detach();
    }
    catch (_com_error & e)
    {
	return e.Error();
    }
    return S_OK;
}

HRESULT SaveRS(_RecordsetPtr pRS/*IN*/, IStream* * ppStream/*OUT*/)
{
    HRESULT hr=S_OK;
    try
    {
	*ppStream=NULL;

        // QI and return IPersistStream
        IPersistStreamPtr pIPersist(pRS);
        if (pIPersist )
        {
            //Create a standard stream in memory
            if (FAILED(hr=CreateStreamOnHGlobal(0, TRUE, (IStream **)ppStream)))
		return hr;

            // Persist the pRS
            if (FAILED(hr=OleSaveToStream(pIPersist, *ppStream)))
		return hr;

        }
        else
            return E_NOINTERFACE;
    }
    catch (_com_error & e)
    {
	return e.Error();
    }
return S_OK;
    
}

HRESULT LoadRS(_Recordset* *ppRS/*OUT*/, IStreamPtr pStream/*IN*/)
{
    HRESULT hr=S_OK;
    try
    {
	*ppRS=NULL;
        if (NULL==pStream)
            return E_NOINTERFACE;
        // Load the pRS.
        LARGE_INTEGER li;
        li.QuadPart = 0;

	//Set the pointer to the beginning of the stream
        if (FAILED(hr=pStream->Seek(li, STREAM_SEEK_SET, 0)))
            return hr;

	if (FAILED(hr=OleLoadFromStream(pStream, 
        	__uuidof(_Recordset),
                reinterpret_cast<LPVOID *>(ppRS)))
		)
            return hr;
    }
    catch (_com_error & e)
    {
	return e.Error();
    }
    return S_OK;
} 
The following files are available for download from the Microsoft Download Center. Click the file names below to download the files:
AdoPersist.exe
For more information about how to download files from the Microsoft Download Center, please visit the Download Center at the following Web address
http://www.microsoft.com/downloads/search.asp
and then click How to use the Microsoft Download Center.

ADOPersist.cpp 4.1KB
ADOPersist.dsp 4.0KB

Additional query words:

Keywords : kbfile kbADO kbADO150 kbADO200 kbDatabase kbGrpVCDB
Version : WINDOWS:1.5,2.0,2.1
Platform : WINDOWS
Issue type : kbhowto


Last Reviewed: December 7, 1999
© 2000 Microsoft Corporation. All rights reserved. Terms of Use.