From d2a253fb24824bd6c436e08dd039777cf8353f42 Mon Sep 17 00:00:00 2001 From: Pratyush Desai Date: Sat, 14 Jun 2025 18:16:55 +0530 Subject: [PATCH] Initialized Add basic CRUD operations for the doselogging and a list command. Signed-off-by: Pratyush Desai --- .gitignore | 2 ++ README.md | 7 ++++++ add.go | 37 ++++++++++++++++++++++++++++++++ db.go | 32 ++++++++++++++++++++++++++++ delete.go | 31 +++++++++++++++++++++++++++ dose.go | 13 ++++++++++++ edit.go | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ go.mod | 5 +++++ go.sum | 2 ++ list.go | 29 +++++++++++++++++++++++++ main.go | 30 ++++++++++++++++++++++++++ 11 files changed, 250 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 add.go create mode 100644 db.go create mode 100644 delete.go create mode 100644 dose.go create mode 100644 edit.go create mode 100644 go.mod create mode 100644 go.sum create mode 100644 list.go create mode 100644 main.go diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1d78859 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +doses.db +godose \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..3bb7f6d --- /dev/null +++ b/README.md @@ -0,0 +1,7 @@ +# godose + +* add +* edit +* delete +* list +* diff --git a/add.go b/add.go new file mode 100644 index 0000000..57fc0a6 --- /dev/null +++ b/add.go @@ -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.") +} diff --git a/db.go b/db.go new file mode 100644 index 0000000..de2d641 --- /dev/null +++ b/db.go @@ -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 +} diff --git a/delete.go b/delete.go new file mode 100644 index 0000000..01dd2a7 --- /dev/null +++ b/delete.go @@ -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.") + } +} diff --git a/dose.go b/dose.go new file mode 100644 index 0000000..91d02c4 --- /dev/null +++ b/dose.go @@ -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 +} diff --git a/edit.go b/edit.go new file mode 100644 index 0000000..8b67026 --- /dev/null +++ b/edit.go @@ -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.") +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..e47d248 --- /dev/null +++ b/go.mod @@ -0,0 +1,5 @@ +module godose + +go 1.24.2 + +require github.com/mattn/go-sqlite3 v1.14.28 diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..42e5bac --- /dev/null +++ b/go.sum @@ -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= diff --git a/list.go b/list.go new file mode 100644 index 0000000..3ed196a --- /dev/null +++ b/list.go @@ -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) + } + } +} diff --git a/main.go b/main.go new file mode 100644 index 0000000..cbd708e --- /dev/null +++ b/main.go @@ -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]) + } + +}