# Build a C++ App with CockroachDB

This tutorial shows you how build a simple C++ application with CockroachDB using a PostgreSQL-compatible driver.

We have tested the C++ libpqxx driver enough to claim beta-level support, so that driver is featured here. If you encounter problems, please open an issue with details to help us make progress toward full support.

## Before you begin

Make sure you have already installed CockroachDB.

## Step 1. Install the libpqxx driver

Install the C++ libpqxx driver as described in the official documentation.

## Step 2. Start a single-node cluster

For the purpose of this tutorial, you need only one CockroachDB node running in insecure mode:

    $ cockroach start \
    --insecure \
    --store=hello-1 \
    --listen-addr=localhost

## Step 3. Create a user

In a new terminal, as the `root` user, use the `cockroach user` command to create a new user, `maxroach`.

    $ cockroach user set maxroach --insecure

## Step 4. Create a database and grant privileges

As the `root` user, use the built-in SQL client to create a `bank` database.

    $ cockroach sql --insecure -e 'CREATE DATABASE bank'

Then grant privileges to the `maxroach` user.

    $ cockroach sql --insecure -e 'GRANT ALL ON DATABASE bank TO maxroach'

## Step 5. Run the C++ code

Now that you have a database and a user, you'll run code to create a table and insert some rows, and then you'll run code to read and update values as an atomic transaction.

### Basic statements

First, use the following code to connect as the `maxroach` user and execute some basic SQL statements, creating a table, inserting rows, and reading and printing the rows.

Download the `basic-sample.cpp` file, or create the file yourself and copy the code into it.

    // Build with g++ -std=c++11 basic-sample.cpp -lpq -lpqxx

    #include <cassert>
    #include <functional>
    #include <iostream>
    #include <stdexcept>
    #include <string>
    #include <pqxx/pqxx>

    using namespace std;

    int main() {
      try {
        // Connect to the "bank" database.
        pqxx::connection c("postgresql://maxroach@localhost:26257/bank");

        pqxx::nontransaction w(c);

        // Create the "accounts" table.
        w.exec("CREATE TABLE IF NOT EXISTS accounts (id INT PRIMARY KEY, balance INT)");

        // Insert two rows into the "accounts" table.
        w.exec("INSERT INTO accounts (id, balance) VALUES (1, 1000), (2, 250)");

        // Print out the balances.
        cout << "Initial balances:" << endl;
        pqxx::result r = w.exec("SELECT id, balance FROM accounts");
        for (auto row : r) {
          cout << row[0].as<int>() << ' ' << row[1].as<int>() << endl;
        }

        w.commit();  // Note this doesn't doesn't do anything
                     // for a nontransaction, but is still required.
      }
      catch (const exception &e) {
        cerr << e.what() << endl;
        return 1;
      }
      cout << "Success" << endl;
      return 0;
    }

### Transaction (with retry logic)

Next, use the following code to again connect as the `maxroach` user but this time execute a batch of statements as an atomic transaction to transfer funds from one account to another, where all included statements are either committed or aborted.

Note:

CockroachDB may require the client to retry a transaction in case of read/write contention. CockroachDB provides a generic retry function that runs inside a transaction and retries it as needed. You can copy and paste the retry function from here into your code.

Download the `txn-sample.cpp` file, or create the file yourself and copy the code into it.

    // Build with g++ -std=c++11 txn-sample.cpp -lpq -lpqxx

    #include <cassert>
    #include <functional>
    #include <iostream>
    #include <stdexcept>
    #include <string>
    #include <pqxx/pqxx>

    using namespace std;

    void transferFunds(
        pqxx::dbtransaction *tx, int from, int to, int amount) {
      // Read the balance.
      pqxx::result r = tx->exec(
          "SELECT balance FROM accounts WHERE id = " + to_string(from));
      assert(r.size() == 1);
      int fromBalance = r[0][0].as<int>();

      if (fromBalance < amount) {
        throw domain_error("insufficient funds");
      }

      // Perform the transfer.
      tx->exec("UPDATE accounts SET balance = balance - "
          + to_string(amount) + " WHERE id = " + to_string(from));
      tx->exec("UPDATE accounts SET balance = balance + "
          + to_string(amount) + " WHERE id = " + to_string(to));
    }

    // ExecuteTx runs fn inside a transaction and retries it as needed.
    // On non-retryable failures, the transaction is aborted and rolled
    // back; on success, the transaction is committed.
    //
    // For more information about CockroachDB's transaction model see
    // https://cockroachlabs.com/docs/transactions.html.
    //
    // NOTE: the supplied exec closure should not have external side
    // effects beyond changes to the database.
    void executeTx(
        pqxx::connection *c, function<void (pqxx::dbtransaction *tx)> fn) {
      pqxx::work tx(*c);
      while (true) {
        try {
          pqxx::subtransaction s(tx, "cockroach_restart");
          fn(&s);
          s.commit();
          break;
        } catch (const pqxx::pqxx_exception& e) {
          // Swallow "transaction restart" errors; the transaction will be retried.
          // Unfortunately libpqxx doesn't give us access to the error code, so we
          // do string matching to identify retriable errors.
          if (string(e.base().what()).find("restart transaction:") == string::npos) {
            throw;
          }
        }
      }
      tx.commit();
    }

    int main() {
      try {
        pqxx::connection c("postgresql://maxroach@localhost:26257/bank");

        executeTx(&c, [](pqxx::dbtransaction *tx) {
              transferFunds(tx, 1, 2, 100);
          });
      }
      catch (const exception &e) {
        cerr << e.what() << endl;
        return 1;
      }
      cout << "Success" << endl;
      return 0;
    }

After running the code, use the built-in SQL client to verify that funds were transferred from one account to another:

    $ cockroach sql --insecure -e 'SELECT id, balance FROM accounts' --database=bank

    +----+---------+
    | id | balance |
    +----+---------+
    |  1 |     900 |
    |  2 |     350 |
    +----+---------+
    (2 rows)

## What's next?

Read more about using the C++ libpqxx driver.

You might also be interested in using a local cluster to explore the following CockroachDB benefits:

- Client Connection Parameters
- Data Replication
- Fault Tolerance & Recovery
- Automatic Rebalancing
- Cross-Cloud Migration
- Follow-the-Workload
- Automated Operations