プロバイダー クラスには多重継承を使います。 次のコードは、データ ソース オブジェクトの継承チェーンを示しています。
/////////////////////////////////////////////////////////////////////////
// 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' クラスも継承します。 各クラスは、1 つのインターフェイスに対する実装を提供します。 データ ソース オブジェクトは、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 セット用の 2 つのプロパティ グループがあります。 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;
};
構造体の各要素は、プロパティを処理するための情報を表しています。 これには、プロパティの GUID と ID を決定するための DBPROPID が含まれています。 また、プロパティの型と値を決定するためのエントリも含まれています。
プロパティの既定値を変更する場合は (コンシューマーは書き込み可能なプロパティの値をいつでも変更できることに注意してください)、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)