player.go 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  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(next_artist.id, prev.id_next) as id_next
  22. from (
  23. select
  24. prev.track_number, prev.title, prev.artist, prev.album
  25. ,coalesce(next_album.id, prev.id_next) as id_next
  26. from (
  27. select
  28. prev.track_number, prev.title, prev.artist, prev.album
  29. ,coalesce(next_title.id, prev.id_next) as id_next
  30. from (
  31. select
  32. prev.track_number, prev.title, prev.artist, prev.album
  33. ,next_track_number.id as id_next
  34. from (
  35. select track_number, title, artist, album from songs
  36. where id = $1
  37. ) prev
  38. left join songs next_track_number on 1=1
  39. and next_track_number.artist = prev.artist
  40. and next_track_number.album = prev.album
  41. and next_track_number.track_number > prev.track_number
  42. order by next_track_number.track_number
  43. limit 1
  44. ) prev
  45. left join songs next_title on 1=1
  46. and prev.id_next is null
  47. and next_title.artist = prev.artist
  48. and next_title.album = prev.album
  49. and next_title.track_number is null
  50. and next_title.title > prev.title
  51. order by next_title.title
  52. limit 1
  53. ) prev
  54. left join songs next_album on 1=1
  55. and prev.id_next is null
  56. and next_album.artist = prev.artist
  57. and next_album.album > prev.album
  58. order by next_album.album, next_album.track_number, next_album.title
  59. limit 1
  60. ) prev
  61. left join songs next_artist on 1=1
  62. and prev.id_next is null
  63. and next_artist.artist > prev.artist
  64. order by next_artist.artist, next_artist.album, next_artist.track_number, next_artist.title
  65. limit 1
  66. ) result
  67. `,
  68. prevSongId,
  69. )
  70. return
  71. }
  72. func GetPrevSongId(db *sqlx.DB, nextSongId int64) (prevSongId int64, err error) {
  73. prevSongId, err = getSongIdOrZero(
  74. db,
  75. `
  76. select coalesce(id_prev, 0) as id from (
  77. select
  78. next.track_number, next.title, next.artist, next.album
  79. ,coalesce(prev_artist.id, next.id_prev) as id_prev
  80. from (
  81. select
  82. next.track_number, next.title, next.artist, next.album
  83. ,coalesce(prev_album.id, next.id_prev) as id_prev
  84. from (
  85. select
  86. next.track_number, next.title, next.artist, next.album
  87. ,coalesce(prev_title.id, next.id_prev) as id_prev
  88. from (
  89. select
  90. next.track_number, next.title, next.artist, next.album
  91. ,prev_track_number.id as id_prev
  92. from (
  93. select track_number, title, artist, album from songs
  94. where id = $1
  95. ) next
  96. left join songs prev_track_number on 1=1
  97. and prev_track_number.artist = next.artist
  98. and prev_track_number.album = next.album
  99. and prev_track_number.track_number < next.track_number
  100. order by prev_track_number.track_number desc
  101. limit 1
  102. ) next
  103. left join songs prev_title on 1=1
  104. and next.id_prev is null
  105. and prev_title.artist = next.artist
  106. and prev_title.album = next.album
  107. and prev_title.track_number is null
  108. and prev_title.title < next.title
  109. order by prev_title.title desc
  110. limit 1
  111. ) next
  112. left join songs prev_album on 1=1
  113. and next.id_prev is null
  114. and prev_album.artist = next.artist
  115. and prev_album.album < next.album
  116. order by prev_album.album desc, prev_album.track_number desc, prev_album.title desc
  117. limit 1
  118. ) next
  119. left join songs prev_artist on 1=1
  120. and next.id_prev is null
  121. and prev_artist.artist < next.artist
  122. order by prev_artist.artist desc, prev_artist.album desc, prev_artist.track_number desc, prev_artist.title desc
  123. limit 1
  124. ) result
  125. `,
  126. nextSongId,
  127. )
  128. return
  129. }