storage/db: mysql specialization for ListUploads

MySQL requires HAVING to refer to a column from a subquery, but SQLite
requires WHERE since the query is not an aggregation. Plumb through
the driver name so ListUploads can change its query slightly.

Change-Id: I07bb8010824d7e2362e203a68fed7bb968d5fe40
Reviewed-on: https://go-review.googlesource.com/39614
Run-TryBot: Quentin Smith <quentin@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Russ Cox <rsc@golang.org>
diff --git a/storage/db/db.go b/storage/db/db.go
index ea0b603..d5674eb 100644
--- a/storage/db/db.go
+++ b/storage/db/db.go
@@ -29,7 +29,8 @@
 // DB is a high-level interface to a database for the storage
 // app. It's safe for concurrent use by multiple goroutines.
 type DB struct {
-	sql *sql.DB // underlying database connection
+	sql        *sql.DB // underlying database connection
+	driverName string  // name of underlying driver for SQL differences
 	// prepared statements
 	lastUpload    *sql.Stmt
 	insertUpload  *sql.Stmt
@@ -51,7 +52,7 @@
 			return nil, err
 		}
 	}
-	d := &DB{sql: db}
+	d := &DB{sql: db, driverName: driverName}
 	if err := d.createTables(driverName); err != nil {
 		return nil, err
 	}
@@ -597,7 +598,14 @@
 	}
 	if len(sql) == 0 {
 		// Optimize empty query.
-		query += " FROM (SELECT UploadID, (SELECT COUNT(*) FROM Records r WHERE r.UploadID = u.UploadID) AS rCount FROM Uploads u WHERE rCount > 0 ORDER BY u.Day DESC, u.Seq DESC, u.UploadID DESC"
+		query += " FROM (SELECT UploadID, (SELECT COUNT(*) FROM Records r WHERE r.UploadID = u.UploadID) AS rCount FROM Uploads u "
+		switch db.driverName {
+		case "sqlite3":
+			query += "WHERE"
+		default:
+			query += "HAVING"
+		}
+		query += " rCount > 0 ORDER BY u.Day DESC, u.Seq DESC, u.UploadID DESC"
 		if limit != 0 {
 			query += fmt.Sprintf(" LIMIT %d", limit)
 		}