From 2dad3f13051c0133d326cd28c080d43a35794bf4 Mon Sep 17 00:00:00 2001 From: bronku Date: Fri, 21 Mar 2025 18:50:26 +0100 Subject: [PATCH] Separate db initialization from store opening --- TODO.md | 2 ++ handler.go | 6 ++++++ main.go | 25 ++++++++++--------------- store.go | 31 +++++++++++++++++-------------- store_test.go | 2 +- 5 files changed, 36 insertions(+), 30 deletions(-) diff --git a/TODO.md b/TODO.md index 31eab8b..6bb1a35 100644 --- a/TODO.md +++ b/TODO.md @@ -4,6 +4,7 @@ - [ ] Database Implementation + - [ ] Init mode to create a new db - [x] Set up SQLite database - [x] Create proper schemas - [x] Implement data persistence @@ -123,6 +124,7 @@ - [ ] Integration Tests - [ ] File structure - [ ] Embed templates +- [ ] Single init function for handler ## Future Considerations diff --git a/handler.go b/handler.go index a7d3490..f9227da 100644 --- a/handler.go +++ b/handler.go @@ -14,6 +14,12 @@ type handler struct { s *store } +func (h *handler) close() { + if h.s != nil { + h.s.close() + } +} + func (h *handler) form(w http.ResponseWriter, r *http.Request) { url := strings.Split(r.URL.String(), "/") o := order{ diff --git a/main.go b/main.go index eb8ac0e..21c4673 100644 --- a/main.go +++ b/main.go @@ -4,33 +4,28 @@ import ( "html/template" "log" "net/http" - "time" _ "github.com/mattn/go-sqlite3" ) func main() { + var err error var h handler - templates, err := template.ParseFiles("index.html", "order.html") + defer h.close() + + h.tmpl, err = template.ParseFiles("index.html", "order.html") if err != nil { log.Fatal("can't parse templates: ", err) } - h.tmpl = templates - // #todo: error handling - h.s, _ = NewStore("./foo.db") - h.s.saveCake(cake{"Sernik ulubiony", -1, 65, 0}) - h.s.saveCake(cake{"Malinowa chmurka", -1, 150, 0}) - h.s.saveCake(cake{"Mako sernik", -1, 150, 0}) - h.s.saveCake(cake{"Rolada makowa", -1, 80, 0}) - h.s.saveCake(cake{"Wieniec bezowy", -1, 120, 0}) - - h.s.saveOrder(order{-1, "Albert", "Camus", "123456789", "Kartuzy", time.Now().AddDate(0, 0, 7), time.Now(), "accepted", 0, nil}) - h.s.saveOrder(order{-1, "George", "Orwell", "", "Kartuzy", time.Now().AddDate(0, 1, 0), time.Now(), "accepted", 0, nil}) - h.s.saveOrder(order{-1, "Karl", "Marx", "0700", "Somonino", time.Now(), time.Now(), "accepted", 0, nil}) + h.s, err = openStore("./foo.db") + if err != nil { + log.Fatal("can't open the databse", err) + } http.HandleFunc("GET /order/", logger(h.form)) http.HandleFunc("GET /", logger(h.index)) http.HandleFunc("POST /", logger(h.addOrder)) - http.ListenAndServe(":8080", nil) + go http.ListenAndServe(":8080", nil) + adminConsole() } diff --git a/store.go b/store.go index ec073c2..e913a4e 100644 --- a/store.go +++ b/store.go @@ -3,6 +3,7 @@ package main import ( "database/sql" _ "embed" + "errors" "os" "strconv" "time" @@ -15,27 +16,29 @@ type store struct { db *sql.DB } -func NewStore(filename string) (*store, error) { +func openStore(filename string) (*store, error) { var out store var err error - if filename != ":memory:" && filename != "file:memdb1?mode=memory&cache=shared" { - os.Remove(filename) + _, err = os.Stat(filename) + if errors.Is(err, os.ErrNotExist) { + defer out.loadSchema() } out.db, err = sql.Open("sqlite3", filename) - if err != nil { - return nil, err - } - - _, err = out.db.Exec(schema) - if err != nil { - out.db.Close() - return nil, err - } - return &out, nil + return &out, err } func (s *store) close() { - s.db.Close() + if s.db != nil { + s.db.Close() + } +} + +func (s *store) loadSchema() error { + if s.db == nil { + return errors.New("database doesn't exist") + } + _, err := s.db.Exec(schema) + return err } func (s *store) getCake(id int) (cake, error) { diff --git a/store_test.go b/store_test.go index fb36b78..97060bf 100644 --- a/store_test.go +++ b/store_test.go @@ -6,7 +6,7 @@ import ( ) func TestStore(t *testing.T) { - s, err := NewStore("file:memdb1?mode=memory&cache=shared") + s, err := openStore("file:memdb1?mode=memory&cache=shared") if err != nil { t.Fatalf("Failed to create store: %v", err) }