api,db: add comments count endpoint

Closes https://gitlab.com/commento/commento-ce/issues/27
This commit is contained in:
Adhityaa Chandrasekar 2018-09-23 00:40:06 -04:00
parent 299649cea2
commit 330131f390
6 changed files with 118 additions and 2 deletions

43
api/comment_count.go Normal file
View File

@ -0,0 +1,43 @@
package main
import (
"net/http"
)
func commentCount(domain string, path string) (int, error) {
// path can be empty
if domain == "" {
return 0, errorMissingField
}
p, err := pageGet(domain, path)
if err != nil {
return 0, errorInternal
}
return p.CommentCount, nil
}
func commentCountHandler(w http.ResponseWriter, r *http.Request) {
type request struct {
Domain *string `json:"domain"`
Path *string `json:"path"`
}
var x request
if err := bodyUnmarshal(r, &x); err != nil {
bodyMarshal(w, response{"success": false, "message": err.Error()})
return
}
domain := domainStrip(*x.Domain)
path := *x.Path
count, err := commentCount(domain, path)
if err != nil {
bodyMarshal(w, response{"success": false, "message": err.Error()})
return
}
bodyMarshal(w, response{"success": true, "count": count})
}

54
api/comment_count_test.go Normal file
View File

@ -0,0 +1,54 @@
package main
import (
"testing"
"time"
)
func TestCommentCountBasics(t *testing.T) {
failTestOnError(t, setupTestEnv())
commenterHex, _ := commenterNew("test@example.com", "Test", "undefined", "http://example.com/photo.jpg", "google", "")
commentNew(commenterHex, "example.com", "/path.html", "root", "**foo**", "approved", time.Now().UTC())
commentNew(commenterHex, "example.com", "/path.html", "root", "**bar**", "approved", time.Now().UTC())
commentNew(commenterHex, "example.com", "/path.html", "root", "**baz**", "unapproved", time.Now().UTC())
count, err := commentCount("example.com", "/path.html")
if err != nil {
t.Errorf("unexpected error counting comments: %v", err)
return
}
if count != 2 {
t.Errorf("expected count=2 got count=%d", count)
return
}
}
func TestCommentCountNewPage(t *testing.T) {
failTestOnError(t, setupTestEnv())
count, err := commentCount("example.com", "/path.html")
if err != nil {
t.Errorf("unexpected error counting comments: %v", err)
return
}
if count != 0 {
t.Errorf("expected count=0 got count=%d", count)
return
}
}
func TestCommentCountEmpty(t *testing.T) {
if _, err := commentCount("example.com", ""); err != nil {
t.Errorf("unexpected error counting comments on empty path: %v", err)
return
}
if _, err := commentCount("", ""); err == nil {
t.Errorf("expected error not found counting comments with empty everything")
return
}
}

View File

@ -6,4 +6,5 @@ type page struct {
Domain string `json:"domain"`
Path string `json:"path"`
IsLocked bool `json:"isLocked"`
CommentCount int `json:"commentCount"`
}

View File

@ -11,19 +11,20 @@ func pageGet(domain string, path string) (page, error) {
}
statement := `
SELECT isLocked
SELECT isLocked, commentCount
FROM pages
WHERE domain=$1 AND path=$2;
`
row := db.QueryRow(statement, domain, path)
p := page{Domain: domain, Path: path}
if err := row.Scan(&p.IsLocked); err != nil {
if err := row.Scan(&p.IsLocked, &p.CommentCount); err != nil {
if err == sql.ErrNoRows {
// If there haven't been any comments, there won't be a record for this
// page. The sane thing to do is return defaults.
// TODO: the defaults are hard-coded in two places: here and the schema
p.IsLocked = false
p.CommentCount = 0
} else {
logger.Errorf("error scanning page: %v", err)
return page{}, errorInternal

View File

@ -9,6 +9,8 @@ func pageUpdate(p page) error {
return errorMissingField
}
// fields to not update:
// commentCount
statement := `
INSERT INTO
pages (domain, path, isLocked)

View File

@ -0,0 +1,15 @@
ALTER TABLE pages
ADD commentCount INTEGER NOT NULL DEFAULT 0;
CREATE OR REPLACE FUNCTION commentsInsertTriggerFunction() RETURNS TRIGGER AS $trigger$
BEGIN
UPDATE pages
SET commentCount = commentCount + 1
WHERE domain = new.domain AND path = new.path;
RETURN NEW;
END;
$trigger$ LANGUAGE plpgsql;
CREATE TRIGGER commentsInsertTrigger AFTER INSERT ON comments
FOR EACH ROW EXECUTE PROCEDURE commentsInsertTriggerFunction();