Any COM application receives an object reference through which it controls an instance of a SQL-DMO object. This is true regardless of the application development tool.
COM defines reference counting as the mechanism for COM server-created object lifetime management. When a COM client application receives an object reference, the reference count on the object instance is implicitly incremented. When the COM client is finished with the object reference, it decrements the reference count using the Release function. When the reference count is zero, the COM server may, at its discretion, free resources used to implement the object instance.
When using an OLE Automation controller, such as Microsoft®Visual Basic®, the controller generally maintains references and reference counts as directed by the scope of the variable referencing the object. For example, the Visual Basic subroutine below shows an application receiving a reference to a Databases collection, and references to multiple SQL-DMO Database and OLE BSTR objects.
Private Sub ListDatabases(oSQLServer as SQLDMO.SQLServer)
Dim oDatabase as SQLDMO.Database
For Each oDatabase in oSQLServer.Databases
lstDatabases.AddItem oDatabase.Name
Next oDatabase
End Sub
No reference is ever released explicitly by the developer. Instead, Database object references are released as the object variable is reassigned in the For Each loop. The reference maintained on the Databases collection and the last reference obtained on a Database object in the collection are released as the variables go out of scope with the End Sub statement. The OLE BSTR object references are hidden, and handled, even more effectively.
The C/C++ application developer must be aware of and control reference counts as necessary. Whenever an object reference is received from the SQL-DMO library, the application implicitly increases the reference count on an instance of the SQL-DMO object, as shown below:
void CDlgSelectDatabase::GetDatabases(LPSQLDMOSERVER pServer)
{
LPSQLDMODATABASE pDatabase;
BSTR bstrDBName;
LONG nDatabase;
LONG nDatabases;
HRESULT hr;
if (FAILED(hr = pServer->GetDatabaseCount(&nDatabases)))
return;
for (nDatabase = 0; nDatabase < nDatabases && SUCCEEDED(hr);
nDatabase++)
{
pDatabase = NULL;
bstrDBName = NULL;
// Getting the next Database object from the collection
// increases the client initiated reference count by one.
hr = pServer->GetDatabaseByOrd(nDatabase, &pDatabase);
// Getting a string back from SQL-DMO is also getting a
// reference on an object. Be sure to release it.
if (SUCCEEDED(hr))
hr = pDatabase->GetName(&bstrDBName);
if (SUCCEEDED(hr))
m_listboxDatabases->AddString(bstrDBName);
if (bstrDBName != NULL)
SysFreeString(bstrDBName);
if (pDatabase != NULL)
pDatabase->Release();
}
}
For the C++ developer, SQL-DMO defines in Sqldmo.h the scope-aware, template classes CTempOLERef and CTempBSTR that can simplify development.
CTempBSTR | CTempOLERef |