Add ability to select sort order
[quanweb.git] / main / db.go
index 53feb90908e7e6fc3d33bb5d579c602a1a06a238..fbc67c8d235f37ac23bc0c180cf53815107fd51b 100644 (file)
@@ -30,7 +30,7 @@ type Book struct {
 // ---------------------------------------------------------------------------
 type Field string
 const (
-  Author, Language, List, Series, Title Field = "aut", "lan", "lst", "ser", "tit"
+  Author, Language, List, Series, Sort, Title Field = "aut", "lan", "lst", "ser", "srt", "tit"
 )
 
 func (f Field) String() string {
@@ -43,10 +43,29 @@ type SearchTerm struct {
   Text      string
 }
 
+// ---------------------------------------------------------------------------
+type SortOrder string
+const (
+  ByArrival, ByAuthor, ByPublication, ByTitle SortOrder = "arr", "aut", "pub", "tit"
+)
+
+func (so SortOrder) String() string {
+  return string(so)
+}
+
+// ---------------------------------------------------------------------------
 var g_db *sql.DB = nil
 var g_mutex = &sync.Mutex{}
 
 // ============================================================================
+func conditional(count int) (string, int) {
+  if (count == 0) {
+    return "WHERE", 1
+  } else {
+    return "AND", (count + 1)
+  }
+}
+
 func dbShutdown() {
   if nil != g_db {
     g_db.Close()
@@ -190,54 +209,68 @@ func queryIds(criteria []SearchTerm) []int {
            " INNER JOIN Authors a ON a.id=b.author" +
            " LEFT OUTER JOIN Series s ON s.id=b.series" +
            " LEFT OUTER JOIN Lists_Books lb ON b.id=lb.book" +
-           " LEFT OUTER JOIN Lists l ON l.id=lb.list"
+           " LEFT OUTER JOIN Lists l ON l.id=lb.list" +
+           " "
 
   args := make([]interface{}, 0)
-
-  i := 0
+  conjunction := "WHERE"
+  count := 0
+  sort := ByAuthor
 
   for _, criterion := range criteria {
-    if 0 == i {
-      query += " WHERE "
-    } else {
-      query += " AND "
-    }
-
     switch criterion.Attribute {
     case Author:
-      query += " UPPER(a.grouping) LIKE UPPER($" + strconv.Itoa(i + 1) + ")"
+      conjunction, count = conditional(count)
+      query += conjunction + " UPPER(a.grouping) LIKE UPPER($" + strconv.Itoa(count) + ")"
       args = append(args, strings.Replace(criterion.Text, " ", "", -1))
     case Language:
-      query += " UPPER(b.language) LIKE UPPER($" + strconv.Itoa(i + 1) + ")"
+      conjunction, count = conditional(count)
+      query += conjunction + " UPPER(b.language) LIKE UPPER($" + strconv.Itoa(count) + ")"
       args = append(args, criterion.Text)
     case List:
+      conjunction, count = conditional(count)
       codes := strings.Split(criterion.Text, ",")
-      query += " UPPER(l.code) IN ("
+      query += conjunction + " UPPER(l.code) IN ("
 
       for j, code := range codes {
         if j > 0 {
           query += ","
         }
-        query += "UPPER($" + strconv.Itoa(i + j + 1) + ")"
+        query += "UPPER($" + strconv.Itoa(count + j + 1) + ")"
         args = append(args, code)
       }
       query += ")"
-      i += len(codes) - 1
+      count += len(codes) - 1
     case Series:
-      query += " UPPER(s.descr) LIKE UPPER($" + strconv.Itoa(i + 1) + ")"
+      conjunction, count = conditional(count)
+      query += conjunction + " UPPER(s.descr) LIKE UPPER($" + strconv.Itoa(count) + ")"
       args = append(args, criterion.Text)
+    case Sort:
+      sort = SortOrder(criterion.Text)
     case Title:
-      query += " UPPER(b.title) LIKE UPPER($" + strconv.Itoa(i + 1) + ")"
+      conjunction, count = conditional(count)
+      query += conjunction + " UPPER(b.title) LIKE UPPER($" + strconv.Itoa(count) + ")"
       args = append(args, criterion.Text)
     default:
       report("Error:  unrecognized search field in queryIds():  " + criterion.Attribute.String(), nil)
       return nil
     }
-
-    i++
   }
 
-  query += " ORDER BY a.grouping,s.descr,b.volume,b.title,b.path"
+  switch sort {
+  case ByArrival:
+    query += " ORDER BY b.arrived DESC,a.grouping,s.descr,b.volume,b.title,b.path"
+  case ByAuthor:
+    query += " ORDER BY a.grouping,s.descr,b.volume,b.title,b.path,b.arrived DESC"
+  case ByPublication:
+    report("Error: cannot sort by publication (not yet implemented)", nil)
+    return nil
+  case ByTitle:
+    query += " ORDER BY b.title,a.grouping,s.descr,b.volume,b.path,b.arrived DESC"
+  default:
+    report("Error: unrecognized sort order in queryIds(): " + sort.String(), nil)
+    return nil
+  }
 
   res := []int{}