player.go 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  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 next_track_number.track_number > prev.track_number
  59. order by next_track_number.track_number
  60. limit 1
  61. ) prev
  62. left join songs next_title on 1=1
  63. and prev.id_next is null
  64. and next_title.artist = prev.artist
  65. and next_title.album = prev.album
  66. and next_title.track_number is null
  67. and next_title.title > prev.title
  68. order by next_title.title
  69. limit 1
  70. ) prev
  71. left join songs next_album on 1=1
  72. and prev.id_next is null
  73. and next_album.artist = prev.artist
  74. and next_album.album > prev.album
  75. order by next_album.album, next_album.track_number, next_album.title
  76. limit 1
  77. ) prev
  78. left join songs next_artist on 1=1
  79. and prev.id_next is null
  80. and next_artist.artist > prev.artist
  81. order by next_artist.artist, next_artist.album, next_artist.track_number, next_artist.title
  82. limit 1
  83. ) result
  84. `,
  85. prevSongId,
  86. )
  87. return
  88. }
  89. func GetPrevSongId(db *sqlx.DB, nextSongId int64) (prevSongId int64, err error) {
  90. prevSongId, err = getSongIdOrZero(
  91. db,
  92. `
  93. select coalesce(id_next, 0) as id from (
  94. select
  95. prev.track_number, prev.title, prev.artist, prev.album
  96. ,coalesce(prev.id_next, next_no_info.id) as id_next
  97. from (
  98. select
  99. prev.track_number, prev.title, prev.artist, prev.album
  100. ,coalesce(prev.id_next, next_artist.id) as id_next
  101. from (
  102. select
  103. prev.track_number, prev.title, prev.artist, prev.album
  104. ,coalesce(prev.id_next, next_album.id) as id_next
  105. from (
  106. select
  107. prev.track_number, prev.title, prev.artist, prev.album
  108. ,coalesce(prev.id_next, next_title.id) as id_next
  109. from (
  110. select
  111. prev.track_number, prev.title, prev.artist, prev.album
  112. ,next_track_number.id as id_next
  113. from (
  114. select track_number, title, artist, album from songs
  115. where id = $1
  116. ) prev
  117. left join songs next_track_number on 1=1
  118. and next_track_number.artist = prev.artist
  119. and next_track_number.album = prev.album
  120. and next_track_number.track_number < prev.track_number
  121. order by next_track_number.track_number desc
  122. limit 1
  123. ) prev
  124. left join songs next_title on 1=1
  125. and prev.id_next is null
  126. and next_title.artist = prev.artist
  127. and next_title.album = prev.album
  128. and next_title.track_number is null
  129. and next_title.title < prev.title
  130. order by next_title.title desc
  131. limit 1
  132. ) prev
  133. left join songs next_album on 1=1
  134. and prev.id_next is null
  135. and next_album.artist = prev.artist
  136. and next_album.album < prev.album
  137. order by
  138. next_album.album desc
  139. ,next_album.track_number desc
  140. ,next_album.title desc
  141. limit 1
  142. ) prev
  143. left join songs next_artist on 1=1
  144. and prev.id_next is null
  145. and next_artist.artist < prev.artist
  146. order by
  147. next_artist.artist desc
  148. ,next_artist.album desc
  149. ,next_artist.track_number desc
  150. ,next_artist.title desc
  151. limit 1
  152. ) prev
  153. inner join songs from_song on from_song.id = $1
  154. left join songs next_no_info on 1=1
  155. and prev.id_next is null
  156. and next_no_info.artist = ''
  157. and next_no_info.album = ''
  158. and next_no_info.id != $1
  159. and (from_song.artist != '' or from_song.album != '' or next_no_info.id < $1)
  160. order by next_no_info.id desc
  161. limit 1
  162. ) result
  163. `,
  164. nextSongId,
  165. )
  166. return
  167. }