Skip to content

Commit

Permalink
feat: delete query
Browse files Browse the repository at this point in the history
  • Loading branch information
Fyko committed Sep 6, 2023
1 parent 9dc798b commit 96c2f12
Show file tree
Hide file tree
Showing 16 changed files with 330 additions and 142 deletions.
23 changes: 23 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Makefile.toml
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,12 @@ args = ["nextest", "run", "--workspace"]
[tasks.cov]
command = "cargo"
env = { "RUN_MODE" = "test" }
args = ["llvm-cov", "nextest", "${@}"]
args = ["llvm-cov", "nextest", "--workspace", "--exclude", "scyllax-macros", "${@}"]

[tasks.cov-ci]
command = "cargo"
env = { "RUN_MODE" = "ci" }
args = ["llvm-cov", "nextest", "--lcov", "--output-path", "lcov.info"]
args = ["llvm-cov", "nextest", "--workspace", "--exclude", "scyllax-macros", "--lcov", "--output-path", "lcov.info"]

[tasks.integration]
env = { "RUN_MODE" = "test", "RUST_LOG" = "info", "RUST_BACKTRACE" = 1 }
Expand Down
3 changes: 3 additions & 0 deletions example/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,6 @@ tokio = { workspace = true }
tracing = { workspace = true }
tracing-subscriber = { workspace = true }
uuid = { workspace = true }

[dev-dependencies]
pretty_assertions = "1"
194 changes: 70 additions & 124 deletions example/src/entities/person/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,136 +16,82 @@ pub struct PersonEntity {
pub created_at: i64,
}

