skytable/
lib.rs

1/*
2 * Copyright 2023, Sayan Nandan <nandansayan@outlook.com>
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15*/
16
17//! # Skytable driver
18//! [![Crates.io](https://img.shields.io/crates/v/skytable?style=flat-square)](https://crates.io/crates/skytable) [![Test](https://github.com/skytable/client-rust/actions/workflows/test.yml/badge.svg)](https://github.com/skytable/client-rust/actions/workflows/test.yml) [![docs.rs](https://img.shields.io/docsrs/skytable?style=flat-square)](https://docs.rs/skytable) [![GitHub release (latest SemVer including pre-releases)](https://img.shields.io/github/v/release/skytable/client-rust?include_prereleases&style=flat-square)](https://github.com/skytable/client-rust/releases)
19//!
20//! This is [Skytable](https://github.com/skytable/skytable)'s official client driver for Rust that you can use to build applications.
21//! The client-driver is distributed under the liberal [Apache-2.0 License](https://www.apache.org/licenses/LICENSE-2.0) and hence
22//! you can use it in your applications without any licensing issues.
23//!
24//! **📁 You can [find some usage examples in this folder here](https://github.com/skytable/client-rust/tree/v0.8.11/examples)**.
25//!
26//! ## Definitive example
27//!
28//! ```no_run
29//! use skytable::{
30//!     Query, Response, Config, query,
31//!     response::Rows,
32//! };
33//!
34//! #[derive(Query, Response)]
35//! #[derive(Clone, PartialEq, Debug)] // we just do these for the assert (they are not needed)
36//! struct User {
37//!     userid: String,
38//!     pass: String,
39//!     followers: u64,
40//!     email: Option<String>,
41//! }
42//!
43//! let our_user = User { userid: "user".into(), pass: "pass".into(), followers: 120, email: None };
44//!
45//! let mut db = Config::new_default("username", "password").connect().unwrap();
46//!
47//! // insert data
48//! let q = query!("insert into myspace.mymodel(?, ?, ?, ?)", our_user.clone());
49//! db.query_parse::<()>(&q).unwrap();
50//!
51//! // select data
52//! let user: User = db.query_parse(&query!("select * from myspace.mymodel where username = ?", &our_user.userid)).unwrap();
53//! assert_eq!(user, our_user);
54//!
55//! // select multiple rows
56//! let users: Rows<User> = db.query_parse(&query!("select all * from myspace.mymodel limit ?", 1000u64)).unwrap();
57//! assert_eq!(users[0].userid, "user");
58//! ```
59//!
60//! ## Getting started
61//!
62//! Make sure you have Skytable set up. If not, follow the [official installation guide here](https://docs.skytable.io/installation)
63//! and then come back here.
64//!
65//! Let's run our first query. Connections are set up using the [`Config`] object and then we establish a connection by calling
66//! [`Config::connect`] or use other functions for different connection configurations (for TLS or async).
67//!
68//! ```no_run
69//! use skytable::{Config, query};
70//! let mut db = Config::new_default("username", "password").connect().unwrap();
71//! // the query `sysctl report status` returns a `Response::Empty` indicating that everything is okay. This is equivalent to
72//! // rust's unit type `()` so that's what the driver uses
73//! db.query_parse::<()>(&query!("sysctl report status")).unwrap();
74//! ```
75//!
76//! We used the [`query!`] macro above which allows us to conveniently create queries when we don't need to handle complex
77//! cases and we have a fixed number of arguments.
78//!
79//! ## Diving in
80//!
81//! Now let's say that we have a model `create model myspace.mymodel(username: string, password: string, followers: uint64)`
82//! and we want to do some DML operations. Here's how we do it.
83//!
84//! ```no_run
85//! use skytable::{Config, query};
86//! let mut db = Config::new_default("username", "password").connect().unwrap();
87//!
88//! let insert_query = query!("insert into myspace.mymodel(?, ?, ?)", "sayan", "pass123", 1_500_000_u64);
89//! db.query_parse::<()>(&insert_query).unwrap(); // insert will return empty on success
90//!
91//! let select_query = query!("select password, followers FROM myspace.mymodel WHERE username = ?", "sayan");
92//! let (pass, followers): (String, u64) = db.query_parse(&select_query).unwrap();
93//! assert_eq!(pass, "pass123");
94//! assert_eq!(followers, 1_500_000_u64);
95//!
96//! let update_query = query!("update myspace.mymodel set followers += ? where username = ?", 1u64, "sayan");
97//! db.query_parse::<()>(&update_query).unwrap(); // update will return empty on success
98//! ```
99//!
100//! Now you're ready to run your own queries!
101//!
102//! ## Going advanced
103//!
104//! You can use the [`macro@Query`] and [`macro@Response`] derive macros to directly pass complex types as parameters
105//! and read as responses. This should cover most of the general use-cases (otherwise you can manually implement them).
106//!
107//! - Custom [`mod@query`] generation
108//! - Custom [`response`] parsing
109//! - [`Connection pooling`](pool)
110//!
111//! ## Need help? Get help!
112//!
113//! Jump into [Skytable's official Discord server](https://discord.com/invite/QptWFdx) where maintainers, developers and fellow
114//! users help each other out.
115//!
116
117#![deny(missing_docs)]
118
119// internal modules
120#[macro_use]
121mod macros;
122mod protocol;
123// public modules
124pub mod config;
125pub mod error;
126pub mod pool;
127pub mod query;
128pub mod response;
129/// The `Query` derive macro enables you to directly pass complex types as parameters into queries
130pub use sky_derive::Query;
131/// The `Response` derive macro enables you to directly pass complex types as parameters into queries
132pub use sky_derive::Response;
133// re-exports
134pub use {
135    config::Config,
136    error::ClientResult,
137    io::{
138        aio::{self, ConnectionAsync, ConnectionTlsAsync},
139        sync::{self as syncio, Connection, ConnectionTls},
140    },
141    query::{Pipeline, Query},
142};
143// private
144mod io;
145
146/// we use a 8KB read buffer by default; allow this to be changed
147const BUFSIZE: usize = 8 * 1024;