Select the types of activity you want to include in your feed.
With work on the repos in go, there is now the ability to get all the
data for an artist page like counts for the date ranges, most played
songs and most played releases from an artist
···1414}
15151616type RecordingCount struct {
1717+ Pagination pagination.Filter
1818+ From time.Time
1919+ To time.Time
2020+ ArtistMBID string
2121+ ReleaseMBID string
2222+ UserID int
2323+}
2424+2525+type ReleaseCount struct {
1726 Pagination pagination.Filter
1827 From time.Time
1928 To time.Time
+4-2
internal/models/catalog.go
···2222}
23232424type Release struct {
2525- MBID string
2626- Name string
2525+ MBID string
2626+ Name string
2727+ Count int
2828+ Artists []ArtistCreditName
2729}
+29-3
internal/repo/db/artist.go
···2525 var statement = /*sql*/ `
2626 SELECT artist.gid, artist.name FROM artist WHERE artist.gid IN (%s);
2727 `
2828- statement = fmt.Sprintf(statement, database.GeneratePlaceholders(len(mbids)))
2828+ statement = fmt.Sprintf(statement, database.Placeholders(len(mbids)))
29293030- args := []any{mbids}
3131- args = database.ExpandArgs(args)
3030+ var args = make([]any, len(mbids))
3131+ args = database.AppendMany(args, mbids)
32323333 items, err := database.QueryMany(ctx, repo.db, statement, args, func(r *sql.Rows) (models.Artist, error) {
3434 var artist models.Artist
···5959 return artist, nil
6060 })
6161}
6262+6363+// Returns a part of the query that can be used to retrieve the artists along with their artist
6464+// credit name value based on the artist credit id that is passed as an argument. For a recording
6565+// one should therefore pass the following value: `recording.artist_credit`, for a release group, it
6666+// would be release_group.artist_credit
6767+func artistCreditNamesJsonStatement(artistCreditColumn string) string {
6868+ const statement = /*sql*/ `
6969+ SELECT JSON_GROUP_ARRAY(
7070+ JSON_OBJECT(
7171+ 'name', artist_credit_name.name,
7272+ 'join_phrase', artist_credit_name.join_phrase,
7373+ 'position', artist_credit_name.position,
7474+ 'artist', JSON_OBJECT(
7575+ 'mbid', artist.gid,
7676+ 'name', artist.name
7777+ )
7878+ )
7979+ )
8080+ FROM artist_credit
8181+ INNER JOIN artist_credit_name ON artist_credit.id = artist_credit_name.artist_credit
8282+ INNER JOIN artist ON artist_credit_name.artist = artist.id
8383+ WHERE artist_credit.id = %s
8484+ `
8585+8686+ return fmt.Sprintf(statement, artistCreditColumn)
8787+}
···66 "strings"
77)
8899-// Expands inner arrays in the slice of args, so it can be used in a query with variadic arguments.
1010-func ExpandArgs(args []any) []any {
1111- out := make([]any, 0)
1212- for _, arg := range args {
1313- switch v := arg.(type) {
1414- case []string:
1515- for _, s := range v {
1616- out = append(out, s)
1717- }
1818- case []int:
1919- for _, i := range v {
2020- out = append(out, i)
2121- }
2222- default:
2323- out = append(out, arg)
2424- }
99+func AppendMany[T any](args []any, values []T) []any {
1010+ for _, value := range values {
1111+ args = append(args, value)
2512 }
2626- return out
1313+ return args
2714}
28152916// QueryMany executes a query and returns a slice of results. It is a small helper function reducing
···70577158// Generates a string of placeholders for a SQL query. For example, if count is 3, the result will
7259// be "?, ?, ?".
7373-func GeneratePlaceholders(count int) string {
6060+func Placeholders(count int) string {
7461 placeholders := make([]string, count)
7562 for i := range placeholders {
7663 placeholders[i] = "?"
7764 }
7865 return strings.Join(placeholders, ", ")
7966}
6767+6868+type Condition struct {
6969+ SQL string
7070+ Value any
7171+ Ok bool
7272+}
7373+7474+// Takes a list of where strings and argument values together with a list of conditions. Those
7575+// conditions that are Ok will be added to the list of where strings and argument values. Useful
7676+// when having optional conditionals that used to filter a query.
7777+func Where(wheres []string, args []any, conditions ...Condition) ([]string, []any) {
7878+ for _, v := range conditions {
7979+ if v.Ok {
8080+ wheres = append(wheres, v.SQL)
8181+ args = append(args, v.Value)
8282+ }
8383+ }
8484+ return wheres, args
8585+}
8686+8787+// Takes a list of SQL condition snippets and joins them with AND. If the list is empty, returns
8888+// TRUE.
8989+func WhereSQL(wheres []string) string {
9090+ where := "TRUE"
9191+ if len(wheres) > 0 {
9292+ where = strings.Join(wheres, " AND ")
9393+ }
9494+ return where
9595+}