macros
This commit is contained in:
@@ -28,5 +28,5 @@
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "6e8fbd5a7269c6a2021b688b58f74f8235554a414f77af5c2524d51920f0e33c"
|
||||
"hash": "cd180dd379d3d7602b05173863939becee61c78da0914836a74943a46b0d3099"
|
||||
}
|
||||
@@ -14,33 +14,25 @@ impl Inventory {
|
||||
#[tracing::instrument]
|
||||
pub async fn load(ctx: &Context, pool: &sqlx::Pool<sqlx::Sqlite>) -> Result<Self, Error> {
|
||||
let user_id = ctx.user.id.to_string();
|
||||
let categories = async {
|
||||
let mut categories = sqlx::query_as!(
|
||||
|
||||
let mut categories = crate::query_all!(
|
||||
pool,
|
||||
DbCategoryRow,
|
||||
Category,
|
||||
"SELECT
|
||||
id,
|
||||
name,
|
||||
description
|
||||
FROM inventory_items_categories
|
||||
WHERE user_id = ?",
|
||||
user_id,
|
||||
user_id
|
||||
)
|
||||
.fetch(pool)
|
||||
.map_ok(|row: DbCategoryRow| row.try_into())
|
||||
.try_collect::<Vec<Result<Category, Error>>>()
|
||||
.await?
|
||||
.into_iter()
|
||||
.collect::<Result<Vec<Category>, Error>>()?;
|
||||
.await?;
|
||||
|
||||
for category in &mut categories {
|
||||
category.populate_items(ctx, pool).await?;
|
||||
}
|
||||
|
||||
Ok::<_, Error>(categories)
|
||||
}
|
||||
.instrument(tracing::info_span!("packager::sql::query", "query"))
|
||||
.await?;
|
||||
|
||||
Ok(Self { categories })
|
||||
}
|
||||
}
|
||||
@@ -81,8 +73,10 @@ impl Category {
|
||||
) -> Result<Option<Category>, Error> {
|
||||
let id_param = id.to_string();
|
||||
let user_id = ctx.user.id.to_string();
|
||||
sqlx::query_as!(
|
||||
crate::query_one!(
|
||||
pool,
|
||||
DbCategoryRow,
|
||||
Category,
|
||||
"SELECT
|
||||
id,
|
||||
name,
|
||||
@@ -94,10 +88,7 @@ impl Category {
|
||||
id_param,
|
||||
user_id,
|
||||
)
|
||||
.fetch_optional(pool)
|
||||
.await?
|
||||
.map(|row| row.try_into())
|
||||
.transpose()
|
||||
.await
|
||||
}
|
||||
|
||||
#[tracing::instrument]
|
||||
@@ -109,7 +100,8 @@ impl Category {
|
||||
let id = Uuid::new_v4();
|
||||
let id_param = id.to_string();
|
||||
let user_id = ctx.user.id.to_string();
|
||||
sqlx::query!(
|
||||
crate::execute!(
|
||||
pool,
|
||||
"INSERT INTO inventory_items_categories
|
||||
(id, name, user_id)
|
||||
VALUES
|
||||
@@ -118,7 +110,6 @@ impl Category {
|
||||
name,
|
||||
user_id,
|
||||
)
|
||||
.execute(pool)
|
||||
.await?;
|
||||
|
||||
Ok(id)
|
||||
@@ -144,8 +135,10 @@ impl Category {
|
||||
) -> Result<(), Error> {
|
||||
let id = self.id.to_string();
|
||||
let user_id = ctx.user.id.to_string();
|
||||
let items = sqlx::query_as!(
|
||||
let items = crate::query_all!(
|
||||
pool,
|
||||
DbInventoryItemsRow,
|
||||
Item,
|
||||
"SELECT
|
||||
id,
|
||||
name,
|
||||
@@ -159,12 +152,7 @@ impl Category {
|
||||
id,
|
||||
user_id,
|
||||
)
|
||||
.fetch(pool)
|
||||
.map_ok(|row| row.try_into())
|
||||
.try_collect::<Vec<Result<Item, Error>>>()
|
||||
.await?
|
||||
.into_iter()
|
||||
.collect::<Result<Vec<Item>, Error>>()?;
|
||||
.await?;
|
||||
|
||||
self.items = Some(items);
|
||||
Ok(())
|
||||
@@ -243,8 +231,10 @@ impl InventoryItem {
|
||||
let id_param = id.to_string();
|
||||
let user_id = ctx.user.id.to_string();
|
||||
|
||||
sqlx::query_as!(
|
||||
crate::query_one!(
|
||||
pool,
|
||||
DbInventoryItemRow,
|
||||
Self,
|
||||
"SELECT
|
||||
item.id AS id,
|
||||
item.name AS name,
|
||||
@@ -268,10 +258,7 @@ impl InventoryItem {
|
||||
id_param,
|
||||
user_id,
|
||||
)
|
||||
.fetch_optional(pool)
|
||||
.await?
|
||||
.map(|row| row.try_into())
|
||||
.transpose()
|
||||
.await
|
||||
}
|
||||
|
||||
#[tracing::instrument]
|
||||
@@ -281,7 +268,8 @@ impl InventoryItem {
|
||||
name: &str,
|
||||
) -> Result<bool, Error> {
|
||||
let user_id = ctx.user.id.to_string();
|
||||
Ok(sqlx::query!(
|
||||
crate::query_exists!(
|
||||
pool,
|
||||
"SELECT id
|
||||
FROM inventory_items
|
||||
WHERE
|
||||
@@ -290,10 +278,7 @@ impl InventoryItem {
|
||||
name,
|
||||
user_id
|
||||
)
|
||||
.fetch_optional(pool)
|
||||
.await?
|
||||
.map(|_row| ())
|
||||
.is_some())
|
||||
.await
|
||||
}
|
||||
|
||||
#[tracing::instrument]
|
||||
@@ -304,7 +289,8 @@ impl InventoryItem {
|
||||
) -> Result<bool, Error> {
|
||||
let id_param = id.to_string();
|
||||
let user_id = ctx.user.id.to_string();
|
||||
let results = sqlx::query!(
|
||||
let results = crate::execute!(
|
||||
pool,
|
||||
"DELETE FROM inventory_items
|
||||
WHERE
|
||||
id = ?
|
||||
@@ -312,7 +298,6 @@ impl InventoryItem {
|
||||
id_param,
|
||||
user_id,
|
||||
)
|
||||
.execute(pool)
|
||||
.await?;
|
||||
|
||||
Ok(results.rows_affected() != 0)
|
||||
@@ -330,7 +315,8 @@ impl InventoryItem {
|
||||
let weight = i64::try_from(weight).unwrap();
|
||||
|
||||
let id_param = id.to_string();
|
||||
Ok(sqlx::query!(
|
||||
crate::execute_returning_uuid!(
|
||||
pool,
|
||||
"UPDATE inventory_items AS item
|
||||
SET
|
||||
name = ?,
|
||||
@@ -345,9 +331,7 @@ impl InventoryItem {
|
||||
id_param,
|
||||
user_id,
|
||||
)
|
||||
.fetch_one(pool)
|
||||
.map_ok(|row| Uuid::try_parse(&row.id))
|
||||
.await??)
|
||||
.await
|
||||
}
|
||||
|
||||
#[tracing::instrument]
|
||||
@@ -363,7 +347,8 @@ impl InventoryItem {
|
||||
let user_id = ctx.user.id.to_string();
|
||||
let category_id_param = category_id.to_string();
|
||||
|
||||
sqlx::query!(
|
||||
crate::execute!(
|
||||
pool,
|
||||
"INSERT INTO inventory_items
|
||||
(id, name, description, weight, category_id, user_id)
|
||||
VALUES
|
||||
@@ -375,7 +360,6 @@ impl InventoryItem {
|
||||
category_id_param,
|
||||
user_id,
|
||||
)
|
||||
.execute(pool)
|
||||
.await?;
|
||||
|
||||
Ok(id)
|
||||
@@ -389,7 +373,8 @@ impl InventoryItem {
|
||||
) -> Result<i64, Error> {
|
||||
let user_id = ctx.user.id.to_string();
|
||||
let category_id_param = category_id.to_string();
|
||||
let weight = sqlx::query!(
|
||||
let weight = crate::execute_returning!(
|
||||
pool,
|
||||
"
|
||||
SELECT COALESCE(MAX(i_item.weight), 0) as weight
|
||||
FROM inventory_items_categories as category
|
||||
@@ -399,15 +384,11 @@ impl InventoryItem {
|
||||
category_id = ?
|
||||
AND category.user_id = ?
|
||||
",
|
||||
i64,
|
||||
|row| i64::from(row.weight),
|
||||
category_id_param,
|
||||
user_id,
|
||||
)
|
||||
.fetch_one(pool)
|
||||
.map_ok(|row| {
|
||||
// convert to i64 because that the default integer type, but looks
|
||||
// like COALESCE return i32?
|
||||
i64::from(row.weight)
|
||||
})
|
||||
.await?;
|
||||
|
||||
Ok(weight)
|
||||
@@ -454,7 +435,8 @@ impl Item {
|
||||
) -> Result<i64, Error> {
|
||||
let user_id = ctx.user.id.to_string();
|
||||
let category_id_param = category_id.to_string();
|
||||
Ok(sqlx::query!(
|
||||
crate::execute_returning!(
|
||||
pool,
|
||||
"
|
||||
SELECT COALESCE(SUM(i_item.weight), 0) as weight
|
||||
FROM inventory_items_categories as category
|
||||
@@ -467,15 +449,11 @@ impl Item {
|
||||
AND category.user_id = ?
|
||||
AND t_item.pick = 1
|
||||
",
|
||||
i64,
|
||||
|row| i64::from(row.weight),
|
||||
category_id_param,
|
||||
user_id,
|
||||
)
|
||||
.fetch_one(pool)
|
||||
.map_ok(|row| {
|
||||
// convert to i64 because that the default integer type, but looks
|
||||
// like COALESCE return i32?
|
||||
i64::from(row.weight)
|
||||
})
|
||||
.await?)
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,3 +47,122 @@ pub async fn migrate(url: &str) -> Result<(), StartError> {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! query_all {
|
||||
( $pool:expr, $struct_row:path, $struct_into:path, $query:expr, $( $args:tt )* ) => {
|
||||
async {
|
||||
let result: Result<Vec<$struct_into>, Error> = sqlx::query_as!(
|
||||
$struct_row,
|
||||
$query,
|
||||
$( $args )*
|
||||
)
|
||||
.fetch($pool)
|
||||
.map_ok(|row: $struct_row| row.try_into())
|
||||
.try_collect::<Vec<Result<$struct_into, Error>>>()
|
||||
.await?
|
||||
.into_iter()
|
||||
.collect::<Result<Vec<$struct_into>, Error>>();
|
||||
|
||||
result
|
||||
|
||||
}.instrument(tracing::info_span!("packager::sql::query", "query"))
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! query_one {
|
||||
( $pool:expr, $struct_row:path, $struct_into:path, $query:expr, $( $args:tt )*) => {
|
||||
async {
|
||||
let result: Result<Option<$struct_into>, Error> = sqlx::query_as!(
|
||||
$struct_row,
|
||||
$query,
|
||||
$( $args )*
|
||||
)
|
||||
.fetch_optional($pool)
|
||||
.await?
|
||||
.map(|row: $struct_row| row.try_into())
|
||||
.transpose();
|
||||
|
||||
result
|
||||
|
||||
}.instrument(tracing::info_span!("packager::sql::query", "query"))
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! query_exists {
|
||||
( $pool:expr, $query:expr, $( $args:tt )*) => {
|
||||
async {
|
||||
let result: bool = sqlx::query!(
|
||||
$query,
|
||||
$( $args )*
|
||||
)
|
||||
.fetch_optional($pool)
|
||||
.await?
|
||||
.is_some();
|
||||
|
||||
Ok(result)
|
||||
|
||||
}.instrument(tracing::info_span!("packager::sql::query", "query"))
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! execute {
|
||||
( $pool:expr, $query:expr, $( $args:tt )*) => {
|
||||
async {
|
||||
let result: Result<sqlx::sqlite::SqliteQueryResult, Error> = sqlx::query!(
|
||||
$query,
|
||||
$( $args )*
|
||||
)
|
||||
.execute($pool)
|
||||
.await
|
||||
.map_err(|e| e.into());
|
||||
|
||||
result
|
||||
|
||||
|
||||
}.instrument(tracing::info_span!("packager::sql::query", "query"))
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! execute_returning {
|
||||
( $pool:expr, $query:expr, $t:path, $fn:expr, $( $args:tt )*) => {
|
||||
async {
|
||||
let result: Result<$t, Error> = sqlx::query!(
|
||||
$query,
|
||||
$( $args )*
|
||||
)
|
||||
.fetch_one($pool)
|
||||
.map_ok($fn)
|
||||
.await
|
||||
.map_err(Into::into);
|
||||
|
||||
result
|
||||
|
||||
|
||||
}.instrument(tracing::info_span!("packager::sql::query", "query"))
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! execute_returning_uuid {
|
||||
( $pool:expr, $query:expr, $( $args:tt )*) => {
|
||||
async {
|
||||
let result: Result<Uuid, Error> = sqlx::query!(
|
||||
$query,
|
||||
$( $args )*
|
||||
)
|
||||
.fetch_one($pool)
|
||||
.map_ok(|row| Uuid::try_parse(&row.id))
|
||||
.await?
|
||||
.map_err(Into::into);
|
||||
|
||||
result
|
||||
|
||||
|
||||
}.instrument(tracing::info_span!("packager::sql::query", "query"))
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user