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