use chrono::NaiveDate;
use sqlx::error::Error;
use sqlx::sqlite::{SqlitePool, SqliteRow};
use sqlx_core::row::Row;
use std::collections::HashMap;
use std::iter::FromIterator;
use crate::model::income::{Create, Form, Stat, Table, Update};
use crate::model::report::Report;
pub async fn count(pool: &SqlitePool) -> i64 {
let query = r#"
SELECT
COUNT(*) AS count
FROM
incomes
WHERE
incomes.deleted_at IS NULL
"#;
let res = sqlx::query(query)
.map(|row: SqliteRow| row.get("count"))
.fetch_one(pool)
.await;
match res {
Ok(count) => count,
Err(err) => {
error!("Error counting incomes: {:?}", err);
0
}
}
}
pub async fn list(pool: &SqlitePool, page: i64, per_page: i64) -> Vec
{
let query = r#"
SELECT
incomes.id,
users.name AS user,
strftime('%m/%Y', incomes.date) AS date,
incomes.amount
FROM
incomes
INNER JOIN
users
ON
incomes.user_id = users.id
WHERE
incomes.deleted_at IS NULL
ORDER BY
incomes.date DESC
LIMIT ?
OFFSET ?
"#;
let res = sqlx::query_as::<_, Table>(query)
.bind(per_page)
.bind((page - 1) * per_page)
.fetch_all(pool)
.await;
match res {
Ok(incomes) => incomes,
Err(err) => {
error!("Error listing incomes: {:?}", err);
vec![]
}
}
}
pub async fn get_row(pool: &SqlitePool, id: i64) -> i64 {
let query = r#"
SELECT
row
FROM (
SELECT
ROW_NUMBER () OVER (ORDER BY date DESC) AS row,
id
FROM
incomes
WHERE
deleted_at IS NULL
)
WHERE
id = ?
"#;
let res = sqlx::query(query)
.bind(id)
.map(|row: SqliteRow| row.get("row"))
.fetch_one(pool)
.await;
match res {
Ok(count) => count,
Err(err) => {
error!("Error getting income row: {:?}", err);
1
}
}
}
pub async fn get(pool: &SqlitePool, id: i64) -> Option