add count to artist songs

This commit is contained in:
2025-02-06 00:58:49 +01:00
parent 6caefaffb2
commit 2afbf31ed6
6 changed files with 256 additions and 76 deletions

View File

@@ -351,21 +351,22 @@ func getSearch(db *sql.DB, q string, limit, offset int) (ActiveSearch, error) {
return ActiveSearch{}, nil return ActiveSearch{}, nil
} }
func getArtists(db *sql.DB, q string, limit, offset int) ([]string, error) { func getArtists(db *sql.DB, q string, limit, offset int) ([]Artist, error) {
rows, err := db.Query("SELECT Artist FROM Beatmap WHERE Artist LIKE ? OR Title LIKE ? GROUP BY Artist LIMIT ? OFFSET ?", "%"+q+"%", "%"+q+"%", limit, offset) rows, err := db.Query("SELECT Artist, COUNT(Artist) FROM Beatmap WHERE Artist LIKE ? OR Title LIKE ? GROUP BY Artist LIMIT ? OFFSET ?", "%"+q+"%", "%"+q+"%", limit, offset)
if err != nil { if err != nil {
return []string{}, err return []Artist{}, err
} }
defer rows.Close() defer rows.Close()
var artist []string artist := []Artist{}
for rows.Next() { for rows.Next() {
var a string var a string
err := rows.Scan(&a) var c int
err := rows.Scan(&a, &c)
if err != nil { if err != nil {
return []string{}, err return []Artist{}, err
} }
artist = append(artist, a) artist = append(artist, Artist{Artist: a, Count: c})
} }
return artist, nil return artist, nil

View File

@@ -287,10 +287,7 @@ const docTemplate = `{
"200": { "200": {
"description": "List of artists", "description": "List of artists",
"schema": { "schema": {
"type": "array", "$ref": "#/definitions/main.Artist"
"items": {
"type": "string"
}
} }
}, },
"400": { "400": {
@@ -413,6 +410,52 @@ const docTemplate = `{
} }
} }
}, },
"/songs/artist": {
"get": {
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"songs"
],
"summary": "Returns all the Songs of a specific Artist",
"parameters": [
{
"type": "string",
"description": "Artist Name",
"name": "artist",
"in": "query",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/main.Song"
}
}
},
"400": {
"description": "Bad Request",
"schema": {
"type": "string"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"type": "string"
}
}
}
}
},
"/songs/favorites": { "/songs/favorites": {
"get": { "get": {
"description": "Retrieves favorite songs filtered by a query with pagination support.", "description": "Retrieves favorite songs filtered by a query with pagination support.",
@@ -540,6 +583,20 @@ const docTemplate = `{
} }
} }
}, },
"main.Artist": {
"description": "Artist holds search results for a given artist",
"type": "object",
"properties": {
"artist": {
"type": "string",
"example": "Miku"
},
"count": {
"type": "integer",
"example": 21
}
}
},
"main.Collection": { "main.Collection": {
"description": "Collection holds a list of songs", "description": "Collection holds a list of songs",
"type": "object", "type": "object",

View File

@@ -281,10 +281,7 @@
"200": { "200": {
"description": "List of artists", "description": "List of artists",
"schema": { "schema": {
"type": "array", "$ref": "#/definitions/main.Artist"
"items": {
"type": "string"
}
} }
}, },
"400": { "400": {
@@ -407,6 +404,52 @@
} }
} }
}, },
"/songs/artist": {
"get": {
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"songs"
],
"summary": "Returns all the Songs of a specific Artist",
"parameters": [
{
"type": "string",
"description": "Artist Name",
"name": "artist",
"in": "query",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/main.Song"
}
}
},
"400": {
"description": "Bad Request",
"schema": {
"type": "string"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"type": "string"
}
}
}
}
},
"/songs/favorites": { "/songs/favorites": {
"get": { "get": {
"description": "Retrieves favorite songs filtered by a query with pagination support.", "description": "Retrieves favorite songs filtered by a query with pagination support.",
@@ -534,6 +577,20 @@
} }
} }
}, },
"main.Artist": {
"description": "Artist holds search results for a given artist",
"type": "object",
"properties": {
"artist": {
"type": "string",
"example": "Miku"
},
"count": {
"type": "integer",
"example": 21
}
}
},
"main.Collection": { "main.Collection": {
"description": "Collection holds a list of songs", "description": "Collection holds a list of songs",
"type": "object", "type": "object",

View File

@@ -11,6 +11,16 @@ definitions:
$ref: '#/definitions/main.Song' $ref: '#/definitions/main.Song'
type: array type: array
type: object type: object
main.Artist:
description: Artist holds search results for a given artist
properties:
artist:
example: Miku
type: string
count:
example: 21
type: integer
type: object
main.Collection: main.Collection:
description: Collection holds a list of songs description: Collection holds a list of songs
properties: properties:
@@ -248,9 +258,7 @@ paths:
"200": "200":
description: List of artists description: List of artists
schema: schema:
items: $ref: '#/definitions/main.Artist'
type: string
type: array
"400": "400":
description: Bad Request description: Bad Request
schema: schema:
@@ -332,6 +340,36 @@ paths:
summary: Get a song by its hash summary: Get a song by its hash
tags: tags:
- songs - songs
/songs/artist:
get:
consumes:
- application/json
parameters:
- description: Artist Name
in: query
name: artist
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
items:
$ref: '#/definitions/main.Song'
type: array
"400":
description: Bad Request
schema:
type: string
"500":
description: Internal Server Error
schema:
type: string
summary: Returns all the Songs of a specific Artist
tags:
- songs
/songs/favorites: /songs/favorites:
get: get:
consumes: consumes:

View File

@@ -36,6 +36,7 @@ func (s *Server) registerRoutes() {
http.HandleFunc("/api/v1/song/{hash}/", s.song) http.HandleFunc("/api/v1/song/{hash}/", s.song)
http.HandleFunc("/api/v1/songs/recents", s.recents) http.HandleFunc("/api/v1/songs/recents", s.recents)
http.HandleFunc("/api/v1/songs/favorites", s.favorites) http.HandleFunc("/api/v1/songs/favorites", s.favorites)
http.HandleFunc("/api/v1/songs/artist", s.aristsSongs)
http.HandleFunc("/api/v1/collection", s.collection) http.HandleFunc("/api/v1/collection", s.collection)
http.HandleFunc("/api/v1/search/collections", s.collectionSearch) http.HandleFunc("/api/v1/search/collections", s.collectionSearch)
@@ -230,6 +231,25 @@ func (s *Server) collectionSearch(w http.ResponseWriter, r *http.Request) {
writeJSON(w, preview, http.StatusOK) writeJSON(w, preview, http.StatusOK)
} }
// @Summary Returns all the Songs of a specific Artist
// @Tags songs
// @Accept json
// @Produce json
// @Param artist query string true "Artist Name"
// @Success 200 {array} Song
// @Failure 400 {object} string "Bad Request"
// @Failure 500 {object} string "Internal Server Error"
// @Router /songs/artist [get]
func (s *Server) aristsSongs(w http.ResponseWriter, r *http.Request) {
artist := r.URL.Query().Get("artist")
if artist == "" {
http.Error(w, ErrRequiredParameterNotPresent.Error(), http.StatusBadRequest)
return
}
writeJSON(w, []Song{}, http.StatusOK)
}
// @Summary Searches active records based on a query // @Summary Searches active records based on a query
// @Description Searches active records in the database based on the query parameter // @Description Searches active records in the database based on the query parameter
// @Tags search // @Tags search
@@ -269,7 +289,7 @@ func (s *Server) activeSearch(w http.ResponseWriter, r *http.Request) {
// @Param query query string true "Search query" // @Param query query string true "Search query"
// @Param limit query int false "Limit the number of results" default(10) // @Param limit query int false "Limit the number of results" default(10)
// @Param offset query int false "Offset for pagination" default(0) // @Param offset query int false "Offset for pagination" default(0)
// @Success 200 {array} string "List of artists" // @Success 200 {object} Artist "List of artists"
// @Failure 400 {object} string "Bad Request" // @Failure 400 {object} string "Bad Request"
// @Failure 500 {object} string "Internal Server Error" // @Failure 500 {object} string "Internal Server Error"
// @Router /search/artist [get] // @Router /search/artist [get]

View File

@@ -37,3 +37,10 @@ type ActiveSearch struct {
Artist string `json:"artist" example:"Ed Sheeran"` Artist string `json:"artist" example:"Ed Sheeran"`
Songs []Song `json:"songs"` Songs []Song `json:"songs"`
} }
// Artist represents an active song search query
// @Description Artist holds search results for a given artist
type Artist struct {
Artist string `json:"artist" example:"Miku"`
Count int `json:"count" example:"21"`
}