I have been a bit silent with it, except for release information on Twitter and LinkedIN. But I would like to (more) publicly introduce QueryC++ or QueryCpp (which ever you prefer) which I released in version 1.1.0 last week.

The purpose of QueryC++ is to reduce the usage of std::string for having SQL commands exposed as raw text strings in C++.

Let us assume that we are working with PostgreSQL and use libpqxx for executing commands in the database. Then if we want to create a user table where the user has an id, a first name, and a last name. Afterwards we insert two users, using a single insert, using std::string it could look something like this:

#include <string>

#include <pqxx/pqxx>

int main(void)
{
    pqxx::connection con; // Assume setup
    std::string query = "CREATE TABLE user (id PRIMARY KEY SERIAL, first_name VARCHAR(255), last_name VARCHAR(255))";
    pqxx::work tx1(con);
    tx1.exec(query);
    tx1.commit();

    query = "INSERT INTO user(first_name, last_name) VALUES ('john', 'doe'), ('jane', 'doe')";
    
    pqxx::work tx2(con);
    tx2.exec(query);
    tx2.commit();
}

It is not bad, but it for sure is not pretty. First of all, if we want to make a change to the table, we need to find where in the “long” SQL string we need to change it and two, if we make a syntax error we have to redo it again.

Secondly, this is example is not difficult to read, but SQL can be if it becomes more complex.

Thirdly, when I write C++ I prefer to write C++ and not some other language embedded in strings. Which is the main reason I started QueryC++. So how would the above code look in QueryC++, well it will look like this:

#include <querycpp/querycpp.hpp>
#include <pqxx/pqxx>

int main(void)
{
    querycpp::column id("id", querycpp::type::postgres::numerical::SERIAL, 
                              {querycpp::constraints::PRIMARY});
    querycpp::column first_name("first_name", querycpp::type::common::string::VARCHAR, {"255"});
    querycpp::column last_name("last_name", querycpp::type::common::string::VARCHAR, {"255"});
    
    querycpp::table user_table("user", {id, first_name, last_name});
    
    querycpp::query user_query(user_table);
    
    pqxx::connection con; // Assume setup
    
    user_query.CREATE();
    
    pqxx::work tx1(con);
    tx1.exec(user_query.str());
    tx1.commit();
    
    // Clear the currently build query
    user_query.clear(); 
    
    std::vector<std::vector<std::string>> users;
    user.push_back({"John", "Doe"});
    user.push_back({"Jane", "Doe"});
    
    user_query.INSERT({first_name, last_name}, users);
    
    pqxx::work tx2(con);
    tx2.exec(user_query.str());
    tx.2.commit();
}

So what did QueryC++ give us besides more code?

  • First it gave us individual columns, where we are able to handle constraints separately for each column.
  • Then it gave us a table and a query object
  • The ability to create the table
    • and neatly insert multiple elements into the table

All in all QueryC++ gave us a program that is easier to read, written in C++, and we work directly with objects. Additionally, if we want to change a specific column, we do not have to go hunting in a string, we do get compile time errors or even intellisense errors if we make a spelling mistake. From my perspective QueryC++ provides pretty good benefits.

FAQ

A few (already) frequently asked questions.

What is the license? It is BSD version 3, check the LICENSE file for more information.

Why are functions all caps? are you crazy? a) Yes I am crazy that should not come as a surprise and b) Even though I am only publicly know contributor to QueryC++. There are a few people who are “beta” testers. One of the main thing people requested was actually to have methods in all caps, to mirror how the write SQL in general. Additionally and also an excuse is that SQL keywords such as and are reserved in C++ and we “get around” this by having our functions in all caps.

Can I contribute to QueryC++? Yes you can and I am working on code style guide and setting up the general workflow. Be a bit patient, please!.

Can I make request? Yes, open an issue ticket and we/I will take a look. If we deem it a feature that should be in QueryC++ we will add it as soon as we get the change.

Who funds this? Technically Aarhus University Department of Electrical and Computer Engineering, but “only” limited. I have been allowed to work on QueryC++ during work hours as I am using QueryC++ in my research and when I find something I need for my research that is missing, then I can added it.

Why waf first? I focus on waf as build system first, because it is the one I am use to and use myself. However, CMake should fully work now.

Why no Conan package? It is coming I SWEAR! Maybe even in version 1.2.0 but I am not promising that!

./Lars