implement basic multi-day support
This commit is contained in:
parent
4a3ffb5ac6
commit
d7fc530201
10 changed files with 98 additions and 44 deletions
BIN
foods.db
BIN
foods.db
Binary file not shown.
|
|
@ -1,14 +1,17 @@
|
|||
UPDATE
|
||||
food
|
||||
SET
|
||||
actual_servings = MAX(
|
||||
(SELECT
|
||||
actual_servings
|
||||
INSERT OR REPLACE INTO
|
||||
day_serving (day, food_id, servings_eaten)
|
||||
VALUES (
|
||||
CURRENT_DATE,
|
||||
?1,
|
||||
MAX(coalesce((
|
||||
SELECT
|
||||
servings_eaten
|
||||
FROM
|
||||
food
|
||||
WHERE id = ?1) - 1,
|
||||
0)
|
||||
day_serving
|
||||
WHERE
|
||||
id = ?1
|
||||
RETURNING
|
||||
actual_servings
|
||||
food_id = ?1
|
||||
AND day = CURRENT_DATE
|
||||
) - 1,
|
||||
0
|
||||
), 0)
|
||||
) RETURNING servings_eaten;
|
||||
|
|
|
|||
|
|
@ -4,9 +4,14 @@ SELECT
|
|||
name,
|
||||
kc_per_serving,
|
||||
target_servings,
|
||||
actual_servings,
|
||||
coalesce(day_serving.servings_eaten, 0),
|
||||
color
|
||||
FROM
|
||||
food
|
||||
LEFT JOIN
|
||||
day_serving
|
||||
ON
|
||||
day_serving.food_id = food.id
|
||||
AND day_serving.day = CURRENT_DATE
|
||||
WHERE
|
||||
id = ?1
|
||||
food.id = ?1;
|
||||
|
|
|
|||
|
|
@ -1,12 +1,18 @@
|
|||
SELECT
|
||||
id,
|
||||
portion,
|
||||
name,
|
||||
kc_per_serving,
|
||||
target_servings,
|
||||
actual_servings,
|
||||
color
|
||||
food.id,
|
||||
food.portion,
|
||||
food.name,
|
||||
food.kc_per_serving,
|
||||
food.target_servings,
|
||||
coalesce(day_serving.servings_eaten, 0) as servings_eaten,
|
||||
food.color
|
||||
FROM
|
||||
food
|
||||
LEFT JOIN
|
||||
day_serving
|
||||
ON
|
||||
day_serving.food_id = food.id
|
||||
WHERE
|
||||
coalesce(day_serving.day, CURRENT_DATE) = CURRENT_DATE
|
||||
ORDER BY
|
||||
sort_order, name;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,11 @@
|
|||
SELECT
|
||||
SUM(kc_per_serving * actual_servings) AS kc,
|
||||
SUM(protein_per_portion * actual_servings) AS protein,
|
||||
SUM(fiber_per_portion * actual_servings) AS bs
|
||||
SUM(kc_per_serving * servings_eaten) AS kc,
|
||||
SUM(protein_per_portion * servings_eaten) AS protein,
|
||||
SUM(fiber_per_portion * servings_eaten) AS bs
|
||||
FROM
|
||||
food
|
||||
LEFT JOIN
|
||||
day_serving
|
||||
ON
|
||||
day_serving.food_id = food.id
|
||||
AND day_serving.day = CURRENT_DATE;
|
||||
|
|
|
|||
|
|
@ -1,9 +1,17 @@
|
|||
UPDATE
|
||||
food
|
||||
SET actual_servings = (
|
||||
SELECT actual_servings
|
||||
FROM food
|
||||
WHERE id = ?1
|
||||
) + 1
|
||||
WHERE id = ?1
|
||||
RETURNING actual_servings
|
||||
INSERT OR REPLACE INTO
|
||||
day_serving (day, food_id, servings_eaten)
|
||||
VALUES (
|
||||
CURRENT_DATE,
|
||||
?1,
|
||||
coalesce((
|
||||
SELECT
|
||||
servings_eaten
|
||||
FROM
|
||||
day_serving
|
||||
WHERE
|
||||
food_id = ?1
|
||||
AND day = CURRENT_DATE
|
||||
) + 1,
|
||||
1
|
||||
)
|
||||
) RETURNING servings_eaten;
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ struct Food {
|
|||
name: String,
|
||||
kc_per_serving: i32,
|
||||
target_servings: i32,
|
||||
actual_servings: i32,
|
||||
servings_eaten: i32,
|
||||
color: String,
|
||||
}
|
||||
|
||||
|
|
@ -69,7 +69,7 @@ impl Food {
|
|||
name: row.get(2)?,
|
||||
kc_per_serving: row.get(3)?,
|
||||
target_servings: row.get(4)?,
|
||||
actual_servings: row.get(5)?,
|
||||
servings_eaten: row.get(5)?,
|
||||
color: row.get(6)?,
|
||||
})
|
||||
}
|
||||
|
|
@ -127,6 +127,8 @@ struct AppError(anyhow::Error);
|
|||
// Tell axum how to convert `AppError` into a response.
|
||||
impl IntoResponse for AppError {
|
||||
fn into_response(self) -> Response {
|
||||
let error = &self.0;
|
||||
error!(?error, "error returned to client");
|
||||
(
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
format!("Something went wrong: {}", self.0),
|
||||
|
|
@ -152,12 +154,13 @@ fn get_version(tx: &Transaction) -> anyhow::Result<usize> {
|
|||
Ok(tx.query_one(include_str!("get_version.sql"), (), |row| row.get(0))?)
|
||||
}
|
||||
|
||||
fn get_migrations() -> [&'static str; 4] {
|
||||
fn get_migrations() -> [&'static str; 5] {
|
||||
[
|
||||
include_str!("migrations/1.sql"),
|
||||
include_str!("migrations/2.sql"),
|
||||
include_str!("migrations/3.sql"),
|
||||
include_str!("migrations/4.sql"),
|
||||
include_str!("migrations/5.sql"),
|
||||
]
|
||||
}
|
||||
|
||||
|
|
|
|||
23
src/migrations/5.sql
Normal file
23
src/migrations/5.sql
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
CREATE TABLE day_serving (
|
||||
-- ISO-8601
|
||||
day TEXT NOT NULL DEFAULT CURRENT_DATE,
|
||||
food_id INTEGER NOT NULL,
|
||||
servings_eaten INTEGER NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY(day, food_id),
|
||||
FOREIGN KEY(food_id) REFERENCES food(id)
|
||||
) STRICT;
|
||||
|
||||
INSERT INTO
|
||||
day_serving (food_id, servings_eaten)
|
||||
SELECT
|
||||
id,
|
||||
actual_servings
|
||||
FROM
|
||||
food;
|
||||
|
||||
ALTER TABLE
|
||||
food
|
||||
DROP COLUMN
|
||||
actual_servings;
|
||||
|
||||
PRAGMA user_version = 5;
|
||||
|
|
@ -1,8 +1,9 @@
|
|||
UPDATE
|
||||
food
|
||||
day_serving
|
||||
SET
|
||||
actual_servings = MAX(?2, 0)
|
||||
servings_eaten = MAX(?2, 0)
|
||||
WHERE
|
||||
id = ?1
|
||||
food_id = ?1
|
||||
AND day = CURRENT_DATE
|
||||
RETURNING
|
||||
actual_servings
|
||||
servings_eaten
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
{% for counter in self::range(10) %}
|
||||
{% if loop.index as i32 <= food.target_servings %}
|
||||
<label class="ok">
|
||||
{% if loop.index as i32 <= food.actual_servings %}
|
||||
{% if loop.index as i32 <= food.servings_eaten %}
|
||||
<input type="button" hx-post="/set/{{ food.id }}/to/{{ loop.index as i32 - 1}}" hx-target="#card-{{ food.id }}" value="●" class="checked">
|
||||
{% else %}
|
||||
<input type="button" hx-post="/set/{{ food.id }}/to/{{ loop.index as i32 }}" hx-target="#card-{{ food.id }}" value="●" class="unchecked">
|
||||
|
|
@ -28,7 +28,7 @@
|
|||
</label>
|
||||
{% else %}
|
||||
<label class="bad">
|
||||
{% if loop.index as i32 <= food.actual_servings %}
|
||||
{% if loop.index as i32 <= food.servings_eaten %}
|
||||
<input type="button" hx-post="/set/{{ food.id }}/to/{{ loop.index as i32 - 1}}" hx-target="#card-{{ food.id }}" value="●" class="checked">
|
||||
{% else %}
|
||||
<input type="button" hx-post="/set/{{ food.id }}/to/{{ loop.index as i32 }}" hx-target="#card-{{ food.id }}" value="●" class="unchecked">
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue