• Stars
    star
    246
  • Rank 164,726 (Top 4 %)
  • Language
    Clojure
  • Created almost 12 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

High performance Cassandra client for clojure

alia

cljdoc badge

Coan-Teen, the female death spirit who walks without feet.

Cassandra CQL3 client for Clojure wrapping datastax/java-driver.

What's in the box?

  • Built on an extremely solid base, datastax/java-driver, based on the new CQL native protocol
  • Simple API with a minimal learning curve
  • Great performance
  • Provides an optional versatile CQL3+ DSL, Hayt
  • Support for Raw queries, Prepared Statements or Hayt queries
  • Can do both Synchronous and Asynchronous query execution
  • Async interfaces using either clojure/core.async , simple callbacks or manifold
  • Support for all of datastax/java-driver advanced options: jmx, auth, SSL, compression, consistency, custom executors, custom routing and more
  • Support and sugar for query tracing, metrics, retry policies, load balancing policies, reconnection policies and UUIDs generation
  • Extensible Clojure data types support & clojure.core/ex-data integration
  • Lazy and potentialy chunked sequences over queries
  • Controled pages and rows streaming via core.async channels and manifold streams
  • First class support for cassandra collections, User defined types, that includes nesting.
  • Lazy row decoding by default, but also optional cheap user controled decoding via IReduce

Our Sponsors:

Astra DB
Astra DB

Use Clojure with DataStax Astra DB - built on Apache Cassandra.

Installation

Alia

