Todays lesson will be about querying the App Engine Datastore to fetch all entities. Luckily we don't need new imports :) We have all what we need.
However we implement a new function called getAllEntries which gets the request and returns a "pointer" to an Food array. Adding a new template for our query output is also included.
We call this function in the save function.
package mycanteen
import(
"net/http"
"html/template"
"strconv"
"fmt"
"appengine"
"appengine/datastore"
)
type Food struct{
Course string
Name string
Date string
Price float64
}
// No main function. Go App Engine use the init-func
func init() {
http.HandleFunc("/", root)
http.HandleFunc("/admin", admin);
http.HandleFunc("/save", save)
}
func root(w http.ResponseWriter, r *http.Request) {
// Here we will add the Userpanel, but not know
}
/*********************ADMINPANEL HANDLER**************************/
func admin(w http.ResponseWriter, r *http.Request) {
// Execute the parsing. We pass the ResponseWriter and a second value, which should be fill the gaps at the template.
// We have no gaps, so we have nothing to fill in.
if err := adminPanelTemplate.Execute(w, ""); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}
/********************SAVE/PERSIST HANDLER************************/
func save(w http.ResponseWriter, r *http.Request) {
// You have to parse the form from our admin panel. It's mandatory!
if err := r.ParseForm(); err != nil {
fmt.Fprint(w,err)
}
// Now we a readey to get the fish ;-)
course := r.FormValue("course")
name := r.FormValue("name")
date := r.FormValue("date")
// The form is string based, for later purpose we parse it to float
price, _ := strconv.ParseFloat(r.FormValue("price"), 64)
f := Food{course,name,date,price,}
// Persist to Datastore
// At this moment we cant save the values, hence we setup only this output to check the values.
if saveToDatastore(f,r) != true{
http.Error(w, "Error until persist the meal", http.StatusInternalServerError)
}
allMeals := getAllEntries(r)
if err := saveTemplate.Execute(w,allMeals);err != nil{
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}
func saveToDatastore(f Food, r *http.Request) bool{
// Get context from
c := appengine.NewContext(r);
key := datastore.NewIncompleteKey(c, "Meal", mealStoreKey(c))
_, err := datastore.Put(c, key, &f)
if err != nil{
return false
}else{
return true
}
}
/******************Fetch all Entries from the datastore********************/
func getAllEntries(r *http.Request) []*Food{
var q *datastore.Query
var allMeals []*Food
c := appengine.NewContext(r);
// Query for all entries in the datastore with the meal store key
q = datastore.NewQuery("Meal").Ancestor(mealStoreKey(c))
if _, err := q.GetAll(c, &allMeals); err != nil {
return allMeals
}
return allMeals
}
// foodKey returns the key used for all food entries.
func mealStoreKey(c appengine.Context) *datastore.Key {
// The string "default_food" here could be varied to have multiple cantines.
return datastore.NewKey(c, "MealStore", "meal", 0, nil)
}
// Parse the HTMLTemplate, despite it is not neccesary yet.
var adminPanelTemplate = template.Must(template.New("adminPanelHTML").Parse(adminPanelHTML))
var saveTemplate = template.Must(template.New("saveHTML").Parse(saveHTML))
// Here you define the HTML which will be parsed.
const adminPanelHTML= `
<html>
<head>
</head>
<body>
</body>
</html>
`
const saveHTML=`
<html>
<head>
</head>
<body>
<table border=1>
<tr><th>Course</th><th>Name</th><th>Price</th><th>Date</th></tr>
{{range .}}
<tr><td>{{.Course}}</td><td>{{.Name}}</td><td>{{.Price}}</td><td>{{.Date}}</td><td><input type="checkbox" /></td></tr>
{{end}}
</table>
<a href="/admin">Back</a>
</body>
</html>
`
For the QueryBuilder look at this page, they describe it very well :) projectionqueries
The c.getAll function needs a query and a array (slice) to fetch all entities.
The checkbox is for later purpose, so we can delete entries later. :) Maybe in the next post.
See ya!
P.S. Checkout my repository on Bitbucket for the latest code! https://bitbucket.org/loose11/mycanteen

No comments:
Post a Comment