Initialized
Add basic CRUD operations for the doselogging and a list command. Signed-off-by: Pratyush Desai <pratyush.desai@liberta.casa>
This commit is contained in:
commit
d2a253fb24
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
doses.db
|
||||||
|
godose
|
||||||
37
add.go
Normal file
37
add.go
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"database/sql"
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func addDose(db *sql.DB, args []string) {
|
||||||
|
fs := flag.NewFlagSet("add", flag.ExitOnError)
|
||||||
|
substance := fs.String("substance", "", "Name of substance")
|
||||||
|
dose := fs.Float64("dose", 0, "Amount taken")
|
||||||
|
unit := fs.String("unit", "", "Unit of dose")
|
||||||
|
roa := fs.String("roa", "", "Route of administration")
|
||||||
|
notes := fs.String("notes", "", "Optional notes")
|
||||||
|
|
||||||
|
fs.Parse(args)
|
||||||
|
|
||||||
|
if *substance == "" || *dose <= 0 || *unit == "" || *roa == "" {
|
||||||
|
fmt.Println("Error: --substance, --dose, --unit, and --roa are required")
|
||||||
|
fs.Usage()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := db.Exec(
|
||||||
|
"INSERT INTO doses (time, substance, dose, unit, roa, notes) VALUES (?, ?, ?, ?, ?, ?)",
|
||||||
|
time.Now().Format(time.RFC3339), *substance, *dose, *unit, *roa, *notes,
|
||||||
|
)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Failed to add dose:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Dose added.")
|
||||||
|
}
|
||||||
32
db.go
Normal file
32
db.go
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"database/sql"
|
||||||
|
"log"
|
||||||
|
|
||||||
|
_ "github.com/mattn/go-sqlite3"
|
||||||
|
)
|
||||||
|
|
||||||
|
func initDB() *sql.DB {
|
||||||
|
db, err := sql.Open("sqlite3", "./doses.db")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
createTable := `
|
||||||
|
CREATE TABLE IF NOT EXISTS doses (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
time TEXT NOT NULL,
|
||||||
|
substance TEXT NOT NULL,
|
||||||
|
dose REAL NOT NULL,
|
||||||
|
unit TEXT NOT NULL,
|
||||||
|
roa TEXT,
|
||||||
|
notes TEXT
|
||||||
|
);
|
||||||
|
`
|
||||||
|
if _, err := db.Exec(createTable); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return db
|
||||||
|
}
|
||||||
31
delete.go
Normal file
31
delete.go
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"database/sql"
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
func deleteDose(db *sql.DB, args []string) {
|
||||||
|
fs := flag.NewFlagSet("delete", flag.ExitOnError)
|
||||||
|
id := fs.Int("id", -1, "ID of dose to delete")
|
||||||
|
fs.Parse(args)
|
||||||
|
|
||||||
|
if *id < 0 {
|
||||||
|
fmt.Println("Error: --id is required")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := db.Exec("DELETE FROM doses WHERE id = ?", *id)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Failed to delete:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
count, _ := res.RowsAffected()
|
||||||
|
if count == 0 {
|
||||||
|
fmt.Println("No dose found with that ID")
|
||||||
|
} else {
|
||||||
|
fmt.Println("Dose deleted.")
|
||||||
|
}
|
||||||
|
}
|
||||||
13
dose.go
Normal file
13
dose.go
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
type Dose struct {
|
||||||
|
ID int
|
||||||
|
Time time.Time
|
||||||
|
Substance string
|
||||||
|
Dose float64
|
||||||
|
Unit string
|
||||||
|
Roa string
|
||||||
|
Notes string
|
||||||
|
}
|
||||||
62
edit.go
Normal file
62
edit.go
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"database/sql"
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
func editDose(db *sql.DB, args []string) {
|
||||||
|
fs := flag.NewFlagSet("edit", flag.ExitOnError)
|
||||||
|
id := fs.Int("id", -1, "ID of dose to edit")
|
||||||
|
substance := fs.String("substance", "", "New substance name")
|
||||||
|
dose := fs.Float64("dose", -1, "New dose")
|
||||||
|
unit := fs.String("unit", "", "New unit")
|
||||||
|
roa := fs.String("roa", "", "New route")
|
||||||
|
notes := fs.String("notes", "", "New notes")
|
||||||
|
|
||||||
|
fs.Parse(args)
|
||||||
|
|
||||||
|
if *id < 0 {
|
||||||
|
fmt.Println("Error: --id is required")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// fetch existing
|
||||||
|
row := db.QueryRow("SELECT substance, dose, unit, roa, notes FROM doses WHERE id = ?", *id)
|
||||||
|
var s, u, r, n string
|
||||||
|
var d float64
|
||||||
|
err := row.Scan(&s, &d, &u, &r, &n)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Dose not found:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// override if new values provided
|
||||||
|
if *substance != "" {
|
||||||
|
s = *substance
|
||||||
|
}
|
||||||
|
if *dose >= 0 {
|
||||||
|
d = *dose
|
||||||
|
}
|
||||||
|
if *unit != "" {
|
||||||
|
u = *unit
|
||||||
|
}
|
||||||
|
if *roa != "" {
|
||||||
|
r = *roa
|
||||||
|
}
|
||||||
|
if *notes != "" {
|
||||||
|
n = *notes
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = db.Exec("UPDATE doses SET substance = ?, dose = ?, unit = ?, roa = ?, notes = ? WHERE id = ?",
|
||||||
|
s, d, u, r, n, *id,
|
||||||
|
)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Update failed:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Dose updated.")
|
||||||
|
}
|
||||||
5
go.mod
Normal file
5
go.mod
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
module godose
|
||||||
|
|
||||||
|
go 1.24.2
|
||||||
|
|
||||||
|
require github.com/mattn/go-sqlite3 v1.14.28
|
||||||
2
go.sum
Normal file
2
go.sum
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
github.com/mattn/go-sqlite3 v1.14.28 h1:ThEiQrnbtumT+QMknw63Befp/ce/nUPgBPMlRFEum7A=
|
||||||
|
github.com/mattn/go-sqlite3 v1.14.28/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
|
||||||
29
list.go
Normal file
29
list.go
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"database/sql"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func listDoses(db *sql.DB) {
|
||||||
|
rows, err := db.Query("SELECT id, time, substance, dose, unit, roa, notes FROM doses ORDER BY time DESC")
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Failed to query doses:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
|
||||||
|
for rows.Next() {
|
||||||
|
var d Dose
|
||||||
|
var t string
|
||||||
|
rows.Scan(&d.ID, &t, &d.Substance, &d.Dose, &d.Unit, &d.Roa, &d.Notes)
|
||||||
|
d.Time, _ = time.Parse(time.RFC3339, t)
|
||||||
|
|
||||||
|
fmt.Printf("#%d | %s | %s: %.2f %s (%s)\n", d.ID, d.Time.Format("2006-01-02 15:04"), d.Substance, d.Dose, d.Unit, d.Roa)
|
||||||
|
if d.Notes != "" {
|
||||||
|
fmt.Println(" Notes:", d.Notes)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
30
main.go
Normal file
30
main.go
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
db := initDB()
|
||||||
|
defer db.Close()
|
||||||
|
|
||||||
|
if len(os.Args) < 2 {
|
||||||
|
fmt.Println("Usage: dose [add|list]")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
switch os.Args[1] {
|
||||||
|
case "add":
|
||||||
|
addDose(db, os.Args[2:])
|
||||||
|
case "list":
|
||||||
|
listDoses(db)
|
||||||
|
case "delete":
|
||||||
|
deleteDose(db, os.Args[2:])
|
||||||
|
case "edit":
|
||||||
|
editDose(db, os.Args[2:])
|
||||||
|
default:
|
||||||
|
fmt.Println("Unknown command:", os.Args[1])
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user