Switch to std::sync::OnceLock
and fix Surreal::clone
(#2370)
This commit is contained in:
parent
4ae1a0d1a9
commit
61f4580ba8
25 changed files with 113 additions and 79 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -24,6 +24,7 @@ name = "actix-example"
|
|||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"actix-web",
|
||||
"once_cell",
|
||||
"serde",
|
||||
"surrealdb",
|
||||
"thiserror",
|
||||
|
|
|
@ -3,7 +3,7 @@ name = "surrealdb"
|
|||
publish = true
|
||||
edition = "2021"
|
||||
version = "1.0.0-beta.9"
|
||||
rust-version = "1.65.0"
|
||||
rust-version = "1.70.0"
|
||||
readme = "CARGO.md"
|
||||
authors = ["Tobie Morgan Hitchcock <tobie@surrealdb.com>"]
|
||||
description = "A scalable, distributed, collaborative, document-graph database, for the realtime web"
|
||||
|
|
|
@ -18,7 +18,6 @@ View the [features](https://surrealdb.com/features), the latest [releases](https
|
|||
- [x] Compiles to WebAssembly
|
||||
- [x] Supports typed SQL statements
|
||||
- [x] Invalid SQL queries are never sent to the server, the client uses the same parser the server uses
|
||||
- [x] Static clients, no need for `once_cell` or `lazy_static`
|
||||
- [x] Clonable connections with auto-reconnect capabilities, no need for a connection pool
|
||||
- [x] Range queries
|
||||
- [x] Consistent API across all supported protocols and storage engines
|
||||
|
|
|
@ -6,6 +6,7 @@ publish = false
|
|||
|
||||
[dependencies]
|
||||
actix-web = { version = "4.3.1", features = ["macros"] }
|
||||
once_cell = "1.18.0"
|
||||
serde = { version = "1.0.171", features = ["derive"] }
|
||||
surrealdb = { path = "../.." }
|
||||
thiserror = "1.0.43"
|
||||
|
|
|
@ -2,12 +2,13 @@ mod error;
|
|||
mod person;
|
||||
|
||||
use actix_web::{App, HttpServer};
|
||||
use once_cell::sync::Lazy;
|
||||
use surrealdb::engine::remote::ws::Client;
|
||||
use surrealdb::engine::remote::ws::Ws;
|
||||
use surrealdb::opt::auth::Root;
|
||||
use surrealdb::Surreal;
|
||||
|
||||
static DB: Surreal<Client> = Surreal::init();
|
||||
static DB: Lazy<Surreal<Client>> = Lazy::new(|| Surreal::init());
|
||||
|
||||
#[actix_web::main]
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
use once_cell::sync::Lazy;
|
||||
use surrealdb::engine::remote::ws::Client;
|
||||
use surrealdb::engine::remote::ws::Ws;
|
||||
use surrealdb::Surreal;
|
||||
use tokio::sync::mpsc;
|
||||
|
||||
static DB: Surreal<Client> = Surreal::init();
|
||||
static DB: Lazy<Surreal<Client>> = Lazy::new(|| Surreal::init());
|
||||
|
||||
const NUM: usize = 100_000;
|
||||
|
||||
|
|
|
@ -125,6 +125,8 @@ use crate::api::Result;
|
|||
use crate::api::Surreal;
|
||||
use crate::iam::Level;
|
||||
use std::marker::PhantomData;
|
||||
use std::sync::Arc;
|
||||
use std::sync::OnceLock;
|
||||
use url::Url;
|
||||
|
||||
/// A trait for converting inputs to a server address object
|
||||
|
@ -583,10 +585,11 @@ impl Surreal<Any> {
|
|||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// use once_cell::sync::Lazy;
|
||||
/// use surrealdb::Surreal;
|
||||
/// use surrealdb::engine::any::Any;
|
||||
///
|
||||
/// static DB: Surreal<Any> = Surreal::init();
|
||||
/// static DB: Lazy<Surreal<Any>> = Lazy::new(|| Surreal::init());
|
||||
///
|
||||
/// # #[tokio::main]
|
||||
/// # async fn main() -> surrealdb::Result<()> {
|
||||
|
@ -596,7 +599,7 @@ impl Surreal<Any> {
|
|||
/// ```
|
||||
pub fn connect(&self, address: impl IntoEndpoint) -> Connect<Any, ()> {
|
||||
Connect {
|
||||
router: Some(&self.router),
|
||||
router: self.router.clone(),
|
||||
address: address.into_endpoint(),
|
||||
capacity: 0,
|
||||
client: PhantomData,
|
||||
|
@ -643,9 +646,9 @@ impl Surreal<Any> {
|
|||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
pub fn connect(address: impl IntoEndpoint) -> Connect<'static, Any, Surreal<Any>> {
|
||||
pub fn connect(address: impl IntoEndpoint) -> Connect<Any, Surreal<Any>> {
|
||||
Connect {
|
||||
router: None,
|
||||
router: Arc::new(OnceLock::new()),
|
||||
address: address.into_endpoint(),
|
||||
capacity: 0,
|
||||
client: PhantomData,
|
||||
|
|
|
@ -16,12 +16,12 @@ use crate::api::opt::Tls;
|
|||
use crate::api::DbResponse;
|
||||
#[allow(unused_imports)] // used by the DB engines
|
||||
use crate::api::ExtraFeatures;
|
||||
use crate::api::OnceLockExt;
|
||||
use crate::api::Result;
|
||||
use crate::api::Surreal;
|
||||
#[allow(unused_imports)]
|
||||
use crate::error::Db as DbError;
|
||||
use flume::Receiver;
|
||||
use once_cell::sync::OnceCell;
|
||||
#[cfg(feature = "protocol-http")]
|
||||
use reqwest::ClientBuilder;
|
||||
use std::collections::HashSet;
|
||||
|
@ -30,6 +30,7 @@ use std::marker::PhantomData;
|
|||
use std::pin::Pin;
|
||||
use std::sync::atomic::AtomicI64;
|
||||
use std::sync::Arc;
|
||||
use std::sync::OnceLock;
|
||||
#[cfg(feature = "protocol-ws")]
|
||||
use tokio_tungstenite::tungstenite::protocol::WebSocketConfig;
|
||||
#[cfg(feature = "protocol-ws")]
|
||||
|
@ -211,7 +212,7 @@ impl Connection for Any {
|
|||
}
|
||||
|
||||
Ok(Surreal {
|
||||
router: OnceCell::with_value(Arc::new(Router {
|
||||
router: Arc::new(OnceLock::with_value(Router {
|
||||
features,
|
||||
conn: PhantomData,
|
||||
sender: route_tx,
|
||||
|
|
|
@ -9,17 +9,18 @@ use crate::api::engine::any::Any;
|
|||
use crate::api::err::Error;
|
||||
use crate::api::opt::Endpoint;
|
||||
use crate::api::DbResponse;
|
||||
use crate::api::OnceLockExt;
|
||||
use crate::api::Result;
|
||||
use crate::api::Surreal;
|
||||
use crate::error::Db as DbError;
|
||||
use flume::Receiver;
|
||||
use once_cell::sync::OnceCell;
|
||||
use std::collections::HashSet;
|
||||
use std::future::Future;
|
||||
use std::marker::PhantomData;
|
||||
use std::pin::Pin;
|
||||
use std::sync::atomic::AtomicI64;
|
||||
use std::sync::Arc;
|
||||
use std::sync::OnceLock;
|
||||
|
||||
impl crate::api::Connection for Any {}
|
||||
|
||||
|
@ -161,7 +162,7 @@ impl Connection for Any {
|
|||
}
|
||||
|
||||
Ok(Surreal {
|
||||
router: OnceCell::with_value(Arc::new(Router {
|
||||
router: Arc::new(OnceLock::with_value(Router {
|
||||
features,
|
||||
conn: PhantomData,
|
||||
sender: route_tx,
|
||||
|
|
|
@ -77,11 +77,12 @@ use tokio::io::AsyncWriteExt;
|
|||
/// Instantiating a global instance
|
||||
///
|
||||
/// ```
|
||||
/// use once_cell::sync::Lazy;
|
||||
/// use surrealdb::{Result, Surreal};
|
||||
/// use surrealdb::engine::local::Db;
|
||||
/// use surrealdb::engine::local::Mem;
|
||||
///
|
||||
/// static DB: Surreal<Db> = Surreal::init();
|
||||
/// static DB: Lazy<Surreal<Db>> = Lazy::new(|| Surreal::init());
|
||||
///
|
||||
/// #[tokio::main]
|
||||
/// async fn main() -> Result<()> {
|
||||
|
@ -343,7 +344,7 @@ impl Surreal<Db> {
|
|||
/// Connects to a specific database endpoint, saving the connection on the static client
|
||||
pub fn connect<P>(&self, address: impl IntoEndpoint<P, Client = Db>) -> Connect<Db, ()> {
|
||||
Connect {
|
||||
router: Some(&self.router),
|
||||
router: self.router.clone(),
|
||||
address: address.into_endpoint(),
|
||||
capacity: 0,
|
||||
client: PhantomData,
|
||||
|
|
|
@ -8,6 +8,7 @@ use crate::api::engine::local::Db;
|
|||
use crate::api::err::Error;
|
||||
use crate::api::opt::Endpoint;
|
||||
use crate::api::ExtraFeatures;
|
||||
use crate::api::OnceLockExt;
|
||||
use crate::api::Result;
|
||||
use crate::api::Surreal;
|
||||
use crate::dbs::Session;
|
||||
|
@ -17,7 +18,6 @@ use crate::opt::auth::Root;
|
|||
use flume::Receiver;
|
||||
use flume::Sender;
|
||||
use futures::StreamExt;
|
||||
use once_cell::sync::OnceCell;
|
||||
use std::collections::BTreeMap;
|
||||
use std::collections::HashSet;
|
||||
use std::future::Future;
|
||||
|
@ -25,6 +25,7 @@ use std::marker::PhantomData;
|
|||
use std::pin::Pin;
|
||||
use std::sync::atomic::AtomicI64;
|
||||
use std::sync::Arc;
|
||||
use std::sync::OnceLock;
|
||||
|
||||
impl crate::api::Connection for Db {}
|
||||
|
||||
|
@ -55,7 +56,7 @@ impl Connection for Db {
|
|||
features.insert(ExtraFeatures::Backup);
|
||||
|
||||
Ok(Surreal {
|
||||
router: OnceCell::with_value(Arc::new(Router {
|
||||
router: Arc::new(OnceLock::with_value(Router {
|
||||
features,
|
||||
conn: PhantomData,
|
||||
sender: route_tx,
|
||||
|
|
|
@ -6,6 +6,7 @@ use crate::api::conn::Route;
|
|||
use crate::api::conn::Router;
|
||||
use crate::api::engine::local::Db;
|
||||
use crate::api::opt::Endpoint;
|
||||
use crate::api::OnceLockExt;
|
||||
use crate::api::Result;
|
||||
use crate::api::Surreal;
|
||||
use crate::dbs::Session;
|
||||
|
@ -15,7 +16,6 @@ use crate::opt::auth::Root;
|
|||
use flume::Receiver;
|
||||
use flume::Sender;
|
||||
use futures::StreamExt;
|
||||
use once_cell::sync::OnceCell;
|
||||
use std::collections::BTreeMap;
|
||||
use std::collections::HashSet;
|
||||
use std::future::Future;
|
||||
|
@ -23,6 +23,7 @@ use std::marker::PhantomData;
|
|||
use std::pin::Pin;
|
||||
use std::sync::atomic::AtomicI64;
|
||||
use std::sync::Arc;
|
||||
use std::sync::OnceLock;
|
||||
use wasm_bindgen_futures::spawn_local;
|
||||
|
||||
impl crate::api::Connection for Db {}
|
||||
|
@ -51,7 +52,7 @@ impl Connection for Db {
|
|||
conn_rx.into_recv_async().await??;
|
||||
|
||||
Ok(Surreal {
|
||||
router: OnceCell::with_value(Arc::new(Router {
|
||||
router: Arc::new(OnceLock::with_value(Router {
|
||||
features: HashSet::new(),
|
||||
conn: PhantomData,
|
||||
sender: route_tx,
|
||||
|
|
|
@ -76,11 +76,12 @@ impl Surreal<Client> {
|
|||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// use once_cell::sync::Lazy;
|
||||
/// use surrealdb::Surreal;
|
||||
/// use surrealdb::engine::remote::http::Client;
|
||||
/// use surrealdb::engine::remote::http::Http;
|
||||
///
|
||||
/// static DB: Surreal<Client> = Surreal::init();
|
||||
/// static DB: Lazy<Surreal<Client>> = Lazy::new(|| Surreal::init());
|
||||
///
|
||||
/// # #[tokio::main]
|
||||
/// # async fn main() -> surrealdb::Result<()> {
|
||||
|
@ -93,7 +94,7 @@ impl Surreal<Client> {
|
|||
address: impl IntoEndpoint<P, Client = Client>,
|
||||
) -> Connect<Client, ()> {
|
||||
Connect {
|
||||
router: Some(&self.router),
|
||||
router: self.router.clone(),
|
||||
address: address.into_endpoint(),
|
||||
capacity: 0,
|
||||
client: PhantomData,
|
||||
|
|
|
@ -9,12 +9,12 @@ use crate::api::opt::Endpoint;
|
|||
#[cfg(any(feature = "native-tls", feature = "rustls"))]
|
||||
use crate::api::opt::Tls;
|
||||
use crate::api::ExtraFeatures;
|
||||
use crate::api::OnceLockExt;
|
||||
use crate::api::Result;
|
||||
use crate::api::Surreal;
|
||||
use flume::Receiver;
|
||||
use futures::StreamExt;
|
||||
use indexmap::IndexMap;
|
||||
use once_cell::sync::OnceCell;
|
||||
use reqwest::header::HeaderMap;
|
||||
use reqwest::ClientBuilder;
|
||||
use std::collections::HashSet;
|
||||
|
@ -23,6 +23,7 @@ use std::marker::PhantomData;
|
|||
use std::pin::Pin;
|
||||
use std::sync::atomic::AtomicI64;
|
||||
use std::sync::Arc;
|
||||
use std::sync::OnceLock;
|
||||
use url::Url;
|
||||
|
||||
impl crate::api::Connection for Client {}
|
||||
|
@ -71,7 +72,7 @@ impl Connection for Client {
|
|||
features.insert(ExtraFeatures::Backup);
|
||||
|
||||
Ok(Surreal {
|
||||
router: OnceCell::with_value(Arc::new(Router {
|
||||
router: Arc::new(OnceLock::with_value(Router {
|
||||
features,
|
||||
conn: PhantomData,
|
||||
sender: route_tx,
|
||||
|
|
|
@ -6,13 +6,13 @@ use crate::api::conn::Param;
|
|||
use crate::api::conn::Route;
|
||||
use crate::api::conn::Router;
|
||||
use crate::api::opt::Endpoint;
|
||||
use crate::api::OnceLockExt;
|
||||
use crate::api::Result;
|
||||
use crate::api::Surreal;
|
||||
use flume::Receiver;
|
||||
use flume::Sender;
|
||||
use futures::StreamExt;
|
||||
use indexmap::IndexMap;
|
||||
use once_cell::sync::OnceCell;
|
||||
use reqwest::header::HeaderMap;
|
||||
use reqwest::ClientBuilder;
|
||||
use std::collections::HashSet;
|
||||
|
@ -21,6 +21,7 @@ use std::marker::PhantomData;
|
|||
use std::pin::Pin;
|
||||
use std::sync::atomic::AtomicI64;
|
||||
use std::sync::Arc;
|
||||
use std::sync::OnceLock;
|
||||
use url::Url;
|
||||
use wasm_bindgen_futures::spawn_local;
|
||||
|
||||
|
@ -50,7 +51,7 @@ impl Connection for Client {
|
|||
conn_rx.into_recv_async().await??;
|
||||
|
||||
Ok(Surreal {
|
||||
router: OnceCell::with_value(Arc::new(Router {
|
||||
router: Arc::new(OnceLock::with_value(Router {
|
||||
features: HashSet::new(),
|
||||
conn: PhantomData,
|
||||
sender: route_tx,
|
||||
|
|
|
@ -58,11 +58,12 @@ impl Surreal<Client> {
|
|||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// use once_cell::sync::Lazy;
|
||||
/// use surrealdb::Surreal;
|
||||
/// use surrealdb::engine::remote::ws::Client;
|
||||
/// use surrealdb::engine::remote::ws::Ws;
|
||||
///
|
||||
/// static DB: Surreal<Client> = Surreal::init();
|
||||
/// static DB: Lazy<Surreal<Client>> = Lazy::new(|| Surreal::init());
|
||||
///
|
||||
/// # #[tokio::main]
|
||||
/// # async fn main() -> surrealdb::Result<()> {
|
||||
|
@ -75,7 +76,7 @@ impl Surreal<Client> {
|
|||
address: impl IntoEndpoint<P, Client = Client>,
|
||||
) -> Connect<Client, ()> {
|
||||
Connect {
|
||||
router: Some(&self.router),
|
||||
router: self.router.clone(),
|
||||
address: address.into_endpoint(),
|
||||
capacity: 0,
|
||||
client: PhantomData,
|
||||
|
|
|
@ -13,6 +13,7 @@ use crate::api::err::Error;
|
|||
use crate::api::opt::Endpoint;
|
||||
#[cfg(any(feature = "native-tls", feature = "rustls"))]
|
||||
use crate::api::opt::Tls;
|
||||
use crate::api::OnceLockExt;
|
||||
use crate::api::Result;
|
||||
use crate::api::Surreal;
|
||||
use crate::engine::remote::ws::IntervalStream;
|
||||
|
@ -25,7 +26,6 @@ use futures::SinkExt;
|
|||
use futures::StreamExt;
|
||||
use futures_concurrency::stream::Merge as _;
|
||||
use indexmap::IndexMap;
|
||||
use once_cell::sync::OnceCell;
|
||||
use serde::Deserialize;
|
||||
use std::borrow::BorrowMut;
|
||||
use std::collections::hash_map::Entry;
|
||||
|
@ -38,6 +38,7 @@ use std::mem;
|
|||
use std::pin::Pin;
|
||||
use std::sync::atomic::AtomicI64;
|
||||
use std::sync::Arc;
|
||||
use std::sync::OnceLock;
|
||||
use tokio::net::TcpStream;
|
||||
use tokio::time;
|
||||
use tokio::time::MissedTickBehavior;
|
||||
|
@ -129,7 +130,7 @@ impl Connection for Client {
|
|||
router(url, maybe_connector, capacity, config, socket, route_rx);
|
||||
|
||||
Ok(Surreal {
|
||||
router: OnceCell::with_value(Arc::new(Router {
|
||||
router: Arc::new(OnceLock::with_value(Router {
|
||||
features: HashSet::new(),
|
||||
conn: PhantomData,
|
||||
sender: route_tx,
|
||||
|
|
|
@ -11,6 +11,7 @@ use crate::api::engine::remote::ws::PING_INTERVAL;
|
|||
use crate::api::engine::remote::ws::PING_METHOD;
|
||||
use crate::api::err::Error;
|
||||
use crate::api::opt::Endpoint;
|
||||
use crate::api::OnceLockExt;
|
||||
use crate::api::Result;
|
||||
use crate::api::Surreal;
|
||||
use crate::engine::remote::ws::IntervalStream;
|
||||
|
@ -23,7 +24,6 @@ use futures::SinkExt;
|
|||
use futures::StreamExt;
|
||||
use futures_concurrency::stream::Merge as _;
|
||||
use indexmap::IndexMap;
|
||||
use once_cell::sync::OnceCell;
|
||||
use pharos::Channel;
|
||||
use pharos::Observable;
|
||||
use pharos::ObserveConfig;
|
||||
|
@ -37,6 +37,7 @@ use std::marker::PhantomData;
|
|||
use std::pin::Pin;
|
||||
use std::sync::atomic::AtomicI64;
|
||||
use std::sync::Arc;
|
||||
use std::sync::OnceLock;
|
||||
use std::time::Duration;
|
||||
use trice::Instant;
|
||||
use wasm_bindgen_futures::spawn_local;
|
||||
|
@ -82,7 +83,7 @@ impl Connection for Client {
|
|||
conn_rx.into_recv_async().await??;
|
||||
|
||||
Ok(Surreal {
|
||||
router: OnceCell::with_value(Arc::new(Router {
|
||||
router: Arc::new(OnceLock::with_value(Router {
|
||||
features: HashSet::new(),
|
||||
conn: PhantomData,
|
||||
sender: route_tx,
|
||||
|
|
|
@ -72,15 +72,16 @@ use crate::api::opt::auth::Jwt;
|
|||
use crate::api::opt::IntoEndpoint;
|
||||
use crate::api::Connect;
|
||||
use crate::api::Connection;
|
||||
use crate::api::ExtractRouter;
|
||||
use crate::api::OnceLockExt;
|
||||
use crate::api::Surreal;
|
||||
use crate::sql::to_value;
|
||||
use crate::sql::Uuid;
|
||||
use crate::sql::Value;
|
||||
use once_cell::sync::OnceCell;
|
||||
use serde::Serialize;
|
||||
use std::marker::PhantomData;
|
||||
use std::path::Path;
|
||||
use std::sync::Arc;
|
||||
use std::sync::OnceLock;
|
||||
|
||||
impl Method {
|
||||
#[allow(dead_code)] // used by `ws` and `http`
|
||||
|
@ -114,18 +115,19 @@ impl<C> Surreal<C>
|
|||
where
|
||||
C: Connection,
|
||||
{
|
||||
/// Creates a new static instance of the client
|
||||
/// Initialises a new unconnected instance of the client
|
||||
///
|
||||
/// The static singleton ensures that a single database instance is available across very large
|
||||
/// or complicated applications. With the singleton, only one connection to the database is
|
||||
/// instantiated, and the database connection does not have to be shared across components
|
||||
/// or controllers.
|
||||
/// This makes it easy to create a static singleton of the client. The static singleton
|
||||
/// ensures that a single database instance is available across very large or complicated
|
||||
/// applications. With the singleton, only one connection to the database is instantiated,
|
||||
/// and the database connection does not have to be shared across components or controllers.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Using a static, compile-time scheme
|
||||
///
|
||||
/// ```no_run
|
||||
/// use once_cell::sync::Lazy;
|
||||
/// use serde::{Serialize, Deserialize};
|
||||
/// use std::borrow::Cow;
|
||||
/// use surrealdb::Surreal;
|
||||
|
@ -134,7 +136,7 @@ where
|
|||
/// use surrealdb::engine::remote::ws::Client;
|
||||
///
|
||||
/// // Creates a new static instance of the client
|
||||
/// static DB: Surreal<Client> = Surreal::init();
|
||||
/// static DB: Lazy<Surreal<Client>> = Lazy::new(|| Surreal::init());
|
||||
///
|
||||
/// #[derive(Serialize, Deserialize)]
|
||||
/// struct Person {
|
||||
|
@ -168,6 +170,7 @@ where
|
|||
/// Using a dynamic, run-time scheme
|
||||
///
|
||||
/// ```no_run
|
||||
/// use once_cell::sync::Lazy;
|
||||
/// use serde::{Serialize, Deserialize};
|
||||
/// use std::borrow::Cow;
|
||||
/// use surrealdb::Surreal;
|
||||
|
@ -175,7 +178,7 @@ where
|
|||
/// use surrealdb::opt::auth::Root;
|
||||
///
|
||||
/// // Creates a new static instance of the client
|
||||
/// static DB: Surreal<Any> = Surreal::init();
|
||||
/// static DB: Lazy<Surreal<Any>> = Lazy::new(|| Surreal::init());
|
||||
///
|
||||
/// #[derive(Serialize, Deserialize)]
|
||||
/// struct Person {
|
||||
|
@ -205,9 +208,9 @@ where
|
|||
/// Ok(())
|
||||
/// }
|
||||
/// ```
|
||||
pub const fn init() -> Self {
|
||||
pub fn init() -> Self {
|
||||
Self {
|
||||
router: OnceCell::new(),
|
||||
router: Arc::new(OnceLock::new()),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -230,9 +233,9 @@ where
|
|||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
pub fn new<P>(address: impl IntoEndpoint<P, Client = C>) -> Connect<'static, C, Self> {
|
||||
pub fn new<P>(address: impl IntoEndpoint<P, Client = C>) -> Connect<C, Self> {
|
||||
Connect {
|
||||
router: None,
|
||||
router: Arc::new(OnceLock::new()),
|
||||
address: address.into_endpoint(),
|
||||
capacity: 0,
|
||||
client: PhantomData,
|
||||
|
|
|
@ -16,6 +16,7 @@ use crate::api::Response as QueryResponse;
|
|||
use crate::api::Surreal;
|
||||
use crate::sql::statements::BeginStatement;
|
||||
use crate::sql::statements::CommitStatement;
|
||||
use once_cell::sync::Lazy;
|
||||
use protocol::Client;
|
||||
use protocol::Test;
|
||||
use semver::Version;
|
||||
|
@ -23,7 +24,7 @@ use std::ops::Bound;
|
|||
use types::User;
|
||||
use types::USER;
|
||||
|
||||
static DB: Surreal<Client> = Surreal::init();
|
||||
static DB: Lazy<Surreal<Client>> = Lazy::new(|| Surreal::init());
|
||||
|
||||
#[tokio::test]
|
||||
async fn api() {
|
||||
|
|
|
@ -9,17 +9,18 @@ use crate::api::opt::Endpoint;
|
|||
use crate::api::opt::IntoEndpoint;
|
||||
use crate::api::Connect;
|
||||
use crate::api::ExtraFeatures;
|
||||
use crate::api::OnceLockExt;
|
||||
use crate::api::Result;
|
||||
use crate::api::Surreal;
|
||||
use crate::iam::Level;
|
||||
use flume::Receiver;
|
||||
use once_cell::sync::OnceCell;
|
||||
use std::collections::HashSet;
|
||||
use std::future::Future;
|
||||
use std::marker::PhantomData;
|
||||
use std::pin::Pin;
|
||||
use std::sync::atomic::AtomicI64;
|
||||
use std::sync::Arc;
|
||||
use std::sync::OnceLock;
|
||||
use url::Url;
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -52,7 +53,7 @@ impl Surreal<Client> {
|
|||
address: impl IntoEndpoint<P, Client = Client>,
|
||||
) -> Connect<Client, ()> {
|
||||
Connect {
|
||||
router: Some(&self.router),
|
||||
router: self.router.clone(),
|
||||
address: address.into_endpoint(),
|
||||
capacity: 0,
|
||||
client: PhantomData,
|
||||
|
@ -86,7 +87,7 @@ impl Connection for Client {
|
|||
};
|
||||
server::mock(route_rx);
|
||||
Ok(Surreal {
|
||||
router: OnceCell::with_value(Arc::new(router)),
|
||||
router: Arc::new(OnceLock::with_value(router)),
|
||||
})
|
||||
})
|
||||
}
|
||||
|
|
|
@ -13,7 +13,6 @@ use crate::api::conn::DbResponse;
|
|||
use crate::api::conn::Router;
|
||||
use crate::api::err::Error;
|
||||
use crate::api::opt::Endpoint;
|
||||
use once_cell::sync::OnceCell;
|
||||
use semver::BuildMetadata;
|
||||
use semver::VersionReq;
|
||||
use std::fmt::Debug;
|
||||
|
@ -22,6 +21,7 @@ use std::future::IntoFuture;
|
|||
use std::marker::PhantomData;
|
||||
use std::pin::Pin;
|
||||
use std::sync::Arc;
|
||||
use std::sync::OnceLock;
|
||||
|
||||
/// A specialized `Result` type
|
||||
pub type Result<T> = std::result::Result<T, crate::Error>;
|
||||
|
@ -34,15 +34,15 @@ pub trait Connection: conn::Connection {}
|
|||
/// The future returned when creating a new SurrealDB instance
|
||||
#[derive(Debug)]
|
||||
#[must_use = "futures do nothing unless you `.await` or poll them"]
|
||||
pub struct Connect<'r, C: Connection, Response> {
|
||||
router: Option<&'r OnceCell<Arc<Router<C>>>>,
|
||||
pub struct Connect<C: Connection, Response> {
|
||||
router: Arc<OnceLock<Router<C>>>,
|
||||
address: Result<Endpoint>,
|
||||
capacity: usize,
|
||||
client: PhantomData<C>,
|
||||
response_type: PhantomData<Response>,
|
||||
}
|
||||
|
||||
impl<C, R> Connect<'_, C, R>
|
||||
impl<C, R> Connect<C, R>
|
||||
where
|
||||
C: Connection,
|
||||
{
|
||||
|
@ -78,12 +78,12 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<'r, Client> IntoFuture for Connect<'r, Client, Surreal<Client>>
|
||||
impl<Client> IntoFuture for Connect<Client, Surreal<Client>>
|
||||
where
|
||||
Client: Connection,
|
||||
{
|
||||
type Output = Result<Surreal<Client>>;
|
||||
type IntoFuture = Pin<Box<dyn Future<Output = Self::Output> + Send + Sync + 'r>>;
|
||||
type IntoFuture = Pin<Box<dyn Future<Output = Self::Output> + Send + Sync>>;
|
||||
|
||||
fn into_future(self) -> Self::IntoFuture {
|
||||
Box::pin(async move {
|
||||
|
@ -94,32 +94,23 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<'r, Client> IntoFuture for Connect<'r, Client, ()>
|
||||
impl<Client> IntoFuture for Connect<Client, ()>
|
||||
where
|
||||
Client: Connection,
|
||||
{
|
||||
type Output = Result<()>;
|
||||
type IntoFuture = Pin<Box<dyn Future<Output = Self::Output> + Send + Sync + 'r>>;
|
||||
type IntoFuture = Pin<Box<dyn Future<Output = Self::Output> + Send + Sync>>;
|
||||
|
||||
fn into_future(self) -> Self::IntoFuture {
|
||||
Box::pin(async move {
|
||||
match self.router {
|
||||
Some(router) => {
|
||||
let option =
|
||||
Client::connect(self.address?, self.capacity).await?.router.into_inner();
|
||||
match option {
|
||||
Some(client) => {
|
||||
if router.set(client).is_ok() {
|
||||
let client = Surreal {
|
||||
router: router.clone(),
|
||||
};
|
||||
client.check_server_version().await?;
|
||||
}
|
||||
}
|
||||
None => unreachable!(),
|
||||
}
|
||||
}
|
||||
None => unreachable!(),
|
||||
let arc = Client::connect(self.address?, self.capacity).await?.router;
|
||||
let cell = Arc::into_inner(arc).expect("new connection to have no references");
|
||||
let router = cell.into_inner().expect("router to be set");
|
||||
if self.router.set(router).is_ok() {
|
||||
let client = Surreal {
|
||||
router: self.router,
|
||||
};
|
||||
client.check_server_version().await?;
|
||||
}
|
||||
Ok(())
|
||||
})
|
||||
|
@ -134,7 +125,7 @@ pub(crate) enum ExtraFeatures {
|
|||
/// A database client instance for embedded or remote databases
|
||||
#[derive(Debug)]
|
||||
pub struct Surreal<C: Connection> {
|
||||
router: OnceCell<Arc<Router<C>>>,
|
||||
router: Arc<OnceLock<Router<C>>>,
|
||||
}
|
||||
|
||||
impl<C> Surreal<C>
|
||||
|
@ -176,14 +167,22 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
trait ExtractRouter<C>
|
||||
trait OnceLockExt<C>
|
||||
where
|
||||
C: Connection,
|
||||
{
|
||||
fn with_value(value: Router<C>) -> OnceLock<Router<C>> {
|
||||
let cell = OnceLock::new();
|
||||
match cell.set(value) {
|
||||
Ok(()) => cell,
|
||||
Err(_) => unreachable!("don't have exclusive access to `cell`"),
|
||||
}
|
||||
}
|
||||
|
||||
fn extract(&self) -> Result<&Router<C>>;
|
||||
}
|
||||
|
||||
impl<C> ExtractRouter<C> for OnceCell<Arc<Router<C>>>
|
||||
impl<C> OnceLockExt<C> for OnceLock<Router<C>>
|
||||
where
|
||||
C: Connection,
|
||||
{
|
||||
|
|
|
@ -182,6 +182,19 @@ mod api_integration {
|
|||
};
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn surreal_clone() {
|
||||
use surrealdb::engine::any::Any;
|
||||
|
||||
let db: Surreal<Db> = Surreal::init();
|
||||
db.clone().connect::<Mem>(()).await.unwrap();
|
||||
db.use_ns("test").use_db("test").await.unwrap();
|
||||
|
||||
let db: Surreal<Any> = Surreal::init();
|
||||
db.clone().connect("memory").await.unwrap();
|
||||
db.use_ns("test").use_db("test").await.unwrap();
|
||||
}
|
||||
|
||||
include!("api/mod.rs");
|
||||
include!("api/backup.rs");
|
||||
}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
#[cfg(feature = "has-storage")]
|
||||
use crate::net::client_ip::ClientIp;
|
||||
#[cfg(feature = "has-storage")]
|
||||
use once_cell::sync::OnceCell;
|
||||
use std::sync::OnceLock;
|
||||
use std::{net::SocketAddr, path::PathBuf};
|
||||
|
||||
#[cfg(feature = "has-storage")]
|
||||
pub static CF: OnceCell<Config> = OnceCell::new();
|
||||
pub static CF: OnceLock<Config> = OnceLock::new();
|
||||
|
||||
use std::time::Duration;
|
||||
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
use crate::cli::CF;
|
||||
use crate::err::Error;
|
||||
use clap::Args;
|
||||
use once_cell::sync::OnceCell;
|
||||
use std::sync::OnceLock;
|
||||
use std::time::Duration;
|
||||
use surrealdb::kvs::Datastore;
|
||||
use surrealdb::opt::auth::Root;
|
||||
|
||||
pub static DB: OnceCell<Datastore> = OnceCell::new();
|
||||
pub static DB: OnceLock<Datastore> = OnceLock::new();
|
||||
|
||||
#[derive(Args, Debug)]
|
||||
pub struct StartCommandDbsOptions {
|
||||
|
|
Loading…
Reference in a new issue