commit 717c9e08d67c833a93d94ef12b9f63a96b145826 Author: Ron Rise Date: Sun Mar 19 22:13:49 2023 -0400 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..00741cb --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.DS_Store +.idea/ \ No newline at end of file diff --git a/Handlers/Guns/Edit.go b/Handlers/Guns/Edit.go new file mode 100644 index 0000000..0ebf046 --- /dev/null +++ b/Handlers/Guns/Edit.go @@ -0,0 +1,27 @@ +package Guns + +import ( + "git.siteworxpro.com/gun-manager/sql" + "github.com/gorilla/mux" + "html/template" + "net/http" + "strconv" +) + +func Edit(w http.ResponseWriter, r *http.Request) { + db := sql.GetDb() + id, _ := strconv.ParseInt(mux.Vars(r)["id"], 10, 32) + + gun, err := db.GunById(uint(id)) + if err != nil { + w.WriteHeader(404) + + return + } + + t, err := template.ParseFiles("templates/Index.gohtml") + err = t.Execute(w, gun) + if err != nil { + panic(err) + } +} diff --git a/Handlers/Guns/Index.go b/Handlers/Guns/Index.go new file mode 100644 index 0000000..412338e --- /dev/null +++ b/Handlers/Guns/Index.go @@ -0,0 +1,37 @@ +package Guns + +import ( + "git.siteworxpro.com/gun-manager/sql" + "html/template" + "net/http" +) + +func Get(w http.ResponseWriter, r *http.Request) { + db := sql.GetDb() + + guns := db.AllGuns() + + t, err := template.ParseFiles("templates/Index.gohtml") + if err != nil { + panic(err) + } + + var total uint = 0 + for _, gun := range guns { + total += gun.ValueAmount + } + + data := struct { + Guns []sql.Gun + Total uint + }{ + Guns: guns, + Total: total, + } + + err = t.Execute(w, data) + + if err != nil { + panic(err) + } +} diff --git a/Handlers/Photo/Index.go b/Handlers/Photo/Index.go new file mode 100644 index 0000000..dbcb991 --- /dev/null +++ b/Handlers/Photo/Index.go @@ -0,0 +1,20 @@ +package Photo + +import ( + "git.siteworxpro.com/gun-manager/sql" + "github.com/gorilla/mux" + "net/http" + "strconv" +) + +func Get(w http.ResponseWriter, r *http.Request) { + db := sql.GetDb() + id, _ := strconv.ParseInt(mux.Vars(r)["id"], 10, 32) + + photo := db.GetPhoto(uint(id)) + + _, err := w.Write([]byte(photo)) + if err != nil { + panic(err) + } +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..3ee89d7 --- /dev/null +++ b/go.mod @@ -0,0 +1,8 @@ +module git.siteworxpro.com/gun-manager + +go 1.19 + +require ( + github.com/gorilla/mux v1.8.0 // indirect + github.com/mattn/go-sqlite3 v1.14.16 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..4f6d3fb --- /dev/null +++ b/go.sum @@ -0,0 +1,4 @@ +github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= +github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y= +github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= diff --git a/main.go b/main.go new file mode 100644 index 0000000..b76a7ad --- /dev/null +++ b/main.go @@ -0,0 +1,46 @@ +package main + +import ( + "flag" + "git.siteworxpro.com/gun-manager/Handlers/Guns" + "git.siteworxpro.com/gun-manager/Handlers/Photo" + "git.siteworxpro.com/gun-manager/sql" + "github.com/gorilla/mux" + "log" + "net/http" + "os" + "time" +) + +func main() { + var dbfile string + + flag.StringVar(&dbfile, "database", "", "the database file to load") + flag.Parse() + + if dbfile == "" { + flag.Usage() + os.Exit(1) + } + + _, err := sql.NewDb(dbfile) + + if err != nil { + log.Fatal(err) + } + + r := mux.NewRouter() + r.HandleFunc("/", Guns.Get).Methods("GET") + r.HandleFunc("/photo/{id}/{fileName}", Photo.Get).Methods("GET") + + srv := &http.Server{ + Handler: r, + Addr: "0.0.0.0:8000", + WriteTimeout: 15 * time.Second, + ReadTimeout: 15 * time.Second, + } + + log.Println("Starting Server: 0.0.0.0:8000") + + log.Fatal(srv.ListenAndServe()) +} diff --git a/sql/client.go b/sql/client.go new file mode 100644 index 0000000..0a9b3e1 --- /dev/null +++ b/sql/client.go @@ -0,0 +1,39 @@ +package sql + +import ( + "context" + "database/sql" + _ "github.com/mattn/go-sqlite3" +) + +type SqlDb struct { + db *sql.DB + created bool +} + +var dbConnection SqlDb + +func NewDb(file string) (*SqlDb, error) { + if dbConnection.created { + return &dbConnection, nil + } + + db, err := sql.Open("sqlite3", file) + if err != nil { + return nil, err + } + + dbConnection.db = db + dbConnection.created = true + + _, err = dbConnection.db.Conn(context.Background()) + if err != nil { + return nil, err + } + + return &dbConnection, nil +} + +func GetDb() *SqlDb { + return &dbConnection +} diff --git a/sql/guns.go b/sql/guns.go new file mode 100644 index 0000000..1f884ed --- /dev/null +++ b/sql/guns.go @@ -0,0 +1,70 @@ +package sql + +import ( + "database/sql" + "log" +) + +func (dbClient *SqlDb) AllGuns() []Gun { + + var guns []Gun + + rows, _ := dbClient.db.Query("select guns.*, p.id, p.gun_id, p.filename from guns join photos p on guns.id = p.gun_id order by guns.id") + defer func(rows *sql.Rows) { + _ = rows.Close() + }(rows) + + for rows.Next() { + i := Gun{} + p := Photo{} + err := rows.Scan( + &i.Id, + &i.Make, + &i.Model, + &i.SerialNumber, + &i.PurchaseAmount, + &i.ValueAmount, + &i.DatePurchased, + &i.Notes, + &p.Id, + &p.GunId, + &p.FileName, + ) + + if err != nil { + log.Fatal(err) + } + + index := -1 + for gunIndex, gun := range guns { + if gun.Id == i.Id { + index = gunIndex + continue + } + + index = -1 + } + + if index == -1 { + guns = append(guns, i) + index = len(guns) - 1 + } + + guns[index].Photos = append(guns[index].Photos, p) + } + + return guns +} + +func (dbClient *SqlDb) GunById(id uint) (*Gun, error) { + var gun Gun + + row, _ := dbClient.db.Query("select guns.*, p.id, p.gun_id, p.filename from guns join photos p on guns.id = p.gun_id where guns.id = ?", id) + + err := row.Scan(gun) + if err != nil { + return nil, err + } + + return &gun, nil +} diff --git a/sql/photos.go b/sql/photos.go new file mode 100644 index 0000000..e476dd2 --- /dev/null +++ b/sql/photos.go @@ -0,0 +1,14 @@ +package sql + +func (dbClient *SqlDb) GetPhoto(id uint) string { + var photo string + + row := dbClient.db.QueryRow("SELECT photo from photos where id = ?", id) + + err := row.Scan(&photo) + if err != nil { + panic(err) + } + + return photo +} diff --git a/sql/types.go b/sql/types.go new file mode 100644 index 0000000..7d83060 --- /dev/null +++ b/sql/types.go @@ -0,0 +1,22 @@ +package sql + +import "database/sql" + +type Gun struct { + Id uint `json:"id"` + Make string `json:"make"` + Model string `json:"model"` + SerialNumber string `json:"serial_number"` + PurchaseAmount uint `json:"purchase_amount"` + ValueAmount uint `json:"value_amount"` + DatePurchased sql.NullString `json:"date_purchased"` + Notes sql.NullString `json:"notes"` + Photos []Photo `json:"photos"` +} + +type Photo struct { + Id uint `json:"id"` + GunId uint `json:"gun_id"` + Photo string `json:"photo"` + FileName string `json:"file_name"` +} diff --git a/templates/Index.gohtml b/templates/Index.gohtml new file mode 100644 index 0000000..df61636 --- /dev/null +++ b/templates/Index.gohtml @@ -0,0 +1,78 @@ +

Guns

+ + + + + + + + + + + + + + +{{ range .Guns }} + + + + + + + + + + + + +{{ end }} + + + + + + + + +
+ ID + + Make + + Model + + Serial Number + + Purchase Amount + + Value Amount + + Date Purchased + + Notes + + Photos +
+ {{ .Id }} + + {{ .Make }} + + {{ .Model }} + + {{ .SerialNumber }} + + {{ .PurchaseAmount }} + + {{ .ValueAmount }} + + {{ .DatePurchased.Value }} + + {{ .Notes.Value }} + + {{ range .Photos}} + Photo + {{ end }} + + Edit +
Total Value{{ .Total }}