func viewBook(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { lib.Trace(2, "handler:viewBook start") // get book book := &d.Book{BookName: ps.ByName("bookname")} resultChan := d.Data("getBook", book) result := <-resultChan if result.Status != d.DataOk { // resultVal contains errMsg http.Error(w, result.Val.(string), http.StatusBadRequest) return } // get book tabs bookTabs := &d.GetBookTabs{Bookid: book.Id} // see data/getbooktabs.go resultChan = d.Data("getBookTabs", bookTabs) result = <-resultChan // build response response := &loginResponse{ Bookid: book.Id, BookName: book.BookName, Tabs: bookTabs.TabInfoMap, Broadcast: getBroadcast(), } // add Login login := &d.Login{Bookid: book.Id, Type: "view"} resultChan = d.Data("addLogin", login) result = <-resultChan response.Token = login.Token jsonResponseWriter(w, r, response) lib.Trace(2, "handler:viewBook end") }
// handle GET(/tabnotes/:token/:bookid/:tabid) func getTabNotes(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { lib.Trace(2, "handler:getTabNotes start") var result d.Result bookid := ps.ByName("bookid") login := &d.Login{Token: ps.ByName("token"), Bookid: bookid, Type: "view"} resultChan := d.Data("auth", login) if result = <-resultChan; result.Status != d.DataOk { http.Error(w, result.Val.(string), http.StatusInternalServerError) return } // get tab notes tabNotes := &d.GetTabNotes{ Bookid: bookid, Tabid: ps.ByName("tabid"), ETag: r.Header.Get("If-None-Match"), } // see data/gettabnotes.go lib.Trace(1, "Request ETag =", tabNotes.ETag) resultChan = d.Data("getTabNotes", tabNotes) result = <-resultChan if result.Status == d.DataNotChanged { w.WriteHeader(http.StatusNotModified) } else { w.Header().Set("Etag", tabNotes.ETag) jsonResponseWriter(w, r, tabNotes.Notes) // Notes = map[string]*d.NoteResponseRec } lib.Trace(2, "handler:getTabNotes end", len(tabNotes.Notes)) }
// handle PUT(/tab/:token/:bookid/:tabid) func changeTab(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { lib.Trace(2, "handler:changeTab start") var result d.Result bookid := ps.ByName("bookid") login := &d.Login{Token: ps.ByName("token"), Bookid: bookid, Type: "edit"} resultChan := d.Data("auth", login) if result = <-resultChan; result.Status != d.DataOk { http.Error(w, result.Val.(string), http.StatusBadRequest) return } request := new(tabRequest) if decodeErr := json.NewDecoder(r.Body).Decode(request); decodeErr != nil { http.Error(w, "Program Error: tabRequest json decode", http.StatusInternalServerError) return } // change tab tab := &d.Tab{ Id: ps.ByName("tabid"), Bookid: bookid, TabNumber: request.TabNumber, TabName: request.TabName, Hidden: request.Hidden, } resultChan = d.Data("changeTab", tab) result = <-resultChan w.Write([]byte("Update Successful")) lib.Trace(2, "handler:changeTab end") }
// handle PUT(/note/:token/:bookid/:tabid/:noteid) func changeNote(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { lib.Trace(2, "handler:changeNote start") var result d.Result bookid := ps.ByName("bookid") login := &d.Login{Token: ps.ByName("token"), Bookid: bookid, Type: "edit"} resultChan := d.Data("auth", login) if result = <-resultChan; result.Status != d.DataOk { http.Error(w, result.Val.(string), http.StatusInternalServerError) return } request := new(noteRequest) if decodeErr := json.NewDecoder(r.Body).Decode(request); decodeErr != nil { http.Error(w, "Program Error: noteRequest json decode", http.StatusInternalServerError) return } note := &d.Note{ Id: ps.ByName("noteid"), Content: request.Content, When: time.Now(), Html: request.Html, Markdown: request.Markdown, Mono: request.Mono, } noteParms := &d.NoteParms{ Bookid: bookid, Tabid: ps.ByName("tabid"), Note: note, } resultChan = d.Data("changeNote", noteParms) result = <-resultChan w.Write([]byte("Update Successful")) lib.Trace(2, "handler:changeNote end") }
func main() { var err error lib.TraceStart("stdout") dbName := "datafiles/test1.db" if err = os.Remove(dbName); err != nil { log.Fatal(err) } d.DataStart(dbName) bk1 := d.Book{BookName: "book1", AccessCode: "ab1cd"} resultChan := d.Data("addBook", &bk1) result := <-resultChan bookid := result.Val.(string) log.Println("bookid=", bookid) tb1 := d.Tab{Bookid: bookid, TabName: "tab1", TabNumber: 10} resultChan = d.Data("addTab", &tb1) result = <-resultChan tabid := result.Val.(string) log.Println("tabid=", tabid) noteids := make([]string, 0, 10) for i := 0; i < 3; i++ { note := new(d.Note) note.Content = "note content " + strconv.Itoa(i) note.When = time.Now() note.Mono = true noteParms := d.NoteParms{Bookid: bookid, Tabid: tabid, Previd: d.Zeroid, Note: note} resultChan = d.Data("addNote", ¬eParms) if result = <-resultChan; result.Status != d.DataOk { log.Fatal(result.Val.(string)) } noteids = append(noteids, result.Val.(string)) } rand.Seed(time.Now().UnixNano()) // rand used by common.RandCode doneChan = make(chan string) //lib.TraceLevel(9) go writeLoop(bookid, tabid, noteids) //time.Sleep(1 * time.Second) go readLoop(bookid, tabid) done1 := <-doneChan log.Println(done1) done2 := <-doneChan log.Println(done2) log.Println("main end") }
func createBook(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { lib.Trace(2, "handler:createBook start") request := new(loginRequest) if decodeErr := json.NewDecoder(r.Body).Decode(request); decodeErr != nil { http.Error(w, "Program Error: loginRequest json decode", http.StatusInternalServerError) return } // add book book := &d.Book{ BookName: ps.ByName("bookname"), AccessCode: request.AccessCode, } resultChan := d.Data("addBook", book) result := <-resultChan if result.Status != d.DataOk { // resultVal contains errMsg http.Error(w, result.Val.(string), http.StatusBadRequest) return } // add tab tab := &d.Tab{ Bookid: book.Id, TabNumber: 1, TabName: "About", Hidden: false, } resultChan = d.Data("addTab", tab) result = <-resultChan // get book tabs (will only be the 1 just added) bookTabs := &d.GetBookTabs{Bookid: book.Id} // see data/getbooktabs.go resultChan = d.Data("getBookTabs", bookTabs) result = <-resultChan // build response response := &loginResponse{ Bookid: book.Id, BookName: book.BookName, Tabs: bookTabs.TabInfoMap, Broadcast: getBroadcast(), } // add Login login := &d.Login{Bookid: book.Id, Type: "edit"} resultChan = d.Data("addLogin", login) result = <-resultChan response.Token = login.Token jsonResponseWriter(w, r, response) lib.Trace(2, "handler:createBook end") }
func setInterrupt() { interruptChan := make(chan os.Signal, 1) // stop pgm if ctrl-c entered signal.Notify(interruptChan, os.Interrupt) waitForInterrupt := func() { <-interruptChan log.Println("interrupt received, pgm shutting down gracefully") d.Data("shutdown", &d.SimpleRequest{nil}) log.Println("waiting") time.Sleep(3 * time.Second) os.Exit(0) } go waitForInterrupt() }
// handles requests with URL = /shutdown/:keyword func shutdown(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { if ps.ByName("keyword") != "downboy" { http.Error(w, "Sorry Charlie", http.StatusInternalServerError) lib.Trace(0, "shutdown - invalid keyword") return } w.Write([]byte("shutdown request received")) lib.Trace(0, "shutdown request received") resultChan := d.Data("shutdown", &d.SimpleRequest{nil}) <-resultChan time.Sleep(3 * time.Second) // wait for Trace buffer to clear os.Exit(0) }
// handle DELETE(/note/:token/:bookid/:tabid/:noteid) func deleteNote(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { lib.Trace(2, "handler:deleteNote start") var result d.Result bookid := ps.ByName("bookid") login := &d.Login{Token: ps.ByName("token"), Bookid: bookid, Type: "edit"} resultChan := d.Data("auth", login) if result = <-resultChan; result.Status != d.DataOk { http.Error(w, result.Val.(string), http.StatusInternalServerError) return } note := &d.Note{Id: ps.ByName("noteid")} noteParms := &d.NoteParms{ Bookid: bookid, Tabid: ps.ByName("tabid"), Note: note, } resultChan = d.Data("deleteNote", noteParms) result = <-resultChan w.Write([]byte("Update Successful")) lib.Trace(2, "handler:deleteNote end") }
func writeLoop(bookid, tabid string, noteids []string) { for i := 0; i < 10; i++ { note := new(d.Note) note.Id = noteids[rand.Intn(len(noteids))] note.Content = "changed Note " + note.Id note.When = time.Now() note.Html = true note.Mono = false noteParms := d.NoteParms{Bookid: bookid, Tabid: tabid, Note: note} resultChan := d.Data("changeNote", ¬eParms) if result := <-resultChan; result.Status != d.DataOk { log.Fatal(result.Val.(string)) } } doneChan <- "writeLoop done" }
func readLoop(bookid, tabid string) { for i := 0; i < 200; i++ { dataParms := new(d.TabNotes) dataParms.Bookid = bookid dataParms.Tabid = tabid resultChan := d.Data("getTabNotes", dataParms) result := <-resultChan if result.Status != d.DataOk { log.Println(result.Val.(string)) break } /* for noteid, note := range dataParms.Notes { log.Println(noteid, note.Content, note.When, note.Mono, note.Html) } for noteid, previd := range dataParms.Previds { log.Println(noteid, previd) } */ } doneChan <- "readLoop done" }