SurrealDB in-memory with SQL demo in Rust - CREATE (INSERT), SELECT, UPDATE, DELETE
-
Mem
-
DEFINE
-
CREATE
-
SELECT
-
UPDATE
-
DELETE
-
surrealdb::Result
-
First think would be to authenticate, but we are skipping that in these examples
-
then select the namespace and the database.
-
There can be as many namespaces as you want and each namespace can have multipled databases.
-
A namespace migh correspond to a department in a company and each database is for a product or (micro)service.
use serde::Deserialize;
use surrealdb::engine::local::{Db, Mem};
use surrealdb::Surreal;
#[derive(Debug, Deserialize)]
struct Person {
name: String,
phone: String,
}
#[tokio::main]
async fn main() -> surrealdb::Result<()> {
let db = Surreal::new::<Mem>(()).await?;
db.use_ns("namespace").use_db("database").await?;
let _response = db
.query("DEFINE INDEX person_email ON TABLE person COLUMNS name UNIQUE")
.await?;
let data = vec![("Joe", "123"), ("Jane", "456"), ("Jil", "789")];
create(&db, data).await?;
let all = get_all(&db).await?;
assert_eq!(all[0].name, "Jane");
assert_eq!(all[0].phone, "456");
assert_eq!(all[1].name, "Jil");
assert_eq!(all[1].phone, "789");
assert_eq!(all[2].name, "Joe");
assert_eq!(all[2].phone, "123");
list_all(all);
update(&db).await?;
let all = get_all(&db).await?;
list_all(all);
delete(&db).await?;
let all = get_all(&db).await?;
list_all(all);
match create(&db, vec![("Joe", "7777777")]).await {
Ok(_) => println!("this will not happen as the previous statement returns an Error"),
Err(err) => println!("The Error: {err}"),
};
println!("-------------");
let all = get_all(&db).await?;
list_all(all);
Ok(())
}
async fn create(db: &Surreal<Db>, data: Vec<(&str, &str)>) -> surrealdb::Result<()> {
for (name, phone) in data {
let response = db
.query("CREATE person SET name=$name, phone=$phone")
.bind(("name", name.to_owned()))
.bind(("phone", phone.to_owned()))
.await?;
match response.check() {
Ok(_) => {}
Err(err) => {
println!("Could not add person: '{}'", err);
return Err(err);
}
};
}
Ok(())
}
async fn get_all(db: &Surreal<Db>) -> surrealdb::Result<Vec<Person>> {
let mut entries = db
.query("SELECT name, phone FROM type::table($table) ORDER BY name ASC")
.bind(("table", "person"))
.await?;
let entries: Vec<Person> = entries.take(0)?;
Ok(entries)
}
fn list_all(entries: Vec<Person>) {
for entry in entries {
println!("{}: {}", entry.name, entry.phone);
}
println!("-------------");
}
async fn update(db: &Surreal<Db>) -> surrealdb::Result<()> {
let name = "Jane";
let phone = "55555555";
let response = db
.query("UPDATE entry SET phone=$phone WHERE name=$name")
.bind(("name", name))
.bind(("phone", phone))
.await?;
match response.check() {
Ok(_) => Ok(()),
Err(err) => {
eprintln!("Could not update entry {}", err);
Err(err)
}
}
}
async fn delete(db: &Surreal<Db>) -> surrealdb::Result<()> {
let name = "Jane";
let response = db
.query("DELETE entry WHERE name=$name")
.bind(("name", name))
.await?;
match response.check() {
Ok(_) => Ok(()),
Err(err) => {
eprintln!("Could not delete entry {}", err);
Err(err)
}
}
}
cargo run -q > out.out 2>&1
Jane: 456
Jil: 789
Joe: 123
-------------
Jane: 456
Jil: 789
Joe: 123
-------------
Jane: 456
Jil: 789
Joe: 123
-------------
Could not add person: 'Database index `person_email` already contains 'Joe', with record `person:kurmttdvdvv9u7x5i83w`'
The Error: Database index `person_email` already contains 'Joe', with record `person:kurmttdvdvv9u7x5i83w`
-------------
Jane: 456
Jil: 789
Joe: 123
-------------