EXPRESS OLE DB Library for C++

Environment:  : VC++ 6.0, Service Pack 5

Library Class Hierarchy

Overview

In my last article, I showed how to extend an OLE DB consumer template class and make it much easier to use in applications. I had also explained how you can utilize the power of C++ exception-handling feature to make your work easier, especially in error handling. It was just a small class in my last article.

In this article, I will present a complete library that is feature-rich, light-weight, lightening fast, and most easy to use. But, before you undestand how to use the library, you have to gain some background knowledge. So,, let us start gaining that knowledge. 

THE DILEMMA OF DATA ACCESS

When it comes to choosing the right data access technology for application development, most Visual C++ programmers face a puzzling set of choices. On one hand, these choices are limited and on the other hand, they are conflicting in terms of performance requirement and ease of use. Whether it is a stand-alone application, a client/server application or a web application, a C++ programmer would never like to compromise the factors of decision such as performance, speed, and resource management. The simple reason for this fact is the underlying tenet that the C++ programmers are supposed to churn out some smartest applications in the programming world. Although the type and make of the database as well as the nature of application can largely influence the decision, it is not as easy as it seems.

Let us try to understand and analyze some of the most obvious data access choices:

Native Library :

Native libraries are supplied by many database vendors and they provide fastest data access for the respective databases. However, due to the well-known fact that the code written using a native library is not portable to other databases, your application gets locked into the database vendors technology. Moreover, each native library is totally different in nature compared to other libraries. So, we will not devout any time discussing this option in detail and leave it to the developers to explore further on this topic.

ADO :

Since its introduction, ADO has been the most widely used option for data access on Windows platform. Though primarily designed and developed for Visual Basic and scripting languages, it is not used less in Visual C++ world either. After ODBC, ADO is the major library that is proven and tested for data access on Windows platform. Thousands of developers using various programming languages on windows platform heavily rely on ADO for the data access need of their applications. Having said that, you might wonder why ADO is not an ideal choice for Visual C++ developers. Well, Here is why:

  • ADO is designed keeping in mind the automation-based languages. So, everything it speaks is in terms of VARIANT, a data type that is hated most by C++ developers. When it comes to using VARIANTs and BSTRs, C++ developers get a hitch. The reason for this disliking is clearly understandable. Converting a VARIANT to and from the native data types of C++ is really a pain. Not only does it call for extra work, but also it affects the overall performance of the application.

  • ADO is a set of wrapper classes that are built on top of OLE DB interfaces. So, it puts an extra layer as far as C++ is concerned since OLE DB interfaces can be directly accessed through C++. Theoretically, an application that uses OLE DB interfaces is considerably faster than the one that uses ADO.

  • Using ADO in Visual C++ also comes with other drawbacks and limitations.

    • If you use #import statement, you cannot avoid jump-to-exception situation even if you want to avoid it. Additionally, you loose flexibility of having default arguments to the methods. You must provide all method arguments.

    • If you use ADO SDK or raw COM interfaces, you have to check for HRESULT values at each and every point. Since data access code normally requires frequent method calls, it becomes cumbersome to check these values.

Concluding on all the points mentioned above, we could say that ADO should be the choice of data access for C++ programmers only if there is no better choice than that.

OLE DB Consumer Templates :

To overcome the limitations of using ADO in C++, Microsoft provided OLE DB consumer templates for C++ developers. Like ADO, they are a set of template classes that are also built around OLE DB interfaces. However, unlike ADO, these classes put only a thin layer on OLE DB and therefore they are lighter, faster, and much powerful. Besides, consumer templates make a native C++ class library, i.e., it is a pure C++ class library and hence it uses the native C++ data types. So, using these classes eliminate the need for using VARIANTs or BSTRs.

