156 lines
4.4 KiB
Rust
156 lines
4.4 KiB
Rust
// SPDX-FileCopyrightText: 2024 Simon Bruder <simon@sbruder.de>
|
|
//
|
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
|
|
use std::collections::HashMap;
|
|
|
|
use sqlx::{query, query_as, query_scalar, PgPool};
|
|
use uuid::Uuid;
|
|
|
|
use crate::models::{Item, NewItem};
|
|
|
|
pub async fn add(pool: &PgPool, new_item: NewItem) -> Result<Item, sqlx::Error> {
|
|
query_as!(
|
|
Item,
|
|
"INSERT INTO items (name, parent, class, original_packaging, description) VALUES ($1, $2, $3, $4, $5) RETURNING *",
|
|
new_item.name,
|
|
new_item.parent,
|
|
new_item.class,
|
|
new_item.original_packaging,
|
|
new_item.description
|
|
)
|
|
.fetch_one(pool)
|
|
.await
|
|
}
|
|
|
|
pub async fn add_multiple(
|
|
pool: &PgPool,
|
|
new_item: NewItem,
|
|
quantity: usize,
|
|
) -> Result<Vec<Item>, sqlx::Error> {
|
|
query_as!(
|
|
Item,
|
|
r#"INSERT INTO items (name, parent, class, original_packaging, description)
|
|
SELECT * FROM UNNEST($1::VARCHAR[], $2::UUID[], $3::UUID[], $4::UUID[], $5::VARCHAR[])
|
|
RETURNING *"#,
|
|
&vec![new_item.name; quantity] as &[Option<String>],
|
|
&vec![new_item.parent; quantity] as &[Option<Uuid>],
|
|
&vec![new_item.class; quantity],
|
|
&vec![new_item.original_packaging; quantity] as &[Option<Uuid>],
|
|
&vec![new_item.description; quantity]
|
|
)
|
|
.fetch_all(pool)
|
|
.await
|
|
}
|
|
|
|
pub async fn get(pool: &PgPool, id: Uuid) -> Result<Item, sqlx::Error> {
|
|
query_as!(Item, "SELECT * FROM items WHERE id = $1", id)
|
|
.fetch_one(pool)
|
|
.await
|
|
}
|
|
|
|
pub async fn get_by_short_id(pool: &PgPool, short_id: i32) -> Result<Item, sqlx::Error> {
|
|
query_as!(Item, "SELECT * FROM items WHERE short_id = $1", short_id)
|
|
.fetch_one(pool)
|
|
.await
|
|
}
|
|
|
|
pub async fn get_all(pool: &PgPool) -> Result<Vec<Item>, sqlx::Error> {
|
|
query_as!(Item, "SELECT * FROM items ORDER BY created_at")
|
|
.fetch_all(pool)
|
|
.await
|
|
}
|
|
|
|
pub async fn get_multiple(pool: &PgPool, ids: &[Uuid]) -> Result<Vec<Item>, sqlx::Error> {
|
|
query_as!(Item, "SELECT * FROM items WHERE id = ANY ($1)", ids)
|
|
.fetch_all(pool)
|
|
.await
|
|
}
|
|
|
|
pub async fn get_all_as_map(pool: &PgPool) -> Result<HashMap<Uuid, Item>, sqlx::Error> {
|
|
Ok(get_all(pool)
|
|
.await?
|
|
.into_iter()
|
|
.map(|i| (i.id, i))
|
|
.collect())
|
|
}
|
|
|
|
pub async fn update(pool: &PgPool, id: Uuid, modified_item: NewItem) -> Result<Item, sqlx::Error> {
|
|
query_as!(
|
|
Item,
|
|
"UPDATE items SET name = $2, parent = $3, class = $4, original_packaging = $5, description = $6 WHERE id = $1 RETURNING *",
|
|
id,
|
|
modified_item.name,
|
|
modified_item.parent,
|
|
modified_item.class,
|
|
modified_item.original_packaging,
|
|
modified_item.description
|
|
)
|
|
.fetch_one(pool)
|
|
.await
|
|
}
|
|
|
|
pub async fn delete(pool: &PgPool, id: Uuid) -> Result<(), sqlx::Error> {
|
|
let res = query!("DELETE FROM items WHERE id = $1", id)
|
|
.execute(pool)
|
|
.await?;
|
|
assert_eq!(res.rows_affected(), 1);
|
|
Ok(())
|
|
}
|
|
|
|
pub async fn get_parents(pool: &PgPool, id: Uuid) -> Result<Vec<Uuid>, sqlx::Error> {
|
|
// force nullable is required for all columns in views
|
|
query_scalar!(
|
|
r#"SELECT unnest(parents) as "parents!" FROM item_tree WHERE id = $1"#,
|
|
id
|
|
)
|
|
.fetch_all(pool)
|
|
.await
|
|
}
|
|
|
|
pub async fn get_all_parents(pool: &PgPool) -> Result<HashMap<Uuid, Vec<Uuid>>, sqlx::Error> {
|
|
let mut parents = HashMap::new();
|
|
for row in query!(r#"SELECT id as "id!", parents as "parents!" FROM item_tree"#)
|
|
.fetch_all(pool)
|
|
.await?
|
|
{
|
|
parents.insert(row.id, row.parents);
|
|
}
|
|
Ok(parents)
|
|
}
|
|
|
|
pub async fn get_parents_details(pool: &PgPool, id: Uuid) -> Result<Vec<Item>, sqlx::Error> {
|
|
query_as!(
|
|
Item,
|
|
"SELECT items.*
|
|
FROM items
|
|
INNER JOIN
|
|
unnest((SELECT parents FROM item_tree WHERE id = $1))
|
|
WITH ORDINALITY AS parents(id, n)
|
|
ON items.id = parents.id
|
|
ORDER BY parents.n;",
|
|
id
|
|
)
|
|
.fetch_all(pool)
|
|
.await
|
|
}
|
|
|
|
pub async fn get_children(pool: &PgPool, id: Uuid) -> Result<Vec<Item>, sqlx::Error> {
|
|
query_as!(Item, "SELECT * FROM items WHERE parent = $1", id)
|
|
.fetch_all(pool)
|
|
.await
|
|
}
|
|
|
|
pub async fn original_packaging_contents(
|
|
pool: &PgPool,
|
|
id: Uuid,
|
|
) -> Result<Vec<Item>, sqlx::Error> {
|
|
query_as!(
|
|
Item,
|
|
"SELECT * FROM items WHERE original_packaging = $1",
|
|
id
|
|
)
|
|
.fetch_all(pool)
|
|
.await
|
|
}
|