summaryrefslogtreecommitdiff
path: root/rust/schist_core/src/queries
diff options
context:
space:
mode:
authorJoe Carstairs <me@joeac.net>2024-11-17 09:29:32 +0000
committerJoe Carstairs <me@joeac.net>2024-11-17 09:30:04 +0000
commit10f071447594f2bdcec84a461df9ad648f71f44b (patch)
tree645924a4948f39a4d9e2ec270d79fc6c2a3a937a /rust/schist_core/src/queries
parent1ae19eb3315c40e3f9062592c27fa76c11cf626c (diff)
Renames app to 'schist'
Diffstat (limited to 'rust/schist_core/src/queries')
-rw-r--r--rust/schist_core/src/queries/accounts/delete_all.rs11
-rw-r--r--rust/schist_core/src/queries/accounts/get_all.rs10
-rw-r--r--rust/schist_core/src/queries/accounts/insert.rs28
-rw-r--r--rust/schist_core/src/queries/accounts/mod.rs7
-rw-r--r--rust/schist_core/src/queries/budget_updates/delete_all.rs11
-rw-r--r--rust/schist_core/src/queries/budget_updates/get_all.rs16
-rw-r--r--rust/schist_core/src/queries/budget_updates/get_first_with_date_and_category_id.rs25
-rw-r--r--rust/schist_core/src/queries/budget_updates/get_most_recent_with_category_id.rs21
-rw-r--r--rust/schist_core/src/queries/budget_updates/insert.rs28
-rw-r--r--rust/schist_core/src/queries/budget_updates/mod.rs11
-rw-r--r--rust/schist_core/src/queries/categories/delete_all.rs11
-rw-r--r--rust/schist_core/src/queries/categories/get_all.rs11
-rw-r--r--rust/schist_core/src/queries/categories/get_all_balances.rs47
-rw-r--r--rust/schist_core/src/queries/categories/get_all_ids.rs11
-rw-r--r--rust/schist_core/src/queries/categories/get_most_recent_budget_per_category_id.rs52
-rw-r--r--rust/schist_core/src/queries/categories/insert.rs28
-rw-r--r--rust/schist_core/src/queries/categories/mod.rs13
-rw-r--r--rust/schist_core/src/queries/category_transfers/delete_all.rs7
-rw-r--r--rust/schist_core/src/queries/category_transfers/get_all.rs11
-rw-r--r--rust/schist_core/src/queries/category_transfers/insert.rs15
-rw-r--r--rust/schist_core/src/queries/category_transfers/mod.rs11
-rw-r--r--rust/schist_core/src/queries/category_transfers/sum_quantity_per_from_category_id.rs18
-rw-r--r--rust/schist_core/src/queries/category_transfers/sum_quantity_per_to_category_id.rs18
-rw-r--r--rust/schist_core/src/queries/clear.rs20
-rw-r--r--rust/schist_core/src/queries/mod.rs7
-rw-r--r--rust/schist_core/src/queries/transaction_categorisations/delete_all.rs7
-rw-r--r--rust/schist_core/src/queries/transaction_categorisations/get_all.rs11
-rw-r--r--rust/schist_core/src/queries/transaction_categorisations/insert.rs15
-rw-r--r--rust/schist_core/src/queries/transaction_categorisations/mod.rs9
-rw-r--r--rust/schist_core/src/queries/transaction_categorisations/sum_quantity_per_category_id.rs18
-rw-r--r--rust/schist_core/src/queries/transactions/delete_all.rs7
-rw-r--r--rust/schist_core/src/queries/transactions/get_all.rs11
-rw-r--r--rust/schist_core/src/queries/transactions/insert.rs15
-rw-r--r--rust/schist_core/src/queries/transactions/mod.rs7
34 files changed, 548 insertions, 0 deletions
diff --git a/rust/schist_core/src/queries/accounts/delete_all.rs b/rust/schist_core/src/queries/accounts/delete_all.rs
new file mode 100644
index 0000000..84d7bf6
--- /dev/null
+++ b/rust/schist_core/src/queries/accounts/delete_all.rs
@@ -0,0 +1,11 @@
+use anyhow::{Context, Result};
+use diesel::{RunQueryDsl, SqliteConnection};
+
+use crate::schema::accounts::dsl::accounts;
+
+pub fn delete_all_accounts(connection: &mut SqliteConnection) -> Result<usize> {
+ let num_rows_deleted = diesel::delete(accounts)
+ .execute(connection)
+ .with_context(|| "failed to delete all accounts")?;
+ Ok(num_rows_deleted)
+}
diff --git a/rust/schist_core/src/queries/accounts/get_all.rs b/rust/schist_core/src/queries/accounts/get_all.rs
new file mode 100644
index 0000000..ab53729
--- /dev/null
+++ b/rust/schist_core/src/queries/accounts/get_all.rs
@@ -0,0 +1,10 @@
+use anyhow::{Context, Result};
+use crate::{models::account::Account, schema::accounts::dsl::accounts};
+use diesel::{QueryDsl, RunQueryDsl, SelectableHelper, SqliteConnection};
+
+pub fn get_all_accounts(connection: &mut SqliteConnection) -> Result<Vec<Account>> {
+ let all_accounts = accounts.select(Account::as_select())
+ .load(connection)
+ .with_context(|| "failed to get all accounts")?;
+ Ok(all_accounts)
+}
diff --git a/rust/schist_core/src/queries/accounts/insert.rs b/rust/schist_core/src/queries/accounts/insert.rs
new file mode 100644
index 0000000..7020b68
--- /dev/null
+++ b/rust/schist_core/src/queries/accounts/insert.rs
@@ -0,0 +1,28 @@
+use anyhow::{Context, Result};
+use crate::{
+ models::account::Account,
+ schema::accounts::dsl::accounts as accounts_table,
+};
+use diesel::prelude::*;
+
+pub fn insert_accounts(
+ accounts: &[Account],
+ connection: &mut SqliteConnection,
+) -> Result<usize> {
+ let num_accounts_inserted = diesel::insert_into(accounts_table)
+ .values(accounts)
+ .execute(connection)
+ .with_context(|| err_msg(accounts))?;
+ Ok(num_accounts_inserted)
+}
+
+fn err_msg(accounts: &[Account]) -> String {
+ format!(
+ "failed to insert accounts: [{}]",
+ accounts
+ .iter()
+ .map(|a| format!("\"{}\": \"{}\"", a.id, a.name))
+ .collect::<Vec<String>>()
+ .join(", ")
+ )
+}
diff --git a/rust/schist_core/src/queries/accounts/mod.rs b/rust/schist_core/src/queries/accounts/mod.rs
new file mode 100644
index 0000000..222b180
--- /dev/null
+++ b/rust/schist_core/src/queries/accounts/mod.rs
@@ -0,0 +1,7 @@
+mod delete_all;
+mod get_all;
+mod insert;
+
+pub use delete_all::delete_all_accounts;
+pub use get_all::get_all_accounts;
+pub use insert::insert_accounts;
diff --git a/rust/schist_core/src/queries/budget_updates/delete_all.rs b/rust/schist_core/src/queries/budget_updates/delete_all.rs
new file mode 100644
index 0000000..b7ad082
--- /dev/null
+++ b/rust/schist_core/src/queries/budget_updates/delete_all.rs
@@ -0,0 +1,11 @@
+use anyhow::{Context, Result};
+use diesel::{RunQueryDsl, SqliteConnection};
+
+use crate::schema::budget_updates::dsl::budget_updates;
+
+pub fn delete_all_budget_updates(connection: &mut SqliteConnection) -> Result<usize> {
+ let num_rows_deleted = diesel::delete(budget_updates)
+ .execute(connection)
+ .with_context(|| "failed to delete all budget updates")?;
+ Ok(num_rows_deleted)
+}
diff --git a/rust/schist_core/src/queries/budget_updates/get_all.rs b/rust/schist_core/src/queries/budget_updates/get_all.rs
new file mode 100644
index 0000000..9c9310b
--- /dev/null
+++ b/rust/schist_core/src/queries/budget_updates/get_all.rs
@@ -0,0 +1,16 @@
+use anyhow::{Context, Result};
+use crate::{
+ models::budget_update::BudgetUpdate,
+ schema::budget_updates::dsl::budget_updates as budget_updates_table,
+};
+use diesel::{QueryDsl, RunQueryDsl, SelectableHelper, SqliteConnection};
+
+pub fn get_all_budget_updates(
+ connection: &mut SqliteConnection,
+) -> Result<Vec<BudgetUpdate>> {
+ let all_budget_updates = budget_updates_table
+ .select(BudgetUpdate::as_select())
+ .load::<BudgetUpdate>(connection)
+ .with_context(|| "failed to get all budget updates")?;
+ Ok(all_budget_updates)
+}
diff --git a/rust/schist_core/src/queries/budget_updates/get_first_with_date_and_category_id.rs b/rust/schist_core/src/queries/budget_updates/get_first_with_date_and_category_id.rs
new file mode 100644
index 0000000..2d8f97c
--- /dev/null
+++ b/rust/schist_core/src/queries/budget_updates/get_first_with_date_and_category_id.rs
@@ -0,0 +1,25 @@
+use anyhow::{Context, Result};
+use crate::{
+ models::{budget_update::BudgetUpdate, date_utc::DateUtc},
+ schema::budget_updates::{
+ self as budget_updates_schema, dsl::budget_updates as budget_updates_table,
+ },
+};
+use diesel::{
+ ExpressionMethods, OptionalExtension, QueryDsl, RunQueryDsl, SelectableHelper, SqliteConnection
+};
+
+pub fn get_first_budget_update_with_date_and_category_id(
+ date: &DateUtc,
+ category_id: i32,
+ connection: &mut SqliteConnection,
+) -> Result<Option<BudgetUpdate>> {
+ let first_budget_update = budget_updates_table
+ .select(BudgetUpdate::as_select())
+ .filter(budget_updates_schema::date.eq(date.to_string()))
+ .filter(budget_updates_schema::category_id.eq(category_id))
+ .first(connection)
+ .optional()
+ .with_context(|| format!("failed to get first budget update with date {}", date.to_string()))?;
+ Ok(first_budget_update)
+}
diff --git a/rust/schist_core/src/queries/budget_updates/get_most_recent_with_category_id.rs b/rust/schist_core/src/queries/budget_updates/get_most_recent_with_category_id.rs
new file mode 100644
index 0000000..41ef5ec
--- /dev/null
+++ b/rust/schist_core/src/queries/budget_updates/get_most_recent_with_category_id.rs
@@ -0,0 +1,21 @@
+use anyhow::{Context, Result};
+use crate::{
+ models::date_utc::DateUtc,
+ schema::budget_updates::{
+ self as budget_updates_schema, dsl::budget_updates as budget_updates_table,
+ }, traits::nowlike::Nowlike,
+};
+use diesel::{dsl::max, ExpressionMethods, QueryDsl, RunQueryDsl, SqliteConnection};
+
+pub fn get_most_recent_budget_update_date_with_category_id(
+ category_id: i32,
+ connection: &mut SqliteConnection,
+) -> Result<Option<DateUtc>> {
+ let most_recent_date = budget_updates_table
+ .select(max(budget_updates_schema::date))
+ .filter(budget_updates_schema::category_id.eq(category_id))
+ .filter(budget_updates_schema::date.le(DateUtc::now()))
+ .first(connection)
+ .with_context(|| format!("failed to get most recent budget update date with category ID {}", category_id))?;
+ Ok(most_recent_date)
+}
diff --git a/rust/schist_core/src/queries/budget_updates/insert.rs b/rust/schist_core/src/queries/budget_updates/insert.rs
new file mode 100644
index 0000000..e8ae271
--- /dev/null
+++ b/rust/schist_core/src/queries/budget_updates/insert.rs
@@ -0,0 +1,28 @@
+use anyhow::{Context, Result};
+use crate::{
+ models::budget_update::BudgetUpdate,
+ schema::budget_updates::dsl::budget_updates as budget_updates_table,
+};
+use diesel::prelude::*;
+
+pub fn insert_budget_updates(
+ budget_updates: &[BudgetUpdate],
+ connection: &mut SqliteConnection,
+) -> Result<usize> {
+ let num_rows_inserted = diesel::insert_into(budget_updates_table)
+ .values(budget_updates)
+ .execute(connection)
+ .with_context(|| err_msg(budget_updates))?;
+ Ok(num_rows_inserted)
+}
+
+fn err_msg(budget_updates: &[BudgetUpdate]) -> String {
+ format!(
+ "failed to insert budget updates: [{}]",
+ budget_updates
+ .iter()
+ .map(|a| a.id.to_string())
+ .collect::<Vec<String>>()
+ .join(", ")
+ )
+}
diff --git a/rust/schist_core/src/queries/budget_updates/mod.rs b/rust/schist_core/src/queries/budget_updates/mod.rs
new file mode 100644
index 0000000..6fc7de0
--- /dev/null
+++ b/rust/schist_core/src/queries/budget_updates/mod.rs
@@ -0,0 +1,11 @@
+mod delete_all;
+mod get_all;
+mod get_first_with_date_and_category_id;
+mod get_most_recent_with_category_id;
+mod insert;
+
+pub use delete_all::delete_all_budget_updates;
+pub use get_all::get_all_budget_updates;
+pub use get_first_with_date_and_category_id::get_first_budget_update_with_date_and_category_id;
+pub use get_most_recent_with_category_id::get_most_recent_budget_update_date_with_category_id;
+pub use insert::insert_budget_updates;
diff --git a/rust/schist_core/src/queries/categories/delete_all.rs b/rust/schist_core/src/queries/categories/delete_all.rs
new file mode 100644
index 0000000..1fd2581
--- /dev/null
+++ b/rust/schist_core/src/queries/categories/delete_all.rs
@@ -0,0 +1,11 @@
+use anyhow::{Context, Result};
+use diesel::{RunQueryDsl, SqliteConnection};
+
+use crate::schema::categories::dsl::categories;
+
+pub fn delete_all_categories(connection: &mut SqliteConnection) -> Result<usize> {
+ let num_rows_deleted = diesel::delete(categories)
+ .execute(connection)
+ .with_context(|| "failed to delete all categories")?;
+ Ok(num_rows_deleted)
+}
diff --git a/rust/schist_core/src/queries/categories/get_all.rs b/rust/schist_core/src/queries/categories/get_all.rs
new file mode 100644
index 0000000..431ed9c
--- /dev/null
+++ b/rust/schist_core/src/queries/categories/get_all.rs
@@ -0,0 +1,11 @@
+use anyhow::{Context, Result};
+use crate::{models::category::Category, schema::categories::dsl::categories as categories_table};
+use diesel::{QueryDsl, RunQueryDsl, SelectableHelper, SqliteConnection};
+
+pub fn get_all_categories(connection: &mut SqliteConnection) -> Result<Vec<Category>> {
+ let all_categories = categories_table
+ .select(Category::as_select())
+ .load(connection)
+ .with_context(|| "failed to get all categories")?;
+ Ok(all_categories)
+}
diff --git a/rust/schist_core/src/queries/categories/get_all_balances.rs b/rust/schist_core/src/queries/categories/get_all_balances.rs
new file mode 100644
index 0000000..c9a0102
--- /dev/null
+++ b/rust/schist_core/src/queries/categories/get_all_balances.rs
@@ -0,0 +1,47 @@
+use anyhow::{Context, Result};
+use crate::{models::category_balance::CategoryBalance, queries::{
+ budget_updates::get_all_budget_updates,
+ categories::get_all_categories,
+ category_transfers::{
+ sum_category_transfer_quantity_per_from_category_id,
+ sum_category_transfer_quantity_per_to_category_id,
+ },
+ transaction_categorisations::sum_transaction_categorisation_quantity_per_category_id,
+ }, utils::calculate_category_balance};
+use diesel::SqliteConnection;
+
+pub fn get_all_category_balances(
+ connection: &mut SqliteConnection,
+) -> Result<Vec<CategoryBalance>> {
+ get_all_category_balances_without_context(connection)
+ .with_context(|| "failed to get all category balances")
+}
+
+fn get_all_category_balances_without_context(
+ connection: &mut SqliteConnection,
+) -> Result<Vec<CategoryBalance>> {
+ let categories = get_all_categories(connection)?;
+ let transaction_sums = sum_transaction_categorisation_quantity_per_category_id(connection)?;
+ let category_transfer_from_sums =
+ sum_category_transfer_quantity_per_from_category_id(connection)?;
+ let category_transfer_to_sums = sum_category_transfer_quantity_per_to_category_id(connection)?;
+ let budget_updates = get_all_budget_updates(connection)?;
+
+ let mut balances = Vec::<CategoryBalance>::new();
+ for category in categories {
+ let balance = calculate_category_balance(
+ &category,
+ &transaction_sums,
+ &category_transfer_from_sums,
+ &category_transfer_to_sums,
+ &budget_updates,
+ )?;
+
+ balances.push(CategoryBalance {
+ category_id: category.id,
+ balance: balance.try_into().unwrap(),
+ })
+ }
+
+ Ok(balances)
+}
diff --git a/rust/schist_core/src/queries/categories/get_all_ids.rs b/rust/schist_core/src/queries/categories/get_all_ids.rs
new file mode 100644
index 0000000..8505e71
--- /dev/null
+++ b/rust/schist_core/src/queries/categories/get_all_ids.rs
@@ -0,0 +1,11 @@
+use anyhow::{Context, Result};
+use crate::schema::categories::{self as categories_schema, dsl::categories as categories_table};
+use diesel::{QueryDsl, RunQueryDsl, SqliteConnection};
+
+pub fn get_all_category_ids(connection: &mut SqliteConnection) -> Result<Vec<i32>> {
+ let all_category_ids = categories_table
+ .select(categories_schema::id)
+ .load(connection)
+ .with_context(|| "failed to get all category IDs")?;
+ Ok(all_category_ids)
+}
diff --git a/rust/schist_core/src/queries/categories/get_most_recent_budget_per_category_id.rs b/rust/schist_core/src/queries/categories/get_most_recent_budget_per_category_id.rs
new file mode 100644
index 0000000..9f2e4f6
--- /dev/null
+++ b/rust/schist_core/src/queries/categories/get_most_recent_budget_per_category_id.rs
@@ -0,0 +1,52 @@
+use anyhow::{Context, Result};
+use crate::{models::{budget::Budget, category_budget::CategoryBudget}, queries::{
+ budget_updates::{
+ get_first_budget_update_with_date_and_category_id, get_most_recent_budget_update_date_with_category_id,
+ },
+ categories::get_all_category_ids,
+}};
+use diesel::SqliteConnection;
+
+pub fn get_most_recent_category_budget_per_category_id(
+ connection: &mut SqliteConnection,
+) -> Result<Vec<CategoryBudget>> {
+ get_most_recent_category_budget_per_category_id_without_context(connection)
+ .with_context(|| "failed to get most recent category budget per category ID")
+}
+
+fn get_most_recent_category_budget_per_category_id_without_context(
+ connection: &mut SqliteConnection,
+) -> Result<Vec<CategoryBudget>> {
+ let category_ids: Vec<i32> = get_all_category_ids(connection)?;
+
+ let mut budgets = Vec::<CategoryBudget>::new();
+ for category_id in category_ids {
+ let most_recent_budget_update_date =
+ get_most_recent_budget_update_date_with_category_id(category_id, connection)?;
+
+ if most_recent_budget_update_date.is_none() {
+ budgets.push(CategoryBudget {
+ category_id,
+ budget: Option::None,
+ });
+ continue;
+ }
+ let most_recent_budget_update_date = most_recent_budget_update_date.unwrap();
+
+ let most_recent_budget_update = get_first_budget_update_with_date_and_category_id(
+ &most_recent_budget_update_date,
+ category_id,
+ connection,
+ )?;
+ // The fact we found the date by getting the most recent budget update
+ // date guarantees that the Option is Some
+ let most_recent_budget_update = most_recent_budget_update.unwrap();
+
+ budgets.push(CategoryBudget {
+ category_id,
+ budget: Some(Budget::from(&most_recent_budget_update)),
+ });
+ }
+
+ Ok(budgets)
+}
diff --git a/rust/schist_core/src/queries/categories/insert.rs b/rust/schist_core/src/queries/categories/insert.rs
new file mode 100644
index 0000000..bccba72
--- /dev/null
+++ b/rust/schist_core/src/queries/categories/insert.rs
@@ -0,0 +1,28 @@
+use anyhow::{Context, Result};
+use crate::{
+ models::category::Category,
+ schema::categories::dsl::categories as categories_table,
+};
+use diesel::prelude::*;
+
+pub fn insert_categories(
+ categories: &[Category],
+ connection: &mut SqliteConnection,
+) -> Result<usize> {
+ let num_categories_inserted = diesel::insert_into(categories_table)
+ .values(categories)
+ .execute(connection)
+ .with_context(|| err_msg(categories))?;
+ Ok(num_categories_inserted)
+}
+
+fn err_msg(categories: &[Category]) -> String {
+ format!(
+ "failed to insert categories: [{}]",
+ categories
+ .iter()
+ .map(|a| format!("\"{}\": \"{}\"", a.id, a.name))
+ .collect::<Vec<String>>()
+ .join(", ")
+ )
+}
diff --git a/rust/schist_core/src/queries/categories/mod.rs b/rust/schist_core/src/queries/categories/mod.rs
new file mode 100644
index 0000000..edeeebf
--- /dev/null
+++ b/rust/schist_core/src/queries/categories/mod.rs
@@ -0,0 +1,13 @@
+mod delete_all;
+mod get_all;
+mod get_all_balances;
+mod get_all_ids;
+mod get_most_recent_budget_per_category_id;
+mod insert;
+
+pub use delete_all::delete_all_categories;
+pub use get_all::get_all_categories;
+pub use get_all_balances::get_all_category_balances;
+pub use get_all_ids::get_all_category_ids;
+pub use get_most_recent_budget_per_category_id::get_most_recent_category_budget_per_category_id;
+pub use insert::insert_categories;
diff --git a/rust/schist_core/src/queries/category_transfers/delete_all.rs b/rust/schist_core/src/queries/category_transfers/delete_all.rs
new file mode 100644
index 0000000..406b80b
--- /dev/null
+++ b/rust/schist_core/src/queries/category_transfers/delete_all.rs
@@ -0,0 +1,7 @@
+use diesel::{result::Error, RunQueryDsl, SqliteConnection};
+
+use crate::schema::category_transfers::dsl::category_transfers;
+
+pub fn delete_all_category_transfers(connection: &mut SqliteConnection) -> Result<usize, Error> {
+ diesel::delete(category_transfers).execute(connection)
+}
diff --git a/rust/schist_core/src/queries/category_transfers/get_all.rs b/rust/schist_core/src/queries/category_transfers/get_all.rs
new file mode 100644
index 0000000..73d7e10
--- /dev/null
+++ b/rust/schist_core/src/queries/category_transfers/get_all.rs
@@ -0,0 +1,11 @@
+use anyhow::{Context, Result};
+use crate::{models::category_transfer::CategoryTransfer, schema::category_transfers::dsl::category_transfers as category_transfers_table};
+use diesel::{QueryDsl, RunQueryDsl, SelectableHelper, SqliteConnection};
+
+pub fn get_all_category_transfers(connection: &mut SqliteConnection) -> Result<Vec<CategoryTransfer>> {
+ let all_category_transfers = category_transfers_table
+ .select(CategoryTransfer::as_select())
+ .load(connection)
+ .with_context(|| "failed to get all category transfers")?;
+ Ok(all_category_transfers)
+}
diff --git a/rust/schist_core/src/queries/category_transfers/insert.rs b/rust/schist_core/src/queries/category_transfers/insert.rs
new file mode 100644
index 0000000..e1db167
--- /dev/null
+++ b/rust/schist_core/src/queries/category_transfers/insert.rs
@@ -0,0 +1,15 @@
+use crate::{
+ models::category_transfer::CategoryTransfer,
+ schema::category_transfers::dsl::category_transfers as category_transfers_table,
+};
+use diesel::prelude::*;
+use diesel::result::Error;
+
+pub fn insert_category_transfers(
+ category_transfers: &[CategoryTransfer],
+ connection: &mut SqliteConnection,
+) -> Result<usize, Error> {
+ diesel::insert_into(category_transfers_table)
+ .values(category_transfers)
+ .execute(connection)
+}
diff --git a/rust/schist_core/src/queries/category_transfers/mod.rs b/rust/schist_core/src/queries/category_transfers/mod.rs
new file mode 100644
index 0000000..eed7946
--- /dev/null
+++ b/rust/schist_core/src/queries/category_transfers/mod.rs
@@ -0,0 +1,11 @@
+mod delete_all;
+mod get_all;
+mod insert;
+mod sum_quantity_per_from_category_id;
+mod sum_quantity_per_to_category_id;
+
+pub use delete_all::delete_all_category_transfers;
+pub use get_all::get_all_category_transfers;
+pub use insert::insert_category_transfers;
+pub use sum_quantity_per_from_category_id::sum_category_transfer_quantity_per_from_category_id;
+pub use sum_quantity_per_to_category_id::sum_category_transfer_quantity_per_to_category_id;
diff --git a/rust/schist_core/src/queries/category_transfers/sum_quantity_per_from_category_id.rs b/rust/schist_core/src/queries/category_transfers/sum_quantity_per_from_category_id.rs
new file mode 100644
index 0000000..a9c2a8c
--- /dev/null
+++ b/rust/schist_core/src/queries/category_transfers/sum_quantity_per_from_category_id.rs
@@ -0,0 +1,18 @@
+use crate::schema::category_transfers::{
+ self as category_transfers_schema,
+ dsl::category_transfers as category_transfers_table,
+};
+use diesel::{dsl::sum, result::Error, QueryDsl, RunQueryDsl, SqliteConnection};
+
+pub fn sum_category_transfer_quantity_per_from_category_id(
+ connection: &mut SqliteConnection,
+) -> Result<Vec<(i32, i64)>, Error> {
+ category_transfers_table
+ .group_by(category_transfers_schema::from_category_id)
+ .select((
+ category_transfers_schema::from_category_id,
+ sum(category_transfers_schema::quantity),
+ ))
+ .load::<(i32, Option<i64>)>(connection)
+ .map(|result| result.iter().map(|sum| (sum.0, sum.1.unwrap_or(0))).collect())
+}
diff --git a/rust/schist_core/src/queries/category_transfers/sum_quantity_per_to_category_id.rs b/rust/schist_core/src/queries/category_transfers/sum_quantity_per_to_category_id.rs
new file mode 100644
index 0000000..f041477
--- /dev/null
+++ b/rust/schist_core/src/queries/category_transfers/sum_quantity_per_to_category_id.rs
@@ -0,0 +1,18 @@
+use crate::schema::category_transfers::{
+ self as category_transfers_schema,
+ dsl::category_transfers as category_transfers_table,
+};
+use diesel::{dsl::sum, result::Error, QueryDsl, RunQueryDsl, SqliteConnection};
+
+pub fn sum_category_transfer_quantity_per_to_category_id(
+ connection: &mut SqliteConnection,
+) -> Result<Vec<(i32, i64)>, Error> {
+ category_transfers_table
+ .group_by(category_transfers_schema::to_category_id)
+ .select((
+ category_transfers_schema::to_category_id,
+ sum(category_transfers_schema::quantity),
+ ))
+ .load::<(i32, Option<i64>)>(connection)
+ .map(|vec| vec.iter().map(|(id, sum)| (*id, sum.unwrap_or(0))).collect())
+}
diff --git a/rust/schist_core/src/queries/clear.rs b/rust/schist_core/src/queries/clear.rs
new file mode 100644
index 0000000..e704634
--- /dev/null
+++ b/rust/schist_core/src/queries/clear.rs
@@ -0,0 +1,20 @@
+use anyhow::Result;
+use crate::queries::{
+ accounts::delete_all_accounts,
+ budget_updates::delete_all_budget_updates,
+ categories::delete_all_categories,
+ category_transfers::delete_all_category_transfers,
+ transactions::delete_all_transactions,
+ transaction_categorisations::delete_all_transaction_categorisations,
+};
+use diesel::SqliteConnection;
+
+pub fn clear(connection: &mut SqliteConnection) -> Result<()> {
+ delete_all_accounts(connection)?;
+ delete_all_budget_updates(connection)?;
+ delete_all_categories(connection)?;
+ delete_all_category_transfers(connection)?;
+ delete_all_transactions(connection)?;
+ delete_all_transaction_categorisations(connection)?;
+ Ok(())
+}
diff --git a/rust/schist_core/src/queries/mod.rs b/rust/schist_core/src/queries/mod.rs
new file mode 100644
index 0000000..f0852ce
--- /dev/null
+++ b/rust/schist_core/src/queries/mod.rs
@@ -0,0 +1,7 @@
+pub mod accounts;
+pub mod budget_updates;
+pub mod categories;
+pub mod category_transfers;
+pub mod clear;
+pub mod transactions;
+pub mod transaction_categorisations;
diff --git a/rust/schist_core/src/queries/transaction_categorisations/delete_all.rs b/rust/schist_core/src/queries/transaction_categorisations/delete_all.rs
new file mode 100644
index 0000000..e80a0ca
--- /dev/null
+++ b/rust/schist_core/src/queries/transaction_categorisations/delete_all.rs
@@ -0,0 +1,7 @@
+use diesel::{result::Error, RunQueryDsl, SqliteConnection};
+
+use crate::schema::transaction_categorisations::dsl::transaction_categorisations;
+
+pub fn delete_all_transaction_categorisations(connection: &mut SqliteConnection) -> Result<usize, Error> {
+ diesel::delete(transaction_categorisations).execute(connection)
+}
diff --git a/rust/schist_core/src/queries/transaction_categorisations/get_all.rs b/rust/schist_core/src/queries/transaction_categorisations/get_all.rs
new file mode 100644
index 0000000..0cacfe6
--- /dev/null
+++ b/rust/schist_core/src/queries/transaction_categorisations/get_all.rs
@@ -0,0 +1,11 @@
+use anyhow::{Context, Result};
+use crate::{models::transaction_categorisation::TransactionCategorisation, schema::transaction_categorisations::dsl::transaction_categorisations as transaction_categorisations_table};
+use diesel::{QueryDsl, RunQueryDsl, SelectableHelper, SqliteConnection};
+
+pub fn get_all_transaction_categorisations(connection: &mut SqliteConnection) -> Result<Vec<TransactionCategorisation>> {
+ let all_transaction_categorisations = transaction_categorisations_table
+ .select(TransactionCategorisation::as_select())
+ .load(connection)
+ .with_context(|| "failed to get all transaction categorisations")?;
+ Ok(all_transaction_categorisations)
+}
diff --git a/rust/schist_core/src/queries/transaction_categorisations/insert.rs b/rust/schist_core/src/queries/transaction_categorisations/insert.rs
new file mode 100644
index 0000000..3da1c33
--- /dev/null
+++ b/rust/schist_core/src/queries/transaction_categorisations/insert.rs
@@ -0,0 +1,15 @@
+use crate::{
+ models::transaction_categorisation::TransactionCategorisation,
+ schema::transaction_categorisations::dsl::transaction_categorisations as transaction_categorisations_table,
+};
+use diesel::prelude::*;
+use diesel::result::Error;
+
+pub fn insert_transaction_categorisations(
+ transaction_categorisations: &[TransactionCategorisation],
+ connection: &mut SqliteConnection,
+) -> Result<usize, Error> {
+ diesel::insert_into(transaction_categorisations_table)
+ .values(transaction_categorisations)
+ .execute(connection)
+}
diff --git a/rust/schist_core/src/queries/transaction_categorisations/mod.rs b/rust/schist_core/src/queries/transaction_categorisations/mod.rs
new file mode 100644
index 0000000..d383791
--- /dev/null
+++ b/rust/schist_core/src/queries/transaction_categorisations/mod.rs
@@ -0,0 +1,9 @@
+mod delete_all;
+mod get_all;
+mod insert;
+mod sum_quantity_per_category_id;
+
+pub use delete_all::delete_all_transaction_categorisations;
+pub use get_all::get_all_transaction_categorisations;
+pub use insert::insert_transaction_categorisations;
+pub use sum_quantity_per_category_id::sum_transaction_categorisation_quantity_per_category_id;
diff --git a/rust/schist_core/src/queries/transaction_categorisations/sum_quantity_per_category_id.rs b/rust/schist_core/src/queries/transaction_categorisations/sum_quantity_per_category_id.rs
new file mode 100644
index 0000000..61f3492
--- /dev/null
+++ b/rust/schist_core/src/queries/transaction_categorisations/sum_quantity_per_category_id.rs
@@ -0,0 +1,18 @@
+use crate::schema::transaction_categorisations::{
+ self as transaction_categorisations_schema,
+ dsl::transaction_categorisations as transaction_categorisations_table,
+};
+use diesel::{dsl::sum, result::Error, QueryDsl, RunQueryDsl, SqliteConnection};
+
+pub fn sum_transaction_categorisation_quantity_per_category_id(
+ connection: &mut SqliteConnection,
+) -> Result<Vec<(i32, i64)>, Error> {
+ transaction_categorisations_table
+ .group_by(transaction_categorisations_schema::category_id)
+ .select((
+ transaction_categorisations_schema::category_id,
+ sum(transaction_categorisations_schema::quantity),
+ ))
+ .load::<(i32, Option<i64>)>(connection)
+ .map(|vec| vec.iter().map(|(category_id, sum)| (*category_id, sum.unwrap_or(0))).collect())
+}
diff --git a/rust/schist_core/src/queries/transactions/delete_all.rs b/rust/schist_core/src/queries/transactions/delete_all.rs
new file mode 100644
index 0000000..43b7976
--- /dev/null
+++ b/rust/schist_core/src/queries/transactions/delete_all.rs
@@ -0,0 +1,7 @@
+use diesel::{result::Error, RunQueryDsl, SqliteConnection};
+
+use crate::schema::transactions::dsl::transactions;
+
+pub fn delete_all_transactions(connection: &mut SqliteConnection) -> Result<usize, Error> {
+ diesel::delete(transactions).execute(connection)
+}
diff --git a/rust/schist_core/src/queries/transactions/get_all.rs b/rust/schist_core/src/queries/transactions/get_all.rs
new file mode 100644
index 0000000..afb87f4
--- /dev/null
+++ b/rust/schist_core/src/queries/transactions/get_all.rs
@@ -0,0 +1,11 @@
+use anyhow::{Context, Result};
+use crate::{models::transaction::Transaction, schema::transactions::dsl::transactions as transactions_table};
+use diesel::{QueryDsl, RunQueryDsl, SelectableHelper, SqliteConnection};
+
+pub fn get_all_transactions(connection: &mut SqliteConnection) -> Result<Vec<Transaction>> {
+ let all_transactions = transactions_table
+ .select(Transaction::as_select())
+ .load(connection)
+ .with_context(|| "failed to get all category transfers")?;
+ Ok(all_transactions)
+}
diff --git a/rust/schist_core/src/queries/transactions/insert.rs b/rust/schist_core/src/queries/transactions/insert.rs
new file mode 100644
index 0000000..32f3dc2
--- /dev/null
+++ b/rust/schist_core/src/queries/transactions/insert.rs
@@ -0,0 +1,15 @@
+use crate::{
+ models::transaction::Transaction,
+ schema::transactions::dsl::transactions as transactions_table,
+};
+use diesel::prelude::*;
+use diesel::result::Error;
+
+pub fn insert_transactions(
+ transactions: &[Transaction],
+ connection: &mut SqliteConnection,
+) -> Result<usize, Error> {
+ diesel::insert_into(transactions_table)
+ .values(transactions)
+ .execute(connection)
+}
diff --git a/rust/schist_core/src/queries/transactions/mod.rs b/rust/schist_core/src/queries/transactions/mod.rs
new file mode 100644
index 0000000..983e9af
--- /dev/null
+++ b/rust/schist_core/src/queries/transactions/mod.rs
@@ -0,0 +1,7 @@
+mod delete_all;
+mod get_all;
+mod insert;
+
+pub use delete_all::delete_all_transactions;
+pub use get_all::get_all_transactions;
+pub use insert::insert_transactions;