initial commit

This commit is contained in:
2023-03-19 22:13:49 -04:00
commit 717c9e08d6
12 changed files with 367 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
.DS_Store
.idea/

27
Handlers/Guns/Edit.go Normal file
View File

@@ -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)
}
}

37
Handlers/Guns/Index.go Normal file
View File

@@ -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)
}
}

20
Handlers/Photo/Index.go Normal file
View File

@@ -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)
}
}

8
go.mod Normal file
View File

@@ -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
)

4
go.sum Normal file
View File

@@ -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=

46
main.go Normal file
View File

@@ -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())
}

39
sql/client.go Normal file
View File

@@ -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
}

70
sql/guns.go Normal file
View File

@@ -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
}

14
sql/photos.go Normal file
View File

@@ -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
}

22
sql/types.go Normal file
View File

@@ -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"`
}

78
templates/Index.gohtml Normal file
View File

@@ -0,0 +1,78 @@
<h1>Guns</h1>
<table>
<tr>
<td>
ID
</td>
<td>
Make
</td>
<td>
Model
</td>
<td>
Serial Number
</td>
<td>
Purchase Amount
</td>
<td>
Value Amount
</td>
<td>
Date Purchased
</td>
<td>
Notes
</td>
<td>
Photos
</td>
<td></td>
</tr>
{{ range .Guns }}
<tr>
<td>
{{ .Id }}
</td>
<td>
{{ .Make }}
</td>
<td>
{{ .Model }}
</td>
<td>
{{ .SerialNumber }}
</td>
<td>
{{ .PurchaseAmount }}
</td>
<td>
{{ .ValueAmount }}
</td>
<td>
{{ .DatePurchased.Value }}
</td>
<td>
{{ .Notes.Value }}
</td>
<td>
{{ range .Photos}}
<a target="_blank" href="/photo/{{ .Id }}/{{ .FileName }}">Photo</a>
{{ end }}
</td>
<td>
<a href="/edit/{{ .Id }}">Edit</a>
</td>
</tr>
{{ end }}
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td>Total Value</td>
<td>{{ .Total }}</td>
</tr>
</table>