Refactor into a few files. Add web service JSON query support.
[quanweb.git] / main / handler.go
diff --git a/main/handler.go b/main/handler.go
new file mode 100644 (file)
index 0000000..52d08e5
--- /dev/null
@@ -0,0 +1,97 @@
+package main
+
+import (
+  "encoding/json"
+  "fmt"
+  "net/http"
+  "strconv"
+  "strings"
+)
+
+const PARAM_IDS = "ids"
+const MAX_TERMS = 10
+
+// ============================================================================
+func handler(w http.ResponseWriter, r *http.Request) {
+  err := r.ParseForm()
+  if nil != err {
+    fmt.Fprintln(w, "ERROR!", err)
+    return
+  }
+
+  action := r.URL.Path[1:]
+
+  switch(action) {
+  case "info":
+    handleInfo(w, r)
+  case "search":
+    handleSearch(w, r)
+  default:
+    fmt.Fprintf(w, "Unrecognized request:  %s\n", r.URL.Path[1:])
+    fmt.Fprintf(w, "id: %s\n", r.FormValue("id"))
+  
+    fmt.Fprintln(w, "URL: ", r.URL)
+    fmt.Fprintln(w, "Query: ", r.URL.Query())
+  }
+}
+
+func handleInfo(w http.ResponseWriter, r *http.Request) {
+  idParams := r.Form[PARAM_IDS]
+  if 1 != len(idParams) {
+    fmt.Fprintln(w, "ERROR!  Detected either zero or multiple ids= parameters.  Exactly one expected.")
+    return 
+  } 
+
+  idParam := idParams[0]
+  idStrings := strings.Split(idParam, ",")
+  ids := make([]int, len(idStrings))
+  for i, v := range(idStrings) {
+    var err error
+    ids[i], err = strconv.Atoi(v)
+    if nil != err {
+      ids[i] = 0
+    }
+  }
+
+  books := queryBooksByIds(ids)
+
+  var jsonValue []byte
+  var err error
+  jsonValue, err = json.Marshal(books)
+  if nil != err {
+    fmt.Fprintln(w, "ERROR!", err)
+  } else {
+    w.Write(jsonValue)
+  }
+}
+
+func handleSearch(w http.ResponseWriter, r *http.Request) {
+  fields := []Field{Author, Title, Series}
+
+  terms := make([]SearchTerm, len(fields))
+  
+  count := 0
+  for _, fv := range(fields) {
+    paramName := fv.String()
+    paramValues := r.Form[paramName]
+    for _, pv := range(paramValues) {
+      if count >= len(terms) {
+        fmt.Printf("WARNING:  limit of %v search terms exceeded.  One or more terms ignored.")
+        break
+      }
+      terms[count] = SearchTerm{Attribute:fv, Text:pv}
+      count++
+    }
+  }
+
+  terms = terms[:count]
+
+  ids := queryIds(terms)
+
+  jsonValue, err := json.Marshal(ids)
+  if nil != err {
+    fmt.Fprintln(w, "ERROR!", err)
+  } else {
+    w.Write(jsonValue)
+  }
+}