Adding bodymass support

This commit is contained in:
2025-10-21 11:21:57 +02:00
parent 090d869bad
commit 3a3d121511
5 changed files with 2604 additions and 4 deletions

View File

@@ -11,7 +11,18 @@ create table account (
id serial primary key, id serial primary key,
name varchar not null, name varchar not null,
login varchar not null, login varchar not null,
birthdate date not null birthdate date not null,
bodymass integer,
constraint fk_bodymass foreign key (bodymass) references bodymass(id)
);
create table bodymass (
id serial primary key,
account integer not null,
time timestamptz not null,
kilos numeric(4,1) not null,
constraint fk_account foreign key (account) references account(id),
constraint unique_account_time unique (account, time),
constraint time_not_infty check (time <> 'infinity'::timestamptz)
); );
create table training ( create table training (
id serial primary key, id serial primary key,

26
db/readme.md Normal file
View File

@@ -0,0 +1,26 @@
## Joining to bodymass table by time
Data in the bodymass table can be transformed as (for account 1):
```sql
select kilos, time as start, (case when lead(time) over (order by time asc) is null then 'infinity'::timestamptz else lead(time) over (order by time asc) end) as end from bodymass where account=1;
```
Thereby giving a table with clear timespans. Joining can then be performed by a nested table:
```
with bm_report as (
select kilos, time as start,
(case when lead(time) over (order by time asc) is null
then 'infinity'::timestamptz
else lead(time) over (order by time asc) end) as end from bodymass
where account=1)
select
t.time, t.exercise, t.kilos, b.kilos as bodymass, round(100*t.kilos/b.kilos, 1) as ratio
from training t
inner join bm_report b on t.time >= b.start and t.time < b.end
where t.account=1 and exercise=1
order by 1;
```

View File

@@ -41,7 +41,7 @@ of unix domain socket in `/var/run/postgresql`.
Now training can be invoked with: Now training can be invoked with:
``` ```
train squat 3 10 60 train report squat 3 10 60
``` ```
Which would register squauts, 3 runs of 10 reps of 60kg -- at local time and date. Optionally a Which would register squauts, 3 runs of 10 reps of 60kg -- at local time and date. Optionally a

2542
train-cli/Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -36,8 +36,9 @@ enum Commands {
/// time, either "2025-05-20T14:15:20+0200", "2025-12-24 18:00:00" or "17:15:00" /// time, either "2025-05-20T14:15:20+0200", "2025-12-24 18:00:00" or "17:15:00"
time: Option<String>, time: Option<String>,
} },
Latest {
},
} }
fn main() { fn main() {
@@ -45,6 +46,7 @@ fn main() {
match &args.command { match &args.command {
Commands::Report { exercise, runs, reps, kilos, time } => insert_training(exercise, runs, reps, kilos, time), Commands::Report { exercise, runs, reps, kilos, time } => insert_training(exercise, runs, reps, kilos, time),
Commands::Message { text, time } => insert_message(text, time), Commands::Message { text, time } => insert_message(text, time),
Commands::Latest {} => get_latest(),
} }
} }
@@ -119,3 +121,22 @@ fn insert_training (exercise: &String, runs: &i16, reps: &i16, kilos: &f32, time
} }
}); });
} }
fn get_latest () {
let mut client = get_client();
let res = client.query("with report as (select distinct on (t.exercise) t.time, t.exercise, t.kilos
from training t inner join account a on a.id=t.account where a.login=$1 order by 2, 1 desc)
select date_trunc('second', r.time), e.name, r.kilos from report r inner join exercise e on e.id=r.exercise order by 2",
&[&whoami::username()]);
match res {
Ok(resultset) => {
for r in resultset {
let time : DateTime<FixedOffset> = r.get(0);
let exercise : String= r.get(1);
let kilos: Decimal = r.get(2);
println!("{time} {exercise:>15} {kilos:>5}", time=time, exercise=exercise, kilos=kilos);
}
},
Err(e) => println!("Report not fetched, since: {}", e)
}
}