songs.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. package repository
  2. import (
  3. "github.com/felamaslen/gmus-backend/pkg/read"
  4. "github.com/jmoiron/sqlx"
  5. "github.com/lib/pq"
  6. )
  7. const BATCH_SIZE = 100
  8. func SelectSong(db *sqlx.DB, ids []int) (songs *[]*read.Song, err error) {
  9. songs = &[]*read.Song{}
  10. var idsArray pq.Int64Array
  11. for _, id := range ids {
  12. idsArray = append(idsArray, int64(id))
  13. }
  14. err = db.Select(songs, `
  15. select
  16. id
  17. ,track_number
  18. ,title
  19. ,artist
  20. ,album
  21. ,duration
  22. ,modified_date
  23. ,base_path
  24. ,relative_path
  25. from songs
  26. where id = ANY($1)
  27. `, idsArray)
  28. return
  29. }
  30. func SelectPagedArtists(db *sqlx.DB, limit int, offset int) (artists *[]string, err error) {
  31. artists = &[]string{}
  32. err = db.Select(artists, `
  33. select distinct artist
  34. from songs
  35. order by artist
  36. limit $1
  37. offset $2
  38. `, limit, offset)
  39. return
  40. }
  41. type CountRow struct {
  42. Count int `db:"count"`
  43. }
  44. func SelectArtistCount(db *sqlx.DB) (count int, err error) {
  45. var countRow CountRow
  46. err = db.QueryRowx(`
  47. select count(*) as count from (
  48. select distinct artist from songs
  49. ) distinct_artists
  50. `).StructScan(&countRow)
  51. count = countRow.Count
  52. return
  53. }
  54. func SelectAllArtists(db *sqlx.DB) (artists *[]string, err error) {
  55. artists = &[]string{}
  56. err = db.Select(artists, `select distinct artist from songs order by artist`)
  57. return
  58. }
  59. func SelectAlbumsByArtist(db *sqlx.DB, artist string) (albums *[]string, err error) {
  60. albums = &[]string{}
  61. err = db.Select(albums, `
  62. select distinct album
  63. from songs
  64. where artist = $1
  65. order by album
  66. `, artist)
  67. return
  68. }
  69. func SelectSongsByArtist(db *sqlx.DB, artist string) (songs *[]*read.SongExternal, err error) {
  70. songs = &[]*read.SongExternal{}
  71. err = db.Select(songs, `
  72. select
  73. id
  74. ,track_number
  75. ,title
  76. ,artist
  77. ,album
  78. ,duration
  79. from songs
  80. where artist = $1
  81. order by album, track_number, title, id
  82. `, artist)
  83. return
  84. }
  85. func BatchUpsertSongs(db *sqlx.DB, batch *[BATCH_SIZE]*read.Song, batchSize int) error {
  86. var trackNumbers pq.Int64Array
  87. var titles pq.StringArray
  88. var artists pq.StringArray
  89. var albums pq.StringArray
  90. var durations pq.Int64Array
  91. var modifiedDates pq.Int64Array
  92. var basePaths pq.StringArray
  93. var relativePaths pq.StringArray
  94. for i := 0; i < batchSize; i++ {
  95. trackNumbers = append(trackNumbers, int64((*batch)[i].TrackNumber))
  96. titles = append(titles, (*batch)[i].Title)
  97. artists = append(artists, (*batch)[i].Artist)
  98. albums = append(albums, (*batch)[i].Album)
  99. durations = append(durations, int64((*batch)[i].Duration))
  100. modifiedDates = append(modifiedDates, (*batch)[i].ModifiedDate)
  101. basePaths = append(basePaths, (*batch)[i].BasePath)
  102. relativePaths = append(relativePaths, (*batch)[i].RelativePath)
  103. }
  104. _, err := db.Exec(
  105. `
  106. insert into songs (
  107. track_number
  108. ,title
  109. ,artist
  110. ,album
  111. ,duration
  112. ,modified_date
  113. ,base_path
  114. ,relative_path
  115. )
  116. select * from unnest(
  117. $1::integer[]
  118. ,$2::varchar[]
  119. ,$3::varchar[]
  120. ,$4::varchar[]
  121. ,$5::integer[]
  122. ,$6::bigint[]
  123. ,$7::varchar[]
  124. ,$8::varchar[]
  125. )
  126. on conflict (base_path, relative_path) do update
  127. set
  128. track_number = excluded.track_number
  129. ,title = excluded.title
  130. ,artist = excluded.artist
  131. ,album = excluded.album
  132. ,duration = excluded.duration
  133. ,modified_date = excluded.modified_date
  134. `,
  135. trackNumbers,
  136. titles,
  137. artists,
  138. albums,
  139. durations,
  140. modifiedDates,
  141. basePaths,
  142. relativePaths,
  143. )
  144. return err
  145. }