{"id":15010695,"url":"https://github.com/mpenet/alia","last_synced_at":"2025-04-08T16:09:52.444Z","repository":{"id":6912312,"uuid":"8162792","full_name":"mpenet/alia","owner":"mpenet","description":"High performance Cassandra client for clojure","archived":false,"fork":false,"pushed_at":"2023-07-28T07:28:41.000Z","size":1581,"stargazers_count":247,"open_issues_count":5,"forks_count":47,"subscribers_count":11,"default_branch":"master","last_synced_at":"2025-04-01T15:13:34.967Z","etag":null,"topics":["cassandra","clojure"],"latest_commit_sha":null,"homepage":"https://mpenet.github.io/alia/qbits.alia.html#docs","language":"Clojure","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"jsuereth/spring-akka-sample","license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mpenet.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":"FUNDING.yml","license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null},"funding":{"github":"mpenet"}},"created_at":"2013-02-12T16:50:27.000Z","updated_at":"2025-01-21T20:58:45.000Z","dependencies_parsed_at":"2024-01-08T18:03:37.358Z","dependency_job_id":"ecd45924-fb7d-4d50-a4c0-8e50d7f1bf20","html_url":"https://github.com/mpenet/alia","commit_stats":{"total_commits":867,"total_committers":29,"mean_commits":"29.896551724137932","dds":0.1014994232987313,"last_synced_commit":"c5dc12ea46f29ec6e6cf4e300690619f5750c0b8"},"previous_names":[],"tags_count":22,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mpenet%2Falia","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mpenet%2Falia/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mpenet%2Falia/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mpenet%2Falia/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mpenet","download_url":"https://codeload.github.com/mpenet/alia/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247878022,"owners_count":21011158,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cassandra","clojure"],"created_at":"2024-09-24T19:35:23.817Z","updated_at":"2025-04-08T16:09:52.425Z","avatar_url":"https://github.com/mpenet.png","language":"Clojure","funding_links":["https://github.com/sponsors/mpenet","https://www.patreon.com/mpenet"],"categories":["Drivers and Libraries","Database"],"sub_categories":["Clojure"],"readme":"# alia\n[![cljdoc badge](https://cljdoc.org/badge/cc.qbits/alia-all)](https://cljdoc.org/d/cc.qbits/alia-all/CURRENT)\n\n\u003e Coan-Teen, the female death spirit who walks without feet.\n\nCassandra CQL3 client for Clojure wrapping [datastax/java-driver](https://github.com/datastax/java-driver).\n\n## What's in the box?\n\n* Built on an **extremely solid base**,\n  [datastax/java-driver](https://github.com/datastax/java-driver),\n  based on the new **CQL native protocol**\n* **Simple API** with a minimal learning curve\n* **Great performance**\n* Provides an optional **versatile CQL3+ DSL**, [Hayt](#hayt-query-dsl)\n* Support for **Raw queries**, **Prepared Statements** or **[Hayt](#hayt-query-dsl) queries**\n* Can do both **Synchronous and Asynchronous** query execution\n* Async interfaces using either **clojure/core.async** , simple\n  *callbacks* or *manifold*\n* Support for **all of\n  [datastax/java-driver](https://github.com/datastax/java-driver)\n  advanced options**: jmx, auth, SSL, compression, consistency, custom\n  executors, custom routing and more\n* Support and sugar for **query tracing**, **metrics**, **retry\n  policies**, **load balancing policies**, **reconnection policies**\n  and **UUIDs** generation\n* Extensible **Clojure data types support** \u0026 **clojure.core/ex-data**\n  integration\n* **Lazy and potentialy chunked sequences over queries**\n* Controled pages and rows **streaming** via core.async channels and manifold streams\n* First class support for cassandra **collections**, **User defined\n  types**, that includes **nesting**.\n* **Lazy row decoding by default**, but also **optional cheap user\n  controled decoding via IReduce**\n\n## Our Sponsors: ##\n\u003ctable\u003e\u003ctr\u003e\n\u003ctd align=\"center\" width=\"300\" \u003e\u003ca href=\"https://astra.dev/3fW6XQB\"\u003e\u003cimg src=\"https://www.datastax.com/sites/default/files/2021-07/astra-negative-square.png\" width=\"90\" height=\"90\" alt=\"Astra DB\" /\u003e\u003cbr /\u003eAstra DB\u003c/a\u003e\u003cbr/\u003eUse Clojure with DataStax Astra DB - built on Apache Cassandra.\u003c/td\u003e\n\u003c/tr\u003e\u003c/table\u003e\n\n## Installation\n\n### Alia\n\nPlease check the\n[Changelog](https://github.com/mpenet/alia/blob/master/CHANGELOG.md) first\nif you are upgrading. Alia runs on Clojure \u003e= 1.7 (we're using IReduceInit internally)\n\nAdd the following to your dependencies:\n\n\n[![Clojars Project](https://img.shields.io/clojars/v/cc.qbits/alia-all.svg)](https://clojars.org/cc.qbits/alia-all)\n\nThis would include all the codec extensions and extra libraries.\n\nBut the better thing to do is to pick and choose what you really need\nfrom alia's [modules](https://github.com/mpenet/alia/tree/master/modules):\n\n* [cc.qbits/alia](https://github.com/mpenet/alia/tree/master/modules/alia)\n  Main module with all the basic alia functions (required).\n\n  [![Clojars Project](https://img.shields.io/clojars/v/cc.qbits/alia.svg)](https://clojars.org/cc.qbits/alia)\n\n* [cc.qbits/alia-async](https://github.com/mpenet/alia/tree/master/modules/alia-async):\n  core.async interface: query as streamed rows over channel, query as promise-chan\n\n  [![Clojars Project](https://img.shields.io/clojars/v/cc.qbits/alia-async.svg)](https://clojars.org/cc.qbits/alia-async)\n\n* [cc.qbits/alia-manifold](https://github.com/mpenet/alia/tree/master/modules/alia-manifold):\n  Manifold interface: query as streamed rows over manifold stream, query as deferred, etc\n\n  [![Clojars Project](https://img.shields.io/clojars/v/cc.qbits/alia-manifold.svg)](https://clojars.org/cc.qbits/alia-manifold)\n\n* [cc.qbits/alia-java-legacy-time](https://github.com/mpenet/alia/tree/master/modules/alia-java-legacy-time):\n  Codec for java legacy time types.\n\n  [![Clojars Project](https://img.shields.io/clojars/v/cc.qbits/alia-java-legacy-time.svg)](https://clojars.org/cc.qbits/alia-java-legacy-time)\n\n* [cc.qbits/alia-joda-time](https://github.com/mpenet/alia/tree/master/modules/alia-joda-time):\n  Codec for joda-time types.\n\n  [![Clojars Project](https://img.shields.io/clojars/v/cc.qbits/alia-joda-time.svg)](https://clojars.org/cc.qbits/alia-joda-time)\n\n* [cc.qbits/alia-spec](https://github.com/mpenet/alia/tree/master/modules/alia-spec):\n  clojure.spec for alia\n\n  [![Clojars Project](https://img.shields.io/clojars/v/cc.qbits/alia-spec.svg)](https://clojars.org/cc.qbits/alia-spec)\n\n* [cc.qbits/alia-component](https://github.com/mpenet/alia/tree/master/modules/alia-component):\n  [Component](https://github.com/stuartsierra/component) integration for alia\n\n  [![Clojars Project](https://img.shields.io/clojars/v/cc.qbits/alia-component.svg)](https://clojars.org/cc.qbits/alia-component)\n\n### Hayt (the query DSL)\n\nIf you wish to use Hayt you need to add it to your dependencies\n\n[![Clojars Project](https://img.shields.io/clojars/v/cc.qbits/hayt.svg)](https://clojars.org/cc.qbits/hayt)\n\n\nThen `require`/`use` `qbits.hayt` and you're good to go.\n\n## Documentation\n\n[codox generated documentation](http://mpenet.github.com/alia/#docs).\n\n## Quickstart\n\nSimple query execution using alia with hayt would look like this:\n\n```clojure\n(execute session (select :users\n                         (where {:name :foo})\n                         (columns :bar \"baz\")))\n```\n\n\nBut first things first: here is an example of a complete session using\nraw queries.\n\n\n```clojure\n(require '[qbits.alia :as alia])\n\n(def session (alia/session {:session-keyspace \"alia\"\n                            :contact-points [\"localhost:9042\"]\n                            :load-balancing-local-datacenter \"Analytics\"}))\n```\n\nExample of a complete session using plain text auth.\n\n\n```clojure\n(require '[qbits.alia :as alia])\n\n(def session (alia/session {:session-keyspace \"alia\"\n                            :contact-points [\"localhost:9042\"]\n                            :load-balancing-local-datacenter \"Analytics\"\n                            :auth-provider-user-name \"user-name\"\n                            :auth-provider-password \"password\"\n                            :auth-provider-class \"PlainTextAuthProvider\"}))\n```\n\nSessions are separate so that you can interact with multiple\nkeyspaces from the same cluster definition.\n\n```clojure\n(def session (alia/connect cluster))\n\n(alia/execute session \"CREATE KEYSPACE alia\n                       WITH replication = {'class': 'SimpleStrategy', 'replication_factor' : 3};\")\n```\n\n\n\n```clojure\n   (alia/execute session \"CREATE TABLE users (user_name varchar,\n                                              first_name varchar,\n                                              last_name varchar,\n                                              auuid uuid,\n                                              birth_year bigint,\n                                              created timestamp,\n                                              valid boolean,\n                                              emails set\u003ctext\u003e,\n                                              tags list\u003cbigint\u003e,\n                                              amap map\u003cvarchar, bigint\u003e,\n                                              PRIMARY KEY (user_name));\")\n  (alia/execute session \"INSERT INTO users\n                         (user_name, first_name, last_name, emails, birth_year, amap, tags, auuid,valid)\n                         VALUES('frodo', 'Frodo', 'Baggins',\n                         {'f@baggins.com', 'baggins@gmail.com'}, 1,\n                         {'foo': 1, 'bar': 2}, [4, 5, 6],\n                         1f84b56b-5481-4ee4-8236-8a3831ee5892, true);\")\n\n  ;; prepared statement with positional parameter(s)\n  (def prepared-statement (alia/prepare session \"select * from users where user_name=?;\"))\n\n  (alia/execute session prepared-statement {:values [\"frodo\"]})\n\n  \u003e\u003e ({:created nil,\n       :last_name \"Baggins\",\n       :emails #{\"baggins@gmail.com\" \"f@baggins.com\"},\n       :tags [4 5 6],\n       :first_name \"Frodo\",\n       :amap {\"foo\" 1, \"bar\" 2},\n       :auuid #uuid \"1f84b56b-5481-4ee4-8236-8a3831ee5892\",\n       :valid true,\n       :birth_year 1,\n       :user_name \"frodo\"})\n\n  ;; prepared statement with named parameter(s)\n  (def prepared-statement (alia/prepare session \"select * from users where user_name= :name limit :lmt;\"))\n\n  (alia/execute session prepared-statement {:values {:name \"frodo\" :lmt (int 1)}})\n\n\n```\n\n### Asynchronous interfaces:\n\nThere are currently 3 interfaces to use the asynchronous methods of\nthe underlying driver, the fundamental one being a simple\n`CompletableFuture` API, and then two alternative streaming APIs\nbuilt with **core.async** and **manifold**\n\n\n### Async returning `CompletableFuture`\n\n```clojure\n@(execute-async session \"select * from users;\")\n\n```\n\n#### Async using clojure/core.async\n\n\n`qbits.alia.async/execute-chan` has the same signature as the other execute\nfunctions and returns a `clojure/core.async` channel of rows, or an exception instance.\n\nThe channel supports backpressure, controlled by buffer-sizes and as rows\nare consumed from the channel more rows will be fetched to fill any buffers.\n\nOnce you run it you have a couple of options to pull data from it.\n\n+ using `clojure.core.async/take!` which takes the channel as first argument\nand a callback as second:\n\n```clojure\n(take! (execute-chan session \"select * from users;\")\n       (fn [rows-or-exception]\n         (do-something rows)))\n```\n\n+ using `clojure.core.async/\u003c!!` to block and pull the rows/exception\n  from the channel.\n\n```clojure\n(def rows-or-exception (\u003c!! (execute-chan session \"select * from users;\")))\n```\n\n+ using `clojure.core.async/merge` you can run a list of queries in\n  parallel and have the results fed to a single output chan:\n\n```clojure\n(let [merged (async/merge [(alia/execute-chan session (select :foo))\n                           (alia/execute-chan session (select :bar))\n                           (alia/execute-chan session (select :baz))])]\n  (go\n    (loop []\n      (when-let [result (\u003c! merged)]\n        (println result)\n        (recur)))))\n```\n\n`qbits.alia.async/execute` returns a `promise-chan` with just the first\npage of results\n\n`qbits.alia.async/execute-chan-pages` returns a channel of pages of results,\nalso supporting backpressure. The page objects are constructed by the\n`:result-set-fn` option.\n\n\n#### Async using manifold\n\n`qbits.alia.manifold/execute-stream` has the same signature as other execute\nfunctions and resturns a manifold stream of rows, or an exception instance\n\nAs with core.async, the stream supports backpressure and as rows are `take!`en\nfrom the stream, more rows will be fetched according to available buffers.\n\n`qbits.alia.manifold/execute` returns a `Deferred` with just the first page of\nresults\n\n`qbits.alia.manifold/execute-stream-pages` returns a stream of pages of\nresults, supporting backpressure. The page objects are constructed by the\n`:result-set-fn` option.\n\n\nAnd it can do a lot more! Head to the\n[codox generated documentation](http://mpenet.github.com/alia/#docs).\n\n## Hayt (Query DSL)\n\nThere is a nicer way to write your queries using\n[Hayt](https://github.com/mpenet/hayt), this should be familiar if you\nknow Korma or ClojureQL.\nOne of the major difference is that Hayt doesn't use macros and just\ngenerates maps, so if you need to compose clauses or queries together\nyou can just use the clojure.core functions that work on maps.\n\nSome examples:\n\n```clojure\n\n(use 'qbits.hayt)\n\n(select :foo (where {:bar 2}))\n\n;; this generates a map\n\u003e\u003e {:select :foo :where {:bar 2}}\n\n(update :foo\n         (set-columns {:bar 1\n                       :baz (inc-by 2)}\n         (where [[= :foo :bar]\n                 [\u003e :moo 3]\n                 [\u003e :meh 4]\n                 [:in :baz  [5 6 7]]]))\n\n\n;; Composability using normal map manipulation functions\n\n(def base (select :foo (where {:foo 1})))\n\n(merge base\n       (columns :bar :baz)\n       (where {:bar 2})\n       (order-by [:bar :asc])\n       (using :ttl 10000))\n\n;; To compile the queries just use -\u003eraw\n\n(-\u003eraw (select :foo))\n\u003e \"SELECT * FROM foo;\"\n\n```\n\nAlia supports hayt query direct execution, if you pass a non-compiled\nquery to `execute` or `execute-async`, it will be compiled and cached on a LU cache with a threshold of\n100 (the cache function is user settable), so to be used carefully. The same is true with `prepare`.\n\nEx\n```clojure\n(execute session (select :users (where {:name :foo})))\n```\n\nIt covers everything that is possible with CQL3 (functions, handling\nof collection types and their operations, ddl, prepared statements,\netc).\nIf you want to know more about it head to its [codox documentation](http://mpenet.github.com/hayt/codox/qbits.hayt.html) or\n[Hayt's tests](https://github.com/mpenet/hayt/blob/master/test/qbits/hayt/core_test.clj).\n\n## Patreon\n\nIf you wish to support the work on this project you can do this here:\n[patreon](https://www.patreon.com/mpenet)\n\n## Mailing list\n\nAlia has a\n[mailing list](https://groups.google.com/forum/?fromgroups#!forum/alia-cassandra)\nhosted on Google Groups.\nDo not hesitate to ask your questions there.\n\n## License\n\nCopyright © 2013-2020 [Max Penet](https://twitter.com/mpenet), [mccraigmccraig](https://github.com/mccraigmccraig)\n\nDistributed under the Eclipse Public License, the same as Clojure.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmpenet%2Falia","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmpenet%2Falia","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmpenet%2Falia/lists"}