<commit_before># Cequel #

Cequel is a Ruby ORM for [Cassandra](http://cassandra.apache.org/) using
[CQL3][].

[![Gem Version](https://badge.fury.io/rb/cequel.png)](http://badge.fury.io/rb/cequel)
[![Build Status](https://travis-ci.org/cequel/cequel.png?branch=master)](https://travis-ci.org/cequel/cequel)
[![Dependency Status](https://gemnasium.com/cequel/cequel.png)](https://gemnasium.com/cequel/cequel)
[![Code Climate](https://codeclimate.com/github/cequel/cequel.png)](https://codeclimate.com/github/cequel/cequel)
[![Inline docs](http://inch-ci.org/github/cequel/cequel.png)](http://inch-ci.org/github/cequel/cequel)

`Cequel::Record` is an ActiveRecord-like domain model layer that exposes
the robust data modeling capabilities of CQL3, including parent-child
relationships via compound primary keys and collection columns.

The lower-level `Cequel::Metal` layer provides a CQL query builder interface
inspired by the excellent [Sequel](http://sequel.rubyforge.org/) library.

## Installation ##

Add it to your Gemfile:

``` ruby
gem 'cequel'
```

If you use Rails 5, add this:
``` ruby
gem 'activemodel-serializers-xml'
```

### Rails integration ###

Cequel does not require Rails, but if you are using Rails, you
will need version 3.2+. Cequel::Record will read from the configuration file
`config/cequel.yml` if it is present. You can generate a default configuration
file with:

```bash
rails g cequel:configuration
```

Once you've got things configured (or decided to accept the defaults), run this
to create your keyspace (database):

```bash
rake cequel:keyspace:create
```

## Setting up Models ##

Unlike in ActiveRecord, models declare their properties inline. We'll start with
a simple `Blog` model:

```ruby
class Blog
  include Cequel::Record

  key :subdomain, :text
  column :name, :text
  column :description, :text
end
```

Unlike a relational database, Cassandra does not have auto-incrementing primary
keys, so you must explicitly set the primary key when you create a new model.
For blogs, we use a natural key, which is the subdomain. Another option is to
use a UUID.

### Compound keys and parent-child relationships ###

While Cassandra is not a relational database, compound keys do naturally map
to parent-child relationships. Cequel supports this explicitly with the
`has_many` and `belongs_to` relations. Let's create a model for posts that acts
as the child of the blog model:

```ruby
class Post
  include Cequel::Record
  belongs_to :blog
  key :id, :timeuuid, auto: true
  column :title, :text
  column :body, :text
end
```

The `auto` option for the `key` declaration means Cequel will initialize new
records with a UUID already generated. This option is only valid for `:uuid` and
`:timeuuid` key columns.

The `belongs_to` association accepts a `:foreign_key` option which allows you to
specify the attribute used as the partition key.

Note that the `belongs_to` declaration must come *before* the `key` declaration.
This is because `belongs_to` defines the
[partition key](http://docs.datastax.com/en/glossary/doc/glossary/gloss_partition_key.html); the `id` column is
the [clustering column](http://docs.datastax.com/en/glossary/doc/glossary/gloss_clustering_column.html).

Practically speaking, this means that posts are accessed using both the
`blog_subdomain` (automatically defined by the `belongs_to` association) and the
`id`. The most natural way to represent this type of lookup is using a
`has_many` association. Let's add one to `Blog`:

```ruby
class Blog
  include Cequel::Record

  key :subdomain, :text
  column :name, :text
  column :description, :text

  has_many :posts
end
```

Now we might do something like this:

```ruby
class PostsController < ActionController::Base
  def show
    Blog.find(current_subdomain).posts.find(params[:id])
  end
end
```

Parent child relationship in a namespaced model can be defined using the `class_name` option of `belongs_to` method as follows:

```ruby
module Blogger
  class Blog
    include Cequel::Record

    key :subdomain, :text
    column :name, :text
    column :description, :text

    has_many :posts
  end
end

module Blogger
  class Post
    include Cequel::Record

    belongs_to :blog, class_name: 'Blogger::Blog'
    key :id, :timeuuid, auto: true
    column :title, :text
    column :body, :text
  end
end
```
<commit_msg>Added documentation for composite partition keys<commit_after># Cequel #

Cequel is a Ruby ORM for [Cassandra](http://cassandra.apache.org/) using
[CQL3][].

[![Gem Version](https://badge.fury.io/rb/cequel.png)](http://badge.fury.io/rb/cequel)
[![Build Status](https://travis-ci.org/cequel/cequel.png?branch=master)](https://travis-ci.org/cequel/cequel)
[![Dependency Status](https://gemnasium.com/cequel/cequel.png)](https://gemnasium.com/cequel/cequel)
[![Code Climate](https://codeclimate.com/github/cequel/cequel.png)](https://codeclimate.com/github/cequel/cequel)
[![Inline docs](http://inch-ci.org/github/cequel/cequel.png)](http://inch-ci.org/github/cequel/cequel)

`Cequel::Record` is an ActiveRecord-like domain model layer that exposes
the robust data modeling capabilities of CQL3, including parent-child
relationships via compound primary keys and collection columns.

The lower-level `Cequel::Metal` layer provides a CQL query builder interface
inspired by the excellent [Sequel](http://sequel.rubyforge.org/) library.

## Installation ##

Add it to your Gemfile:

``` ruby
gem 'cequel'
```

If you use Rails 5, add this:
``` ruby
gem 'activemodel-serializers-xml'
```

### Rails integration ###

Cequel does not require Rails, but if you are using Rails, you
will need version 3.2+. Cequel::Record will read from the configuration file
`config/cequel.yml` if it is present. You can generate a default configuration
file with:

```bash
rails g cequel:configuration
```

Once you've got things configured (or decided to accept the defaults), run this
to create your keyspace (database):

```bash
rake cequel:keyspace:create
```

## Setting up Models ##

Unlike in ActiveRecord, models declare their properties inline. We'll start with
a simple `Blog` model:

```ruby
class Blog
  include Cequel::Record

  key :subdomain, :text
  column :name, :text
  column :description, :text
end
```

Unlike a relational database, Cassandra does not have auto-incrementing primary
keys, so you must explicitly set the primary key when you create a new model.
For blogs, we use a natural key, which is the subdomain. Another option is to
use a UUID.

### Compound keys and parent-child relationships ###

While Cassandra is not a relational database, compound keys do naturally map
to parent-child relationships. Cequel supports this explicitly with the
`has_many` and `belongs_to` relations. Let's create a model for posts that acts
as the child of the blog model:

```ruby
class Post
  include Cequel::Record
  belongs_to :blog
  key :id, :timeuuid, auto: true
  column :title, :text
  column :body, :text
end
```

The `auto` option for the `key` declaration means Cequel will initialize new
records with a UUID already generated. This option is only valid for `:uuid` and
`:timeuuid` key columns.

The `belongs_to` association accepts a `:foreign_key` option which allows you to
specify the attribute used as the partition key.

Note that the `belongs_to` declaration must come *before* the `key` declaration.
This is because `belongs_to` defines the
[partition key](http://docs.datastax.com/en/glossary/doc/glossary/gloss_partition_key.html); the `id` column is
the [clustering column](http://docs.datastax.com/en/glossary/doc/glossary/gloss_clustering_column.html).

Practically speaking, this means that posts are accessed using both the
`blog_subdomain` (automatically defined by the `belongs_to` association) and the
`id`. The most natural way to represent this type of lookup is using a
`has_many` association. Let's add one to `Blog`:

```ruby
class Blog
  include Cequel::Record

  key :subdomain, :text
  column :name, :text
  column :description, :text

  has_many :posts
end
```

Now we might do something like this:

```ruby
class PostsController < ActionController::Base
  def show
    Blog.find(current_subdomain).posts.find(params[:id])
  end
end
```

Parent child relationship in a namespaced model can be defined using the `class_name` option of `belongs_to` method as follows:

```ruby
module Blogger
  class Blog
    include Cequel::Record

    key :subdomain, :text
    column :name, :text
    column :description, :text

    has_many :posts
  end
end

module Blogger
  class Post
    include Cequel::Record

    belongs_to :blog, class_name: 'Blogger::Blog'
    key :id, :timeuuid, auto: true
    column :title, :text
    column :body, :text
  end
end
```

### Compound Partition Keys ###

If you wish to declare a compound partition key in a model, you can do something like:

```ruby
class Post
  include Cequel::Record

  key :country, :text, partition: true
  key :blog, :text, partition: true
  key :id, :timeuuid, auto: true
  column :title, :text
  column :body, :text
end
```

Your compound partition key here is `(country, blog)`, and the entire compound primary key is `((country, blog), id)`.
Any key values defined after the last partition key value are clustering columns.

{'fraction_non_alphanumeric': 0.10582639714625446, 'fraction_numerical': 0.0010809642200843152, 'mean_word_length': 4.669117647058823, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 3, 'https://': 14, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7600276', 'n_tokens_mistral': 2941, 'n_tokens_neox': 2795, 'n_words': 1073}