package main import ( "database/sql" "fmt" _ "github.com/mattn/go-sqlite3" "log" "net/http" "strconv" ) type Response struct { FirstName, Name string Answer string NumAdult, NumKids uint Vegi, Vegan bool NumVegi, NumVegan uint Allerien bool Allergene string Accumodation bool NumRooms uint Arrival string Musik string Email string Permission bool Covid19 string } func newRespose(db *sql.DB, row *Response) error { sqlStmt := fmt.Sprintf(`INSERT INTO response (fName, lName, answer, numAdult, numKids, vegi, numVegi, vegan, numVegan, allergiger, allergene, accommodation, numRooms, arrival, musik, email, permission, covid19) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);`) tx, err := db.Begin() if err != nil { return err } stmt, err := tx.Prepare(sqlStmt) defer tx.Commit() if err != nil { return err } defer stmt.Close() log.Printf("Add new response: %s", row) _, err = stmt.Exec( row.FirstName, row.Name, row.Answer, row.NumAdult, row.NumKids, row.Vegi, row.NumVegi, row.Vegan, row.NumVegan, row.Allerien, row.Allergene, row.Accumodation, row.NumRooms, row.Arrival, row.Musik, row.Email, row.Permission, row.Covid19, ) if err != nil { return err } return nil } func initDB(dbS string) (*sql.DB, error) { db, err := sql.Open("sqlite3", dbS) if err != nil { return nil, err } sqlStmt := fmt.Sprintf(`CREATE TABLE IF NOT EXISTS response (id INTEGER NOT NULL PRIMARY KEY, fName TEXT NOT NULL, lName TEXT NOT NULL, answer TEXT NOT NULL, numAdult INTEGER NOT NULL, numKids INTEGER NOT NULL, vegi BOOLEAN, numVegi INTEGER, vegan BOOLEAN, numVegan INTEGER, allergiger BOOLEAN, allergene TEXT, accommodation BOOLEAN, numRooms INTEGER, arrival TEXT, musik TEXT, email TEXT, permission BOOLEAN, covid19 TEXT, created DATETIME DEFAULT CURRENT_TIMESTAMP);`) _, err = db.Exec(sqlStmt) if err != nil { return db, err } log.Printf("DB %s is up and running", dbS) return db, nil } func main() { // init database db, err := initDB("data/response.sqlite") if err != nil { if db != nil { db.Close() } log.Panic(err) } defer db.Close() // init http server with two routes for onepage website and endpoint for sending the response // http.Handle("/", httpLogHandler(http.FileServer(http.Dir("../../../../frontend")))) http.Handle("/", httpLogHandler(http.FileServer(http.Dir("./frontend")))) http.HandleFunc("/response", func(w http.ResponseWriter, r *http.Request) { processAnmeldung(w, r, db) }) http.ListenAndServe(":8080", nil) } func parseBool(s string) bool { return s == "on" } func parseUInt(s string) uint { u64, err := strconv.ParseUint(s, 10, 32) if err != nil { return 0 } return uint(u64) } func httpLogHandler(h http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { log.Printf("Webseiten Aufruf: '%v:%v' %v", r.Method, r.URL, r.Header) h.ServeHTTP(w, r) }) } func processAnmeldung(w http.ResponseWriter, r *http.Request, db *sql.DB) { log.Printf("Process Endpoint Aufruf: '%v:%v' %v", r.Method, r.URL, r.Header) if r.Method != http.MethodPost { http.Redirect(w, r, "/", http.StatusSeeOther) return } // Call ParseForm() to parse the raw query and update r.PostForm and r.Form. if err := r.ParseForm(); err != nil { fmt.Fprintf(w, "ParseForm() err: %v", err) w.WriteHeader(http.StatusInternalServerError) return } log.Printf("Post from website: %v", r.PostForm) response := Response{ FirstName: r.FormValue("firstname"), Name: r.FormValue("name"), Answer: r.FormValue("rueckmeldung"), NumAdult: parseUInt(r.FormValue("numAdult")), NumKids: parseUInt(r.FormValue("numKids")), Vegi: parseBool(r.FormValue("vegi")), Vegan: parseBool(r.FormValue("vegan")), NumVegi: parseUInt(r.FormValue("numVegi")), NumVegan: parseUInt(r.FormValue("numVegan")), Allergene: r.FormValue("allagene"), Allerien: parseBool(r.FormValue("allergiger")), Accumodation: parseBool(r.FormValue("unterkunft")), Arrival: r.FormValue("arrival"), NumRooms: parseUInt(r.FormValue("numUnterkunft")), Musik: r.FormValue("musik"), Email: r.FormValue("email"), Permission: parseBool(r.FormValue("weitergabe")), Covid19: r.FormValue("covid19"), } log.Printf("Form values parsed: %v", response) err := newRespose(db, &response) if err != nil { log.Print("Fehler beim einfügen in die DB: %v", err) w.WriteHeader(http.StatusInternalServerError) return } //return success w.WriteHeader(http.StatusCreated) }