Got it working!
This commit is contained in:
27
Database.go
Normal file
27
Database.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
var ClimateDb *sql.DB
|
||||
|
||||
func InitDb() error {
|
||||
db, err := sql.Open("mysql", "admin:sekna123jk@tcp(127.0.0.1:3306)/climate")
|
||||
if err != nil {
|
||||
fmt.Println("error connecting to database")
|
||||
return err
|
||||
}
|
||||
ClimateDb = db
|
||||
return nil
|
||||
}
|
||||
|
||||
func CloseDb() {
|
||||
if ClimateDb != nil {
|
||||
err := ClimateDb.Close()
|
||||
if err != nil {
|
||||
fmt.Println("error closing database: " + err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
91
HandlerHelpers.go
Normal file
91
HandlerHelpers.go
Normal file
@@ -0,0 +1,91 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type HandlerFuncWithError = func (http.ResponseWriter, *http.Request) error
|
||||
|
||||
type HttpMethod string
|
||||
|
||||
const(
|
||||
HttpGet HttpMethod = "GET"
|
||||
HttpPost HttpMethod = "POST"
|
||||
)
|
||||
|
||||
type RequestContext struct {
|
||||
ResponseWriter http.ResponseWriter
|
||||
Request *http.Request
|
||||
MethodType HttpMethod
|
||||
Pattern string
|
||||
}
|
||||
|
||||
type Router struct {
|
||||
patterns map[string] *PatternRouter
|
||||
}
|
||||
|
||||
type PatternRouter struct {
|
||||
Get HandlerFuncWithError
|
||||
Post HandlerFuncWithError
|
||||
}
|
||||
|
||||
func (p *Router) MethodFuncForPattern(methodType HttpMethod, pattern string) (HandlerFuncWithError, error) {
|
||||
var methodFunc HandlerFuncWithError
|
||||
switch methodType {
|
||||
case HttpGet:
|
||||
methodFunc = p.patterns[pattern].Get
|
||||
case HttpPost:
|
||||
methodFunc = p.patterns[pattern].Post
|
||||
}
|
||||
if methodFunc == nil {
|
||||
return nil, fmt.Errorf("method %s not defined on pattern %s", methodType, pattern)
|
||||
}
|
||||
return methodFunc, nil
|
||||
}
|
||||
|
||||
func (p *Router) setGet(pattern string, cb HandlerFuncWithError) {
|
||||
if _, ok := p.patterns[pattern]; ok {
|
||||
p.patterns[pattern].Get = cb
|
||||
} else {
|
||||
p.patterns[pattern] = &PatternRouter{cb, nil}
|
||||
http.HandleFunc(pattern, getPatternHandler(pattern))
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Router) setPost(pattern string, cb HandlerFuncWithError) {
|
||||
if _, ok := p.patterns[pattern]; ok {
|
||||
p.patterns[pattern].Post = cb
|
||||
} else {
|
||||
p.patterns[pattern] = &PatternRouter{nil, cb}
|
||||
http.HandleFunc(pattern, getPatternHandler(pattern))
|
||||
}
|
||||
}
|
||||
|
||||
var MainRouter = Router{make(map[string] *PatternRouter)}
|
||||
|
||||
func getPatternHandler(pattern string) http.HandlerFunc {
|
||||
return func (w http.ResponseWriter, r *http.Request) {
|
||||
cb, err := MainRouter.MethodFuncForPattern(HttpMethod(r.Method), pattern)
|
||||
if err == nil {
|
||||
err = cb(w, r)
|
||||
}
|
||||
if err != nil {
|
||||
context := RequestContext{w, r, HttpMethod(r.Method), pattern}
|
||||
sendInternalError(err, context)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func sendInternalError(err error, context RequestContext) {
|
||||
errorMessage := "Internal Server Error!"
|
||||
if DEBUG {
|
||||
errorMessage += fmt.Sprintf( " Happened during %s request for pattern '%s': %s",
|
||||
context.MethodType,
|
||||
context.Pattern,
|
||||
err.Error())
|
||||
}
|
||||
fmt.Println(errorMessage)
|
||||
http.Error(context.ResponseWriter, errorMessage, 500)
|
||||
}
|
||||
|
||||
41
Snapshot.go
Normal file
41
Snapshot.go
Normal file
@@ -0,0 +1,41 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"time"
|
||||
)
|
||||
|
||||
type SnapshotRecord struct {
|
||||
Id int
|
||||
Timestamp time.Time
|
||||
Temp float32
|
||||
Humidity float32
|
||||
Co2 float32
|
||||
}
|
||||
|
||||
type SnapshotSubmission struct {
|
||||
Timestamp float32 `json:"time"`
|
||||
Temp float32 `json:"temp"`
|
||||
Humidity float32 `json:"humidity"`
|
||||
Co2 float32 `json:"co2"`
|
||||
}
|
||||
|
||||
func createSnapshotFromJson(jsonBodyStream io.ReadCloser) (*SnapshotSubmission, error) {
|
||||
var snapshotSub SnapshotSubmission
|
||||
body, err := ioutil.ReadAll(jsonBodyStream)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error reading body stream: %w", err)
|
||||
}
|
||||
err = jsonBodyStream.Close()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("couldn't close body stream: %w", err)
|
||||
}
|
||||
err = json.Unmarshal(body, &snapshotSub)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("couldn't unmarshal json: %w", err)
|
||||
}
|
||||
return &snapshotSub, nil
|
||||
}
|
||||
60
climate-server.go
Normal file
60
climate-server.go
Normal file
@@ -0,0 +1,60 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
"log"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
const DEBUG = true
|
||||
|
||||
func main() {
|
||||
err := setup()
|
||||
defer teardown()
|
||||
if err == nil {
|
||||
startServer()
|
||||
}
|
||||
}
|
||||
|
||||
func setup() error {
|
||||
err := InitDb()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func teardown() {
|
||||
CloseDb()
|
||||
}
|
||||
|
||||
func startServer() {
|
||||
port := "8001"
|
||||
MainRouter.setGet("/", showCharts)
|
||||
MainRouter.setPost("/", saveSnapshot)
|
||||
fmt.Printf("Listening on port %s...\n", port)
|
||||
log.Fatal(http.ListenAndServe(":" + port, nil))
|
||||
}
|
||||
|
||||
func showCharts(w http.ResponseWriter, r *http.Request) error {
|
||||
_, err := fmt.Fprint(w, "<h1>Climate Stuff</h1><div>The data will show up here at some stage...</div>")
|
||||
return err
|
||||
}
|
||||
|
||||
func saveSnapshot(w http.ResponseWriter, r *http.Request) error {
|
||||
snapshotSub, err := createSnapshotFromJson(r.Body)
|
||||
if err != nil {
|
||||
return fmt.Errorf("couldn't create snapshot from JSON: %w", err)
|
||||
}
|
||||
_, err = ClimateDb.Query(
|
||||
fmt.Sprintf("INSERT INTO `snapshots` (`temp`, `humidity`, `co2`, `time`, `id`) VALUES (%v, %v, %v, %v, NULL);",
|
||||
snapshotSub.Temp,
|
||||
snapshotSub.Humidity,
|
||||
snapshotSub.Co2,
|
||||
snapshotSub.Timestamp))
|
||||
if err != nil {
|
||||
return fmt.Errorf("couldn't submit snapshot into the database: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
73
server.go
73
server.go
@@ -1,73 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"database/sql"
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
//"net/url"
|
||||
"time"
|
||||
)
|
||||
|
||||
type SnapshotRecord struct {
|
||||
Id int
|
||||
Timestamp time.Time
|
||||
Temp float32
|
||||
Humidity float32
|
||||
Co2 float32
|
||||
}
|
||||
|
||||
type SnapshotSubmission struct {
|
||||
Timestamp float32 `json:"time"`
|
||||
Temp float32 `json:"temp"`
|
||||
Humidity float32 `json:"humidity"`
|
||||
Co2 float32 `json:"co2"`
|
||||
}
|
||||
|
||||
|
||||
var climateDb *sql.DB
|
||||
|
||||
func setupDb() *sql.DB {
|
||||
db, err := sql.Open("mysql", "admin:sekna123jk@tcp(127.0.0.1:3306)/climate")
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
return db
|
||||
}
|
||||
|
||||
func main() {
|
||||
climateDb = setupDb()
|
||||
defer climateDb.Close()
|
||||
http.HandleFunc("/", viewHandler)
|
||||
fmt.Println("Listening on port 8001...")
|
||||
log.Fatal(http.ListenAndServe(":8001", nil))
|
||||
}
|
||||
|
||||
func viewHandler(w http.ResponseWriter, r *http.Request) {
|
||||
switch r.Method {
|
||||
case "GET":
|
||||
_, _ = fmt.Fprint(w, "<h1>Climate Stuff</h1><div>The data will show up here at some stage...</div>")
|
||||
case "POST":
|
||||
var snapshotSub SnapshotSubmission
|
||||
body, err := ioutil.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
http.Error(w, "Internal Server Error!", 500)
|
||||
}
|
||||
err = json.Unmarshal(body, &snapshotSub)
|
||||
if err != nil {
|
||||
http.Error(w, "Internal Server Error!", 500)
|
||||
}
|
||||
_, err = climateDb.Query(
|
||||
fmt.Sprintf("INSERT INTO `snapshots` (`temp`, `humidity`, `co2`, `time`, `id`) VALUES (%v, %v, %v, %v, NULL);",
|
||||
snapshotSub.Temp,
|
||||
snapshotSub.Humidity,
|
||||
snapshotSub.Co2,
|
||||
snapshotSub.Timestamp))
|
||||
if err != nil {
|
||||
http.Error(w, "Internal Server Error!", 500)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user