From f9672558d3c3ddbd96c486c0c9d068c7b3d97df4 Mon Sep 17 00:00:00 2001 From: Sayan Nandan Date: Thu, 1 Oct 2020 11:35:24 +0530 Subject: [PATCH] Update project metadata and add tests for `KEYLEN` --- README.md | 9 ++++-- actions.jsonc | 8 +++++ server/src/kvengine/keylen.rs | 3 +- server/src/kvengine/mod.rs | 4 ++- server/src/queryengine/mod.rs | 2 +- server/src/tests/kvengine_tests.rs | 48 ++++++++++++++++++++++++++++++ 6 files changed, 67 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 8a2ddc9f..664fbcd3 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ ![GitHub Workflow Status](https://img.shields.io/github/workflow/status/terrabasedb/terrabasedb/Tests?style=flat-square) ![Status: Alpha](https://img.shields.io/badge/status-alpha-critical?style=flat-square) ![Development](https://img.shields.io/badge/development-actively%20developed-32CD32?style=flat-square) ![GitHub release (latest SemVer including pre-releases)](https://img.shields.io/github/v/release/terrabasedb/terrabasedb?include_prereleases&sort=semver&style=flat-square) ![GitHub commit activity](https://img.shields.io/github/commit-activity/m/terrabasedb/terrabasedb?label=commits&style=flat-square) [![Docker Pulls](https://img.shields.io/docker/pulls/terrabasedb/tdb?style=flat-square)](https://hub.docker.com/r/terrabasedb/tdb) -[![Docs](https://img.shields.io/badge/readthedocs-here-blueviolet?style=flat-square)](https://git.io/JJZ8Z) +[![Docs](https://img.shields.io/badge/readthedocs-here-blueviolet?style=flat-square)](https://terrabasedb.github.io/docs) @@ -31,11 +31,11 @@ TerrabaseDB (or TDB for short) is an effort to provide the best of key/value sto * `EXISTS` - Check if a single/multiple key(s) exist(s) * `DEL` - Delete a single/multiple key(s) -And, a lot more actions are coming soon! +And [many more](https://terrabasedb.github.io/docs/List-Of-Actions) ## Clients 🔌 -We're officially working on a [Python Driver](https://github.com/terrabasedb/python-driver) and we plan to support more languages along the way 🎉! You're free to write your own clients - all you need to do is implement the simple and performant [Terrapipe protocol spec](https://git.io/JJZ4Z). +We're officially working on a [Python Driver](https://github.com/terrabasedb/python-driver) and we plan to support more languages along the way 🎉! You're free to write your own clients - all you need to do is implement the simple and performant [Terrapipe protocol spec](https://terrabasedb.github.io/docs/Protocols/terrapipe/). ## Community 👐 @@ -59,6 +59,9 @@ This project strictly follows semver, however, since this project is currently i **Yes - we need you!** Be it a typo, a bizarre idea, a dirty bug🐞 or an amazing patch - you're welcome to contribute to TDB! Beginner friendly issues are marked with the [](https://github.com/terrabasedb/terrabasedb/labels/L-easy) label. Read the guide [here](./CONTRIBUTING.md). +## Contributors + +You can see a full list of contributors [here](https://ohsayan.github.io/thanks) ## License diff --git a/actions.jsonc b/actions.jsonc index 8159b5be..10d51b3f 100644 --- a/actions.jsonc +++ b/actions.jsonc @@ -135,5 +135,13 @@ "args": "USET ...", "desc": "SET all keys if they don't exist, or UPDATE them if they do exist", "return": "Number of keys that were `USET`ed, as an integer" + }, + { + "name": "KEYLEN", + "since": "0.4.4", + "complexity": "O(1)", + "args": "KEYLEN ", + "desc": "Returns the length of the UTF-8 string", + "return": "Length of the key as an integer", } ] \ No newline at end of file diff --git a/server/src/kvengine/keylen.rs b/server/src/kvengine/keylen.rs index a9ddad8a..918237fd 100644 --- a/server/src/kvengine/keylen.rs +++ b/server/src/kvengine/keylen.rs @@ -20,8 +20,7 @@ */ use crate::coredb::CoreDB; use crate::protocol::{responses, ActionGroup, Connection}; -use crate::resp::{BytesWrapper, GroupBegin}; -use bytes::Bytes; +use crate::resp::GroupBegin; use libtdb::TResult; /// Run a `KEYLEN` query diff --git a/server/src/kvengine/mod.rs b/server/src/kvengine/mod.rs index 19d9b98a..5d60fb93 100644 --- a/server/src/kvengine/mod.rs +++ b/server/src/kvengine/mod.rs @@ -40,10 +40,12 @@ pub mod uset; pub mod heya { //! Respond to `HEYA` queries use crate::protocol; + use crate::protocol::ActionGroup; + use crate::CoreDB; use libtdb::TResult; use protocol::{responses, Connection}; /// Returns a `HEY!` `Response` - pub async fn heya(con: &mut Connection) -> TResult<()> { + pub async fn heya(_db: &CoreDB, con: &mut Connection, _buf: ActionGroup) -> TResult<()> { con.write_response(responses::fresp::R_HEYA.to_owned()) .await } diff --git a/server/src/queryengine/mod.rs b/server/src/queryengine/mod.rs index d85a636b..0a028fb1 100644 --- a/server/src/queryengine/mod.rs +++ b/server/src/queryengine/mod.rs @@ -76,7 +76,7 @@ pub async fn execute_simple(db: &CoreDB, con: &mut Connection, buf: ActionGroup) match first.as_str() { tags::TAG_DEL => kvengine::del::del(db, con, buf).await?, tags::TAG_GET => kvengine::get::get(db, con, buf).await?, - tags::TAG_HEYA => kvengine::heya::heya(con).await?, + tags::TAG_HEYA => kvengine::heya::heya(db, con, buf).await?, tags::TAG_EXISTS => kvengine::exists::exists(db, con, buf).await?, tags::TAG_SET => kvengine::set::set(db, con, buf).await?, tags::TAG_MGET => kvengine::mget::mget(db, con, buf).await?, diff --git a/server/src/tests/kvengine_tests.rs b/server/src/tests/kvengine_tests.rs index 4944f9d0..775d1171 100644 --- a/server/src/tests/kvengine_tests.rs +++ b/server/src/tests/kvengine_tests.rs @@ -76,6 +76,8 @@ async fn test_queries() { queries.add(test_flushdb_syntax_error).await; queries.add(test_uset_all_okay).await; queries.add(test_uset_syntax_error).await; + queries.add(test_keylen).await; + queries.add(test_keylen_syntax_error).await; queries.run_queries_and_close_sockets(); // Clean up everything else @@ -772,6 +774,7 @@ async fn test_dbsize_mixed(stream: TcpStream) -> TcpStream { stream } +/// Test `DBSIZE` with an incorrect number of arguments async fn test_dbsize_syntax_error(mut stream: TcpStream) -> TcpStream { let query = terrapipe::proc_query("DBSIZE x y z"); stream.write_all(&query).await.unwrap(); @@ -781,6 +784,7 @@ async fn test_dbsize_syntax_error(mut stream: TcpStream) -> TcpStream { stream } +/// Test `FLUSHDB` async fn test_flushdb_okay(stream: TcpStream) -> TcpStream { let mut stream = set_values( "x ex y why z zed a firstalphabet b secondalphabet", @@ -802,6 +806,7 @@ async fn test_flushdb_okay(stream: TcpStream) -> TcpStream { stream } +/// Test `FLUSHDB` with an incorrect number of arguments async fn test_flushdb_syntax_error(mut stream: TcpStream) -> TcpStream { let query = terrapipe::proc_query("FLUSHDB x y z"); stream.write_all(&query).await.unwrap(); @@ -811,6 +816,9 @@ async fn test_flushdb_syntax_error(mut stream: TcpStream) -> TcpStream { stream } +/// Test `USET` which returns okay +/// +/// `USET` almost always returns okay for the correct number of key(s)/value(s) async fn test_uset_all_okay(stream: TcpStream) -> TcpStream { let mut stream = set_values("x 100 y 200 z 300", 3, stream).await; let query = terrapipe::proc_query("USET x ex y why z zed"); @@ -822,6 +830,7 @@ async fn test_uset_all_okay(stream: TcpStream) -> TcpStream { stream } +/// Test `USET` with an incorrect number of arguments async fn test_uset_syntax_error(mut stream: TcpStream) -> TcpStream { let query = terrapipe::proc_query("USET"); let query2 = terrapipe::proc_query("USET x"); @@ -847,3 +856,42 @@ async fn test_uset_syntax_error(mut stream: TcpStream) -> TcpStream { ); stream } + +/// Test `KEYLEN` +async fn test_keylen(stream: TcpStream) -> TcpStream { + let mut stream = set_values("4 four", 1, stream).await; + let query = terrapipe::proc_query("keylen 4"); + stream.write_all(&query).await.unwrap(); + let res_should_be = "#2\n*1\n#2\n&1\n:1\n4\n".to_owned().into_bytes(); + let mut response = vec![0; res_should_be.len()]; + stream.read_exact(&mut response).await.unwrap(); + assert_eq!(response, res_should_be, "{}", __func__!()); + stream +} + +/// Test `KEYLEN` with an incorrect number of arguments +async fn test_keylen_syntax_error(mut stream: TcpStream) -> TcpStream { + let query = terrapipe::proc_query("KEYLEN"); + stream.write_all(&query).await.unwrap(); + let mut response = vec![0; fresp::R_ACTION_ERR.len()]; + stream.read_exact(&mut response).await.unwrap(); + assert_eq!( + response, + fresp::R_ACTION_ERR.to_owned(), + "{}:{}", + __func__!(), + "with 1 arg(s)" + ); + let query = terrapipe::proc_query("KEYLEN x y"); + stream.write_all(&query).await.unwrap(); + let mut response = vec![0; fresp::R_ACTION_ERR.len()]; + stream.read_exact(&mut response).await.unwrap(); + assert_eq!( + response, + fresp::R_ACTION_ERR.to_owned(), + "{}:{}", + __func__!(), + "with 2 arg(s)" + ); + stream +}