CCustomSource (CustomDS.h)
提供程序类使用多重继承。 以下代码显示了数据源对象的继承链:
/////////////////////////////////////////////////////////////////////////
// CCustomSource
class ATL_NO_VTABLE CCustomSource :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CCustomSource, &CLSID_Custom>,
public IDBCreateSessionImpl<CCustomSource, CCustomSession>,
public IDBInitializeImpl<CCustomSource>,
public IDBPropertiesImpl<CCustomSource>,
public IPersistImpl<CCustomSource>,
public IInternalConnectionImpl<CCustomSource>
所有 COM 组件派生自 CComObjectRootEx
和 CComCoClass
。 CComObjectRootEx
提供 IUnknown
接口的所有实现。 它可以处理任何线程模型。 CComCoClass
处理所需的任何错误支持。 如果要将更丰富的错误信息发送到客户端,可以使用 CComCoClass
中的一些错误 API。
数据源对象还继承自多个“Impl”类。 每个类都为一个接口提供实现。 数据源对象实现 IPersist
、IDBProperties
、IDBInitialize
和 IDBCreateSession
接口。 OLE DB 需要每个接口来实现数据源对象。 你可以选择通过继承或不继承这些“Impl”类之一来支持或不支持特定功能。 如果要支持 IDBDataSourceAdmin
接口,请从 IDBDataSourceAdminImpl
类进行继承以获取所需的功能。
COM 映射
每当客户端为数据源上的接口调用 QueryInterface
时,它都会经历以下 COM 映射:
BEGIN_COM_MAP(CCustomSource)
COM_INTERFACE_ENTRY(IDBCreateSession)
COM_INTERFACE_ENTRY(IDBInitialize)
COM_INTERFACE_ENTRY(IDBProperties)
COM_INTERFACE_ENTRY(IPersist)
COM_INTERFACE_ENTRY(IInternalConnection)
END_COM_MAP()
COM_INTERFACE_ENTRY 宏来自 ATL,它会告知 CComObjectRootEx
中的 QueryInterface
实现返回相应的接口。
属性映射
属性映射指定提供程序分配的所有属性:
BEGIN_PROPSET_MAP(CCustomSource)
BEGIN_PROPERTY_SET(DBPROPSET_DATASOURCEINFO)
PROPERTY_INFO_ENTRY(ACTIVESESSIONS)
PROPERTY_INFO_ENTRY(ASYNCTXNABORT)
PROPERTY_INFO_ENTRY(ASYNCTXNCOMMIT)
PROPERTY_INFO_ENTRY(BYREFACCESSORS)
PROPERTY_INFO_ENTRY_VALUE(CATALOGLOCATION, DBPROPVAL_CL_START)
PROPERTY_INFO_ENTRY(CATALOGTERM)
PROPERTY_INFO_ENTRY(CATALOGUSAGE)
PROPERTY_INFO_ENTRY(COLUMNDEFINITION)
PROPERTY_INFO_ENTRY(CONCATNULLBEHAVIOR)
PROPERTY_INFO_ENTRY(DATASOURCENAME)
PROPERTY_INFO_ENTRY(DATASOURCEREADONLY)
PROPERTY_INFO_ENTRY(DBMSNAME)
PROPERTY_INFO_ENTRY(DBMSVER)
PROPERTY_INFO_ENTRY_VALUE(DSOTHREADMODEL, DBPROPVAL_RT_FREETHREAD)
PROPERTY_INFO_ENTRY(GROUPBY)
PROPERTY_INFO_ENTRY(HETEROGENEOUSTABLES)
PROPERTY_INFO_ENTRY(IDENTIFIERCASE)
PROPERTY_INFO_ENTRY(MAXINDEXSIZE)
PROPERTY_INFO_ENTRY(MAXROWSIZE)
PROPERTY_INFO_ENTRY(MAXROWSIZEINCLUDESBLOB)
PROPERTY_INFO_ENTRY(MAXTABLESINSELECT)
PROPERTY_INFO_ENTRY(MULTIPLEPARAMSETS)
PROPERTY_INFO_ENTRY(MULTIPLERESULTS)
PROPERTY_INFO_ENTRY(MULTIPLESTORAGEOBJECTS)
PROPERTY_INFO_ENTRY(MULTITABLEUPDATE)
PROPERTY_INFO_ENTRY(NULLCOLLATION)
PROPERTY_INFO_ENTRY(OLEOBJECTS)
PROPERTY_INFO_ENTRY(ORDERBYCOLUMNSINSELECT)
PROPERTY_INFO_ENTRY(OUTPUTPARAMETERAVAILABILITY)
PROPERTY_INFO_ENTRY(PERSISTENTIDTYPE)
PROPERTY_INFO_ENTRY(PREPAREABORTBEHAVIOR)
PROPERTY_INFO_ENTRY(PREPARECOMMITBEHAVIOR)
PROPERTY_INFO_ENTRY(PROCEDURETERM)
PROPERTY_INFO_ENTRY(PROVIDERNAME)
PROPERTY_INFO_ENTRY(PROVIDEROLEDBVER)
PROPERTY_INFO_ENTRY(PROVIDERVER)
PROPERTY_INFO_ENTRY(QUOTEDIDENTIFIERCASE)
PROPERTY_INFO_ENTRY(ROWSETCONVERSIONSONCOMMAND)
PROPERTY_INFO_ENTRY(SCHEMATERM)
PROPERTY_INFO_ENTRY(SCHEMAUSAGE)
PROPERTY_INFO_ENTRY(STRUCTUREDSTORAGE)
PROPERTY_INFO_ENTRY(SUBQUERIES)
PROPERTY_INFO_ENTRY(TABLETERM)
PROPERTY_INFO_ENTRY(USERNAME)
END_PROPERTY_SET(DBPROPSET_DATASOURCEINFO)
BEGIN_PROPERTY_SET(DBPROPSET_DBINIT)
PROPERTY_INFO_ENTRY(AUTH_PASSWORD)
PROPERTY_INFO_ENTRY(AUTH_PERSIST_SENSITIVE_AUTHINFO)
PROPERTY_INFO_ENTRY(AUTH_USERID)
PROPERTY_INFO_ENTRY(INIT_DATASOURCE)
PROPERTY_INFO_ENTRY(INIT_HWND)
PROPERTY_INFO_ENTRY(INIT_LCID)
PROPERTY_INFO_ENTRY(INIT_LOCATION)
PROPERTY_INFO_ENTRY(INIT_MODE)
PROPERTY_INFO_ENTRY(INIT_PROMPT)
PROPERTY_INFO_ENTRY(INIT_PROVIDERSTRING)
PROPERTY_INFO_ENTRY(INIT_TIMEOUT)
END_PROPERTY_SET(DBPROPSET_DBINIT)
BEGIN_PROPERTY_SET(DBPROPSET_DATASOURCE)
PROPERTY_INFO_ENTRY(CURRENTCATALOG)
END_PROPERTY_SET(DBPROPSET_DATASOURCE)
CHAIN_PROPERTY_SET(CCustomSession)
END_PROPSET_MAP()
OLE DB 中的属性已分组。 数据源对象有两组属性:一组用于 DBPROPSET_DATASOURCEINFO 集,一组用于 DBPROPSET_DBINIT 集。 DBPROPSET_DATASOURCEINFO 集对应于有关提供程序及其数据源的属性。 DBPROPSET_DBINIT 集对应于初始化时使用的属性。 OLE DB 提供程序模板使用 PROPERTY_SET 宏处理这些集。 宏创建一个包含属性数组的块。 每当客户端调用 IDBProperties
接口时,提供程序都使用属性映射。
无需在规范中实现每个属性。 但是,必须支持所需的属性;有关详细信息,请参阅级别 0 一致性规范。 如果不想支持某个属性,可以从映射中删除它。 如果要支持某个属性,请使用 PROPERTY_INFO_ENTRY 宏将其添加到映射中。 该宏对应于以下代码所示的 UPROPINFO
结构:
struct UPROPINFO
{
DBPROPID dwPropId;
ULONG ulIDS;
VARTYPE VarType;
DBPROPFLAGS dwFlags;
union
{
DWORD dwVal;
LPOLESTR szVal;
};
DBPROPOPTIONS dwOption;
};
结构中的每个元素表示处理属性所需的信息。 它包含一个 DBPROPID
,用于确定属性的 GUID 和 ID。 它还包含用于确定属性的类型和值的条目。
如果要更改属性的默认值(注意,使用者可以随时更改可写属性的值),可以使用 PROPERTY_INFO_ENTRY_VALUE 或 PROPERTY_INFO_ENTRY_EX 宏。 这些宏允许指定相应属性的值。 PROPERTY_INFO_ENTRY_VALUE 宏是一种简写表示法,可用于更改值。 PROPERTY_INFO_ENTRY_VALUE 宏调用 PROPERTY_INFO_ENTRY_EX 宏。 此宏允许添加或更改 UPROPINFO
结构中的所有属性。
如果要定义你自己的属性集,可以通过创建其他 BEGIN_PROPSET_MAP/END_PROPSET_MAP 组合来添加一个属性集。 为属性集定义 GUID,然后定义你自己的属性。 如果你有特定于提供程序的属性,请将它们添加到新属性集,而不是使用现有属性集。 这样就避免了更高版本的 OLE DB 中出现的问题。
用户定义的属性集
Visual C++ 支持用户定义的属性集。 无需重写 GetProperties
或 GetPropertyInfo
。 可以改为让模板检测任何用户定义的属性集,并将其添加到相应的对象。
如果你有一个需要在初始化时(即在使用者调用 IDBInitialize::Initialize
之前)提供的用户定义的属性集,可以使用 UPROPSET_USERINIT 标志以及 BEGIN_PROPERTY_SET_EX 宏来指定它。 属性集必须位于数据源对象中这才会生效(因为 OLE DB 规范要求这样做)。 例如:
BEGIN_PROPERTY_SET_EX(DBPROPSET_MYPROPSET, UPROPSET_USERINIT)
PROPERTY_INFO_ENTRY(DBPROP_MYPROP)
END_PROPERTY_SET_EX(DBPROPSET_MYPROPSET)