Podpora sad řádků schématu
Sady řádků schématu umožňují uživatelům získat informace o úložišti dat bez znalosti základní struktury nebo schématu. Úložiště dat může mít například tabulky uspořádané do uživatelem definované hierarchie, takže neexistuje způsob, jak zajistit znalost schématu s výjimkou jeho čtení. (Jako další příklad používají průvodci Visual C++ sady řádků schématu ke generování přístupových objektů pro příjemce.) Aby to uživatel mohl provést, objekt relace poskytovatele zveřejňuje metody v rozhraní IDBSchemaRowset . V aplikacích Visual C++ použijete k implementaci IDBSchemaRowset
třídu IDBSchemaRowsetImpl .
IDBSchemaRowsetImpl
podporuje následující metody:
CheckRestrictions kontroluje platnost omezení u sady řádků schématu.
CreateSchemaRowset implementuje funkci tvůrce objektu modelu COM pro objekt určený parametrem šablony.
SetRestrictions určuje, která omezení u konkrétní sady řádků schématu podporujete.
IDBSchemaRowset::GetRowset vrátí sadu řádků schématu (zděděnou z rozhraní).
Funkce GetSchemas vrátí seznam sad řádků schématu, které
IDBSchemaRowsetImpl::GetRowset
jsou přístupné (zděděné z rozhraní).
Podpora průvodce zprostředkovatelem ATL OLE DB
Průvodce zprostředkovatelem ATL OLE DB není v sadě Visual Studio 2019 a novější k dispozici.
Průvodce zprostředkovatelem ATL OLE DB vytvoří v souboru hlavičky relace tři třídy schématu:
CShortNameSessionTRSchemaRowset
CShortNameSessionColSchemaRowset
CShortNameSessionPTSchemaRowset
Tyto třídy reagují na žádosti příjemců o informace o schématu; Všimněte si, že specifikace OLE DB vyžaduje, aby byly podporovány tyto tři sady řádků schématu:
CShortNameSessionTRSchemaRowset zpracovává požadavky na informace tabulky (sada řádků schématu DBSCHEMA_TABLES).
CShortNameSessionColSchemaRowset zpracovává požadavky na informace o sloupci (sada řádků schématu DBSCHEMA_COLUMNS). Průvodce poskytuje ukázkové implementace pro tyto třídy, které vracejí informace o schématu pro poskytovatele SYSTÉMU DOS.
CShortNameSessionPTSchemaRowset zpracovává požadavky na informace o schématu o typu zprostředkovatele (sada řádků schématu DBSCHEMA_PROVIDER_TYPES). Výchozí implementace poskytovaná průvodcem vrátí S_OK.
Tyto třídy můžete přizpůsobit tak, aby zpracovávaly informace o schématu vhodné pro vašeho poskytovatele:
V jazyce CShortNameSessionTRSchemaRowset musíte vyplnit pole katalogu, tabulky a popisu (
trData.m_szType
,trData.m_szTable
atrData.m_szDesc
). Příklad vygenerovaný průvodce používá pouze jeden řádek (tabulku). Jiní poskytovatelé můžou vrátit více než jednu tabulku.V CShortNameSessionColSchemaRowset předáte název tabulky jako .
DBID
Nastavení omezení
Důležitým konceptem podpory sady řádků schématu je nastavení omezení, která používáte SetRestrictions
. Omezení umožňují uživatelům načíst pouze odpovídající řádky (například najít všechny sloupce v tabulce MyTable). Omezení jsou volitelná a v případě, že nejsou podporovány žádné (výchozí), vrátí se vždy všechna data. Příklad poskytovatele, který podporuje omezení, najdete v ukázce UpdatePV .
Nastavení mapy schématu
Nastavte mapu schématu, jako je tato v Session.h v updatePV:
BEGIN_SCHEMA_MAP(CUpdateSession)
SCHEMA_ENTRY(DBSCHEMA_TABLES, CUpdateSessionTRSchemaRowset)
SCHEMA_ENTRY(DBSCHEMA_COLUMNS, CUpdateSessionColSchemaRowset)
SCHEMA_ENTRY(DBSCHEMA_PROVIDER_TYPES, CUpdateSessionPTSchemaRowset)
END_SCHEMA_MAP()
Pokud chcete podporu IDBSchemaRowset
, musíte podporovat DBSCHEMA_TABLES, DBSCHEMA_COLUMNS a DBSCHEMA_PROVIDER_TYPES. Podle vlastního uvážení můžete přidat další sady řádků schématu.
Deklarujte třídu sady řádků schématu Execute
pomocí metody, například CUpdateSessionTRSchemaRowset
v UpdatePV
:
class CUpdateSessionTRSchemaRowset :
public CSchemaRowsetImpl < CUpdateSessionTRSchemaRowset,
CTABLESRow, CUpdateSession >
...
// Execute looks like this; what pointers does the consumer use?
HRESULT Execute(DBROWCOUNT* pcRowsAffected,
ULONG cRestrictions, const VARIANT* rgRestrictions)
CUpdateSession
dědí z IDBSchemaRowsetImpl
, takže má všechny metody zpracování omezení. Použití CSchemaRowsetImpl
, deklarujte tři podřízené třídy (uvedené v mapě schématu výše): CUpdateSessionTRSchemaRowset
, CUpdateSessionColSchemaRowset
a CUpdateSessionPTSchemaRowset
. Každá z těchto podřízených tříd má metodu Execute
, která zpracovává příslušnou sadu omezení (kritéria vyhledávání). Každá Execute
metoda porovnává hodnoty parametrů cRestrictions a rgRestrictions. Podívejte se na popis těchto parametrů v setRestrictions.
Další informace o tom, která omezení odpovídají konkrétní sadě řádků schématu, naleznete v tabulce identifikátorů GUID sady řádků schématu v IDBSchemaRowset v odkazech programátorů OLE DB v sadě Windows SDK.
Pokud jste například podporovali omezení TABLE_NAME pro DBSCHEMA_TABLES, postupujte takto:
Nejprve vyhledejte DBSCHEMA_TABLES a zjistěte, že podporuje čtyři omezení (v pořadí).
Omezení sady řádků schématu | Hodnota omezení |
---|---|
TABLE_CATALOG | 0x1 (binární 1) |
TABLE_SCHEMA | 0x2 (binární 10) |
TABLE_NAME | 0x4 (binární 100) |
TABLE_TYPE | 0x8 (binární 1000) |
V dalším kroku je pro každé omezení jeden bit. Protože chcete podporovat pouze TABLE_NAME, vrátíte 0x4 v elementu rgRestrictions
. Pokud jste podporovali TABLE_CATALOG a TABLE_NAME, vrátili byste 0x5 (binární číslo 101).
Ve výchozím nastavení vrátí implementace hodnotu 0 (nepodporuje žádná omezení) pro jakýkoli požadavek. UpdatePV je příkladem poskytovatele, který podporuje omezení.
Příklad
Tento kód je převzat z ukázky UpdatePV . UpdatePv
podporuje tři požadované sady řádků schématu: DBSCHEMA_TABLES, DBSCHEMA_COLUMNS a DBSCHEMA_PROVIDER_TYPES. Jako příklad implementace podpory schématu ve vašem poskytovateli vás toto téma provede implementací sady řádků DBSCHEMA_TABLE.
Poznámka:
Vzorový kód se může lišit od toho, co je zde uvedeno; vzorový kód byste měli považovat za aktuální verzi.
Prvním krokem při přidávání podpory schématu je určit, která omezení budete podporovat. Chcete-li určit, která omezení jsou k dispozici pro sadu řádků schématu, podívejte se na specifikaci OLE DB pro definici IDBSchemaRowset
. Po hlavní definici uvidíte tabulku, která obsahuje název sady řádků schématu, počet omezení a sloupce omezení. Vyberte sadu řádků schématu, kterou chcete podporovat, a poznamenejte si počet omezení a sloupců omezení. Například DBSCHEMA_TABLES podporuje čtyři omezení (TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME a TABLE_TYPE):
void SetRestrictions(ULONG cRestrictions, GUID* rguidSchema,
ULONG* rgRestrictions)
{
for (ULONG l=0; l<cRestrictions; l++)
{
if (InlineIsEqualGUID(rguidSchema[l], DBSCHEMA_TABLES))
rgRestrictions[l] = 0x0C;
else if (InlineIsEqualGUID(rguidSchema[l], DBSCHEMA_COLUMNS))
rgRestrictions[l] = 0x04;
else if (InlineIsEqualGUID(rguidSchema[l],
DBSCHEMA_PROVIDER_TYPES))
rgRestrictions[l] = 0x00;
}
}
Bit představuje každý sloupec omezení. Pokud chcete podporovat omezení (to znamená, že ho můžete dotazovat), nastavte tento bit na hodnotu 1. Pokud nechcete podporovat omezení, nastavte tento bit na nulu. Z řádku výše uvedeného UpdatePV
kódu podporuje TABLE_NAME a TABLE_TYPE omezení sady řádků DBSCHEMA_TABLES. Toto jsou omezení třetí (bitová maska 100) a čtvrtá (maska bitu 1000). Proto je bitová maska UpdatePv
1100 (nebo 0x0C):
if (InlineIsEqualGUID(rguidSchema[l], DBSCHEMA_TABLES))
rgRestrictions[l] = 0x0C;
Následující Execute
funkce je podobná funkcím v běžných sadách řádků. Máte tři argumenty: pcRowsAffected, cRestrictions a rgRestrictions. Proměnná pcRowsAffected je výstupní parametr, který může poskytovatel vrátit počet řádků v sadě řádků schématu. CRestrictions parametr je vstupní parametr, který obsahuje počet omezení předaných příjemcem zprostředkovateli. Parametr rgRestrictions je pole hodnot VARIANT, které obsahují hodnoty omezení.
HRESULT Execute(DBROWCOUNT* pcRowsAffected, ULONG cRestrictions,
const VARIANT* rgRestrictions)
Proměnná cRestrictions je založená na celkovém počtu omezení sady řádků schématu bez ohledu na to, jestli je poskytovatel podporuje. Protože UpdatePv podporuje dvě omezení (třetí a čtvrtý), tento kód hledá pouze hodnotu cRestrictions větší než nebo rovno třem.
Hodnota omezení TABLE_NAME je uložena v rgRestrictions[2] (třetí omezení v poli založeném na nule je 2). Zkontrolujte, že omezení není VT_EMPTY, aby ho skutečně podporovalo. Všimněte si, že VT_NULL se nerovná VT_EMPTY. VT_NULL určuje platnou hodnotu omezení.
Definice UpdatePv
názvu tabulky je plně kvalifikovaný název cesty k textovému souboru. Extrahujte hodnotu omezení a pokuste se soubor otevřít, abyste zajistili, že soubor skutečně existuje. Pokud soubor neexistuje, vraťte S_OK. Může to vypadat trochu zpětně, ale to, co kód skutečně říká příjemci, je, že zadaný název neobsahuje žádné podporované tabulky. Vrácená S_OK znamená, že se kód správně spustil.
USES_CONVERSION;
enum {
sizeOfszFile = 255
};
CTABLESRow trData;
FILE *pFile = NULL;
TCHAR szFile[ sizeOfszFile ];
errcode err = 0;
// Handle any restrictions sent to us. This only handles
// the TABLE_NAME & TABLE_TYPE restictions (the 3rd and 4th
// restrictions in DBSCHEMA_TABLES...look in IDBSchemaRowsets
// in part 2 of the prog. ref) so your restrictions are 0x08 & 0x04
// for a total of (0x0C)
if (cRestrictions >= 3 && rgRestrictions[2].vt != VT_EMPTY)
{
CComBSTR bstrName = rgRestrictions[2].bstrVal;
if ((rgRestrictions[2].vt == VT_BSTR) && (bstrName != (BSTR)NULL))
{
// Check to see if the file exists
_tcscpy_s(&szFile[0], sizeOfszFile, OLE2T(bstrName));
if (szFile[0] == _T('\0') ||
((err = _tfopen(&pFile, &szFile[0], _T("r"))) == 0))
{
return S_OK;// Their restriction was invalid return no data
}
else
{
fclose(pFile);
}
}
}
Podpora čtvrtého omezení (TABLE_TYPE) se podobá třetímu omezení. Zkontrolujte, jestli hodnota není VT_EMPTY. Toto omezení vrátí pouze typ tabulky TABLE. Pokud chcete určit platné hodnoty pro DBSCHEMA_TABLES, podívejte se do dodatku B reference programátora OLE DB v části SADA řádků TABULKY.
// TABLE_TYPE restriction:
if (cRestrictions >=4 && rgRestrictions[3].vt != VT_EMPTY)
{
CComBSTR bstrType = rgRestrictions[3].bstrVal;
if ((rgRestrictions[3].vt == VT_BSTR) && (bstrType != (BSTR)NULL))
{
// This is kind of a blind restriction.
// This only actually supports
// TABLES so if you get anything else,
// just return an empty rowset.
if (_tcscmp(_T("TABLE"), OLE2T(bstrType)) != 0)
return S_OK;
}
}
Tady ve skutečnosti vytvoříte položku řádku pro sadu řádků. Proměnná trData
odpovídá CTABLESRow
, struktura definovaná v šablonách zprostředkovatele OLE DB. CTABLESRow
odpovídá definici sady řádků TABULKY v dodatku B specifikace OLE DB. Přidat můžete jenom jeden řádek, protože můžete podporovat jenom jednu tabulku najednou.
// Bring over the data:
wcspy_s(trData.m_szType, OLESTR("TABLE"), 5);
wcspy_s(trData.m_szDesc, OLESTR("The Directory Table"), 19);
wcsncpy_s(trData.m_szTable, T2OLE(szFile), _TRUNCATE());
UpdatePV
nastaví pouze tři sloupce: TABLE_NAME, TABLE_TYPE a DESCRIPTION. Poznamenejte si sloupce, pro které vracíte informace, protože tyto informace potřebujete při implementaci GetDBStatus
:
_ATLTRY
{
m_rgRowData.Add(trData);
}
_ATLCATCHALL()
{
return E_OUTOFMEMORY;
}
//if (!m_rgRowData.Add(trData))
// return E_OUTOFMEMORY;
*pcRowsAffected = 1;
return S_OK;
}
Funkce GetDBStatus
je důležitá pro správnou operaci sady řádků schématu. Vzhledem k tomu, že nevracíte data pro každý sloupec v sadě řádků TABULKY, musíte určit, pro které sloupce vracíte data a pro které ne.
virtual DBSTATUS GetDBStatus(CSimpleRow* , ATLCOLUMNINFO* pColInfo)
{
ATLASSERT(pColInfo != NULL);
switch(pColInfo->iOrdinal)
{
case 3: // TABLE_NAME
case 4: // TABLE_TYPE
case 6: // DESCRIPTION
return DBSTATUS_S_OK;
break;
default:
return DBSTATUS_S_ISNULL;
break;
}
}
Vzhledem k tomu, že funkce Execute
vrací data pro pole TABLE_NAME, TABLE_TYPE a DESCRIPTION ze sady řádků TABULKY, můžete se podívat do dodatku B specifikace OLE DB a určit (počítáním shora dolů), že jsou ordinaly 3, 4 a 6. Pro každý z těchto sloupců vraťte DBSTATUS_S_OK. Pro všechny ostatní sloupce vraťte DBSTATUS_S_ISNULL. Je důležité vrátit tento stav, protože příjemce nemusí pochopit, že vrácená hodnota je NULL nebo něco jiného. Opět mějte na paměti, že hodnota NULL není ekvivalentní prázdnému.
Další informace o rozhraní sady řádků schématu OLE DB naleznete v IDBSchemaRowset rozhraní v OLE DB Programátor reference.
Informace o tom, jak uživatelé mohou používat IDBSchemaRowset
metody, naleznete v tématu Získání metadat pomocí sad řádků schématu.
Příklad zprostředkovatele, který podporuje sady řádků schématu, najdete v ukázce UpdatePV .