First version

This commit is contained in:
Dmitriy Shishkov 2022-09-26 23:25:10 +03:00
parent 8b28b22064
commit 3805b8267a
5 changed files with 188 additions and 0 deletions

5
go.mod Normal file
View File

@ -0,0 +1,5 @@
module git.dm1sh.ru/dm1sh/gotemptracker
go 1.19
require github.com/lib/pq v1.10.7

2
go.sum Normal file
View File

@ -0,0 +1,2 @@
github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw=
github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=

49
index.gohtml Normal file
View File

@ -0,0 +1,49 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>gotemptracker</title>
</head>
<body>
<h1>This is the first step to quantified selt, brought in by Golang app with PostgreSQL database</h1>
<form method="post">
<label>Temperature:</label><br />
<input type="number" step="0.1" name="value">
<input type="submit">
</form>
<canvas id="tempChart" style="width:100%;max-width:700px"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.js">
</script>
<script>
const vals = [
{{range .}}
{{.Value}},
{{end}}
];
const dates = [
{{range .}}
{{.CreatedAt.Format "2006-01-02"}},
{{end}}
];
new Chart("tempChart", {
type: "line",
data: {
labels: dates,
datasets: [{
data: vals
}]
}
});
</script>
</body>
</html>

66
main.go Normal file
View File

@ -0,0 +1,66 @@
package main
import (
"html/template"
"log"
"net/http"
"os"
"strconv"
"git.dm1sh.ru/dm1sh/gotemptracker/models"
)
func getEnv(name, default_val string) string {
val := os.Getenv(name)
if val == "" {
return default_val
}
return val
}
var tmpl *template.Template
func indexHandler(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodPost {
strvalue := r.FormValue("value")
value, err := strconv.ParseFloat(strvalue, 32)
if err != nil {
http.Error(w, "Expected floating point value", http.StatusBadRequest)
}
models.InsertMeasurement(value)
}
measurements, err := models.AllMeasurements()
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
err = tmpl.Execute(w, measurements)
if err != nil {
log.Fatal(err)
}
}
func main() {
tmpl = template.Must(template.ParseFiles("index.gohtml"))
err := models.InitDB(getEnv("DB_CONNECTION_STRING", "postgres://gotemptracker:gotemptracker@localhost:5432/gotemptracker?sslmode=disable"))
if err != nil {
log.Fatal(err)
}
http.HandleFunc("/", indexHandler)
port := getEnv("PORT", "80")
log.Printf("Listening on %s\n", port)
if err := http.ListenAndServe(":"+port, nil); err != nil {
log.Fatal(err)
}
}

66
models/models.go Normal file
View File

@ -0,0 +1,66 @@
package models
import (
"database/sql"
"time"
_ "github.com/lib/pq"
)
var db *sql.DB
type Measurement struct {
CreatedAt time.Time
Value float32
}
func InitDB(dataSourceName string) (err error) {
db, err = sql.Open("postgres", dataSourceName)
if err != nil {
return err
}
if err = db.Ping(); err != nil {
return err
}
_, err = db.Exec(`
CREATE TABLE IF NOT EXISTS measurements (
created_at TIMESTAMP,
value NUMERIC (3, 1)
)
`)
return err
}
func AllMeasurements() (measurements []Measurement, err error) {
rows, err := db.Query("SELECT * FROM measurements")
if err != nil {
return nil, err
}
defer rows.Close()
for rows.Next() {
var measurement Measurement
err = rows.Scan(&measurement.CreatedAt, &measurement.Value)
if err != nil {
return nil, err
}
measurements = append(measurements, measurement)
}
if err = rows.Err(); err != nil {
return nil, err
}
return measurements, nil
}
func InsertMeasurement(value float64) (err error) {
_, err = db.Exec(`
INSERT INTO measurements VALUES (current_timestamp, $1)
`, value)
return err
}