Adding bodymass support
This commit is contained in:
@@ -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
26
db/readme.md
Normal 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;
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
@@ -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
2542
train-cli/Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user