Sdílet prostřednictvím


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 IDBSchemaRowsettří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_szTablea trData.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, CUpdateSessionColSchemaRowseta 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 .

Viz také

Pokročilé techniky zprostředkování