{"id":20776448,"url":"https://github.com/eprothro/cassie","last_synced_at":"2025-04-30T17:43:36.403Z","repository":{"id":56843328,"uuid":"49006467","full_name":"eprothro/cassie","owner":"eprothro","description":"Ruby application support for Apache Cassandra","archived":false,"fork":false,"pushed_at":"2018-01-12T17:05:34.000Z","size":483,"stargazers_count":2,"open_issues_count":9,"forks_count":0,"subscribers_count":2,"default_branch":"latest_stable","last_synced_at":"2025-04-20T20:06:41.802Z","etag":null,"topics":["cassandra","database-configuration","migrations","query-dsl","ruby","schema","versioning"],"latest_commit_sha":null,"homepage":"https://rubygems.org/gems/cassie","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/eprothro.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-01-04T15:46:27.000Z","updated_at":"2022-11-02T19:26:01.000Z","dependencies_parsed_at":"2022-09-09T02:32:13.169Z","dependency_job_id":null,"html_url":"https://github.com/eprothro/cassie","commit_stats":null,"previous_names":[],"tags_count":31,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eprothro%2Fcassie","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eprothro%2Fcassie/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eprothro%2Fcassie/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eprothro%2Fcassie/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/eprothro","download_url":"https://codeload.github.com/eprothro/cassie/tar.gz/refs/heads/latest_stable","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251753689,"owners_count":21638367,"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","database-configuration","migrations","query-dsl","ruby","schema","versioning"],"created_at":"2024-11-17T13:08:42.029Z","updated_at":"2025-04-30T17:43:36.369Z","avatar_url":"https://github.com/eprothro.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"## Cassie\n[![Code Health](https://codeclimate.com/github/eprothro/cassie/badges/gpa.svg)](https://codeclimate.com/github/eprothro/cassie)\n[![Test Coverage](https://codeclimate.com/github/eprothro/cassie/badges/coverage.svg)](https://codeclimate.com/github/eprothro/cassie/coverage)\n[![Build Status](https://travis-ci.org/eprothro/cassie.svg?branch=latest_stable)](https://travis-ci.org/eprothro/cassie/branches)\n[![Inline Docs](http://inch-ci.org/github/eprothro/cassie.svg?branch=latest_stable)](http://www.rubydoc.info/github/eprothro/cassie/dev)\n\n\nCassie provides ruby application support for Apache Cassandra. It provides components that most applications will need that are out of scope of the official `cassandra-driver`, including:\n\n* Database configuration\n* Cluster/session management\n* Cassandra server command helpers\n* Versioned schema migrations\n* Query classes and DSL\n* Test harnessing\n\nEach of these components are designed to be used independently or together in a ruby application. If you want to manage your own configuration, use Cassie for session management, and some other gem for your queries -- great!\n\n**Tested against:**\n\n* Ruby: MRI 2.2, 2.3, and JRuby 1.9\n* `cassandra-driver` 3.0\n\n### Installation\n\n[![Gem Version](https://badge.fury.io/rb/cassie.svg)](https://badge.fury.io/rb/cassie)\n\n```ruby\n# Gemfile\ngem 'cassie', '~\u003e 1.1.0'\n```\n\nor\n\n```bash\n$ gem install cassie\n```\n\nSee [`cassie-rails`](https://github.com/eprothro/cassie-rails) for Rails integration.\n\n### Database Configuration\n\nCassie provies database connection configuration (e.g. cluster and session) per environment. Support for a default YAML back-end is provided.\n\n```bash\n$ cassie configuration:generate\n```\n\n`Cassie::configurations` are loaded from this configuration file at runtime.\n\n```ruby\nCassie.confurations\n=\u003e {\"development\"=\u003e{\"hosts\"=\u003e[\"127.0.0.1\"], \"port\"=\u003e9042, \"keyspace\"=\u003e\"my_app_development\"}, \"test\"=\u003e{\"hosts\"=\u003e[\"127.0.0.1\"], \"port\"=\u003e9042, \"idle_timeout\"=\u003e\"nil\", \"keyspace\"=\u003e\"my_app_test\"}, \"production\"=\u003e{\"hosts\"=\u003e[\"cass1.my_app.biz\", \"cass2.my_app.biz\", \"cass3.my_app.biz\"], \"port\"=\u003e9042, \"keyspace\"=\u003e\"my_app_production\"}}\n```\n\nCassie.configuration` pulls the appropriate configuration from `Cassie.configurations`, based on `Cassie.env`.\n\n```ruby\nCassie.env = \"production\"\n\nCassie.configuration\n{\"hosts\"=\u003e[\"cass1.my_app.biz\", \"cass2.my_app.biz\", \"cass3.my_app.biz\"], \"port\"=\u003e9042, \"keyspace\"=\u003e\"my_app_production\"}\n\nCassie.keyspace\n=\u003e 'my_app_production'\n```\n\n`Cassie.env` prefers `ENV[\"CASSANDRA_ENV\"]`, then `ENV[\"RACK_ENV\"]`, and falls back to `development`.\n\nSee the [`Configuration` README](./lib/cassie/configuration/README.md#readme) for more on features and usage.\n\n\n### Connection Handling\n\nCassie provides cluster and session connection creation according to `cassie-driver` [best practices](http://www.datastax.com/dev/blog/4-simple-rules-when-using-the-datastax-drivers-for-cassandra).\n\n##### Using cached cluster and session objects\n\n`cluster` and `session` objects are created, cached, and reused globally.\n\n```ruby\n# continuing from above 'production' configuration\n\nCassie.cluster\n=\u003e #\u003cCassandra::Cluster:0x3fc032f7f9b8\u003e #\u003c= configured with production cluster `configuration` options\n\nCassie.session\n=\u003e #\u003cCassandra::Session:0x3fc084caa344\u003e #\u003c= session scoped to default 'my_app_production' keyspace\n\nCassie.session(nil)\n=\u003e #\u003cCassandra::Session:0x3fc084caba22\u003e #\u003c= session without scoped keyspace\n\nCassie.session('my_other_keyspace')\n=\u003e #\u003cCassandra::Session:0x3fc084cabf33\u003e #\u003c= session scoped to 'my_other_keyspace' keyspace\n\nCassie.session\n=\u003e #\u003cCassandra::Session:0x3fc084caa344\u003e #\u003c= cached session, scoped to default 'my_app_production' keyspace\n```\n\nIf using Cassie Configuration as described above via `cassandra.yml`, cluster configuration happens automatically. If not, assign a cluster environments hash to `Cassie::configurations` before using a `cluster` or `session`.\n\n##### Using cluster and session objects in Classes\n\nInclude `Cassie::Connection` in a class for `session` and `keyspace` functionality in your objects.\n\n```ruby\nclass MyQuery\n  include Cassie::Connection\n\n  # An explicit keyspace that will determine the session used\n  # instead of falling back to the value in `Cassie.keyspace`\n  # for all instances of this class.\n  # Override `#keyspace` for per-object evaluation.\n  keyspace :some_other_keyspace\n\n  def find_user(id)\n    # `session` is a vanilla Cassandra::Session\n    # connected to `some_other_keyspace`\n    session.execute('SELECT * FROM users WHERE id = ?;', arguments: [id])\n  end\nend\n```\n\nSee the [Connection README](./lib/cassie/connection_handler/README.md#readme) for more on features and usage.\n\n### Cassandra Control\n\nCassie provides simple commands to control Cassandra execution in *nix development. These simplify execution and reduce output to provide faster management of your Cassandra processes.\n\n#### Start\n\n```\n$ cassie start\nStarting Cassandra...\n[✓] Cassandra Running\n```\n\n#### Stop\n\n```\n$ cassie stop\nStopping Cassandra...\n[✓] Cassandra Stopped\n```\n\n```\n$ cassie stop\nCouldn't single out a Cassandra process.\n  - Is cqlsh running?\n  - Kill all cassandra processes with --all\n    - 9542  | /usr/local/apache-cassandra-3.0.8/bin/cqlsh.py\n    - 2832  | org.apache.cassandra.service.CassandraDaemon\n\n$ cassie stop --all\nStopping Cassandra...\n[✓] Cassandra Stopped\n```\n\n#### Restart\n\n```\n$ cassie restart\nStopping Cassandra...\n[✓] Cassandra Stopped\nStarting Cassandra...\n[✓] Cassandra Running\n```\n\n#### Tail\n\n```\n$ cassie tail\nTailing Cassandra system log, Ctrl-C to stop...\n  /usr/local/cassandra/logs/system.log:\n\nINFO  [main] 2016-09-23 11:18:05,073 StorageService.java:1902 - Node localhost/127.0.0.1 state jump to NORMAL\nINFO  [main] 2016-09-23 11:18:05,215 NativeTransportService.java:75 - Netty using Java NIO event loop\nINFO  [main] 2016-09-23 11:18:05,343 Server.java:159 - Using Netty Version: [netty-buffer=netty-buffer-4.0.23.Final.208198c, netty-codec=netty-codec-4.0.23.Final.208198c, netty-codec-http=netty-codec-http-4.0.23.Final.208198c, netty-codec-socks=netty-codec-socks-4.0.23.Final.208198c, netty-common=netty-common-4.0.23.Final.208198c, netty-handler=netty-handler-4.0.23.Final.208198c, netty-transport=netty-transport-4.0.23.Final.208198c, netty-transport-rxtx=netty-transport-rxtx-4.0.23.Final.208198c, netty-transport-sctp=netty-transport-sctp-4.0.23.Final.208198c, netty-transport-udt=netty-transport-udt-4.0.23.Final.208198c]\nINFO  [main] 2016-09-23 11:18:05,344 Server.java:160 - Starting listening for CQL clients on localhost/127.0.0.1:9042 (unencrypted)...\nINFO  [main] 2016-09-23 11:18:05,407 CassandraDaemon.java:477 - Not starting RPC server as requested. Use JMX (StorageService-\u003estartRPCServer()) or nodetool (enablethrift) to start it\n```\n\n### Versioned Schema Migrations\n\nCassie supports migration between schema states using semantically versioned, incremental migration files.\n\nSchema Version information is stored in Cassandra persistence, in the `cassie_schema.versions` table (configurable).\n\nA schema file holds the current state of the schema in-repo, at `db/cassandra/schema.rb`, (configurable).\n\nVarious `cassie \u003ctask\u003e` tasks are used to manage the schema version and migrations.\n\n#### Tasks\n\n| Task | Description |\n| --- | --- |\n| migrations:import | Import existing `cassandra_migrations` migration files and convert to semantic versioning |\n| migration:create | Generates an empty migration file prefixed with the next semantic version number |\n| migrate | Migrates the schema by running the `up` methods in any migrations starting after the current schema version |\n| migrate:reset | runs schema:reset and migrate |\n| schema:init | Create versioned migrations schema, and the environment's keyspace if it doesn't exist |\n| schema:version | Print the current schema version information for the Cassandra cluster |\n| schema:history | Print the the historical version information the current Cassandra cluster state |\n| schema:status | Print the the migration status for each local migration (up/down) |\n| schema:load | Creates the schema by executing the CQL schema in the schema file (`db/cassandra/schema.rb` by default) |\n| schema:drop | drop keyspace(s) |\n| schema:dump | Dumps the schema for all non-system keyspaces in CQL format (`db/cassandra/schema.rb` by default) |\n| schema:reset | runs schema:drop and schema:load|\n| schema:import | Create an initial migration based on the current Cassandra non-system schema |\n\nSee the [Migrations README](./lib/cassie/schema/README.md#readme) for more on features and usage.\n\n### Query DSL\n\nCassie provides base Query Classes to manage interactions to the database.\nCreate application specific subclasses and construct queries with a simple CQL DSL.\n\n```ruby\nclass UserByUsernameQuery \u003c Cassie::Query\n\n  select_from :users_by_username\n\n  where :username, :eq\n\n  consistency :quorum\nend\n```\n\n```ruby\nUserByUsernameQuery.new.fetch_first(username: \"eprothro\")\n=\u003e #\u003cStruct user_id=123, username=\"eprothro\"\u003e\n```\n\nSee the [Queries README](./lib/cassie/statements/README.md#readme) for more on features and usage.\n\n### Test Harnessing\n\nAvoid making queries into the persistnace layer when you can afford it.\n\n```ruby\nsome_query = SomeQuery.new\nsome_query.extend(Cassie::Testing::Fake::Query)\nsome_query.session.rows = [{'user_id' =\u003e 123, 'username' =\u003e 'eprothro'}]\n\nsome_query.fetch\n=\u003e [#\u003cStruct user_id=123, username=\"eprothro\"\u003e]\n\nsome_query.session.last_statement\n=\u003e #\u003cCassandra::Statements::Simple:0x3ffde09930b8 @cql=\"SELECT * FROM users LIMIT 500;\" @params=[]\u003e\n```\n\nSee the [Testing README](./lib/cassie/testing/README.md#readme) for more on features and usage.\n\n### Contributing\n\nPull requests and issues are welcome. Please read the [contributing guidelines](./CONTRIBUTING.md).","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feprothro%2Fcassie","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Feprothro%2Fcassie","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feprothro%2Fcassie/lists"}