Please check the Changelog first if you are upgrading. Alia runs on Clojure >= 1.7 (we're using IReduceInit internally)

Add the following to your dependencies:

Clojars Project

This would include all the codec extensions and extra libraries.

But the better thing to do is to pick and choose what you really need from alia's modules:

Hayt (the query DSL)

If you wish to use Hayt you need to add it to your dependencies

Clojars Project

Then require/use qbits.hayt and you're good to go.

Documentation

codox generated documentation.

Quickstart

Simple query execution using alia with hayt would look like this:

(execute session (select :users
                         (where {:name :foo})
                         (columns :bar "baz")))

But first things first: here is an example of a complete session using raw queries.

(require '[qbits.alia :as alia])

(def session (alia/session {:session-keyspace "alia"
                            :contact-points ["localhost:9042"]
                            :load-balancing-local-datacenter "Analytics"}))

Example of a complete session using plain text auth.

(require '[qbits.alia :as alia])

(def session (alia/session {:session-keyspace "alia"
                            :contact-points ["localhost:9042"]
                            :load-balancing-local-datacenter "Analytics"
                            :auth-provider-user-name "user-name"
                            :auth-provider-password "password"
                            :auth-provider-class "PlainTextAuthProvider"}))

Sessions are separate so that you can interact with multiple keyspaces from the same cluster definition.

(def session (alia/connect cluster))

(alia/execute session "CREATE KEYSPACE alia
                       WITH replication = {'class': 'SimpleStrategy', 'replication_factor' : 3};")
   (alia/execute session "CREATE TABLE users (user_name varchar,
                                              first_name varchar,
                                              last_name varchar,
                                              auuid uuid,
                                              birth_year bigint,
                                              created timestamp,
                                              valid boolean,
                                              emails set<text>,
                                              tags list<bigint>,
                                              amap map<varchar, bigint>,
                                              PRIMARY KEY (user_name));")
  (alia/execute session "INSERT INTO users
                         (user_name, first_name, last_name, emails, birth_year, amap, tags, auuid,valid)
                         VALUES('frodo', 'Frodo', 'Baggins',
                         {'[email protected]', '[email protected]'}, 1,
                         {'foo': 1, 'bar': 2}, [4, 5, 6],
                         1f84b56b-5481-4ee4-8236-8a3831ee5892, true);")

  ;; prepared statement with positional parameter(s)
  (def prepared-statement (alia/prepare session "select * from users where user_name=?;"))

  (alia/execute session prepared-statement {:values ["frodo"]})

  >> ({:created nil,
       :last_name "Baggins",
       :emails #{"[email protected]" "[email protected]"},
       :tags [4 5 6],
       :first_name "Frodo",
       :amap {"foo" 1, "bar" 2},
       :auuid #uuid "1f84b56b-5481-4ee4-8236-8a3831ee5892",
       :valid true,
       :birth_year 1,
       :user_name "frodo"})

  ;; prepared statement with named parameter(s)
  (def prepared-statement (alia/prepare session "select * from users where user_name= :name limit :lmt;"))

  (alia/execute session prepared-statement {:values {:name "frodo" :lmt (int 1)}})

Asynchronous interfaces:

There are currently 3 interfaces to use the asynchronous methods of the underlying driver, the fundamental one being a simple CompletableFuture API, and then two alternative streaming APIs built with core.async and manifold

Async returning CompletableFuture

@(execute-async session "select * from users;")

Async using clojure/core.async

qbits.alia.async/execute-chan has the same signature as the other execute functions and returns a clojure/core.async channel of rows, or an exception instance.

The channel supports backpressure, controlled by buffer-sizes and as rows are consumed from the channel more rows will be fetched to fill any buffers.

Once you run it you have a couple of options to pull data from it.

  • using clojure.core.async/take! which takes the channel as first argument and a callback as second:
(take! (execute-chan session "select * from users;")
       (fn [rows-or-exception]
         (do-something rows)))
  • using clojure.core.async/<!! to block and pull the rows/exception from the channel.
(def rows-or-exception (<!! (execute-chan session "select * from users;")))
  • using clojure.core.async/merge you can run a list of queries in parallel and have the results fed to a single output chan:
(let [merged (async/merge [(alia/execute-chan session (select :foo))
                           (alia/execute-chan session (select :bar))
                           (alia/execute-chan session (select :baz))])]
  (go
    (loop []
      (when-let [result (<! merged)]
        (println result)
        (recur)))))

qbits.alia.async/execute returns a promise-chan with just the first page of results

qbits.alia.async/execute-chan-pages returns a channel of pages of results, also supporting backpressure. The page objects are constructed by the :result-set-fn option.

Async using manifold

qbits.alia.manifold/execute-stream has the same signature as other execute functions and resturns a manifold stream of rows, or an exception instance

As with core.async, the stream supports backpressure and as rows are take!en from the stream, more rows will be fetched according to available buffers.

qbits.alia.manifold/execute returns a Deferred with just the first page of results

qbits.alia.manifold/execute-stream-pages returns a stream of pages of results, supporting backpressure. The page objects are constructed by the :result-set-fn option.

And it can do a lot more! Head to the codox generated documentation.

Hayt (Query DSL)

There is a nicer way to write your queries using Hayt, this should be familiar if you know Korma or ClojureQL. One of the major difference is that Hayt doesn't use macros and just generates maps, so if you need to compose clauses or queries together you can just use the clojure.core functions that work on maps.

Some examples:

(use 'qbits.hayt)

(select :foo (where {:bar 2}))

;; this generates a map
>> {:select :foo :where {:bar 2}}

(update :foo
         (set-columns {:bar 1
                       :baz (inc-by 2)}
         (where [[= :foo :bar]
                 [> :moo 3]
                 [> :meh 4]
                 [:in :baz  [5 6 7]]]))


;; Composability using normal map manipulation functions

(def base (select :foo (where {:foo 1})))

(merge base
       (columns :bar :baz)
       (where {:bar 2})
       (order-by [:bar :asc])
       (using :ttl 10000))

;; To compile the queries just use ->raw

(->raw (select :foo))
> "SELECT * FROM foo;"

Alia supports hayt query direct execution, if you pass a non-compiled query to execute or execute-async, it will be compiled and cached on a LU cache with a threshold of 100 (the cache function is user settable), so to be used carefully. The same is true with prepare.

Ex

(execute session (select :users (where {:name :foo})))

It covers everything that is possible with CQL3 (functions, handling of collection types and their operations, ddl, prepared statements, etc). If you want to know more about it head to its codox documentation or Hayt's tests.

Patreon

If you wish to support the work on this project you can do this here: patreon

Mailing list

Alia has a mailing list hosted on Google Groups. Do not hesitate to ask your questions there.

License

Copyright ยฉ 2013-2020 Max Penet, mccraigmccraig

Distributed under the Eclipse Public License, the same as Clojure.

More Repositories

1

spandex

Elasticsearch client for Clojure (built on new ES 8.x java client)
Clojure
261
star
2

jet

[not maintained, use at own risk] Jetty9 ring server adapter with WebSocket support via core.async and Jetty9 based HTTP & WebSocket clients (jvm based, no cljs)
Clojure
167
star
3

tape

Chronicle Queue helpers
Clojure
134
star
4

hirundo

Helidon 4.x RING adapter - using loom/java21+
Clojure
100
star
5

hayt

CQL3 DSL for Clojure
Clojure
74
star
6

clojure-snippets

yasnippet 0.7.0+ snippets for clojure
Emacs Lisp
58
star
7

auspex

Mini wrapper over java CompletableFuture with a manifold deferred after-taste
Clojure
42
star
8

knit

Thin wrapper around Java Executors/Threads, including configurable `future`, `c.core/thread`, and `future-call`
HTML
33
star
9

pact

clojure.spec to json-schema generation library
Clojure
25
star
10

thorn

Homoglyph/IDN homograph detection/handling - Clojure port of python confusable_homoglyphs
Clojure
22
star
11

flex

Using TCP congestion control methods to find/set real limits of a system over time
Clojure
20
star
12

sextant

Offline location geocoder/reverse geocoder from GeoName datasets
Java
18
star
13

ex

Exception net
Clojure
17
star
14

casyn

Clojure client for Cassandra using Thrift AsyncClient - For a better/more robust client using CQL3 see https://github.com/mpenet/alia
Clojure
17
star
15

spex

Utils/Helpers for clojure spec
Clojure
16
star
16

checkmate

All your fails are belong to us
Clojure
14
star
17

jilch

Clojure ZeroMQ Library using Jeromq (drop in replacement for zilch)
Clojure
12
star
18

emax

my .emacs.d
Emacs Lisp
12
star
19

esearch

Elastic Search client for Clojure
Clojure
11
star
20

eddy

Jetty11+ wrapper/adapter for clojure
Clojure
7
star
21

caffeine

Simple wrapper for com.github.ben-manes.caffeine/caffeine
Clojure
7
star
22

nippy-lz4

LZ4 compression for ptaoussanis/nippy
Clojure
6
star
23

commons

stuff
Clojure
5
star
24

bootstrap-mod

Modular twitter/bootstrap
5
star
25

thera

Deprecated: give a try to mpenet/casyn (thrift) or mpenet/alia (CQL3) instead- Clojure Cassandra CQL client
Clojure
5
star
26

tardis

Minimalistic library to manage Type 1 UUIDs (time based) - com.eaio.uuid wrapper
Clojure
4
star
27

grease

Some utils for performance critical situations
Java
4
star
28

ash

Simple, extensible irc bot based on pircbotx
Clojure
4
star
29

xmonad

(minimalistic) xmonad/trayer/xmobar config with a zenburn'ish theme. Supports both t410s and xps13 sputnik
Shell
4
star
30

sextant_

Geo location utility functions
Clojure
3
star
31

unilog-sentry

Sentry appender for pyr/unilog
Clojure
3
star
32

ring-spec

clojure.specs for the latest RING
Clojure
2
star
33

tempel-clojure

tempel snippets for clojure
Emacs Lisp
2
star
34

quiver

Clojure 1.5 new threading macros as a library
Clojure
2
star
35

softshake-talk

2
star
36

mehub

GitHub personal page (static, js/ClojureScript based)
JavaScript
2
star
37

pod

Walks like an atom, and quacks like an atom but...
Clojure
2
star
38

dam

Redis/LUA backed rate limiting for clojure
Clojure
2
star
39

sibilant-mode

sibilant emacs mode
Emacs Lisp
2
star
40

padded-modeline

Padded emacs modeline
Emacs Lisp
1
star
41

bug-playground

where bugs multiply and thrive
Clojure
1
star
42

record-utils

Clojure
1
star