Cassandra.Ecto v0.5.1 Cassandra.Ecto.Adapter

Implements Ecto.Adapter behaviour.

Queries

Cassandra repo supports only following keywords for Ecto.Query.from/2:

:where
:order_by
:limit
:select
:preload

NOTE: don’t try to find :offset. It’s not supported by Cassandra.

NOTE: you should remember that by default in Cassandra it is not possible to filter and order by non primary key columns. To override this behaviour you could pass additional option allow_filtering: true. But it is not recommended, because of strong performance penalty. So it is very common to add extra tables that better fits specific queries, also you are free to create additional seconary indexes.

Repo.all((from p in Post, where: "abra" in p.tags), allow_filtering: true)

Upserts and Lightweight transactions

By default in Apache Cassandra insert and update both are equivalent to upsert. But Ecto by default expects that if record already exists it will raise error on insert and it should not create new record on update. So when Cassandra.Ecto executes insert it makes it conditional with IF NOT EXISTS and when executes update - IF EXISTS.

To perform upsert with insert just use option on_conflict: :nothing. To perform upsert with update just use option if: nil.

If you wish to perform upserts by default you need to specify upsert: true option in you repo. It might be very usefull for CQL version prior 3.2.

By the way, you can set :if option for your update and insert queries. Here is available types for :if option:

:exists
:not_exists
[field1: value1, field2: value2, ...]

HINT: please take a look at last option with keyword list. You can use it for optimistic locking like so:

Repo.update!(post, if: [version: 2])

Comparision table

Ecto function       :on_conflict     :if           Cassandra
-------------       ------------     --            ---------
insert/2            :raise           (no option)   insert with 'IF NOT EXISTS'
insert/2            :nothing         (no option)   insert/upsert
insert/2            :nothing         :not_exists   insert with 'IF NOT EXISTS'
update/2            (no option)      (no option)   updates with 'IF EXISTS'
update/2            (no option)      nil           insert/upsert
update/2            (no option)      :exists       updates with 'IF EXISTS'

NOTE: this comparision table works only for repo without upsert: true option.

Batched queries

Batched queries are done by Ecto.Repo.insert_all/3 with option batched: true. By default all batched queries runs in :logged mode. But it is possible to override this on two levels:

  1. Repo level, by setting :batch_mode repo option

    config :my_app, Repo,
      adapter: Cassandra.Ecto
      batch_mode: :unlogged
  2. Query level, by setting :batch_mode query option

    Repo.insert_all(Post, posts, on_conflict: :nothing, batched: true, batch_mode: :unlogged)

Available types:

:logged
:unlogged
:serial

Default type is :logged.

NOTE: don’t forget to set proper :on_conflict option.

Learn more about using batching in Using and misusing batches

Consistency

There are to options to configure consistency:

  1. Tunable consistency.

    Sets by :consistency option. Available types:

    :any
    :one
    :two
    :three
    :quorum
    :all
    :local_quorum
    :each_quorum

    Default type is :one.

  2. Linearizable consistency.

    Sets by :serial_consistency option. Available types:

    :serial
    :local_serial

    Default type is :undefined.

Every type of consistency can be set at repo and query level deparately.

Please see Consistency for more information.

TIMESTAMP and TTL

You can specify TTL and TIMESTAMP with :ttl and :timestamp respectively on query level.

:binary_id autogeneration

By default Cassandra adapter generates :binary_id with Ecto.UUID.bingenerate().

But it is also possible to override this behaviour and generate id natively on Cassandra side with build-in functions now() or uuid() like so:

post = Repo.insert!(post, binary_id: :now)

If you have decided to make it default for repo:

config :my_app, Repo,
  keyspace: "my_keyspace"
  binary_id: :now

Possible option variants:

:now
:uuid
:default

Transactions

CASSANDRA DOESN’T SUPPORT TRANSACTIONS!

Summary

Functions

autogenerate(atom)

See Ecto.Adapter.autogenerate/1

delete(repo, meta, fields, opts)

See Ecto.Adapter.delete/4

dumpers(datetime, type)

See Ecto.Adapter.dumpers/2

execute(repo, map, arg, params, process, opts)

See Ecto.Adapter.execute/6

insert(repo, meta, fields, on_conflict, returning, opts)

See Ecto.Adapter.insert/6

insert_all(repo, meta, header, rows, on_conflict, returning, opts)

See Ecto.Adapter.insert_all/7

loaders(datetime, type)

See Ecto.Adapter.loaders/2

prepare(func, query)

See Ecto.Adapter.prepare/2

update(repo, meta, fields, filters, returning, opts)

See Ecto.Adapter.update/6