About this guide

This guide covers Cassandra schema management with Cassaforte:

  • Operations on keyspaces
  • Operations on tables

What version of Cassaforte does this guide cover?

This guide covers Cassaforte 3.0.0 (including preview releases).

Creating Keyspaces

Cassandra organizes data in keyspaces. They're somewhat similar to databases in relational databases. Typically one keyspace is used by one application.

(ns cassaforte.docs
  (:require [clojurewerkz.cassaforte.client :as client]
            [clojurewerkz.cassaforte.cql    :refer :all]))

(let [session (client/connect ["127.0.0.1"])]
  (create-keyspace session "cassaforte_keyspace"
                   (with {:replication
                          {"class" "SimpleStrategy"
                           "replication_factor" 1 }})))

will execute the following query:

CREATE KEYSPACE "cassaforte_keyspace"
  WITH replication = {'class' : 'SimpleStrategy', 'replication_factor' : 1};

This will create new CQL keyspace with simple replication strategy and replication factor of 1. Note that this replication factor is not advised for production.

Switching Keyspaces

Before you can use a keyspace, you have to switch to it with clojurewerkz.cassaforte.use-keyspace:

(ns cassaforte.docs
  (:require [clojurewerkz.cassaforte.client :as client]
            [clojurewerkz.cassaforte.cql    :refer :all]))

(let [session (client/connect ["127.0.0.1"])]
  (use-keyspace session "cassaforte_keyspace"))

which will use the following CQL:

USE "cassaforte_keyspace";

Creating Tables

Cassandra historically is a column-oriented database but CQL 3 makes its data model look a lot more familair to relational database users. Data is stored in tables, which are collections of rows identified by a primary key and composed of multiple columns. How exactly CQL 3 maps to internal column-oriented model in Cassandra is outside of the scope of this guide.

To create a table, use create-table function. To to create a table with a single primary key, specify it in primary-key in column definitions:

(ns cassaforte.docs
  (:require [clojurewerkz.cassaforte.client :as client]
            [clojurewerkz.cassaforte.cql    :refer :all]))

(let [session (client/connect ["127.0.0.1"])]
  (create-table session "users"
                (column-definitions {:name :varchar
                                     :age  :int
                                     :primary-key [:name]})))

The example above will execute the following CQL:

CREATE TABLE "users" (age int,
                      name varchar,
                      PRIMARY KEY (name));

To create a table with a composite primary key, pass a vector holding the names of columns that the key will be composed of:

(ns cassaforte.docs
  (:require [clojurewerkz.cassaforte.client :as client]
            [clojurewerkz.cassaforte.cql    :refer :all]))

(let [session (client/connect ["127.0.0.1"])]
  (create-table session "user_posts"
                (column-definitions {:username :varchar
                                     :post_id  :varchar
                                     :body     :text
                                     :primary-key [:username :post_id]})))

The example above will execute the following CQL:

CREATE TABLE "user_posts" (username varchar,
                           body text,
                           post_id varchar,
                           PRIMARY KEY (username, post_id));

User posts will now be identified by both username and post_id.

Updating Tables

In order to update an existing table, use clojurewerkz.cassaforte.alter-table. You can add new columns and rename and change types of the existing ones:

Change the type of a column to integer:

(ns cassaforte.docs
  (:require [clojurewerkz.cassaforte.client :as client]
            [clojurewerkz.cassaforte.cql    :refer :all]))

(let [session (client/connect ["127.0.0.1"])]
  (alter-table session "users"
               (alter-column :post_id :int)))

The example above will execute

ALTER TABLE "users" ALTER post_id TYPE int;

Here's how to add an integer column:

(ns cassaforte.docs
  (:require [clojurewerkz.cassaforte.client :as client]
            [clojurewerkz.cassaforte.cql    :refer :all]))

(let [session (client/connect ["127.0.0.1"])]
  (alter-table session "users"
               (add-column :age :integer)))

this will execute

ALTER TABLE "users" ADD age integer;

It is possible to rename a column:

(ns cassaforte.docs
  (:require [clojurewerkz.cassaforte.client :as client]
            [clojurewerkz.cassaforte.cql    :refer :all]))

(let [session (client/connect ["127.0.0.1"])]
  (alter-table session "users"
               (rename-column :username :name)))

which will use the following CQL:

ALTER TABLE "users" RENAME username TO name;

Collection Columns

Cassandra tables can have collection columns, that is, columns of types list, map, and set. To define them with Cassaforte, use ,, and ``:

(ns cassaforte.docs
  (:require [clojurewerkz.cassaforte.client :as client]
            [clojurewerkz.cassaforte.cql    :refer :all]))

(let [session (client/connect ["127.0.0.1"])]
  (create-table session "thingies"
                (column-definitions {:name :varchar
                                     :test_map  (map-type :varchar :varchar)
                                     :test_set  (set-type :int)
                                     :test_list (list-type :varchar)
                                     :primary-key [:name]})))

When data is loaded from Cassandra, Cassaforte will convert the types to their respective immutable Clojure counterparts.

Wrapping Up

Cassaforte provides a nice way to manipulate keyspaces and table to define the schema your system needs.

The rest of this documentation covers more features Cassaforte and Cassandra provide.

Tell Us What You Think!

Please take a moment to tell us what you think about this guide on Twitter or the Cassaforte mailing list

Let us know what was unclear or what has not been covered. Maybe you do not like the guide style or grammar or discover spelling mistakes. Reader feedback is key to making the documentation better.