// struct UpsertPerson {
// pub id: uuid::Uuid,
// pub email: MaybeUnset<String>,
// pub age: MaybeUnset<Option<i32>>,
// pub first_name: MaybeUnset<String>,
// }
#[cfg(test)]
mod test {
use super::PersonEntity;
use crate::entities::person::model::UpsertPerson;
use pretty_assertions::assert_eq;
use scyllax::prelude::*;

// TODO: macroify
// TODO: use insert if every field is a PK
// #[scyllax::async_trait]
// impl UpsertQuery<PersonEntity> for UpsertPerson {
// fn query(
// &self,
// ) -> Result<(String, scylla::frame::value::SerializedValues), BuildUpsertQueryError> {
// let mut query = String::from("update person set ");
// let mut variables = scylla::frame::value::SerializedValues::new();
#[test]
fn test_pks() {
assert_eq!(PersonEntity::pks(), vec!["id".to_string()]);
}

// if let MaybeUnset::Set(first_name) = &self.first_name {
// query.push_str(&format!(r##"first_name = ?, "##));
#[test]
fn test_keys() {
assert_eq!(
PersonEntity::keys(),
vec![
"id".to_string(),
"email".to_string(),
"age".to_string(),
"\"createdAt\"".to_string()
]
);
}

// match variables.add_value(first_name) {
// Ok(_) => (),
// Err(SerializeValuesError::TooManyValues) => {
// return Err(BuildUpsertQueryError::TooManyValues {
// field: "first_name".to_string(),
// })
// }
// Err(SerializeValuesError::MixingNamedAndNotNamedValues) => {
// return Err(BuildUpsertQueryError::MixingNamedAndNotNamedValues)
// }
// Err(SerializeValuesError::ValueTooBig(_)) => {
// return Err(BuildUpsertQueryError::ValueTooBig {
// field: "first_name".to_string(),
// })
// }
// Err(SerializeValuesError::ParseError) => {
// return Err(BuildUpsertQueryError::ParseError {
// field: "first_name".to_string(),
// })
// }
// }
// }
#[test]
fn test_upsert_v1() {
let upsert = UpsertPerson {
id: v1_uuid(),
email: MaybeUnset::Set("[email protected]".to_string()),
age: MaybeUnset::Set(Some(21)),
created_at: MaybeUnset::Unset,
};

// if let MaybeUnset::Set(email) = &self.email {
// query.push_str(r##"email = ?, "##);
// match variables.add_value(email) {
// Ok(_) => (),
// Err(SerializeValuesError::TooManyValues) => {
// return Err(BuildUpsertQueryError::TooManyValues {
// field: "email".to_string(),
// })
// }
// Err(SerializeValuesError::MixingNamedAndNotNamedValues) => {
// return Err(BuildUpsertQueryError::MixingNamedAndNotNamedValues)
// }
// Err(SerializeValuesError::ValueTooBig(_)) => {
// return Err(BuildUpsertQueryError::ValueTooBig {
// field: "email".to_string(),
// })
// }
// Err(SerializeValuesError::ParseError) => {
// return Err(BuildUpsertQueryError::ParseError {
// field: "email".to_string(),
// })
// }
// }
// }
let (query, values) = upsert.query().expect("failed to parse into query");

// if let MaybeUnset::Set(age) = &self.age {
// // age is also optional, so we have to unwrap it
// if let Some(age) = age {
// query.push_str("age = ?, ");
// match variables.add_value(age) {
// Ok(_) => (),
// Err(SerializeValuesError::TooManyValues) => {
// return Err(BuildUpsertQueryError::TooManyValues {
// field: "age".to_string(),
// })
// }
// Err(SerializeValuesError::MixingNamedAndNotNamedValues) => {
// return Err(BuildUpsertQueryError::MixingNamedAndNotNamedValues)
// }
// Err(SerializeValuesError::ValueTooBig(_)) => {
// return Err(BuildUpsertQueryError::ValueTooBig {
// field: "age".to_string(),
// })
// }
// Err(SerializeValuesError::ParseError) => {
// return Err(BuildUpsertQueryError::ParseError {
// field: "age".to_string(),
// })
// }
// }
// }
// }
assert_eq!(
query,
r#"update "person" set "email" = ?, "age" = ? where "id" = ?;"#
);

// query.pop();
// query.pop();
// query.push_str(" where id = ?;");
// match variables.add_value(&self.id) {
// Ok(_) => (),
// Err(SerializeValuesError::TooManyValues) => {
// return Err(BuildUpsertQueryError::TooManyValues {
// field: "id".to_string(),
// })
// }
// Err(SerializeValuesError::MixingNamedAndNotNamedValues) => {
// return Err(BuildUpsertQueryError::MixingNamedAndNotNamedValues)
// }
// Err(SerializeValuesError::ValueTooBig(_)) => {
// return Err(BuildUpsertQueryError::ValueTooBig {
// field: "id".to_string(),
// })
// }
// Err(SerializeValuesError::ParseError) => {
// return Err(BuildUpsertQueryError::ParseError {
// field: "id".to_string(),
// })
// }
// }
let mut result_values = SerializedValues::new();
result_values
.add_value(&upsert.email)
.expect("failed to add value");
result_values
.add_value(&upsert.age)
.expect("failed to add value");
result_values
.add_value(&upsert.id)
.expect("failed to add value");

// Ok((query, variables))
// }
assert_eq!(values, result_values);
}

// async fn execute(
// self,
// db: &scyllax::Executor,
// ) -> anyhow::Result<scylla::QueryResult, ScyllaxError> {
// let (query, values) = self.query()?;
#[test]
fn test_upsert_v2() {
let upsert = UpsertPerson {
id: v1_uuid(),
email: MaybeUnset::Set("[email protected]".to_string()),
age: MaybeUnset::Unset,
created_at: MaybeUnset::Unset,
};

// db.session.execute(query, values).await.map_err(|e| e.into())
// }
// }
let (query, values) = upsert.query().expect("failed to parse into query");

assert_eq!(query, r#"update "person" set "email" = ? where "id" = ?;"#);

let mut result_values = SerializedValues::new();
result_values
.add_value(&upsert.email)
.expect("failed to add value");
result_values
.add_value(&upsert.id)
.expect("failed to add value");

assert_eq!(values, result_values);
}
}
66 changes: 65 additions & 1 deletion example/src/entities/person/queries.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
use scyllax::prelude::*;
use scyllax::{delete_query, prelude::*};
use uuid::Uuid;

/// Load all queries for this entity
#[tracing::instrument(skip(db))]
pub async fn load(db: &mut Executor) -> anyhow::Result<()> {
let _ = GetPersonById::prepare(db).await;
let _ = GetPeopleByIds::prepare(db).await;
let _ = GetPersonByEmail::prepare(db).await;
let _ = DeletePersonById::prepare(db).await;

Ok(())
}
Expand Down Expand Up @@ -40,3 +43,64 @@ pub struct GetPersonByEmail {
/// The email address of the [`super::model::PersonEntity`] to get
pub email: String,
}

/// Get a [`super::model::PersonEntity`] by its [`uuid::Uuid`]
#[delete_query(

Check warning on line 48 in example/src/entities/person/queries.rs

View check run for this annotation

Codecov / codecov/patch

example/src/entities/person/queries.rs#L48

Added line #L48 was not covered by tests
query = "delete from person where id = ?",
entity_type = "super::model::PersonEntity"
)]
pub struct DeletePersonById {
/// The [`uuid::Uuid`] of the [`super::model::PersonEntity`] to get
pub id: Uuid,
}

#[cfg(test)]
mod test {
use super::*;
use scyllax::prelude::*;

Check warning on line 60 in example/src/entities/person/queries.rs

View workflow job for this annotation

GitHub Actions / Check Suite

unused import: `scyllax::prelude::*`

Check warning on line 60 in example/src/entities/person/queries.rs

View workflow job for this annotation

GitHub Actions / Check Suite

unused import: `scyllax::prelude::*`

#[test]
fn test_get_person_by_id() {
let _query = GetPersonById { id: v1_uuid() };

assert_eq!(
GetPersonById::query(),
r#"select id, email, age, "createdAt" from person where id = ? limit 1"#
);
}

#[test]
fn test_get_people_by_ids() {
let _query = GetPeopleByIds {
ids: vec![v1_uuid(), v1_uuid()],
limit: 10,
};

assert_eq!(
GetPeopleByIds::query(),
r#"select id, email, age, "createdAt" from person where id in ? limit ?"#
);
}

#[test]
fn test_get_person_by_email() {
let _query = GetPersonByEmail {
email: "[email protected]".to_string(),
};

assert_eq!(
GetPersonByEmail::query(),
r#"select id, email, age, "createdAt" from person_by_email where email = ? limit 1"#
);
}

#[test]
fn test_delete_person_by_id() {
let _query = DeletePersonById { id: v1_uuid() };

assert_eq!(
DeletePersonById::query(),
r#"delete from person where id = ?"#
);
}
}
Loading

0 comments on commit 96c2f12

Please sign in to comment.