[server] Limit support while fetching collections (#5148)

## Description
This endpoint let's us add limit which fetching collections.

## Tests
This commit is contained in:
Manav Rathi 2025-02-24 14:18:44 +05:30 committed by GitHub
commit b15b707600
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 56 additions and 12 deletions

View File

@ -538,6 +538,7 @@ func main() {
//lint:ignore SA1019 Deprecated API will be removed in the future
privateAPI.GET("/collections", collectionHandler.Get)
privateAPI.GET("/collections/v2", collectionHandler.GetV2)
privateAPI.GET("/collections/v3", collectionHandler.GetWithLimit)
privateAPI.POST("/collections/share", collectionHandler.Share)
privateAPI.POST("/collections/join-link", collectionHandler.JoinLink)
privateAPI.POST("/collections/share-url", collectionHandler.ShareURL)

View File

@ -73,12 +73,12 @@ func (h *CollectionHandler) GetV2(c *gin.Context) {
userID := auth.GetUserID(c.Request.Header)
sinceTime, _ := strconv.ParseInt(c.Query("sinceTime"), 10, 64)
app := auth.GetApp(c)
ownedCollections, err := h.Controller.GetOwnedV2(userID, sinceTime, app)
ownedCollections, err := h.Controller.GetOwnedV2(userID, sinceTime, app, nil)
if err != nil {
handler.Error(c, stacktrace.Propagate(err, "Failed to get owned collections"))
return
}
sharedCollections, err := h.Controller.GetSharedWith(userID, sinceTime, app)
sharedCollections, err := h.Controller.GetSharedWith(userID, sinceTime, app, nil)
if err != nil {
handler.Error(c, stacktrace.Propagate(err, "Failed to get shared collections"))
return
@ -88,6 +88,35 @@ func (h *CollectionHandler) GetV2(c *gin.Context) {
})
}
// GetWithLimit returns owned and shared collections accessible to a user
func (h *CollectionHandler) GetWithLimit(c *gin.Context) {
userID := auth.GetUserID(c.Request.Header)
sinceTime, _ := strconv.ParseInt(c.Query("sinceTime"), 10, 64)
sharedSinceTime, _ := strconv.ParseInt(c.Query("sharedSinceTime"), 10, 64)
limit := int64(1000)
if c.Query("limit") != "" {
limit, _ = strconv.ParseInt(c.Query("limit"), 10, 64)
if limit > 1000 {
limit = 1000
}
}
app := auth.GetApp(c)
ownedCollections, err := h.Controller.GetOwnedV2(userID, sinceTime, app, &limit)
if err != nil {
handler.Error(c, stacktrace.Propagate(err, "Failed to get owned collections"))
return
}
sharedCollections, err := h.Controller.GetSharedWith(userID, sharedSinceTime, app, &limit)
if err != nil {
handler.Error(c, stacktrace.Propagate(err, "Failed to get shared collections"))
return
}
c.JSON(http.StatusOK, gin.H{
"owned": ownedCollections,
"shared": sharedCollections,
})
}
// Share shares a collection with a user
func (h *CollectionHandler) Share(c *gin.Context) {
var request ente.AlterShareRequest

View File

@ -6,8 +6,8 @@ import (
)
// GetOwnedV2 returns the list of collections owned by a user using optimized query
func (c *CollectionController) GetOwnedV2(userID int64, sinceTime int64, app ente.App) ([]ente.Collection, error) {
collections, err := c.CollectionRepo.GetCollectionsOwnedByUserV2(userID, sinceTime, app)
func (c *CollectionController) GetOwnedV2(userID int64, sinceTime int64, app ente.App, limit *int64) ([]ente.Collection, error) {
collections, err := c.CollectionRepo.GetCollectionsOwnedByUserV2(userID, sinceTime, app, limit)
if err != nil {
return nil, stacktrace.Propagate(err, "")
}
@ -15,8 +15,8 @@ func (c *CollectionController) GetOwnedV2(userID int64, sinceTime int64, app ent
}
// GetSharedWith returns the list of collections that are shared with a user
func (c *CollectionController) GetSharedWith(userID int64, sinceTime int64, app ente.App) ([]ente.Collection, error) {
collections, err := c.CollectionRepo.GetCollectionsSharedWithUser(userID, sinceTime, app)
func (c *CollectionController) GetSharedWith(userID int64, sinceTime int64, app ente.App, limit *int64) ([]ente.Collection, error) {
collections, err := c.CollectionRepo.GetCollectionsSharedWithUser(userID, sinceTime, app, limit)
if err != nil {
return nil, stacktrace.Propagate(err, "")
}

View File

@ -101,8 +101,8 @@ func (repo *CollectionRepository) GetCollectionByType(userID int64, collectionTy
return c, nil
}
func (repo *CollectionRepository) GetCollectionsOwnedByUserV2(userID int64, updationTime int64, app ente.App) ([]ente.Collection, error) {
rows, err := repo.DB.Query(`
func (repo *CollectionRepository) GetCollectionsOwnedByUserV2(userID int64, updationTime int64, app ente.App, limit *int64) ([]ente.Collection, error) {
query := `
SELECT
c.collection_id, c.owner_id, c.encrypted_key,c.key_decryption_nonce, c.name, c.encrypted_name, c.name_decryption_nonce, c.type, c.app, c.attributes, c.updation_time, c.is_deleted, c.magic_metadata, c.pub_magic_metadata,
users.user_id, users.encrypted_email, users.email_decryption_nonce, cs.role_type,
@ -114,7 +114,14 @@ pct.access_token, pct.valid_till, pct.device_limit, pct.created_at, pct.updated_
ON (cs.to_user_id = users.user_id AND users.encrypted_email IS NOT NULL)
LEFT JOIN public_collection_tokens pct
ON (pct.collection_id = c.collection_id and pct.is_disabled=FALSE)
WHERE c.owner_id = $1 AND c.updation_time > $2 and c.app = $3`, userID, updationTime, string(app))
WHERE c.owner_id = $1 AND c.updation_time > $2 and c.app = $3`
args := []interface{}{userID, updationTime, string(app)}
if limit != nil {
query += " ORDER BY c.updation_time ASC LIMIT $4"
args = append(args, *limit)
}
rows, err := repo.DB.Query(query, args...)
if err != nil {
return nil, stacktrace.Propagate(err, "")
}
@ -192,14 +199,21 @@ pct.access_token, pct.valid_till, pct.device_limit, pct.created_at, pct.updated_
// GetCollectionsSharedWithUser returns the list of collections that are shared
// with a user
func (repo *CollectionRepository) GetCollectionsSharedWithUser(userID int64, updationTime int64, app ente.App) ([]ente.Collection, error) {
rows, err := repo.DB.Query(`
func (repo *CollectionRepository) GetCollectionsSharedWithUser(userID int64, updationTime int64, app ente.App, limit *int64) ([]ente.Collection, error) {
query := `
SELECT collections.collection_id, collections.owner_id, users.encrypted_email, users.email_decryption_nonce, collection_shares.encrypted_key, collections.name, collections.encrypted_name, collections.name_decryption_nonce, collections.type, collections.app, collections.pub_magic_metadata, collection_shares.magic_metadata, collections.updation_time, collection_shares.is_deleted
FROM collections
INNER JOIN users
ON collections.owner_id = users.user_id
INNER JOIN collection_shares
ON collections.collection_id = collection_shares.collection_id AND collection_shares.to_user_id = $1 AND (collection_shares.updation_time > $2 OR collections.updation_time > $2) AND users.encrypted_email IS NOT NULL AND app = $3`, userID, updationTime, string(app))
ON collections.collection_id = collection_shares.collection_id AND collection_shares.to_user_id = $1 AND (collection_shares.updation_time > $2 OR collections.updation_time > $2) AND users.encrypted_email IS NOT NULL AND app = $3`
args := []interface{}{userID, updationTime, string(app)}
if limit != nil {
query += " ORDER BY collections.updation_time ASC LIMIT $4"
args = append(args, *limit)
}
rows, err := repo.DB.Query(query, args...)
if err != nil {
return nil, stacktrace.Propagate(err, "")
}