{"id":13636411,"url":"https://github.com/jbochi/lua-resty-cassandra","last_synced_at":"2025-04-11T21:29:01.777Z","repository":{"id":18398073,"uuid":"21579476","full_name":"jbochi/lua-resty-cassandra","owner":"jbochi","description":"Pure Lua Cassandra client using CQL binary protocol","archived":false,"fork":false,"pushed_at":"2017-06-09T18:40:44.000Z","size":173,"stargazers_count":68,"open_issues_count":5,"forks_count":16,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-11-09T06:38:31.199Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Lua","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/jbochi.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-07-07T17:17:23.000Z","updated_at":"2024-11-06T22:11:55.000Z","dependencies_parsed_at":"2022-09-09T23:41:02.795Z","dependency_job_id":null,"html_url":"https://github.com/jbochi/lua-resty-cassandra","commit_stats":null,"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jbochi%2Flua-resty-cassandra","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jbochi%2Flua-resty-cassandra/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jbochi%2Flua-resty-cassandra/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jbochi%2Flua-resty-cassandra/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jbochi","download_url":"https://codeload.github.com/jbochi/lua-resty-cassandra/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248482579,"owners_count":21111355,"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":[],"created_at":"2024-08-02T00:01:00.991Z","updated_at":"2025-04-11T21:29:01.742Z","avatar_url":"https://github.com/jbochi.png","language":"Lua","funding_links":[],"categories":["Libraries","Third Modules","Rust Modules","资源","Resources"],"sub_categories":["C Modules","Lua Modules","Data Stores"],"readme":"This repo is **not** being actively maintained. I highly recommend that you try [lua-cassandra](https://github.com/thibaultcha/lua-cassandra)\n\n# lua-resty-cassandra\n\n[![Build Status][badge-travis-image]][badge-travis-url]\n[![Coverage Status][badge-coveralls-image]][badge-coveralls-url]\n![Module Version][badge-version-image]\n[![Join the chat at https://gitter.im/jbochi/lua-resty-cassandra](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/jbochi/lua-resty-cassandra?utm_source=badge\u0026utm_medium=badge\u0026utm_campaign=pr-badge\u0026utm_content=badge)\n\nPure Lua Cassandra client using CQL binary protocol v2.\n\nIt is 100% non-blocking if used in Nginx/Openresty but can also be used with luasocket.\n\n## Installation\n\n#### Luarocks\n\nInstallation through [luarocks][luarocks-url] is recommended:\n\n```bash\n$ luarocks install cassandra\n```\n\n#### Manual\n\nCopy the `src/` folder and require `cassandra.lua`.\n\n## Usage\n\nOverview:\n\n```lua\nlocal cassandra = require \"cassandra\"\n\nlocal session = cassandra.new()\nsession:set_timeout(1000) -- 1000ms timeout\n\nlocal connected, err = session:connect(\"127.0.0.1\", 9042)\n\nsession:set_keyspace(\"lua_tests\")\n\n-- simple query\nlocal table_created, err = session:execute [[\n  CREATE TABLE users(\n    user_id uuid PRIMARY KEY,\n    name varchar,\n    age int\n  )\n]]\n\n-- query with arguments\nlocal ok, err = session:execute([[\n  INSERT INTO users(name, age, user_id) VALUES(?, ?, ?)\n]], {\"John O'Reilly\", 42, cassandra.uuid(\"1144bada-852c-11e3-89fb-e0b9a54a6d11\")})\n\n\n-- select statement\nlocal users, err = session:execute(\"SELECT name, age, user_id from users\")\n\nassert(1 == #users)\nlocal user = users[1]\nngx.say(user.name) -- \"John O'Reilly\"\nngx.say(user.user_id) -- \"1144bada-852c-11e3-89fb-e0b9a54a6d11\"\nngx.say(user.age) -- 42\n```\n\nYou can check more examples in the [tests](https://github.com/jbochi/lua-resty-cassandra/blob/master/spec/functional_spec.lua) or [here][anchor-examples].\n\n## Socket methods\n\n### session, err = cassandra.new()\n\nCreates a new session. Create a socket with the cosocket API if available, fallback on luasocket otherwise.\n\n\u003e **Return values:**\n\u003e\n\u003e * `session`: A lua-resty-cassandra session.\n\u003e * `err`: Any error encountered during the socket creation.\n\n### session:set_timeout(timeout)\n\nSets timeout (in miliseconds). Uses Nginx [tcpsock:settimeout](http://wiki.nginx.org/HttpLuaModule#tcpsock:settimeout).\n\n\u003e **Parameters:**\n\u003e\n\u003e * `timeout`: A number being the timeout in miliseconds\n\n### ok, err = session:connect(contact_points, port)\n\nConnects to a single or multiple hosts at the given port.\n\n\u003e **Parameters:**\n\u003e\n\u003e * `contact_points`: A string or an array of strings (hosts) to connect to.\n\u003e   * **Note:** If you wish to give a different port to one of those hosts, format the string as: \"host:port\" for that specific contact point. The specified `port` value will overwrite the `port` argument of `connect` for that contact point.\n\u003e * `port`: The port number. **Default:** `9042`.\n\n\u003e **Return values:**\n\u003e\n\u003e * `ok`: true if connected, false otherwise. Nil of the session doesn't have a socket.\n\u003e * `err`: Any encountered error.\n\n### ok, err = session:set_keepalive(max_idle_timeout, pool_size)  -- Nginx only\n\nPuts the current Cassandra connection immediately into the ngx_lua cosocket connection pool.\n\n**Note**: Only call this method in the place you would have called the close method instead. Calling this method will immediately turn the current cassandra session object into the closed state. Any subsequent operations other than connect() on the current objet will return the closed error.\n\n\u003e **Parameters:**\n\u003e\n\u003e * `max_idle_timeout`: Max idle timeout (in ms) when the connection is in the pool\n\u003e * `pool_size`: Maximal size of the pool every nginx worker process.\n\n\u003e **Return values:**\n\u003e\n\u003e * `ok`: `1` if success, nil otherwise.\n\u003e * `err`: Encountered error if any\n\n### times, err = session:get_reused_times() -- Nginx only\n\nThis method returns the (successfully) reused times for the current connection. In case of error, it returns `nil` and a string describing the error.\n\n**Note:** If the current connection does not come from the built-in connection pool, then this method always returns `0`, that is, the connection has never been reused (yet). If the connection comes from the connection pool, then the return value is always non-zero. So this method can also be used to determine if the current connection comes from the pool.\n\n\u003e **Return values:**\n\u003e\n\u003e * `times`: Number of times the current connection was successfully reused, nil if error\n\u003e * `err`: Encountered error if any\n\n### ok, err = session:close()\n\nCloses the current connection and returns the status.\n\n\u003e **Return values:**\n\u003e\n\u003e * `ok`: `1` if success, nil otherwise.\n\u003e * `err`: Encountered error if any\n\n## Client methods\n\nAll errors returned by functions in this section are tables with the following properties:\n\n\u003e * `code`: A string from one of the `error_codes` in `cassandra.contants`.\n\u003e * `raw_message`: The error message being returned by Cassandra.\n\u003e * `message`: A constructed error message with `code` + `raw_message`.\n\nError tables implement the `__tostring` method and are thus printable. A stringified error table will outputs its `message` property.\n\n### ok, err = session:set_keyspace(keyspace_name)\n\nSets session keyspace to the given `keyspace_name`.\n\n\u003e **Parameters:**\n\u003e\n\u003e * `keyspace_name`: Name of the keyspace to use.\n\n\u003e **Return values:**\n\u003e\n\u003e See `:execute()`\n\n### stmt, err = session:prepare(query, options)\n\nPrepare a statement for later execution.\n\n\u003e **Parameters:**\n\u003e\n\u003e * `query`: A string representing a query to prepare.\n\u003e * `options`: The same options available on `:execute()`.\n\n\u003e **Return values:**\n\u003e\n\u003e * `stmt`: A prepareed statement to be used by `:execute()`, nil if the preparation failed.\n\u003e * `err`: Encountered error if any.\n\n### result, err = session:execute(query, args, options)\n\nExecute a query or previously prepared statement.\n\n\u003e **Parameters:**\n\u003e\n\u003e * `query`: A string representing a query or a previously prepared statement.\n\u003e * `args`: An array of arguments to bind to the query. Those arguments can be type annotated (example: `cassandra.bigint(4)`. If there is no annotation, the driver will try to infer a type. Since integer numbers are serialized as int with 4 bytes, Cassandra would return an error if we tried to insert it in a bigint column.\n\u003e * `options` is a table of options:\n\u003e   * `consistency_level`: for example `cassandra.consistency.ONE`\n\u003e   * `tracing`: if set to true, enables tracing for this query. In this case, the result table will contain a key named `tracing_id` with an uuid of the tracing session.\n\u003e   * `page_size`: Maximum size of the page to fetch (default: 5000).\n\u003e   * `auto_paging`: If set to true, `execute` will return an iterator. See the [example below][anchor-examples] on how to use auto pagination.\n\n\u003e **Return values:**\n\u003e\n\u003e * `result`: A table containing the result of this query if successful, ni otherwise. The table can contain additional keys:\n\u003e   * `type`: Type of the result set, can either be \"VOID\", \"ROWS\", \"SET_KEYSPACE\" or \"SCHEMA_CHANGE\".\n\u003e   * `meta`: If the result type is \"ROWS\" and the result has more pages that haven't been returned, this property will contain 2 values: `has_more_pages` and `paging_state`. See the [example below][anchor-examples] on how to use pagination.\n\u003e * `err`: Encountered error if any.\n\n### batch, err = cassandra.BatchStatement(type)\n\nInitialized a batch statement. See the [example below][anchor-examples] on how to use batch statements and [this](http://www.datastax.com/documentation/cql/3.1/cql/cql_reference/batch_r.html) for informations about the type of batch to use.\n\n\u003e **Parameters:**\n\u003e\n\u003e * `type`: The type of batch statement. Can be ony of those:\n\u003e   * `cassandra.batch_types.LOGGED` (default)\n\u003e   * `cassandra.batch_types.UNLOGGED`\n\u003e   * `cassandra.batch_types.COUNTER`\n\n\u003e **Return values:**\n\u003e\n\u003e * `batch`: An empty batch statement on which to add operations.\n\u003e * `err`: Encountered error if any.\n\n### batch:add(query, args)\n\nAdd an operation to a batch statement. See the [example below][anchor-examples] on how to use batch statements.\n\n\u003e **Parameters:**\n\u003e\n\u003e * `query`: A string representing a query or a previously prepared statement.\n\u003e * `args`: An array of arguments to bind to the query, similar to `:execute()`.\n\n### trace, err = session:get_trace(result)\n\nReturn the trace of a given result, if possible.\n\n\u003e **Parameters:**\n\u003e\n\u003e * `result`: A previous query result.\n\n\u003e **Return values:**\n\u003e\n\u003e `trace`: is a table with the following keys (from `system_traces.sessions` and `system_traces.events` [system tracing tables](http://www.datastax.com/dev/blog/advanced-request-tracing-in-cassandra-1-2):\n\u003e\n\u003e * coordinator\n\u003e * duration\n\u003e * parameters\n\u003e * request\n\u003e * started_at\n\u003e * events: an array of tables with the following keys:\n\u003e    * event_id\n\u003e    * activity\n\u003e    * source\n\u003e    * source_elapsed\n\u003e    * thread\n\u003e\n\u003e `err`: Encountered error if any.\n\n## Examples\n\nBatches:\n\n```lua\n-- Create a batch statement\nlocal batch = cassandra.BatchStatement()\n\n-- Add a query\nbatch:add(\"INSERT INTO users (name, age, user_id) VALUES (?, ?, ?)\",\n          {\"James\", 32, cassandra.uuid(\"2644bada-852c-11e3-89fb-e0b9a54a6d93\")})\n\n-- Add a prepared statement\nlocal stmt, err = session:prepare(\"INSERT INTO users (name, age, user_id) VALUES (?, ?, ?)\")\nbatch:add(stmt, {\"John\", 45, cassandra.uuid(\"1144bada-852c-11e3-89fb-e0b9a54a6d11\")})\n\n-- Execute the batch\nlocal result, err = session:execute(batch)\n```\n\nPagination might be very useful to build web services:\n\n```lua\n-- Assuming our users table contains 1000 rows\n\nlocal query = \"SELECT * FROM users\"\nlocal rows, err = session:execute(query, nil, {page_size = 500}) -- default page_size is 5000\n\nassert.same(500, #rows) -- rows contains the 500 first rows\n\nif rows.meta.has_more_pages then\n  local next_rows, err = session:execute(query, nil, {paging_state = rows.meta.paging_state})\n\n  assert.same(500, #next_rows) -- next_rows contains the next (and last) 500 rows\nend\n```\n\nAutomated pagination:\n\n```lua\n-- Assuming our users table now contains 10.000 rows\n\nlocal query = \"SELECT * FROM users\"\n\nfor _, rows, page, err in session:execute(query, nil, {auto_paging=true}) do\n  assert.same(5000, #rows) -- rows contains 5000 rows on each iteration in this case\n  -- page: will be 1 on the first iteration, 2 on the second\n  -- err: in case any fetch returns an error\n  -- _: (the first for argument) is the current paging_state used to fetch the rows\nend\n```\n\n## Running unit tests\n\nWe use `busted` and require `luasocket` to mock `ngx.socket.tcp()`. To run the tests, start a local cassandra instance and run:\n\n```bash\n$ luarocks install busted\n$ make test\n```\n\n## Running coverage\n\n```bash\n$ luarocks install luacov\n$ make coverage\n```\n\nReport will be in `./luacov.report.out`.\n\n## Running linting\n\n```bash\n$ luarocks install luacheck\n$ make lint\n```\n\n## Contributors\n\nJuarez Bochi (@jbochi)\n\nThibault Charbonnier (@thibaultCha) -\u003e Several contributions, including paging support, improved batch statements, better documentation, specs and code style.\n\nLeandro Moreira (@leandromoreira) -\u003e Added support for doubles\n\nMarco Palladino (@thefosk)\n\n[badge-travis-url]: https://travis-ci.org/jbochi/lua-resty-cassandra\n[badge-travis-image]: https://img.shields.io/travis/jbochi/lua-resty-cassandra.svg?style=flat\n\n[badge-coveralls-url]: https://coveralls.io/r/jbochi/lua-resty-cassandra?branch=master\n[badge-coveralls-image]: https://coveralls.io/repos/jbochi/lua-resty-cassandra/badge.svg?branch=master\n\n[badge-version-image]: https://img.shields.io/badge/version-0.5--7-green.svg?style=flat\n\n[luarocks-url]: https://luarocks.org\n\n[anchor-examples]: #examples\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjbochi%2Flua-resty-cassandra","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjbochi%2Flua-resty-cassandra","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjbochi%2Flua-resty-cassandra/lists"}