INFO: Changes in Consumer Templates Since VC++ Tech Preview
ID: Q190472
|
The information in this article applies to:
-
Microsoft Visual C++, 32-bit Editions, version 6.0
SUMMARY
In November 1997 the Visual C++ Technology Preview was released to
illustrate features being developed for the next version of Visual C++.
Included were the OLE DB Consumer Templates. These templates have been
further developed and are included in Visual C++ 6.0.
To help with projects that might have been started with the Visual C++
Technology Preview this article lists the changes made to the OLE DB
Consumer classes since the Technology Preview.
MORE INFORMATION
Static Accessor Hierarchy
The user's record no longer derives from CAccessor, in fact it no longer
needs to derive from any class. Now, you can make copies of the data in the
record class and you don't need to worry about the extra 12 bytes of
instance data that is in CAccessorBase. The class CAccessor is still
templated on the user record class but now derives from the user record
(instead of the other way around) and CAccessorBase.
As CAccessor now derives from the user's record, you no longer pass the
user record as the first template parameter to CTable or CCommand when you
use a static accessor. You now pass CAccessor (which is templated on the
user record).
For example:
CTable<CMyProduct> myTable;
becomes
CTable<CAccessor<CMyProduct> > myTable;
// note the extra space between > and >
Macros
The column entry macros that you use to specify the bindings have been
simplified. Previously you had to specify the OLE DB type and the size of
the column in the COLUMN_ENTRY macro. The OLE DB type and size are now
worked out automatically at compile time based upon the Visual C++ data
type that the column binds to. If you wish to explicitly specify the type,
you can use the new macro COLUMN_ENTRY_TYPE. One of the advantages of the
new COLUMN_ENTRY macro is that you can now have data members that are
arrays of TCHAR's, and they are automatically bound as DBTYPE_STR or
DBTYPE_WSTR depending upon whether you are building an ANSI or UNICODE
version.
The DEFINE_COMMAND() macro now requires the class name to be passed in as
the first parameter.
The following code snippets show the old way and the new way of accessing
data with a static accessor.
Sample Code - the Old Way
class CProductAccessor :
public CAccessor<CProductAccessor>,
{
public:
long nProductID;
char szName[40];
DEFINE_COMMAND("SELECT * FROM Products WHERE UnitsInStock < ?");
BEGIN_COLUMN_MAP(CProductAccessor)
COLUMN_ENTRY(1, DBTYPE_I4, 4, nProductID)
COLUMN_ENTRY(2, DBTYPE_STR, 40, szName)
END_COLUMN_MAP()
BEGIN_PARAM_MAP(CProductAccessor)
COLUMN_ENTRY(1, DBTYPE_I4, 4, nProductID)
END_PARAM_MAP()
};
void OpenTable(CSession& session)
{
CTable<CProductAccessor> product;
product.Open(session, ...
...
}
Sample Code - the New Way
class CProductAccessor
{
public:
long nProductID;
char szName[40];
DEFINE_COMMAND(CProductAccessor,"SELECT * FROM Products WHERE
UnitsInStock < ?");
BEGIN_COLUMN_MAP(CProductAccessor)
COLUMN_ENTRY(1, nProductID)
COLUMN_ENTRY(2, szName)
END_COLUMN_MAP()
BEGIN_PARAM_MAP(CProductAccessor)
COLUMN_ENTRY(1, nProductID)
END_PARAM_MAP()
};
void OpenTable(CSession& session)
{
CTable<CAccessor<CProductAccessor> > product;
product.Open(session, ...
...
}
GUIDs
The guids from Oledb.lib are now been in Uuid.lib along with other guids
that used to require that you have a Guids.cpp in your project. You should
therefore remove any Guids.cpp program you have in your project and remove
Oledb.lib from your linker line.
Other Changes and Additions
- There is another rowset and accessor class type. CNoAccessor is
optimized for when there are no output columns or parameters and
CNoRowset, which is optimized for when there is no output rowset.
- It is no longer necessary to have an output column map in the static
accessor. This means you can now create an accessor class with only a
parameter map. This is useful if you have a command that has input
parameters but no output columns. For example:
class CShippers
{
public:
long nShipID;
BEGIN_PARAM_MAP(CShippers)
COLUMN_ENTRY(1, nShipID)
END_PARAM_MAP()
};
void DeleteShippers(CSession& session)
{
CCommand<CAccessor<CShippers>, CNoRowset> cmd;
LONG nRowsAffected;
cmd.nShipID = 3;
cmd.Open(session,
_T("DELETE * FROM Shippers2 WHERE ShipperID < ? "), NULL,
&nRowsAffected);
}
- CTable and CCommand now default to CNoAccessor as the first template
parameter instead of CDynamicAccessor.
- The new standard Data Links dialog is supported by new Open function
overloads in the CDataSource class.
- There is a new function on the accessor classes called FreeRecordMemory.
You can call this to automatically free any columns that need to be
freed before you make another call to MoveNext. For example, the
function releases any columns that are interface pointers, calls
SysFreeString on any columns that are BSTRs, and calls VariantClear() on
any variants.
- There is a new function called GetDataHere on Crowset, which can be used
to get data into a specific buffer. You can use this if you wish to read
through a rowset on multiple threads. See the MultiRead sample for an
example of its use.
- The class CMultipleResultsCommand no longer exists because its
functionality has been added to CCommand. Passing in CMultipleResults as
the third template parameter to CCommand, instead of the default (which
is CNoMultipleResults), activates this functionality.
- The ATL Object Wizard now automatically generates an accessor class and
a class with code to open the datasource and rowset.
Additional query words:
Keywords : kbtemplate kbATL kbDatabase kbOLEDB kbVC600
Version : WINNT:6.0
Platform : winnt
Issue type : kbinfo
Last Reviewed: August 8, 1999