OLE DB is a specification. It is not a set of components or files. It defines the way that a consumer, the client who is retrieving the data, talks to a provider, the server who is supplying the data. The provider is a COM object which is created by calling CoCreateInstance() . After creating an instance of the provider, the consumer than talks to the provider using the OLE DB defined interfaces. These interfaces are acquired by calling QueryInterface().
Figure 1 – OLE DB Object Model
· Enumerators. Enumerators search for available data sources and other enumerators. Consumers that are not customized for a particular data source use enumerators to search for a data source to use.
· Data Source Objects. Data source objects contain the machinery to connect to a data source, such as a file or a DBMS. They are a factory for sessions.
· Sessions. Sessions provide a context for transactions and can be implicitly or explicitly transacted. A single data source object can create multiple sessions. Sessions are a factory for transactions, commands, and rowsets.
· Transactions. Transaction objects are used when committing or aborting nested transactions at other than the lowest level.
· Commands. Commands execute a text command, such as an SQL statement. If the text command specifies a rowset, such as an SQL SELECT statement, the command is a factory for the rowset. A single session can create multiple commands.
· Rowsets. Rowsets expose data in tabular format. A special case of a rowset is an index. Rowsets can be created from the session or the command.
The only object which gets created using the OLE function CoCreateInstance() function is the Data Source object which is classified as the OLE DB Provider. It is given a CLSID and ProgID. No other OLE DB objects shown above have a CLSID or ProgID as they are not creatable COM Classes (CoClasses). The remaining OLE DB objects are created by calling methods of an interface like IDBCreateSession::CreateSession() and IDBCreateCommand::CreateCommand().
A Walk Through Using OLE DB
To better understand how OLE DB works and how the objects are created and used, this section will walk through the steps of traversing data supplied by an OLE DB Provider.
1. Create an instance of the OLE DB Provider by calling the appropriate COM functions such as CoCreateInstance(). Request one of the interfaces of the data source object such as IDBInitialize or IDBProperties.
2. Get information about the data source or set the data source properties. Finally, call IDBInitialize::Initialize().
3. Create a Session object from the data source object and possibly start a transaction.
4. Create a rowset immediately if there are no commands needs to access the data or create a command object. One example where a rowset could be created immediately is when a data source object is fed the property of a text file and no other information is needed to read the file. The provider could simply support the creation of the rowset immediately without having to receive a command. This is done through the OLE DB interface IOpenRowset which is a interface of the Session object. If a command is necessary, the Session object is queried for the IDBCreateCommand interface and IDBCreateCommand::CreateCommand is called. In the call to CreateCommand() the programmer specifies which interface of the command object to retrieve.
5. In the command object, set the command text by calling ICommandText::SetCommandText().
6. Set the properties of the rowset that will be retrieved by using the ICommandProperties::SetProperties(). Some of these properties determine updatability, scrollablity, and whether or not the cursor will be a server-side cursor.
7. Create OLE DB accessors for any parameters which will be used in the command.
8. Call ICommand::Execute() to retrieve the rowset and get back an interface to the rowset.
9. Create an accessor for the returned rowset
10. Move through the rowset using GetNextRows() to retrive the handles to the rowset rows.
11. Call IRowset::GetData() using the accessor to retrieve the data of the current record.
12. Retrieve all of the data and be sure to free all of the handles (row and accessor).
13. Release all of the interfaces of the OLE DB objects. This will unload the OLE DB Provider.