use self::query::ValidQuery;
use crate::api::opt;
use crate::api::opt::auth;
use crate::api::opt::auth::Credentials;
use crate::api::opt::auth::Jwt;
use crate::api::opt::IntoEndpoint;
use crate::api::Connect;
use crate::api::Connection;
use crate::api::OnceLockExt;
use crate::api::Surreal;
use crate::opt::IntoExportDestination;
use crate::opt::WaitFor;
use serde::Serialize;
use std::borrow::Cow;
use std::marker::PhantomData;
use std::path::Path;
use std::pin::Pin;
use std::sync::Arc;
use std::sync::OnceLock;
use std::time::Duration;
use surrealdb_core::sql::to_value as to_core_value;
pub(crate) mod live;
pub(crate) mod query;
mod authenticate;
mod begin;
mod cancel;
mod commit;
mod content;
mod create;
mod delete;
mod export;
mod health;
mod import;
mod insert;
mod insert_relation;
mod invalidate;
mod merge;
mod patch;
mod run;
mod select;
mod set;
mod signin;
mod signup;
mod unset;
mod update;
mod upsert;
mod use_db;
mod use_ns;
mod version;
#[cfg(test)]
mod tests;
pub use authenticate::Authenticate;
#[doc(hidden)]
pub use begin::Begin;
#[doc(hidden)]
pub use begin::Transaction;
#[doc(hidden)]
pub use cancel::Cancel;
#[doc(hidden)]
pub use commit::Commit;
pub use content::Content;
pub use create::Create;
pub use delete::Delete;
pub use export::{Backup, Export};
use futures::Future;
pub use health::Health;
pub use import::Import;
pub use insert::Insert;
pub use invalidate::Invalidate;
pub use live::Stream;
pub use merge::Merge;
pub use patch::Patch;
pub use query::Query;
pub use query::QueryStream;
pub use run::IntoFn;
pub use run::Run;
pub use select::Select;
use serde_content::Serializer;
pub use set::Set;
pub use signin::Signin;
pub use signup::Signup;
use tokio::sync::watch;
pub use unset::Unset;
pub use update::Update;
pub use upsert::Upsert;
pub use use_db::UseDb;
pub use use_ns::UseNs;
pub use version::Version;
use super::opt::CreateResource;
use super::opt::IntoResource;
pub(crate) type BoxFuture<'a, T> = Pin<Box<dyn Future<Output = T> + Send + Sync + 'a>>;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[non_exhaustive]
pub struct Stats {
pub execution_time: Option<Duration>,
}
pub struct Model;
pub struct ExportConfig;
pub struct Live;
#[derive(Debug)]
pub struct WithStats<T>(pub T);
impl<C> Surreal<C>
where
C: Connection,
{
pub fn init() -> Self {
Self {
router: Arc::new(OnceLock::new()),
waiter: Arc::new(watch::channel(None)),
engine: PhantomData,
}
}
pub fn new<P>(address: impl IntoEndpoint<P, Client = C>) -> Connect<C, Self> {
Connect {
router: Arc::new(OnceLock::new()),
engine: PhantomData,
address: address.into_endpoint(),
capacity: 0,
waiter: Arc::new(watch::channel(None)),
response_type: PhantomData,
}
}
#[doc(hidden)]
#[cfg(surrealdb_unstable)] pub fn transaction(self) -> Begin<C> {
warn!("Client side transactions are not yet supported. This API doesn't do anything yet.");
Begin {
client: self,
}
}
pub fn use_ns(&self, ns: impl Into<String>) -> UseNs<C> {
UseNs {
client: Cow::Borrowed(self),
ns: ns.into(),
}
}
pub fn use_db(&self, db: impl Into<String>) -> UseDb<C> {
UseDb {
client: Cow::Borrowed(self),
ns: None,
db: db.into(),
}
}
pub fn set(&self, key: impl Into<String>, value: impl Serialize + 'static) -> Set<C> {
Set {
client: Cow::Borrowed(self),
key: key.into(),
value: to_core_value(value).map_err(Into::into),
}
}
pub fn unset(&self, key: impl Into<String>) -> Unset<C> {
Unset {
client: Cow::Borrowed(self),
key: key.into(),
}
}
pub fn signup<R>(&self, credentials: impl Credentials<auth::Signup, R>) -> Signup<C, R> {
Signup {
client: Cow::Borrowed(self),
credentials: Serializer::new().serialize(credentials),
response_type: PhantomData,
}
}
pub fn signin<R>(&self, credentials: impl Credentials<auth::Signin, R>) -> Signin<C, R> {
Signin {
client: Cow::Borrowed(self),
credentials: Serializer::new().serialize(credentials),
response_type: PhantomData,
}
}
pub fn invalidate(&self) -> Invalidate<C> {
Invalidate {
client: Cow::Borrowed(self),
}
}
pub fn authenticate(&self, token: impl Into<Jwt>) -> Authenticate<C> {
Authenticate {
client: Cow::Borrowed(self),
token: token.into(),
}
}
pub fn query(&self, query: impl opt::IntoQuery) -> Query<C> {
let inner = query.into_query().map(|x| ValidQuery {
client: Cow::Borrowed(self),
query: x,
bindings: Default::default(),
register_live_queries: true,
});
Query {
inner,
}
}
pub fn select<O>(&self, resource: impl IntoResource<O>) -> Select<C, O> {
Select {
client: Cow::Borrowed(self),
resource: resource.into_resource(),
response_type: PhantomData,
query_type: PhantomData,
}
}
pub fn create<R>(&self, resource: impl CreateResource<R>) -> Create<C, R> {
Create {
client: Cow::Borrowed(self),
resource: resource.into_resource(),
response_type: PhantomData,
}
}
pub fn insert<O>(&self, resource: impl IntoResource<O>) -> Insert<C, O> {
Insert {
client: Cow::Borrowed(self),
resource: resource.into_resource(),
response_type: PhantomData,
}
}
pub fn upsert<O>(&self, resource: impl IntoResource<O>) -> Upsert<C, O> {
Upsert {
client: Cow::Borrowed(self),
resource: resource.into_resource(),
response_type: PhantomData,
}
}
pub fn update<O>(&self, resource: impl IntoResource<O>) -> Update<C, O> {
Update {
client: Cow::Borrowed(self),
resource: resource.into_resource(),
response_type: PhantomData,
}
}
pub fn delete<O>(&self, resource: impl IntoResource<O>) -> Delete<C, O> {
Delete {
client: Cow::Borrowed(self),
resource: resource.into_resource(),
response_type: PhantomData,
}
}
pub fn version(&self) -> Version<C> {
Version {
client: Cow::Borrowed(self),
}
}
pub fn run<R>(&self, function: impl IntoFn) -> Run<C, R> {
Run {
client: Cow::Borrowed(self),
function: function.into_fn(),
args: Ok(serde_content::Value::Tuple(vec![])),
response_type: PhantomData,
}
}
pub fn health(&self) -> Health<C> {
Health {
client: Cow::Borrowed(self),
}
}
pub async fn wait_for(&self, event: WaitFor) {
let mut rx = self.waiter.0.subscribe();
rx.wait_for(|current| match current {
None => false,
Some(WaitFor::Connection) => matches!(event, WaitFor::Connection),
Some(WaitFor::Database) => matches!(event, WaitFor::Connection | WaitFor::Database),
})
.await
.ok();
}
pub fn export<R>(&self, target: impl IntoExportDestination<R>) -> Export<C, R> {
Export {
client: Cow::Borrowed(self),
target: target.into_export_destination(),
ml_config: None,
db_config: None,
response: PhantomData,
export_type: PhantomData,
}
}
pub fn import<P>(&self, file: P) -> Import<C>
where
P: AsRef<Path>,
{
Import {
client: Cow::Borrowed(self),
file: file.as_ref().to_owned(),
is_ml: false,
import_type: PhantomData,
}
}
}