Putting all these facts together, one can easily conclude that OLE DB consumer classes have an edge over ADO. Yes, they definitely have. You might wonder then why in the world would any C++ programmer use ADO at all. Adding to your wonder is the fact that more C++ developers use ADO in their applications than OLE DB consumer templates. But, wait a minute. There are several good reasons for this fact. Let us see. I am going to list a few of these reasons below.

  • Memory leaks & bugs : The OLE DB consumer templates contain several classes with bugs and memory leak problems. Most notable of them are the methods of CDataSource class that leak memory and the column binding in CDynamicAccessor class that does not handle wide characters properly. As of Service Pack 5 of Visual Studio 6.0, these problems are not fixed.

  • Lack of features and flexibility : Although consumer templates are much easier to use than raw OLE DB interfaces, they lack several features and functionalities compared to ADO. Checking EOF/BOF status in a rowset, handling BLOB data, refreshing and updating a rowset, fetching error details from HRESULT values are just a few of them to list. Using a data access library without these features in your application is a big work in itself.

  • Error reporting : Most methods of consumer template classes return some HRESULT value. Getting error details from these values requires a fair amount of effort, especially if you want to get the error messages from database server. There is no easy shortcut in consumer templates to do this.

  • Lack of XML support : There is no XML support so far in the consumer template classes. Looking at the .NET version of Visual C++, it seems like Microsoft is planning to incorporate XML support in .NET consumer templates. But till then, you have to resort to your own knowledge of database and XML if you use consumer templates.

  • Cryptic and sparse documentation : If you have moved from ADO to consumer templates, you would find the documentation of consumer templates suffocating. The documentation provided in MSDN is short and sparse and very limited in terms of providing examples and samples. In addition to all these facts, there is hardly any good book in market on OLE DB consumer classes that provides the complete coverage of all the classes.

  • Binding to controls : Unless you are writing a middleware component or a web application, you need to display your data in some form of GUI components. It could be as simple as a text box or as complex as a compound spreadsheet grid. In any case, you need to bind your data to the user interface at some point of time in your application development cycle. Most commercial controls provide data-binding support for ADO. However, since consumer templates are a low-level interface to data, the binding responsibility is rested upon the developer. And binding data to a control is not as simple as point-and-click. This is the reason why many developers choose to convert their OLE DB rowset data into ADO Recordset object for displaying them in GUI.

  • Steeper learning curve : Using OLE DB consumer templates for such basic tasks as inserting and deleting rows from a database table is not a problem. However, if you want to move little above that level, you need to understand well the nitty-gritty of OLE DB. As for example, if you want to create an updateable client-side cursor, not only a lot of work is needed, but also the firm understanding of OLE DB interfaces is must. The fact remains that no matter what technology you use, if you want to access databases at lower level, there is no easy way. And consumer templates are no exception.

INTRODUCTION TO EXPRESS OLE DB LIBRARY

Considering all the aforementioned issues about ADO and consumer templates, the fact becomes clearer that there is no panacea for C++ programmers as far as data access is concerned. No single library is both sufficient as well as efficient. Although consumer template classes are excellent tool for accessing databases, they are incomplete in feature and insufficient from an application development point of view.

