From 77e9f405c6e9f789c4d27f4bdd62bc26aefe1f69 Mon Sep 17 00:00:00 2001
From: Marco Realacci <marco@marcorealacci.me>
Date: Tue, 22 Nov 2022 15:27:05 +0100
Subject: [PATCH] Add start_index & limit to GetFollowersFollowing

---
 service/api/followers.go     | 12 ++++++++++--
 service/database/database.go |  6 +++---
 service/database/db-users.go | 12 ++++++++----
 3 files changed, 21 insertions(+), 9 deletions(-)

diff --git a/service/api/followers.go b/service/api/followers.go
index 37d3f02..be19e35 100644
--- a/service/api/followers.go
+++ b/service/api/followers.go
@@ -25,13 +25,21 @@ func (rt *_router) GetFollowersFollowing(w http.ResponseWriter, r *http.Request,
 	var err error
 	var status database.QueryResult
 
+	// Get limits, or use default values
+	start_index, limit, err := helpers.GetLimits(r.URL.Query())
+
+	if err != nil {
+		helpers.SendBadRequest(w, "Invalid start_index or limit", rt.baseLogger)
+		return
+	}
+
 	// Check if client is asking for followers or following
 	if strings.HasSuffix(r.URL.Path, "/followers") {
 		// Get the followers from the database
-		status, users, err = rt.db.GetUserFollowers(uid, ctx.Auth.GetUserID())
+		status, users, err = rt.db.GetUserFollowers(uid, ctx.Auth.GetUserID(), start_index, limit)
 	} else {
 		// Get the following users from the database
-		status, users, err = rt.db.GetUserFollowing(uid, ctx.Auth.GetUserID())
+		status, users, err = rt.db.GetUserFollowing(uid, ctx.Auth.GetUserID(), start_index, limit)
 	}
 
 	// Send a 500 response if there was an error
diff --git a/service/database/database.go b/service/database/database.go
index e2e07b3..09b4e2b 100644
--- a/service/database/database.go
+++ b/service/database/database.go
@@ -48,8 +48,8 @@ type AppDatabase interface {
 
 	UpdateUsername(uid, name string) error
 
-	GetUserFollowers(uid string, requesting_uid string) (QueryResult, *[]structures.UIDName, error) // todo: maybe use a pointer to a slice?
-	GetUserFollowing(uid string, requesting_uid string) (QueryResult, *[]structures.UIDName, error)
+	GetUserFollowers(uid string, requesting_uid string, start_index int, limit int) (QueryResult, *[]structures.UIDName, error)
+	GetUserFollowing(uid string, requesting_uid string, start_index int, offset int) (QueryResult, *[]structures.UIDName, error)
 	FollowUser(uid string, follow string) (QueryResult, error)
 	UnfollowUser(uid string, unfollow string) (QueryResult, error)
 
@@ -64,7 +64,7 @@ type AppDatabase interface {
 	LikePhoto(uid string, photo int64, liker_uid string) (QueryResult, error)
 	UnlikePhoto(uid string, photo int64, liker_uid string) (QueryResult, error)
 
-	GetUserProfile(uid string) (QueryResult, *structures.UserProfile, error)
+	GetUserProfile(uid string) (QueryResult, *structures.UserProfile, error) // should support limits
 	GetUserStream(uid string, start_index int, limit int) (*[]structures.Photo, error)
 
 	GetComments(uid string, photo_id int64, requesting_uid string, start_index int, offset int) (QueryResult, *[]structures.Comment, error)
diff --git a/service/database/db-users.go b/service/database/db-users.go
index 5ef26a8..cda6867 100644
--- a/service/database/db-users.go
+++ b/service/database/db-users.go
@@ -48,7 +48,7 @@ func (db *appdbimpl) UpdateUsername(uid string, name string) error {
 }
 
 // Get user followers
-func (db *appdbimpl) GetUserFollowers(uid string, requesting_uid string) (QueryResult, *[]structures.UIDName, error) {
+func (db *appdbimpl) GetUserFollowers(uid string, requesting_uid string, start_index int, limit int) (QueryResult, *[]structures.UIDName, error) {
 
 	// user may exist but have no followers
 	exists, err := db.UserExists(uid)
@@ -70,7 +70,9 @@ func (db *appdbimpl) GetUserFollowers(uid string, requesting_uid string) (QueryR
 								AND "bans"."ban" = "follows"."follower"
 							)
 
-							AND "followed" = ?`, uid, requesting_uid)
+							AND "followed" = ?
+							OFFSET ?
+							LIMIT ?`, uid, requesting_uid, start_index, limit)
 
 	followers, err := db.uidNameQuery(rows, err)
 
@@ -82,7 +84,7 @@ func (db *appdbimpl) GetUserFollowers(uid string, requesting_uid string) (QueryR
 }
 
 // Get user following
-func (db *appdbimpl) GetUserFollowing(uid string, requesting_uid string) (QueryResult, *[]structures.UIDName, error) {
+func (db *appdbimpl) GetUserFollowing(uid string, requesting_uid string, start_index int, offset int) (QueryResult, *[]structures.UIDName, error) {
 
 	// user may exist but have no followers
 	exists, err := db.UserExists(uid)
@@ -104,7 +106,9 @@ func (db *appdbimpl) GetUserFollowing(uid string, requesting_uid string) (QueryR
 								AND "bans"."ban" = "follows"."followed"
 							)
 
-							AND "follower" = ?`, uid, requesting_uid)
+							AND "follower" = ?
+							OFFSET ?
+							LIMIT ?`, uid, requesting_uid, start_index, offset)
 
 	following, err := db.uidNameQuery(rows, err)