commit d2a253fb24824bd6c436e08dd039777cf8353f42 Author: Pratyush Desai Date: Sat Jun 14 18:16:55 2025 +0530 Initialized Add basic CRUD operations for the doselogging and a list command. Signed-off-by: Pratyush Desai 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]) + } + +}