Compare commits
No commits in common. "a969acca6ad0aa8849b5bd41c491413f8532152d" and "d98570d50cc04fd06e9f7a274a4b89fe98d5cbbb" have entirely different histories.
a969acca6a
...
d98570d50c
@ -4,6 +4,8 @@ use syn::{parse_macro_input, Data, DeriveInput, Fields};
|
|||||||
|
|
||||||
// TODO: wrap functions in a trait
|
// TODO: wrap functions in a trait
|
||||||
|
|
||||||
|
// TODO: add sync function (set fields of self by querying db)
|
||||||
|
|
||||||
// TODO: doc comments
|
// TODO: doc comments
|
||||||
|
|
||||||
#[proc_macro_derive(Table)]
|
#[proc_macro_derive(Table)]
|
||||||
@ -124,7 +126,7 @@ pub fn derive_table(input: TokenStream) -> TokenStream {
|
|||||||
);
|
);
|
||||||
|
|
||||||
let update_fn = quote! {
|
let update_fn = quote! {
|
||||||
pub fn update(&self, conn: &rusqlite::Connection) -> rusqlite::Result<bool>
|
pub fn update(&mut self, conn: &rusqlite::Connection) -> rusqlite::Result<bool>
|
||||||
where #(#to_sql_trait_bounds),*
|
where #(#to_sql_trait_bounds),*
|
||||||
{
|
{
|
||||||
if self.id.is_none() {
|
if self.id.is_none() {
|
||||||
@ -136,22 +138,6 @@ pub fn derive_table(input: TokenStream) -> TokenStream {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
let sync_fn = quote! {
|
|
||||||
pub fn sync(&mut self, conn: &rusqlite::Connection) -> rusqlite::Result<bool>
|
|
||||||
where #(#from_sql_trait_bounds),*
|
|
||||||
{
|
|
||||||
if self.id.is_none() {
|
|
||||||
return Ok(false);
|
|
||||||
}
|
|
||||||
match #struct_name::get_by_id(conn, self.id.unwrap())? {
|
|
||||||
Some(person) => *self = person,
|
|
||||||
_ => return Ok(false),
|
|
||||||
};
|
|
||||||
Ok(true)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
let get_by_id_fn = quote! {
|
let get_by_id_fn = quote! {
|
||||||
pub fn get_by_id(conn: &rusqlite::Connection, id: i64) -> rusqlite::Result<Option<Self>>
|
pub fn get_by_id(conn: &rusqlite::Connection, id: i64) -> rusqlite::Result<Option<Self>>
|
||||||
where
|
where
|
||||||
@ -211,7 +197,6 @@ pub fn derive_table(input: TokenStream) -> TokenStream {
|
|||||||
#insert_fn
|
#insert_fn
|
||||||
#upsert_fn
|
#upsert_fn
|
||||||
#update_fn
|
#update_fn
|
||||||
#sync_fn
|
|
||||||
#get_by_id_fn
|
#get_by_id_fn
|
||||||
#delete_fn
|
#delete_fn
|
||||||
#delete_by_id_fn
|
#delete_by_id_fn
|
||||||
|
|||||||
@ -16,7 +16,7 @@ fn test_table_derive_macro() {
|
|||||||
#[derive(Clone, Default, Debug, PartialEq, Eq)]
|
#[derive(Clone, Default, Debug, PartialEq, Eq)]
|
||||||
struct Point {
|
struct Point {
|
||||||
x: i16,
|
x: i16,
|
||||||
y: i16,
|
y: i16
|
||||||
}
|
}
|
||||||
|
|
||||||
impl rusqlite::types::ToSql for Point {
|
impl rusqlite::types::ToSql for Point {
|
||||||
@ -26,14 +26,11 @@ fn test_table_derive_macro() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl rusqlite::types::FromSql for Point {
|
impl rusqlite::types::FromSql for Point {
|
||||||
fn column_result(
|
fn column_result(value: rusqlite::types::ValueRef<'_>) -> rusqlite::types::FromSqlResult<Self> {
|
||||||
value: rusqlite::types::ValueRef<'_>,
|
|
||||||
) -> rusqlite::types::FromSqlResult<Self> {
|
|
||||||
match value {
|
match value {
|
||||||
rusqlite::types::ValueRef::Text(v) => {
|
rusqlite::types::ValueRef::Text(v) => {
|
||||||
let values = String::from_utf8(v.into()).unwrap();
|
let values = String::from_utf8(v.into()).unwrap();
|
||||||
let values = values
|
let values = values.split_ascii_whitespace()
|
||||||
.split_ascii_whitespace()
|
|
||||||
.map(|w| w.parse::<i16>().unwrap())
|
.map(|w| w.parse::<i16>().unwrap())
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
@ -41,11 +38,8 @@ fn test_table_derive_macro() {
|
|||||||
x: values[0],
|
x: values[0],
|
||||||
y: values[1],
|
y: values[1],
|
||||||
})
|
})
|
||||||
}
|
},
|
||||||
t => panic!(
|
t => panic!("Wrong SQL type recieved for query of Point. Should be Text but is {:?}", t),
|
||||||
"Wrong SQL type recieved for query of Point. Should be Text but is {:?}",
|
|
||||||
t
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -62,84 +56,42 @@ fn test_table_derive_macro() {
|
|||||||
Person::create_table(&conn).unwrap();
|
Person::create_table(&conn).unwrap();
|
||||||
|
|
||||||
larry.insert(&conn).unwrap();
|
larry.insert(&conn).unwrap();
|
||||||
let larry_id = larry
|
let larry_id = larry.id.expect("After (mutable) insertion, id should not be None");
|
||||||
.id
|
|
||||||
.expect("After (mutable) insertion, id should not be None");
|
|
||||||
|
|
||||||
larry.age += 1;
|
larry.age += 1;
|
||||||
let updated_something = larry.update(&conn).expect("Updating should work");
|
let updated_something = larry.update(&conn).expect("Updating should work");
|
||||||
assert!(updated_something, "Should have updated a row");
|
assert!(updated_something, "Should have updated a row");
|
||||||
|
|
||||||
let larry_copy = Person::get_by_id(&conn, larry_id).expect("Querying a row should work");
|
let larry_copy = Person::get_by_id(&conn, larry_id).expect("Querying a row should work");
|
||||||
assert_eq!(
|
assert_eq!(larry_copy, Some(larry.clone()), "Retrieving inserted row should give an identical row");
|
||||||
larry_copy,
|
|
||||||
Some(larry.clone()),
|
|
||||||
"Retrieving inserted row should give an identical row"
|
|
||||||
);
|
|
||||||
|
|
||||||
let deleted_something = larry.delete(&conn).expect("Deletion should work");
|
let deleted_something = larry.delete(&conn).expect("Deletion should work");
|
||||||
// also works: `Person::delete_by_id(&conn, larry_id).unwrap();`
|
// also works: `Person::delete_by_id(&conn, larry_id).unwrap();`
|
||||||
assert!(deleted_something, "Should have deleted something");
|
assert!(deleted_something, "Should have deleted something");
|
||||||
|
|
||||||
let deleted_larry = Person::get_by_id(&conn, larry_id)
|
let deleted_larry = Person::get_by_id(&conn, larry_id).expect("Querying a deleted row should return Ok(None), not Err(_)");
|
||||||
.expect("Querying a deleted row should return Ok(None), not Err(_)");
|
assert_eq!(deleted_larry, None, "Received row that should have been deleted");
|
||||||
assert_eq!(
|
|
||||||
deleted_larry, None,
|
|
||||||
"Received row that should have been deleted"
|
|
||||||
);
|
|
||||||
|
|
||||||
let id = larry.upsert(&conn).expect("Upsertion (insert) should work");
|
let id = larry.upsert(&conn).expect("Upsertion (insert) should work");
|
||||||
let larry_id = larry
|
let larry_id = larry.id.expect("After (mutable) upsertion, id should not be None");
|
||||||
.id
|
|
||||||
.expect("After (mutable) upsertion, id should not be None");
|
|
||||||
|
|
||||||
let larry_copy = Person::get_by_id(&conn, larry_id).expect("Querying a row should work");
|
let larry_copy = Person::get_by_id(&conn, larry_id).expect("Querying a row should work");
|
||||||
assert_eq!(id, larry_id, "Upsert should return correct id");
|
assert_eq!(id, larry_id, "Upsert should return correct id");
|
||||||
assert_eq!(
|
assert_eq!(larry_copy, Some(larry.clone()), "Retrieving upserted row should give an identical row");
|
||||||
larry_copy,
|
|
||||||
Some(larry.clone()),
|
|
||||||
"Retrieving upserted row should give an identical row"
|
|
||||||
);
|
|
||||||
|
|
||||||
larry.age += 1;
|
larry.age += 1;
|
||||||
let id = larry.upsert(&conn).expect("Upsertion (update) should work");
|
let id = larry.upsert(&conn).expect("Upsertion (update) should work");
|
||||||
let larry_id = larry
|
let larry_id = larry.id.expect("After (mutable) upsertion, id should not be None");
|
||||||
.id
|
|
||||||
.expect("After (mutable) upsertion, id should not be None");
|
|
||||||
assert_eq!(id, larry_id, "Upsert should return correct id");
|
assert_eq!(id, larry_id, "Upsert should return correct id");
|
||||||
|
|
||||||
let larry_copy = Person::get_by_id(&conn, larry_id).expect("Querying a row should work");
|
let larry_copy = Person::get_by_id(&conn, larry_id).expect("Querying a row should work");
|
||||||
assert_eq!(
|
assert_eq!(larry_copy, Some(larry.clone()), "Retrieving upserted row should give an identical row");
|
||||||
larry_copy,
|
|
||||||
Some(larry.clone()),
|
|
||||||
"Retrieving upserted row should give an identical row"
|
|
||||||
);
|
|
||||||
|
|
||||||
conn.execute("UPDATE Person SET (age) = (27) WHERE id = ?1", [larry_id])
|
|
||||||
.expect("Explicit Sqlite statement (not a library test) failed");
|
|
||||||
|
|
||||||
let found = larry
|
|
||||||
.sync(&conn)
|
|
||||||
.expect("Syncing struct to existing row should succeed");
|
|
||||||
assert!(found, "Row should have been found");
|
|
||||||
assert_eq!(
|
|
||||||
larry.age, 27,
|
|
||||||
"Syncing struct to edited table row should work"
|
|
||||||
);
|
|
||||||
|
|
||||||
Person::drop_table(&conn).expect("Dropping table should work");
|
Person::drop_table(&conn).expect("Dropping table should work");
|
||||||
Person::drop_table(&conn).expect_err("Dropping previously dropped table should err");
|
Person::drop_table(&conn).expect_err("Dropping previously dropped table should err");
|
||||||
|
|
||||||
let exists: bool = conn
|
|
||||||
.query_row(
|
|
||||||
"SELECT EXISTS(SELECT 1 FROM sqlite_master WHERE type='table' AND name='Person');",
|
|
||||||
[],
|
|
||||||
|row| row.get(0),
|
|
||||||
)
|
|
||||||
.expect("Explicit Sqlite statement (not a library test) failed");
|
|
||||||
assert!(!exists, "Deleted table should not exist anymore but does");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// TODO: implement compile-error test(s) -- perhaps with `trybuild`?
|
// TODO: implement compile-error test(s) -- perhaps with `trybuild`?
|
||||||
//
|
//
|
||||||
// #[test]
|
// #[test]
|
||||||
@ -153,3 +105,4 @@ fn test_table_derive_macro() {
|
|||||||
// data: i64, // missing `id: Option<i64>`
|
// data: i64, // missing `id: Option<i64>`
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user