diff --git a/CHANGELOG.md b/CHANGELOG.md index 451a98e..827084c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,13 @@ All changes in this project will be noted in this file. +## 0.8.11 + +### Additions + +- Added `QList` and `RList` for using dynamic lists +- Allow using references for custom types in `query!` macro + ## 0.8.10 ### Fixes diff --git a/Cargo.toml b/Cargo.toml index 727d646..a986b0e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,7 @@ license = "Apache-2.0" name = "skytable" readme = "README.md" repository = "https://github.com/skytable/client-rust" -version = "0.8.10" +version = "0.8.11" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] diff --git a/README.md b/README.md index 66f16fd..bd89544 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,9 @@ ## Introduction -This library is the official client for the free and open-source NoSQL database [Skytable](https://github.com/skytable/skytable). First, go ahead and install Skytable by following the instructions [here](https://docs.skytable.io/getting-started). This library supports all Skytable versions that work with the [Skyhash 2 Protocol](https://docs.skytable.io/protocol/overview). This version of the library was tested with the latest Skytable release (release [0.8.3](https://github.com/skytable/skytable/releases/v0.8.3)). [Read more about supported versions here](#version-support). +This library is the official client for the free and open-source NoSQL database [Skytable](https://github.com/skytable/skytable). First, go ahead and install Skytable by following the instructions [here](https://docs.skytable.io/getting-started). This library supports all Skytable versions that work with the [Skyhash 2 Protocol](https://docs.skytable.io/protocol/overview). This version of the library was tested with the latest Skytable release (release [0.8.4](https://github.com/skytable/skytable/releases/v0.8.4)). [Read more about supported versions here](#version-support). + +**📁 You can [find some usage examples in this folder here](/examples)**. ## Definitive example diff --git a/examples/dynamic_lists_advanced.rs b/examples/dynamic_lists_advanced.rs new file mode 100644 index 0000000..7521529 --- /dev/null +++ b/examples/dynamic_lists_advanced.rs @@ -0,0 +1,80 @@ +/* + assume the model is created using: + + > create space myapp + > create model myapp.mydb(username: string, password: string, data: [string]) + + ------------- + + This is an example just like `dynamic_lists_simple.rs` but using a struct instead +*/ + +use skytable::{ + query::{QList, SQParam}, + response::{FromResponse, RList}, + Config, +}; + +#[derive(Debug, PartialEq)] +struct User { + username: String, + password: String, + data: Vec, +} + +impl User { + fn new(username: String, password: String, data: Vec) -> Self { + Self { + username, + password, + data, + } + } +} + +impl SQParam for User { + fn append_param(&self, q: &mut Vec) -> usize { + self.username.append_param(q) + + self.password.append_param(q) + + QList::new(&self.data).append_param(q) + } +} + +impl FromResponse for User { + fn from_response(resp: skytable::response::Response) -> skytable::ClientResult { + let (username, password, data) = resp.parse::<(_, _, RList)>()?; + Ok(Self::new(username, password, data.into_values())) + } +} + +fn get_data_from_api() -> User { + User { + username: "sayan".to_owned(), + password: "ulw06afuMCAg+1gh2lh1Y9xTIr/dUv2vqGLeZ39cVrE=".to_owned(), + data: vec![ + "stuff".to_owned(), + "from".to_owned(), + "the".to_owned(), + "api".to_owned(), + ], + } +} + +fn main() { + let mut db = Config::new_default("root", "password12345678") + .connect() + .unwrap(); + let data_from_api = get_data_from_api(); + db.query_parse::<()>(&skytable::query!( + "insert into myapp.mydb { username: ?, password: ?, data: ? }", + &data_from_api + )) + .unwrap(); + let fetched_user: User = db + .query_parse(&skytable::query!( + "select * from myapp.mydb where username = ?", + "sayan" + )) + .unwrap(); + assert_eq!(data_from_api, fetched_user); +} diff --git a/examples/dynamic_lists_simple.rs b/examples/dynamic_lists_simple.rs new file mode 100644 index 0000000..bb0586f --- /dev/null +++ b/examples/dynamic_lists_simple.rs @@ -0,0 +1,41 @@ +/* + assume the model is created using: + + > create space myapp + > create model myapp.mydb(username: string, password: string, data: [string]) +*/ + +use skytable::{query::QList, response::RList, Config}; + +fn get_list_data_from_api() -> Vec { + vec![ + "stuff".to_owned(), + "from".to_owned(), + "the".to_owned(), + "api".to_owned(), + ] +} + +fn main() { + let mut db = Config::new_default("root", "password12345678") + .connect() + .unwrap(); + let data_from_api = get_list_data_from_api(); + let q = skytable::query!( + "insert into myapp.mydb { username: ?, password: ?, data: ? }", + "sayan", + "ulw06afuMCAg+1gh2lh1Y9xTIr/dUv2vqGLeZ39cVrE=", + QList::new(&data_from_api) + ); + db.query_parse::<()>(&q).unwrap(); // expect this data to be inserted correctly + // now fetch this data + let (username, password, data): (String, String, RList) = db + .query_parse(&skytable::query!( + "select * from myapp.mydb where username = ?", + "sayan" + )) + .unwrap(); + assert_eq!(username, "sayan"); + assert_eq!(password, "ulw06afuMCAg+1gh2lh1Y9xTIr/dUv2vqGLeZ39cVrE="); + assert_eq!(data.into_values(), data_from_api); +} diff --git a/src/lib.rs b/src/lib.rs index c3bc593..670564a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -21,6 +21,8 @@ //! The client-driver is distributed under the liberal [Apache-2.0 License](https://www.apache.org/licenses/LICENSE-2.0) and hence //! you can use it in your applications without any licensing issues. //! +//! **📁 You can [find some usage examples in this folder here](https://github.com/skytable/client-rust/tree/v0.8.11/examples)**. +//! //! ## Definitive example //! //! ```no_run @@ -35,7 +37,7 @@ //! userid: String, //! pass: String, //! followers: u64, -//! email: Option +//! email: Option, //! } //! //! let our_user = User { userid: "user".into(), pass: "pass".into(), followers: 120, email: None }; diff --git a/src/query.rs b/src/query.rs index 8fb0e33..0de6722 100644 --- a/src/query.rs +++ b/src/query.rs @@ -290,6 +290,12 @@ where } } +impl<'a, T: SQParam> SQParam for &'a T { + fn append_param(&self, q: &mut Vec) -> usize { + T::append_param(self, q) + } +} + /// Use this when you need to use `null` pub struct Null; impl SQParam for Null { @@ -350,14 +356,6 @@ impl SQParam for [u8; N] { 1 } } -impl<'a, const N: usize> SQParam for &'a [u8; N] { - fn append_param(&self, buf: &mut Vec) -> usize { - buf.push(5); - pushlen!(buf, self.len()); - buf.extend(*self); - 1 - } -} impl SQParam for Vec { fn append_param(&self, buf: &mut Vec) -> usize { buf.push(5); @@ -366,11 +364,6 @@ impl SQParam for Vec { 1 } } -impl<'a> SQParam for &'a Vec { - fn append_param(&self, q: &mut Vec) -> usize { - self.as_slice().append_param(q) - } -} // str impl<'a> SQParam for &'a str { fn append_param(&self, buf: &mut Vec) -> usize { @@ -380,11 +373,6 @@ impl<'a> SQParam for &'a str { 1 } } -impl<'a> SQParam for &'a String { - fn append_param(&self, q: &mut Vec) -> usize { - self.as_str().append_param(q) - } -} impl SQParam for String { fn append_param(&self, buf: &mut Vec) -> usize { self.as_str().append_param(buf) diff --git a/src/response.rs b/src/response.rs index 5ed2aaf..5a4f285 100644 --- a/src/response.rs +++ b/src/response.rs @@ -414,7 +414,7 @@ impl Deref for Rows { /// A list received from a response #[derive(Debug, PartialEq, Clone)] -pub struct RList(Vec); +pub struct RList(Vec); impl From> for RList { fn from(values: Vec) -> Self {