using mongoDB with C++

While it is very easy to connect to mongo via node.js, I wanted to write an article about using C++  to connect to this great DB. This is done under ubuntu.

Ingredients (using apt-get here will do)

  1. git
  2. scons
  3. build-utils
  4. openssl
  5. libboost1.54-all-dev (or 55, or whatever going to be the version when you read it)
Compile the driver

Don't install from repo; Drivers should be compiled and it's actually pretty easy.

  1. create the directory in which you want the driver to reside.
  2. clone this repository: git clone git@github.com:mongodb/mongo-cxx-driver.git
  3. get into the folder created by git
  4. run scons --prefix=$HOME/mongo-client-install --ssl install  to build the target. (if you are getting scons error, you are not in the folder, or you didn't install the entire list above). Let me clear this command as you run it: it will build and install from wherever you are now, to a new location, which is your home/mongo-client-install. You might wanna change that later on, but for now, this is fine.
  5. You can now use your favorite IDE to create a project to use with mongo. in your IDE, make sure you don't have any residues of old installations. If you do, remove them.
  6. make sure you are using paths to the include folder, path to the library and the library you created.
  7. more libraries you will need (you might need to adjust the names/path, under ubuntu64 this should be fine):

    1. /usr/lib/x86_64-linux-gnu/libcrypto.so
    2. /usr/lib/x86_64-linux-gnu/libssl.so
    3. /usr/lib/x86_64-linux-gnu/libboost_regex.so
  8. That's all! You are now ready to write your first program.

Test program can be found here: https://github.com/talreg/mongoclient

 

Updates:

On ubuntu 1604, you'll have gcc 5.x. the scons command should be :scons –ssl –prefix=/programs/mongocpp –c++11=on CCFLAGS="-Wno-unused-variable -Wno-maybe-uninitialized"

where prefix is where you want to driver files to be.

Processing XML with C++ under ubuntu with xerces

Setting up

  • apt-get this: ¬†apt-get install libxerces-c3.1 libxmltooling-dev -y
  • Project linking libraries: /usr/lib/x86_64-linux-gnu/libxerces-c.so (path might vary, use locate to find out)

After setting up everything, first thing is to generate XML data that we can port to a file and a string. the file is for storage and for us to read from in the second part, the string is to pass the data around.

First thing: initializing Xerces:

before any xerces method is called, XMLPlatformUtils::Initialize(); must be executed. At the end of your program, don’t forget to call XMLPlatformUtils::Terminate();. both are defined in xercesc/util/PlatformUtils.hpp.

The XML “factory”

First thing in creating DOM documents, is to initialize the key object, the DOMImplementation.This is done like this:

DOMImplementation *pImplement = nullptr;
pImplement = DOMImplementationRegistry::getDOMImplementation(XMLString::transcode("LS"));

To create a document, Xerces requires us to create a document type first.

DOMDocumentType* pDoctype = nullptr;
pDoctype=pImplement->createDocumentType(XMLString::transcode("xml"),0,0);
DOMDocument * pDoc = pImplement->createDocument(XMLString::transcode("xml"),

XMLString::transcode("xml"),pDoctype);

Sidebar: theXMLString

The XML string is a utf16 string. after creating it, you have to release it or it will leak memory! I’m not doing this here to get a cleaner code, but it must be done. there are many ways to handle this, and I will show one of them later

From this point, the creating of elements is very easy and done by calling

DOMDocument::createElement(XMLString). Again, elements returned here, must be release.

To add a child element to a parent, use DOMElement::appendChild(DOMElement * child)

To extract the xml data to a string we use the DOMLSSerializer class. Like many others, this class is also retained from the DOMImplementation class:

DOMImplementation *pImplement = nullptr;
pImplement = DOMImplementationRegistry::getDOMImplementation(XMLString::transcode("LS"));
pSerializer=pImplement->createLSSerializer();

(of course, if you already have an instance you don’t need to create a new one!)

Sidebar: nullptr is a new type that is a part of the C11 standard. If you can’t compile with it, you can replace it with a regular NULL

To extract the whole document to a string we need to root element and not the document itself. Here is how to do that:

string data=XMLString::transcode(pSerializer->writeToString(pRoot));

Fixing the XMLString memory leaks:

As I mentioned, there are many options to solve this problem. Here is one:

Define a buffer to hold the data, for example:XMLCh buffer[100];

Now, you can use this buffer with the XMLString::transcode method. This method usually create a new string (that you have to release!) but when used like this: XMLString::transcode(“user”,buffer,99); it will only copy the standard string to the XMLCh buffer, saving you all the releasing problems. Seeing this, you are probably thinking of macro or encapsulating class. If you re familiar with them, I strongly recommend that you use one of them!

 

Xerces API here: http://xerces.apache.org/xerces-c/apiDocs-3/classes.html

Developping linux mysql application under ubuntu

apt-get this:

apt-get install libmysqlcppconn5 libmysqlcppconn-dev libmysqlclient-dev -y

Note here that you need to check the version of libmysqlcppconn. It might be higher then 5.

Include this library in your linker code:libmysqlcppconn.so.

To create a connection:

  1. create a driver
  2. call the drivers connect method (it might throw an error, so use a try catch block).

includes and name spaces:

#include<mysql_connection.h>
#include<mysql_driver.h>
#include<cppconn/statement.h>
using namespace sql::mysql;

You don’t have to use name spaces obviously, but this will usually make things easier.

create the driver:MySQL_Driver * p_driver = sql::mysql::get_driver_instance();
Then you can use it to connect with the connect method. Sample connection strings can be found here: http://dev.mysql.com/doc/refman/5.1/en/connector-cpp-examples-query.html.

creating the statement object:

p_stmt=p_connection->createStatement(); The important thing here is to remember to include the right headers. many of them are under cppconn, including the statement (<cppconn/statement.h>) and RecordSet(<cppconn/resultset.h>).

using the statement object:

ResultSet * set = p_stmt->executeQuery(“select username from users_tbl”);

The statement has many more options to look at. also, you should be looking at the prepare statement object(cppconn/prepared_statement.h).

Getting values from the record set

The first value from the record set can be fetched with the first() method.

To get the rest of the data use the next() method. Each of these return boolean that state the result.

To get a value from Result set use one of the getXXXXX(index column). methods. Note that the column index starts with 1.