EXPRESS OLE DB is a C++ class library that extends the OLE DB consumer template classes and is a complete, feature-rich, and extremely powerful data access solution for C++ programmers. It is built with the aim of eliminating the limitations and drawbacks of consumer templates while still retaining power and performance of consumer templates. Some of the features of this library can be summarized briefly as follows:

  • Easy to use : The library is designed to be as developer-friendly as possible. An attempt is also made to make it as simple as possible.

  • Easy to learn : Many of the features of this library are modeled after ADO and, as such, it is extremely intuitive. The bottom line is that if you know the basics of any data access library, you can easily learn this one too.

  • Easy to debug : Several debug macros and validations are embedded in almost every method in this library. This fact makes a big difference as far as application debugging is concerned. Frequently, it is much easier to debug an application written using EXPRESS OLE DB than the one written using ADO.

  • High performance : Although so many features are added to the library and a lot of care is taken to avoid errors as far as possible, a big effort is made to keep it lightweight and reduce unnecessary overhead. Basic benchmark tests show that a performance gain of EXPRESS OLE DB library over ADO range from 20% to 200% depending upon various factors.

  • Rich in features : We have seen that consumer template classes lack several functionalities and features that are necessary for such basic database operations as checking for EOF, counting rows in a recordset, checking data type of a column etc. So, almost all of these features are added in EXPRESS OLE DB.

  • XML support : EXPRESS OLE DB provides built-in support for XML. Using this library, you can extract the column structure as well as any data from any source in XML format.

  • Powerful Error-Trapping : Automatic error-trapping mechanism is provided through exception handling and a powerful error object can be used to analyze and extract various types of errors.

  • Flexibility : The biggest advantage offered by this library is the flexibility it offers. Take an example of error trapping. You have three different ways to control errors: exceptions, error object, and custom class.

  • Integration : The Express OLE DB library is currently integrated with other commercial libraries such as RogueWave. Stingray studio's Objective Grid library. Future versions will see more integration with many other libraries from different vendors.

  • Free : Above all other points, the biggest advantage is that the Express OLE DB library is absolutely freely distributed by Sypram Technology.

Since this library requires a lot of files, I have included only the sample files in this article. The complete library can be downloaded from the website www.sypram.com. It is distributed completely FREE for the purpose of sharing knowledge. The samples proveded here are also included as part of the class library. Moreover, the complete documentation is also bundled with the library setup. So, I am skipping the details of explanation and use of library. In case you have any technical question on this library, you may contact Support@SypramTech.com

Downloads

Download source - sample projects - 298 Kb
Library file - Part 1 - 1,205 kb
Library file - Part 2 - 1,090 kb


