Update create API ()

This commit is contained in:
Rushmore Mushambi 2024-09-04 13:48:31 +01:00 committed by GitHub
parent ebe8d49ed9
commit 29c6914b04
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 101 additions and 58 deletions
sdk
benches/sdb_benches/sdk/routines
examples/fetch
src/api/method
tests

View file

@ -33,7 +33,7 @@ impl super::Routine for Create {
let data = data.clone(); let data = data.clone();
tasks.spawn(async move { tasks.spawn(async move {
let res: Vec<Record> = criterion::black_box( let res: Option<Record> = criterion::black_box(
client client
.create(table_name) .create(table_name)
.content(data) .content(data)
@ -41,12 +41,7 @@ impl super::Routine for Create {
.expect("[run] record creation failed"), .expect("[run] record creation failed"),
); );
assert_eq!( res.expect("[run] record creation should return a result");
res.len(),
1,
"[run] expected record creation to return 1 record, got {}",
res.len()
);
}); });
} }

View file

@ -56,7 +56,7 @@ async fn main() -> surrealdb::Result<()> {
db.use_ns("namespace").use_db("database").await?; db.use_ns("namespace").use_db("database").await?;
// Create a dance class and store the result // Create a dance class and store the result
let classes: Vec<DanceClass> = db let classes: Option<DanceClass> = db
.create(DANCE) .create(DANCE)
.content(DanceClass { .content(DanceClass {
id: Thing::from((DANCE, Id::rand())), id: Thing::from((DANCE, Id::rand())),

View file

@ -83,18 +83,68 @@ where
Client: Connection, Client: Connection,
R: DeserializeOwned, R: DeserializeOwned,
{ {
type Output = Result<Vec<R>>; type Output = Result<Option<R>>;
type IntoFuture = BoxFuture<'r, Self::Output>; type IntoFuture = BoxFuture<'r, Self::Output>;
into_future! {execute_vec} into_future! {execute_opt}
} }
impl<'r, C, R> Create<'r, C, R> impl<'r, C> Create<'r, C, Value>
where where
C: Connection, C: Connection,
{ {
/// Sets content of a record /// Sets content of a record
pub fn content<D>(self, data: D) -> Content<'r, C, R> pub fn content<D>(self, data: D) -> Content<'r, C, Value>
where
D: Serialize + 'static,
{
Content::from_closure(self.client, || {
let content = to_core_value(data)?;
let data = match content {
CoreValue::None | CoreValue::Null => None,
content => Some(content),
};
Ok(Command::Create {
what: self.resource?,
data,
})
})
}
}
impl<'r, C, R> Create<'r, C, Option<R>>
where
C: Connection,
{
/// Sets content of a record
pub fn content<D>(self, data: D) -> Content<'r, C, Option<R>>
where
D: Serialize + 'static,
{
Content::from_closure(self.client, || {
let content = to_core_value(data)?;
let data = match content {
CoreValue::None | CoreValue::Null => None,
content => Some(content),
};
Ok(Command::Create {
what: self.resource?,
data,
})
})
}
}
impl<'r, C, R> Create<'r, C, Vec<R>>
where
C: Connection,
{
/// Sets content of a record
pub fn content<D>(self, data: D) -> Content<'r, C, Option<R>>
where where
D: Serialize + 'static, D: Serialize + 'static,
{ {

View file

@ -733,7 +733,7 @@ where
/// db.use_ns("namespace").use_db("database").await?; /// db.use_ns("namespace").use_db("database").await?;
/// ///
/// // Create a record with a random ID /// // Create a record with a random ID
/// let person: Vec<Person> = db.create("person").await?; /// let person: Option<Person> = db.create("person").await?;
/// ///
/// // Create a record with a specific ID /// // Create a record with a specific ID
/// let record: Option<Person> = db.create(("person", "tobie")) /// let record: Option<Person> = db.create(("person", "tobie"))

View file

@ -111,9 +111,9 @@ async fn api() {
.unwrap(); .unwrap();
// create // create
let _: Vec<User> = DB.create(USER).await.unwrap(); let _: Option<User> = DB.create(USER).await.unwrap();
let _: Option<User> = DB.create((USER, "john")).await.unwrap(); let _: Option<User> = DB.create((USER, "john")).await.unwrap();
let _: Vec<User> = DB.create(USER).content(User::default()).await.unwrap(); let _: Option<User> = DB.create(USER).content(User::default()).await.unwrap();
let _: Option<User> = DB.create((USER, "john")).content(User::default()).await.unwrap(); let _: Option<User> = DB.create((USER, "john")).content(User::default()).await.unwrap();
// select // select

View file

@ -10,7 +10,7 @@ async fn export_import() {
let db_name = Ulid::new().to_string(); let db_name = Ulid::new().to_string();
db.use_ns(NS).use_db(&db_name).await.unwrap(); db.use_ns(NS).use_db(&db_name).await.unwrap();
for i in 0..10 { for i in 0..10 {
let _: Vec<ApiRecordId> = db let _: Option<ApiRecordId> = db
.create("user") .create("user")
.content(Record { .content(Record {
name: format!("User {i}"), name: format!("User {i}"),

View file

@ -35,12 +35,12 @@ async fn live_select_table() {
let mut users = db.select(&table).live().await.unwrap(); let mut users = db.select(&table).live().await.unwrap();
// Create a record // Create a record
let created: Vec<ApiRecordId> = db.create(table).await.unwrap(); let created: Option<ApiRecordId> = db.create(table).await.unwrap();
// Pull the notification // Pull the notification
let notification: Notification<ApiRecordId> = let notification: Notification<ApiRecordId> =
tokio::time::timeout(LQ_TIMEOUT, users.next()).await.unwrap().unwrap().unwrap(); tokio::time::timeout(LQ_TIMEOUT, users.next()).await.unwrap().unwrap().unwrap();
// The returned record should match the created record // The returned record should match the created record
assert_eq!(created, vec![notification.data.clone()]); assert_eq!(created, Some(notification.data.clone()));
// It should be newly created // It should be newly created
assert_eq!(notification.action, Action::Create); assert_eq!(notification.action, Action::Create);
@ -291,7 +291,7 @@ async fn live_select_query() {
// Create a record // Create a record
info!("Creating record"); info!("Creating record");
let created: Vec<ApiRecordId> = db.create(table).await.unwrap(); let created: Option<ApiRecordId> = db.create(table).await.unwrap();
// Pull the notification // Pull the notification
let notifications = receive_all_pending_notifications(users.clone(), LQ_TIMEOUT).await; let notifications = receive_all_pending_notifications(users.clone(), LQ_TIMEOUT).await;
// It should be newly created // It should be newly created
@ -302,7 +302,7 @@ async fn live_select_query() {
notifications notifications
); );
// The returned record should match the created record // The returned record should match the created record
assert_eq!(created, vec![notifications[0].data.clone()]); assert_eq!(created, Some(notifications[0].data.clone()));
// Update the record // Update the record
info!("Updating record"); info!("Updating record");
@ -368,12 +368,12 @@ async fn live_select_query() {
.unwrap(); .unwrap();
// Create a record // Create a record
let created: Vec<ApiRecordId> = db.create(table).await.unwrap(); let created: Option<ApiRecordId> = db.create(table).await.unwrap();
// Pull the notification // Pull the notification
let notification: Notification<ApiRecordId> = let notification: Notification<ApiRecordId> =
tokio::time::timeout(LQ_TIMEOUT, users.next()).await.unwrap().unwrap().unwrap(); tokio::time::timeout(LQ_TIMEOUT, users.next()).await.unwrap().unwrap().unwrap();
// The returned record should match the created record // The returned record should match the created record
assert_eq!(created, vec![notification.data.clone()]); assert_eq!(created, Some(notification.data.clone()));
// It should be newly created // It should be newly created
assert_eq!(notification.action, Action::Create, "{:?}", notification); assert_eq!(notification.action, Action::Create, "{:?}", notification);

View file

@ -441,7 +441,7 @@ async fn create_record_no_id() {
let (permit, db) = new_db().await; let (permit, db) = new_db().await;
db.use_ns(NS).use_db(Ulid::new().to_string()).await.unwrap(); db.use_ns(NS).use_db(Ulid::new().to_string()).await.unwrap();
drop(permit); drop(permit);
let _: Vec<ApiRecordId> = db.create("user").await.unwrap(); let _: Option<ApiRecordId> = db.create("user").await.unwrap();
let _: Value = db.create(Resource::from("user")).await.unwrap(); let _: Value = db.create(Resource::from("user")).await.unwrap();
} }
@ -460,7 +460,7 @@ async fn create_record_no_id_with_content() {
let (permit, db) = new_db().await; let (permit, db) = new_db().await;
db.use_ns(NS).use_db(Ulid::new().to_string()).await.unwrap(); db.use_ns(NS).use_db(Ulid::new().to_string()).await.unwrap();
drop(permit); drop(permit);
let _: Vec<ApiRecordId> = db let _: Option<ApiRecordId> = db
.create("user") .create("user")
.content(Record { .content(Record {
name: "John Doe".to_owned(), name: "John Doe".to_owned(),
@ -599,8 +599,8 @@ async fn select_table() {
db.use_ns(NS).use_db(Ulid::new().to_string()).await.unwrap(); db.use_ns(NS).use_db(Ulid::new().to_string()).await.unwrap();
drop(permit); drop(permit);
let table = "user"; let table = "user";
let _: Vec<ApiRecordId> = db.create(table).await.unwrap(); let _: Option<ApiRecordId> = db.create(table).await.unwrap();
let _: Vec<ApiRecordId> = db.create(table).await.unwrap(); let _: Option<ApiRecordId> = db.create(table).await.unwrap();
let _: Value = db.create(Resource::from(table)).await.unwrap(); let _: Value = db.create(Resource::from(table)).await.unwrap();
let users: Vec<ApiRecordId> = db.select(table).await.unwrap(); let users: Vec<ApiRecordId> = db.select(table).await.unwrap();
assert_eq!(users.len(), 3); assert_eq!(users.len(), 3);
@ -827,8 +827,8 @@ async fn update_table() {
db.use_ns(NS).use_db(Ulid::new().to_string()).await.unwrap(); db.use_ns(NS).use_db(Ulid::new().to_string()).await.unwrap();
drop(permit); drop(permit);
let table = "user"; let table = "user";
let _: Vec<ApiRecordId> = db.create(table).await.unwrap(); let _: Option<ApiRecordId> = db.create(table).await.unwrap();
let _: Vec<ApiRecordId> = db.create(table).await.unwrap(); let _: Option<ApiRecordId> = db.create(table).await.unwrap();
let _: Value = db.update(Resource::from(table)).await.unwrap(); let _: Value = db.update(Resource::from(table)).await.unwrap();
let users: Vec<ApiRecordId> = db.update(table).await.unwrap(); let users: Vec<ApiRecordId> = db.update(table).await.unwrap();
assert_eq!(users.len(), 2); assert_eq!(users.len(), 2);
@ -1072,9 +1072,9 @@ async fn delete_table() {
db.use_ns(NS).use_db(Ulid::new().to_string()).await.unwrap(); db.use_ns(NS).use_db(Ulid::new().to_string()).await.unwrap();
drop(permit); drop(permit);
let table = "user"; let table = "user";
let _: Vec<ApiRecordId> = db.create(table).await.unwrap(); let _: Option<ApiRecordId> = db.create(table).await.unwrap();
let _: Vec<ApiRecordId> = db.create(table).await.unwrap(); let _: Option<ApiRecordId> = db.create(table).await.unwrap();
let _: Vec<ApiRecordId> = db.create(table).await.unwrap(); let _: Option<ApiRecordId> = db.create(table).await.unwrap();
let users: Vec<ApiRecordId> = db.select(table).await.unwrap(); let users: Vec<ApiRecordId> = db.select(table).await.unwrap();
assert_eq!(users.len(), 3); assert_eq!(users.len(), 3);
let users: Vec<ApiRecordId> = db.delete(table).await.unwrap(); let users: Vec<ApiRecordId> = db.delete(table).await.unwrap();

View file

@ -922,8 +922,7 @@ async fn define_statement_index_concurrently_building_status() -> Result<(), Err
let mut r = ds.execute("INFO FOR INDEX test ON user", &session, None).await?; let mut r = ds.execute("INFO FOR INDEX test ON user", &session, None).await?;
let tmp = r.remove(0).result?; let tmp = r.remove(0).result?;
if let Value::Object(o) = &tmp { if let Value::Object(o) = &tmp {
if let Some(b) = o.get("building") { if let Some(Value::Object(b)) = o.get("building") {
if let Value::Object(b) = b {
if let Some(v) = b.get("status") { if let Some(v) = b.get("status") {
if Value::from("started").eq(v) { if Value::from("started").eq(v) {
continue; continue;
@ -957,7 +956,6 @@ async fn define_statement_index_concurrently_building_status() -> Result<(), Err
} }
} }
} }
}
panic!("Unexpected value {tmp:#}"); panic!("Unexpected value {tmp:#}");
} }
Ok(()) Ok(())