Improve comments in public library package

This commit is contained in:
Tobie Morgan Hitchcock 2022-05-04 00:38:16 +01:00
parent 65d0e3138a
commit c5960a028e
6 changed files with 94 additions and 22 deletions

View file

@ -7,12 +7,18 @@ pub enum Level {
Sc,
}
/// Specifies the authentication level for the datastore execution context.
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd)]
pub enum Auth {
/// Specifies that the user is not authenticated
No,
/// Specifies that the user is authenticated with full root permissions
Kv,
/// Specifies that the user is has full permissions for a particular Namespace
Ns(String),
/// Specifies that the user is has full permissions for a particular Namespace and Database
Db(String, String),
/// Specifies that the user is has full permissions for a particular Namespace, Database, and Scope
Sc(String, String, String),
}
@ -23,7 +29,8 @@ impl Default for Auth {
}
impl Auth {
pub fn perms(&self) -> bool {
/// Checks whether permissions clauses need to be processed
pub(crate) fn perms(&self) -> bool {
match self {
Auth::No => true,
Auth::Sc(_, _, _) => true,
@ -32,7 +39,8 @@ impl Auth {
Auth::Kv => false,
}
}
pub fn check(&self, level: Level) -> bool {
/// Checks whether the current authentication matches the required level
pub(crate) fn check(&self, level: Level) -> bool {
match self {
Auth::No => matches!(level, Level::No),
Auth::Sc(_, _, _) => matches!(level, Level::No | Level::Sc),

View file

@ -4,6 +4,7 @@ use serde::ser::SerializeStruct;
use serde::Serialize;
use std::time::Duration;
/// The return value when running a query set on the database.
#[derive(Debug)]
pub struct Response {
pub sql: Option<String>,
@ -12,11 +13,11 @@ pub struct Response {
}
impl Response {
// Return the transaction speed
/// Return the transaction duration as a string
pub fn speed(&self) -> String {
format!("{:?}", self.time)
}
// Retrieve the response as a result
/// Retrieve the response as a result by reference
pub fn output(&self) -> Result<&Value, &Error> {
match &self.result {
Ok(v) => Ok(v),

View file

@ -3,29 +3,38 @@ use crate::dbs::Auth;
use crate::sql::value::Value;
use std::sync::Arc;
/// Specifies the current session information when processing a query.
#[derive(Clone, Debug, Default, Eq, PartialEq)]
pub struct Session {
pub au: Arc<Auth>, // Authentication info
pub ip: Option<String>, // Session ip address
pub or: Option<String>, // Session origin
pub id: Option<String>, // Session id
pub ns: Option<String>, // Namespace
pub db: Option<String>, // Database
pub sc: Option<String>, // Scope
pub sd: Option<Value>, // Scope auth data
/// The current [`Auth`] information
pub au: Arc<Auth>,
/// The current connection IP address
pub ip: Option<String>,
/// The current connection origin
pub or: Option<String>,
/// The current connection ID
pub id: Option<String>,
/// THe currently selected namespace
pub ns: Option<String>,
/// THe currently selected database
pub db: Option<String>,
/// The currently selected authentication scope
pub sc: Option<String>,
/// The current scope authentication data
pub sd: Option<Value>,
}
impl Session {
// Retrieves the selected namespace
pub fn ns(&self) -> Option<Arc<String>> {
pub(crate) fn ns(&self) -> Option<Arc<String>> {
self.ns.to_owned().map(Arc::new)
}
// Retrieves the selected database
pub fn db(&self) -> Option<Arc<String>> {
pub(crate) fn db(&self) -> Option<Arc<String>> {
self.db.to_owned().map(Arc::new)
}
// Convert a session into a runtime
pub fn context(&self, mut ctx: Context) -> Context {
pub(crate) fn context(&self, mut ctx: Context) -> Context {
// Add session value
let key = String::from("session");
let val: Value = self.into();

View file

@ -20,35 +20,47 @@ use indxdb::err::Error as IndxDBError;
#[cfg(feature = "parallel")]
use tokio::sync::mpsc::error::SendError as TokioError;
/// An error originating from the SurrealDB client library.
#[derive(Error, Debug)]
pub enum Error {
/// This error is used for ignoring a document when processing a query
#[doc(hidden)]
#[error("Conditional clause is not truthy")]
Ignore,
/// There was an error when connecting to the underlying datastore
#[error("Couldn't setup connection to underlying datastore")]
Ds,
/// There was an error when starting a new transaction
#[error("Couldn't create a database transaction")]
Tx,
/// The transaction was already cancelled or committed
#[error("Couldn't update a finished transaction")]
TxFinished,
/// The current transaction was created as read-only
#[error("Couldn't write to a read only transaction")]
TxReadonly,
/// The conditional value in the request was not equal
#[error("Value being checked was not correct")]
TxConditionNotMet,
/// No namespace has been selected
#[error("Specify a namespace to use")]
NsEmpty,
/// No database has been selected
#[error("Specify a database to use")]
DbEmpty,
/// No SQL query has been specified
#[error("Specify some SQL code to execute")]
QueryEmpty,
/// There was an error with the SQL query
#[error("Parse error on line {line} at character {char} when parsing '{sql}'")]
InvalidQuery {
line: usize,
@ -56,125 +68,154 @@ pub enum Error {
sql: String,
},
/// There was an error with the provided JSON Patch
#[error("The JSON Patch contains invalid operations. {message}")]
InvalidPatch {
message: String,
},
/// There was an error with the provided JavaScript code
#[error("Problem with embedded script function. {message}")]
InvalidScript {
message: String,
},
/// The wrong number of arguments was given for the specified function
#[error("Incorrect arguments for function {name}(). {message}")]
InvalidArguments {
name: String,
message: String,
},
/// The query timedout
#[error("Query timeout of {timer:?} exceeded")]
QueryTimeout {
timer: Duration,
},
/// The query did not execute, because the transaction was cancelled
#[error("Query not executed due to cancelled transaction")]
QueryCancelled,
/// The query did not execute, because the transaction has failed
#[error("Query not executed due to failed transaction")]
QueryNotExecuted,
/// The permissions do not allow for performing the specified query
#[error("You don't have permission to perform this query type")]
QueryPermissions,
/// The permissions do not allow for changing to the specified namespace
#[error("You don't have permission to change to the {ns} namespace")]
NsNotAllowed {
ns: String,
},
/// The permissions do not allow for changing to the specified database
#[error("You don't have permission to change to the {db} database")]
DbNotAllowed {
db: String,
},
/// The requested namespace does not exist
#[error("The namespace does not exist")]
NsNotFound,
/// The requested namespace token does not exist
#[error("The namespace token does not exist")]
NtNotFound,
/// The requested namespace login does not exist
#[error("The namespace login does not exist")]
NlNotFound,
/// The requested database does not exist
#[error("The database does not exist")]
DbNotFound,
/// The requested database token does not exist
#[error("The database token does not exist")]
DtNotFound,
/// The requested database login does not exist
#[error("The database login does not exist")]
DlNotFound,
/// The requested scope does not exist
#[error("The scope does not exist")]
ScNotFound,
/// The requested scope token does not exist
#[error("The scope token does not exist")]
StNotFound,
/// The requested table does not exist
#[error("The table does not exist")]
TbNotFound,
#[error("Too many recursive subqueries have been set")]
/// Too many recursive subqueries have been processed
#[error("Too many recursive subqueries have been processed")]
TooManySubqueries {
limit: usize,
},
/// Can not execute CREATE query using the specified value
#[error("Can not execute CREATE query using value '{value}'")]
CreateStatement {
value: Value,
},
/// Can not execute UPDATE query using the specified value
#[error("Can not execute UPDATE query using value '{value}'")]
UpdateStatement {
value: Value,
},
/// Can not execute RELATE query using the specified value
#[error("Can not execute RELATE query using value '{value}'")]
RelateStatement {
value: Value,
},
/// Can not execute DELETE query using the specified value
#[error("Can not execute DELETE query using value '{value}'")]
DeleteStatement {
value: Value,
},
/// Can not execute INSERT query using the specified value
#[error("Can not execute INSERT query using value '{value}'")]
InsertStatement {
value: Value,
},
/// The permissions do not allow this query to be run on this table
#[error("You don't have permission to run the `{query}` query on the `{table}` table")]
TablePermissions {
query: String,
table: String,
},
/// The specified table can not be written as it is setup as a foreign table view
#[error("Unable to write to the `{table}` table while setup as a view")]
TableIsView {
table: String,
},
/// A database entry for the specified record already exists
#[error("Database record `{thing}` already exists")]
RecordExists {
thing: Thing,
},
/// A database index entry for the specified record already exists
#[error("Database index `{index}` already contains `{thing}`")]
IndexExists {
index: String,
thing: Thing,
},
/// The specified field did not conform to the field ASSERT clause
#[error("Found '{value}' for field '{field}' but field must conform to: {check}")]
FieldValue {
value: Value,
@ -182,27 +223,34 @@ pub enum Error {
check: Value,
},
/// Represents an underlying error with Serde encoding / decoding
#[error("Serde error: {0}")]
Serde(#[from] SerdeError),
/// Represents an underlying error from the EchoDB instance
#[error("Key encoding error: {0}")]
Encode(#[from] EncodeError),
/// Represents an underlying error from the EchoDB instance
#[error("Key decoding error: {0}")]
Decode(#[from] DecodeError),
/// Represents an underlying error from the EchoDB instance
#[cfg(feature = "kv-echodb")]
#[error("Datastore error: {0}")]
EchoDB(#[from] EchoDBError),
/// Represents an underlying error from the IndxDB instance
#[cfg(feature = "kv-indxdb")]
#[error("Datastore error: {0}")]
IndxDB(#[from] IndxDBError),
/// Represents an underlying error from the TiKV instance
#[cfg(feature = "kv-tikv")]
#[error("Datastore error: {0}")]
TiKV(#[from] TiKVError),
/// Represents an underlying error with Tokio message channels
#[cfg(feature = "parallel")]
#[error("Tokio Error: {0}")]
Tokio(#[from] TokioError<(Option<Thing>, Value)>),

View file

@ -98,7 +98,7 @@ impl Datastore {
_ => unreachable!(),
}
}
/// Create a new transaction
/// Create a new transaction on this datastore
pub async fn transaction(&self, write: bool, lock: bool) -> Result<Transaction, Error> {
match &self.inner {
#[cfg(feature = "kv-echodb")]
@ -131,7 +131,7 @@ impl Datastore {
}
}
}
/// Execute a query
/// Parse and execute an SQL query
pub async fn execute(
&self,
txt: &str,
@ -158,7 +158,7 @@ impl Datastore {
opt.db = sess.db();
exe.execute(ctx, opt, ast).await
}
/// Execute a query
/// Execute a pre-parsed SQL query
pub async fn process(
&self,
ast: Query,

View file

@ -1,3 +1,11 @@
//! This library provides an easy-to-use client for [SurrealDB](https://surrealdb.com),
//! the ultimate cloud database for tomorrow's applications. SurrealDB is a scalable,
//! distributed, collaborative, document-graph database for the realtime web.
//!
//! This library can be used to start an embedded in-memory datastore, an embedded
//! datastore persisted to disk, or for connecting to a distributed [TiKV](https://tikv.org)
//! key-value store.
#![forbid(unsafe_code)]
#[macro_use]
@ -17,12 +25,10 @@ mod kvs;
pub mod sql;
pub use err::Error;
pub use dbs::Auth;
pub use dbs::Response;
pub use dbs::Session;
pub use err::Error;
pub use kvs::Datastore;
pub use kvs::Key;
pub use kvs::Transaction;