@@ -67,15 +67,9 @@ func GetDependents(c *gin.Context) {
|
||||
}
|
||||
|
||||
limit := parseLimit(c.Query("limit"))
|
||||
offset := parseOffset(c.Query("offset"))
|
||||
|
||||
dependents := []models.AddonSearchResult{}
|
||||
err := initializers.DB.Model(&models.Addon{}).
|
||||
Select("addons.id, addons.name, addons.type, addons.summary, addons.preview, addons.subscriber_count, addons.current_version_number, addons.author").
|
||||
Joins("JOIN addon_dependencies ad ON ad.addon_id = addons.id").
|
||||
Where("ad.dependency_id = ?", addonID).
|
||||
Order("addons.subscriber_count DESC").
|
||||
Limit(limit).
|
||||
Find(&dependents).Error
|
||||
dependents, total, err := queryRelatedAddons(addonID, "ad.addon_id", "ad.dependency_id", limit, offset)
|
||||
if err != nil {
|
||||
c.JSON(500, gin.H{"error": err.Error()})
|
||||
return
|
||||
@@ -84,7 +78,9 @@ func GetDependents(c *gin.Context) {
|
||||
c.JSON(200, models.DependentsResponse{
|
||||
AddonID: addonID,
|
||||
Dependents: dependents,
|
||||
Total: len(dependents),
|
||||
Total: total,
|
||||
Limit: limit,
|
||||
Offset: offset,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -99,15 +95,9 @@ func GetDependencies(c *gin.Context) {
|
||||
}
|
||||
|
||||
limit := parseLimit(c.Query("limit"))
|
||||
offset := parseOffset(c.Query("offset"))
|
||||
|
||||
dependencies := []models.AddonSearchResult{}
|
||||
err := initializers.DB.Model(&models.Addon{}).
|
||||
Select("addons.id, addons.name, addons.type, addons.summary, addons.preview, addons.subscriber_count, addons.current_version_number, addons.author").
|
||||
Joins("JOIN addon_dependencies ad ON ad.dependency_id = addons.id").
|
||||
Where("ad.addon_id = ?", addonID).
|
||||
Order("addons.subscriber_count DESC").
|
||||
Limit(limit).
|
||||
Find(&dependencies).Error
|
||||
dependencies, total, err := queryRelatedAddons(addonID, "ad.dependency_id", "ad.addon_id", limit, offset)
|
||||
if err != nil {
|
||||
c.JSON(500, gin.H{"error": err.Error()})
|
||||
return
|
||||
@@ -116,10 +106,46 @@ func GetDependencies(c *gin.Context) {
|
||||
c.JSON(200, models.DependenciesResponse{
|
||||
AddonID: addonID,
|
||||
Dependencies: dependencies,
|
||||
Total: len(dependencies),
|
||||
Total: total,
|
||||
Limit: limit,
|
||||
Offset: offset,
|
||||
})
|
||||
}
|
||||
|
||||
// queryRelatedAddons returns one page of addons linked to addonID through the
|
||||
// addon_dependencies edge table, plus the total number of matches.
|
||||
//
|
||||
// joinCol is the edge column joined to addons.id; filterCol is the edge column
|
||||
// matched against addonID. Both are caller-supplied constants, never user input.
|
||||
//
|
||||
// The addons.id tiebreaker in the ORDER BY is required: subscriber_count alone
|
||||
// is not a unique ordering, so without it paging could repeat or skip rows.
|
||||
func queryRelatedAddons(addonID, joinCol, filterCol string, limit, offset int) ([]models.AddonSearchResult, int, error) {
|
||||
base := func() *gorm.DB {
|
||||
return initializers.DB.Model(&models.Addon{}).
|
||||
Joins("JOIN addon_dependencies ad ON "+joinCol+" = addons.id").
|
||||
Where(filterCol+" = ?", addonID)
|
||||
}
|
||||
|
||||
var total int64
|
||||
if err := base().Count(&total).Error; err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
results := []models.AddonSearchResult{}
|
||||
err := base().
|
||||
Select("addons.id, addons.name, addons.type, addons.summary, addons.preview, addons.subscriber_count, addons.current_version_number, addons.author").
|
||||
Order("addons.subscriber_count DESC, addons.id ASC").
|
||||
Limit(limit).
|
||||
Offset(offset).
|
||||
Find(&results).Error
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
return results, int(total), nil
|
||||
}
|
||||
|
||||
func parseLimit(raw string) int {
|
||||
limit := 100
|
||||
if raw != "" {
|
||||
@@ -132,3 +158,14 @@ func parseLimit(raw string) int {
|
||||
}
|
||||
return limit
|
||||
}
|
||||
|
||||
func parseOffset(raw string) int {
|
||||
if raw == "" {
|
||||
return 0
|
||||
}
|
||||
val, err := strconv.Atoi(raw)
|
||||
if err != nil || val < 0 {
|
||||
return 0
|
||||
}
|
||||
return val
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user