Comments

  • The Secret dominate the nike-arena Is Pretty Straight forward!

    Posted by Acuddence on 04/27/2013 01:35am

    Creative questions on nike replied and the reasons you should definitely go through every single message within this documentation.[url=http://www.nikejpgolf.biz/]ナイキ[/url] A fair double twist on nike [url=http://www.nikejpgolf.biz/nike-ゴルフボール-c-23.html]ナイキgolf[/url] Different queries about nike clarified and as a result reasons why you really need to analyze each phrase of this specific e book. [url=http://www.nikejpgolf.biz/nike-アイアン-c-1.html]ナイキクラブ[/url] Unbiased page shares A couple of completely new things regarding nike that no company is covering. [url=http://www.nikejpgolf.biz/nike-アイアン-c-1.html]nike ゴルフ[/url] I would say the nike Service Talk - Who cares about nothing gains all the revs? [url=http://www.nikejpgolf.biz/nike-ゴルフシューズ-c-15.html]ナイキ nike[/url] Items and release throughout Sin City : mizuno leaves without adios [url=http://www.nikeyasuyi.com/]nike[/url] Gadgets and creation in The philipines - nike leaves without any farewell [url=http://www.nikeyasuyi.com/nikeナイキRunning-c-3.html]nike ランニング[/url] This nike Sector Presentation : Those Who cares triumphs?!? [url=http://www.nikeyasuyi.com/nikeナイキDunk-c-9.html]ナイシューズ[/url] The main nike Home business Call : Which means, who cares profit?! [url=http://www.nikeyasuyi.com/nikeナイキDunk-c-9.html]nike シューズ[/url] nike adds spanking new lifespan to a old problem: silver set

    Reply
  • nvarchar

    Posted by uvraman on 07/28/2005 05:49am

    When a stored procedure which has a nvarchar parameter is called using OLEDB library, the nvarchar parameter value is garbled. It works when the stored proc parameter is changed to varchar. I am using CSypODLQuery::SetParamValue's overloaded LPWSTR to set value of nvarchar parameter. I also checked with overloaded CString member, the result is the same. Any ideas ? Thanks

    Reply
  • .NET

    Posted by Legacy on 06/20/2003 12:00am

    Originally posted by: Federico Ercolessi

    Any version for VS.NET?
    Compiler error using .NET

    Reply
  • Unable to open recordset error

    Posted by Legacy on 04/11/2003 12:00am

    Originally posted by: David

    I have been unable to open a recordset to work with a table.  I have been using the following code:
    
    

    #define DB_NAME "db_world"
    #define WORLD_DATA "data"
    #define WORLD_NAMES "worlds"
    #define DB_PROVIDER "MySQLProv"
    #define DB_ROOT "mysql"

    CSypODLConnection m_mainConn;

    try
    {
    m_mainConn.SetProvider(DB_PROVIDER);
    if (m_mainConn.Open(_T(DB_ROOT),"Admin",""))
    {
    //add record for new world here in db_world
    CSypODLRecordset rs;
    rs.m_bEnableThrow = true;
    rs.m_bHasClientCursor = false;
    try
    {
    if (rs.Open(WORLD_DATA,&m_mainConn,SYPODL_COMMANDTYPE_TABLE,SYPODL_RECORDSETTYPE_DYNAMIC))
    {
    rs.AddNew();
    rs.SetFieldValue("world","worldnamehere");
    rs.Insert();
    }
    }
    catch (CSypODLException& e)
    {
    e.DisplayError();
    }
    }
    }
    catch(CSypODLException& e)
    {
    e.DisplayError();
    }

    When I run this code it fails on "if (rs.Open(...)" jumps to the catch and displays the following error:
    "Errorcode: 1006, Internal Error occurred(GetSingleError),Recordset could not be opened"

    I've read the documentation exenstively, I do not know what I am doing wrong if I am doing anything wrong.

    Reply
  • Cannot load BLOB from MySql

    Posted by Legacy on 03/25/2003 12:00am

    Originally posted by: Markus Rinninger

    So far I�ve based my whole application on this wonderful library. By now, I need to access some sort of BLOB Data in a MySql database. But I can�t open the recordset. Any ideas ?

    Thanx, Markus

    Reply
  • Memory leak

    Posted by Legacy on 12/20/2002 12:00am

    Originally posted by: Donald

    I have a memory leak in my program.  I have eliminated all functionality except, connect to db, query one table into recordset, disconnect from db.  
    
    

    My connect is:
    int CDBModule::DBMConnect(BOOL pReconnect)
    {
    CSypODLConnection * Con;
    try {
    Con = new CSypODLConnection;
    if (!Con) {
    return 1;
    }
    // open the connection
    Con->SetProvider("sqloledb");
    Con->Open(m_SQLServer, m_SQLUserName,
    m_SQLPassword, m_SQLDatabase);

    }
    catch(CSypODLException& e) {
    e.GetError(m_ErrorMsg);
    LogMsg("OLEDB Error");
    }
    catch(...) {
    LogMsg("Error");
    }
    if (!Con){
    return 1;
    } else {
    m_OLEDBConn=Con;
    return 0;
    }
    }


    My disconnect is:
    int CDBModule::DBMDisconnect()
    {
    if (m_OLEDBConn != NULL) {
    try {
    m_OLEDBConn->Close();
    }
    catch(CSypODLException& e) {
    e.GetError(m_ErrorMsg);
    LogMsg("OLEDB Error");
    }
    catch(...) {
    LogMsg("Error");
    }
    delete m_OLEDBConn;
    m_OLEDBConn=NULL;
    }
    return 0;
    }


    My query is:
    int CDBModule::testquery(CString * pRequestFile)
    {
    int retcode=0;
    char m_Statement[500];
    pRequestFile->Empty();
    memset((char *) m_Statement,0,sizeof(m_Statement));
    sprintf((char *) m_Statement,"SELECT FileName FROM Config_ReqFilename WHERE machine_no = %d", m_MachineNo);
    try {
    //Create Recordset
    CSypODLRecordset* rs;
    rs = new(CSypODLRecordset);
    rs->Open(m_Statement, m_OLEDBConn, 2, SYPODL_RECORDSETTYPE_FORWARDONLY);
    if (!rs->IsEOF()) {
    //FILENAME
    rs->GetFieldValue("FILENAME", *pRequestFile);
    pRequestFile->TrimRight();
    }
    rs->Close();
    delete rs;
    }
    catch(CSypODLException& e)
    {
    e.GetError(m_ErrorMsg);
    LogMsg("OLEDB Error");
    retcode = 1;
    }
    catch(...)
    {
    LogMsg("Unknown Error");
    retcode = 1;
    }
    return retcode;
    }

    Reply
  • Resolved - can't connect to database

    Posted by Legacy on 11/21/2002 12:00am

    Originally posted by: Laurent Dussutour

    I can't connect to a access database.
    
    I made a database dll in my project and the Open method on the connection object doesn't work. I don't know why.
    I tried the same code in a little wizard test application and it works good.

    this is my code :

    ::CoInitialize(NULL);

    CString DSN = _T("CCSys.mdb");
    CString UID = _T("Admin");
    CString PWD = _T("");
    CString Catalog = _T("");

    try
    {
    m_Connection.SetTimeOutValue(15L);
    m_Connection.m_bIncludeServiceComponents = FALSE;
    m_Connection.SetProvider(_T("Microsoft.Jet.OLEDB.4.0"));
    m_Connection.Open(DSN, UID, PWD, Catalog);

    }
    catch(CSypODLException& e)
    {
    CString str;
    e.GetError(str); // Fetch error details in 'str'
    AfxMessageBox(str);
    }

    When i run in step by step debug mode, i see that the SetProvider works good because i see the good string in the m_Provider of the m_connection object.
    On the other hand the Open method have the good parameters but the m_DSN, the m_UID of the m_Connection object are not good.
    And then I got the error message :
    "Errorcode 1012 Internal error occured (GetSingleError) Can not open datasource"

    Please help


    Resolved : the problem was in code generation. Struct member alignment must be 8 bytes.

    Reply
  • how to delete a field value ?

    Posted by Legacy on 11/21/2002 12:00am

    Originally posted by: Laurent Dussutour

    I'd like to know how to delete a value from a field.
    SetFieldValue("MyField", ""); returns me an error message.
    Thanks...

    Reply
  • Doesn't works for Oracle datatype NUMBER

    Posted by Legacy on 11/07/2002 12:00am

    Originally posted by: VJ

    Hi this code doesn't works for NUMBER datatype of ORACLE. I am not able to find a way to map this datatype to any of VC++'s datatype.
    

    Reply
  • Cannot execute ! Please help....

    Posted by Legacy on 09/16/2002 12:00am

    Originally posted by: Siddharth Barman

    This is the small bit of code I have written for developing the database part of my application:

    CSypODLConnection conn;
    CString strQuery;
    char strTime[30];

    strcpy(strQtmNo, "QT01");
    strcpy(strParamCode, "DM");
    fValue = 4.5F;

    conn.SetProvider("CSypODLConnection conn;");


    the application compiles fine. But when this code is run,
    I get a DEBUG exception.

    Please help. This library seems pretty useful and easy..
    any help would be appreciated.

    Reply
  • Loading, Please Wait ...

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • The explosion in mobile devices and applications has generated a great deal of interest in APIs. Today's businesses are under increased pressure to make it easy to build apps, supply tools to help developers work more quickly, and deploy operational analytics so they can track users, developers, application performance, and more. Apigee Edge provides comprehensive API delivery tools and both operational and business-level analytics in an integrated platform. It is available as on-premise software or through …

  • Best-in-Class organizations execute on a strategy that supports the multi-channel nature of customer requests. These leading organizations do not just open up their service infrastructures to accommodate new channels, but also empower their teams to deliver an effective and consistent experience regardless of the channel selected by the customer. This document will highlight the key business capabilities that support a Best-in-Class customer engagement strategy.

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds