player.go 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. package repository
  2. import (
  3. "database/sql"
  4. "github.com/jmoiron/sqlx"
  5. )
  6. func getSongIdOrZero(db *sqlx.DB, query string, songId int64) (assocSongId int64, err error) {
  7. err = db.QueryRowx(query, songId).Scan(&assocSongId)
  8. if err != nil && err == sql.ErrNoRows {
  9. err = nil
  10. assocSongId = 0
  11. }
  12. return
  13. }
  14. func GetNextSongId(db *sqlx.DB, prevSongId int64) (nextSongId int64, err error) {
  15. nextSongId, err = getSongIdOrZero(
  16. db,
  17. `
  18. select coalesce(id_next, 0) as id from (
  19. select
  20. prev.track_number, prev.title, prev.artist, prev.album
  21. ,coalesce(prev.id_next, next_artist.id) as id_next
  22. from (
  23. select
  24. prev.track_number, prev.title, prev.artist, prev.album
  25. ,coalesce(prev.id_next, next_album.id) as id_next
  26. from (
  27. select
  28. prev.track_number, prev.title, prev.artist, prev.album
  29. ,coalesce(prev.id_next, next_title.id) as id_next
  30. from (
  31. select
  32. prev.track_number, prev.title, prev.artist, prev.album
  33. ,coalesce(prev.id_next, next_track_number.id) as id_next
  34. from (
  35. select
  36. prev.track_number, prev.title, prev.artist, prev.album
  37. ,next_no_info.id as id_next
  38. from (
  39. select track_number, title, artist, album from songs
  40. where id = $1
  41. ) prev
  42. left join songs next_no_info on 1=1
  43. and prev.artist = ''
  44. and prev.album = ''
  45. and next_no_info.id > $1
  46. order by
  47. next_no_info.artist
  48. ,next_no_info.album
  49. ,next_no_info.track_number
  50. ,next_no_info.title
  51. ,next_no_info.id
  52. limit 1
  53. ) prev
  54. left join songs next_track_number on 1=1
  55. and prev.id_next is null
  56. and next_track_number.artist = prev.artist
  57. and next_track_number.album = prev.album
  58. and (
  59. (prev.track_number > 0 and next_track_number.track_number > prev.track_number)
  60. or (prev.track_number = 0 and next_track_number.id > $1)
  61. )
  62. order by next_track_number.track_number, next_track_number.id
  63. limit 1
  64. ) prev
  65. left join songs next_title on 1=1
  66. and prev.id_next is null
  67. and next_title.artist = prev.artist
  68. and next_title.album = prev.album
  69. and next_title.track_number is null
  70. and next_title.title > prev.title
  71. order by next_title.title
  72. limit 1
  73. ) prev
  74. left join songs next_album on 1=1
  75. and prev.id_next is null
  76. and next_album.artist = prev.artist
  77. and next_album.album > prev.album
  78. order by next_album.album, next_album.track_number, next_album.title
  79. limit 1
  80. ) prev
  81. left join songs next_artist on 1=1
  82. and prev.id_next is null
  83. and next_artist.artist > prev.artist
  84. order by next_artist.artist, next_artist.album, next_artist.track_number, next_artist.title
  85. limit 1
  86. ) result
  87. `,
  88. prevSongId,
  89. )
  90. return
  91. }
  92. func GetPrevSongId(db *sqlx.DB, nextSongId int64) (prevSongId int64, err error) {
  93. prevSongId, err = getSongIdOrZero(
  94. db,
  95. `
  96. select coalesce(id_next, 0) as id from (
  97. select
  98. prev.track_number, prev.title, prev.artist, prev.album
  99. ,coalesce(prev.id_next, next_no_info.id) as id_next
  100. from (
  101. select
  102. prev.track_number, prev.title, prev.artist, prev.album
  103. ,coalesce(prev.id_next, next_artist.id) as id_next
  104. from (
  105. select
  106. prev.track_number, prev.title, prev.artist, prev.album
  107. ,coalesce(prev.id_next, next_album.id) as id_next
  108. from (
  109. select
  110. prev.track_number, prev.title, prev.artist, prev.album
  111. ,coalesce(prev.id_next, next_title.id) as id_next
  112. from (
  113. select
  114. prev.track_number, prev.title, prev.artist, prev.album
  115. ,next_track_number.id as id_next
  116. from (
  117. select track_number, title, artist, album from songs
  118. where id = $1
  119. ) prev
  120. left join songs next_track_number on 1=1
  121. and next_track_number.artist = prev.artist
  122. and next_track_number.album = prev.album
  123. and next_track_number.track_number < prev.track_number
  124. order by next_track_number.track_number desc
  125. limit 1
  126. ) prev
  127. left join songs next_title on 1=1
  128. and prev.id_next is null
  129. and next_title.artist = prev.artist
  130. and next_title.album = prev.album
  131. and next_title.track_number is null
  132. and next_title.title < prev.title
  133. order by next_title.title desc
  134. limit 1
  135. ) prev
  136. left join songs next_album on 1=1
  137. and prev.id_next is null
  138. and next_album.artist = prev.artist
  139. and next_album.album < prev.album
  140. order by
  141. next_album.album desc
  142. ,next_album.track_number desc
  143. ,next_album.title desc
  144. limit 1
  145. ) prev
  146. left join songs next_artist on 1=1
  147. and prev.id_next is null
  148. and next_artist.artist < prev.artist
  149. order by
  150. next_artist.artist desc
  151. ,next_artist.album desc
  152. ,next_artist.track_number desc
  153. ,next_artist.title desc
  154. limit 1
  155. ) prev
  156. inner join songs from_song on from_song.id = $1
  157. left join songs next_no_info on 1=1
  158. and prev.id_next is null
  159. and next_no_info.artist = ''
  160. and next_no_info.album = ''
  161. and next_no_info.id != $1
  162. and (from_song.artist != '' or from_song.album != '' or next_no_info.id < $1)
  163. order by next_no_info.id desc
  164. limit 1
  165. ) result
  166. `,
  167. nextSongId,
  168. )
  169. return
  170. }