Implementace jednoduchého příjemce
Následující témata ukazují, jak upravit soubory vytvořené v průvodci aplikace knihovny MFC a průvodce příjemce knihovny ATL technologie OLE DB, abyste vytvořili jednoduchého příjemce.Tento příklad má následující části:
"Načítání dat pomocí příjemce" ukazuje, jak implementovat kód v příjemci, který načte všechna data po řádcích z databázové tabulky.
"Přidání podpory záložky do příjemce" ukazuje, jak přidat podporu záložky do příjemce.
"Přidání podpory jazyka XML do příjemce" ukazuje, jak změnit kód příjemce, aby byla odeslána data načtených řádků na výstup jako data jazyka XML.
[!POZNÁMKA]
Můžete použít aplikaci příjemce popsanou v tomto oddíle, abyste otestovali MyProv a ukázkové zprostředkovatele Provider.
[!POZNÁMKA]
Chcete-li sestavit aplikaci příjemce, abyste otestovali MyProv (stejný zprostředkovatel popsaný v Posílení jednoduchého zprostředkovatele pouze pro čtení), je nutné zahrnout podporu záložky podle popisu v "Přidání podpory záložky k příjemci".
[!POZNÁMKA]
Chcete-li sestavit aplikaci příjemce, abyste otestovali Provider, ponechte podporu záložky, jak je popsáno u kroku Přidání podpory záložky do příjemce, a pokračujte na Přidání podpory jazyka XML do příjemce"
Načítání dat pomocí příjemce
Chcete-li změnit konzolovou aplikaci, aby používala příjemce technologie OLE DB
V MyCons.cpp změňte hlavní kód tím, že vložíte tučný text takto:
// MyCons.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include "Products.h" ... int main(int argc, char* argv[]) { HRESULT hr = CoInitialize(NULL); // Instantiate rowset CProducts rs; hr = rs.OpenAll(); ATLASSERT( SUCCEEDED( hr ) ); hr = rs.MoveFirst(); // Iterate through the rowset while( SUCCEEDED(hr) && hr != DB_S_ENDOFROWSET ) { // Print out the column information for each row printf("Product ID: %d, Name: %s, Unit Price: %d, Quantity per Unit: %d, Units in Stock %d, Reorder Level %d\n", rs.m_ProductID, rs.m_ProductName, rs.m_UnitPrice, rs.m_QuantityPerUnit, rs.m_UnitsInStock, rs.m_ReorderLevel ); hr = rs.MoveNext(); } rs.Close(); rs.ReleaseCommand(); CoUninitialize(); return 0; }
Přidání podpory záložky do příjemce
Záložka je sloupec, který jednoznačně identifikuje řádky tabulky.Obvykle je to klíčový sloupec, ale ne vždy; je to specifické pro zprostředkovatele.V této sekci se dozvíte, jak přidat podporu záložky.Chcete-li tak učinit, musíte v třídě uživatelského záznamu provést následující:
Vytvořit instanci záložky.Jedná se o objekty typu CBookmark.
Požádat o sloupec záložky od zprostředkovatele nastavením vlastnosti DBPROP_IRowsetLocate.
Přidání položky záložky do mapy sloupce pomocí makra BOOKMARK_ENTRY.
Předchozí kroky vám umožní podporu záložky a objektu záložky, se kterým chcete pracovat.Tento příklad kódu ukazuje záložku takto:
Otevře soubor pro zápis.
Odešle výstupní data sady řádků do souboru řádek po řádku.
Přesune kurzor sady řádků na záložku voláním MoveToBookmark.
Odešle řádek označený záložkou na výstup a připojí jej na konec souboru.
[!POZNÁMKA]
Jestliže používáte tuto aplikaci příjemce, abyste otestovali ukázku aplikace zprostředkovatele Provider, nevšímejte si podpory záložky popsané v tomto oddíle.
Chcete-li vytvořit instanci záložky
Přistupující objekt musí obsahovat objekt typu CBookmark.Parametr nSize určuje velikost vyrovnávací paměti záložky v bajtech (obvykle 4 pro 32bitové platformy a 8 pro 64bitové platformy).Přidejte následující deklaraci třídy k datovým členům sloupce v třídě uživatelského záznamu:
////////////////////////////////////////////////////////////////////// // Products.h class CProductsAccessor { public: CBookmark<4> m_bookmark; // Add bookmark declaration LONG m_ProductID; ...
Chcete-li požadovat sloupec záložky od zprostředkovatele
Přidejte následující kód v metodě GetRowsetProperties v třídě uživatelského záznamu:
// Set the DBPROP_IRowsetLocate property. void GetRowsetProperties(CDBPropSet* pPropSet) { pPropSet->AddProperty(DBPROP_CANFETCHBACKWARDS, true, DBPROPOPTIONS_OPTIONAL); pPropSet->AddProperty(DBPROP_CANSCROLLBACKWARDS, true, DBPROPOPTIONS_OPTIONAL); // Add DBPROP_IRowsetLocate property to support bookmarks pPropSet->AddProperty(DBPROP_IRowsetLocate, true); }
Chcete-li přidat položku záložky do mapy sloupce
Přidejte následující položku do mapy sloupce v třídě uživatelského záznamu:
// Set a bookmark entry in the column map. BEGIN_COLUMN_MAP(CProductsAccessor) BOOKMARK_ENTRY(m_bookmark) // Add bookmark entry COLUMN_ENTRY_LENGTH_STATUS(1, m_ProductID, m_dwProductIDLength, m_dwProductIDStatus) COLUMN_ENTRY_LENGTH_STATUS(2, m_ProductName, m_dwProductNameLength, m_dwProductNameStatus) ... END_COLUMN_MAP()
Chcete-li používat záložky v hlavním kódu
V souboru MyCons.cpp z konzolové aplikace, kterou jste dříve vytvořili, změňte hlavní kód takto.Pro použití záložek musí hlavní kód vytvořit vlastní instanci objektu záložky (myBookmark); toto je jiná záložka než ta v přistupujícím objektu (m_bookmark).
/////////////////////////////////////////////////////////////////////// // MyCons.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include "Products.h" #include <iostream> #include <fstream> using namespace std; int _tmain(int argc, _TCHAR* argv[]) { HRESULT hr = CoInitialize(NULL); // Instantiate rowset CProducts rs; hr = rs.OpenAll(); hr = rs.MoveFirst(); // Cast CURRENCY m_UnitPrice to a long value LONGLONG lPrice = rs.m_UnitPrice.int64; // Open file output.txt for writing in overwrite mode ofstream outfile( "C:\\output.txt", ios::out ); if (!outfile) // Test for invalid file return -1; // Instantiate a bookmark object myBookmark for the main code CBookmark<4> myBookmark; int nCounter = 0; // Iterate through the rowset and output column data to output.txt row by row // In the file, mark the beginning of this set of data: outfile << "initial row dump" << endl; while( SUCCEEDED(hr) && hr != DB_S_ENDOFROWSET ) { nCounter++; if( nCounter == 5 ) myBookmark = rs.bookmark; // Output the column information for each row: outfile << rs.m_ProductID << rs.m_ProductName << lPrice << rs.m_QuantityPerUnit << rs.m_UnitsInStock << rs.m_ReorderLevel << endl; hr = rs.MoveNext(); } // Move cursor to bookmark hr = rs.MoveToBookmark(myBookmark); // Iterate through the rowset and output column data to output.txt row by row // In the file, mark the beginning of this set of data: outfile << "row dump starting from bookmarked row" << endl; while( SUCCEEDED(hr) && hr != DB_S_ENDOFROWSET ) { // Output the column information for each row outfile << rs.m_ProductID << rs.m_ProductName << lPrice << rs.m_QuantityPerUnit << rs.m_UnitsInStock << rs.m_ReorderLevel << endl; hr = rs.MoveNext(); } rs.CloseAll(); CoUninitialize(); return 0; }
Další informace o záložkách naleznete v tématu Použití záložek.Příklady záložek jsou také uvedeny v Aktualizace sad řádků.
Přidání podpory jazyka XML do příjemce
Jak je uvedeno v Přístup k datům XML, existují dva způsoby k načtení XML dat ze zdroje dat: pomocí CStreamRowset nebo pomocí CXMLAccessor.V tomto příkladu je použit CStreamRowset, který je efektivnější, ale je nutné mít spuštěn SQL Server 2000 v počítači, na kterém bude tato ukázková aplikace prováděna.
Chcete-li upravit příkaz třídy, aby dědila z CStreamRowset
V aplikaci příjemce, kterou jste již dříve vytvořili, změňte vaši deklaraci CCommand tak, aby specifikovala CStreamRowset jako třídu řádků takto:
class CProducts : public CCommand<CAccessor<CProductsAccessor>, CStreamRowset >
Chcete-li upravit hlavní kód, aby načetl a odeslal XML data na výstup
V souboru MyCons.cpp z konzolové aplikace, kterou jste dříve vytvořili, změňte hlavní kód takto:
/////////////////////////////////////////////////////////////////////// // MyCons.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include "Products.h" #include <iostream> #include <fstream> using namespace std; int _tmain(int argc, _TCHAR* argv[]) { HRESULT hr = CoInitialize(NULL); // Instantiate rowset CProducts rs; // Add variable declarations for the Read method to handle sequential stream data CHAR buffer[1001]; // Pointer to buffer into which data stream is read ULONG cbRead; // Actual number of bytes read from the data stream hr = rs.OpenAll(); // Open file output.txt for writing in overwrite mode ofstream outfile( "C:\\output.txt", ios::out ); if (!outfile) // Test for invalid file return -1; // The following loop reads 1000 bytes of the data stream at a time // until it reaches the end of the data stream for (;;) { // Read sequential stream data into buffer HRESULT hr = rs.m_spStream->Read(buffer, 1000, &cbRead); if (FAILED (hr)) break; // Output buffer to file buffer[cbRead] = 0; outfile << buffer; // Test for end of data stream if (cbRead < 1000) break; } rs.CloseAll(); CoUninitialize(); return 0; }