package main import ( "fmt" "log" ) type ( WeightService struct { db *DB } Weight struct { Rowid int64 `json:"rowid"` Date string `json:"date"` Weight float32 `json:"weight"` } AggregatedWeight struct { Period string `json:"period"` Amount float32 `json:"amount"` } ) const weightcolumns = "rowid, date, weight" const weightAggregatedColumns = "period, amount" func (w *WeightService) GetRecent() ([]Weight, error) { var res []Weight if w.db == nil || !w.db.Ready { return res, fmt.Errorf("cannot get recent weight, db is nil or is not ready") } row, err := w.db.readConn.Query(fmt.Sprintf("SELECT %s from weightView WHERE date > datetime('now', '-%d days') order by date desc;", weightcolumns, Settings.WeightDaysLookback)) if err != nil { log.Printf("error getting daily weight: %v", err) return res, err } for row.Next() { var weight Weight err := row.Scan(&weight.Rowid, &weight.Date, &weight.Weight) if err != nil { log.Printf("error scanning row: %v", err) continue } res = append(res, weight) } return res, nil } func (w *WeightService) Create(weight Weight) (Weight, error) { if w.db == nil || !w.db.Ready { return weight, fmt.Errorf("cannot create weight, db is nil or is not ready") } if weight.Weight <= 0 { return weight, fmt.Errorf("cannot create weight, weight is empty") } res, err := w.db.writeConn.Exec("INSERT INTO weight (weight) VALUES (?)", weight.Weight) if err != nil { return weight, fmt.Errorf("error inserting weight: %v", err) } rowid, err := res.LastInsertId() if err != nil { return weight, fmt.Errorf("error getting last insert id: %v", err) } return w.GetByRowid(rowid) } func (w *WeightService) GetByRowid(rowid int64) (Weight, error) { var res Weight if w.db == nil || !w.db.Ready { return res, fmt.Errorf("cannot get weight by rowid, db is nil or is not ready") } row := w.db.readConn.QueryRow(fmt.Sprintf("SELECT %s from weightView WHERE rowid = ?", weightcolumns), rowid) err := row.Scan(&res.Rowid, &res.Date, &res.Weight) if err != nil { return res, fmt.Errorf("error scanning row: %v", err) } return res, nil } // I could probably refactor this to be less of a disaster... // But I think it'll work for now func (w *WeightService) GetDaily() ([]AggregatedWeight, error) { var res []AggregatedWeight if w.db == nil || !w.db.Ready { return res, fmt.Errorf("cannot get daily weight, db is nil or is not ready") } row, err := w.db.readConn.Query(fmt.Sprintf("SELECT %s from weightDaily LIMIT %d", weightAggregatedColumns, Settings.WeightDailyLookback)) if err != nil { log.Printf("error getting daily weight: %v", err) return res, err } for row.Next() { var weight AggregatedWeight err := row.Scan(&weight.Period, &weight.Amount) if err != nil { log.Printf("error scanning row: %v", err) continue } res = append(res, weight) } return res, nil } func (w *WeightService) GetWeekly() ([]AggregatedWeight, error) { var res []AggregatedWeight if w.db == nil || !w.db.Ready { return res, fmt.Errorf("cannot get weekly weight, db is nil or is not ready") } row, err := w.db.readConn.Query(fmt.Sprintf("SELECT %s from weightWeekly LIMIT %d", weightAggregatedColumns, Settings.WeightWeeklyLookback)) if err != nil { log.Printf("error getting weekly weight: %v", err) return res, err } for row.Next() { var weight AggregatedWeight err := row.Scan(&weight.Period, &weight.Amount) if err != nil { log.Printf("error scanning row: %v", err) continue } res = append(res, weight) } return res, nil } func (w *WeightService) GetMonthly() ([]AggregatedWeight, error) { var res []AggregatedWeight if w.db == nil || !w.db.Ready { return res, fmt.Errorf("cannot get monthly weight, db is nil or is not ready") } row, err := w.db.readConn.Query(fmt.Sprintf("SELECT %s from weightMonthly LIMIT %d", weightAggregatedColumns, Settings.WeightMonthlyLookback)) if err != nil { log.Printf("error getting monthly weight: %v", err) return res, err } for row.Next() { var weight AggregatedWeight err := row.Scan(&weight.Period, &weight.Amount) if err != nil { log.Printf("error scanning row: %v", err) continue } res = append(res, weight) } return res, nil } func (w *WeightService) GetYearly() ([]AggregatedWeight, error) { var res []AggregatedWeight if w.db == nil || !w.db.Ready { return res, fmt.Errorf("cannot get yearly weight, db is nil or is not ready") } row, err := w.db.readConn.Query(fmt.Sprintf("SELECT %s from weightYearly LIMIT %d", weightAggregatedColumns, Settings.WeightYearlyLookback)) if err != nil { log.Printf("error getting yearly weight: %v", err) return res, err } for row.Next() { var weight AggregatedWeight err := row.Scan(&weight.Period, &weight.Amount) if err != nil { log.Printf("error scanning row: %v", err) continue } res = append(res, weight) } return res, nil }