Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / database / MySQL

Lean and extensible mySQL C++ wrapper

3.76/5 (9 votes)
26 Feb 20071 min read 2   2K  
An article on a lean (2 header files) C++ template class that provides mySQL query

Introduction

This article present a lean C++ wrapper of mySQL client. All of the functions are defined in two header files. Users can build the file with mySQL C API library and header files of boost::shared_ptr which is used to manage the MYSQL connection and result set.

Using the code

The classes diagram of the mySQL client wrapper is shown as the following diagram.

Screenshot - mysql_simple_wrapper_1.jpg

The structure is pretty simple. The only special note is the member function CMysqlConn::Query. The function has a template parameter 'ProcessQuery' which is a 'policy' class to cope with the concreted client requirements of using the API. Different clients have different purposes of querying a database. Some clients want to fetch the data that meets certain predications. Some clients want to insert and update records in which no return data is required. Other clients may just fetch the ID type of data that meets given 'where' clause. Inspired by the policy based solution addressed in Andrei Alexandrescu's "Modern C++ design", the 'Query' member function uses the template solution to separate the usage policy from the general query algorithm.

I have defined three policy classes for the CMysqlConn::Query. Here are the use cases.

  1. Query DB that needs returned data

    SQL
    CMysqlSet rset=conn.Query<WithData>("select * from mytable");

  2. Query DB that does not need returned data

    SQL
    bool ret =conn.Query<NoData>("insert into mytable values 
                        (5000, 'testing message')");

  3. Query DB that only fetches one value

    SQL
    pair<bool, string> value=conn.Query<CheckOneRecord>
            ("select field from mytable where errorcode='2005'"); 

Users can define their own policy class by following this sample:

C++
struct Nodata
{
    //Define your return type
    typedef boolReturnType;

    //Define your failed return function for the query failure case
    static ReturnType ReturnInFail() {return false;}

    //Define your records processing implementation after the 
    //query statement is successfully issued.
    static ReturnType DeepQuery(ConnPtr ptr) {return true;}
};

Here is the sample code of using this wrapper:

C++
int Test()
{
 string query="select * from mytable";
 CMysqlConn conn("myhost","mytable", "login","password");
 if (conn)
 {
    CMysqlSet rset=conn.Query<WithData>(query);
    if (rset)
    {
      cout<<"I got a result";
      unsigned size=rset.NumberOfRecords();

     for (unsigned int i=0;i<size; i++){
       CMysqlRow row=rset.GetNextRow();
       if (row)
       {
        for (unsigned int j=0; j<row.NumberOfFields();j++)
        {
          cout<<row[j];
        }
        cout<<endl;
      }
    }
  }
  cout<<"Last error is 
        "<<conn.GetLastfiled1()<<":"<<conn.GetLastErrorString()<<endl;

   string updateQuery="insert into mytable values (5000, 'testing message')";
  conn.Query<NoData>(updateQuery);

  //
  // Query single data test
  //
  cout<<"query single data..."<<endl;
  pair<bool, string> value=conn.Query<CheckOneRecord>
            ("select filed1s from mytable where filed1='2005'");
  if (value.first)
  {
   cout<<"get value of "<<value.second<<endl;
  }
 }
  return 0;
}

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here