diff --git a/db/manifest b/db/manifest index 22a6bfa7d..2600c5981 100755 --- a/db/manifest +++ b/db/manifest @@ -173,3 +173,4 @@ scheduled_sessions_next_session_scheduled.sql fix_users_location_fields.sql audio_latency.sql ams_index.sql +update_ams_index.sql diff --git a/db/up/update_ams_index.sql b/db/up/update_ams_index.sql new file mode 100644 index 000000000..b2bb4b92d --- /dev/null +++ b/db/up/update_ams_index.sql @@ -0,0 +1,55 @@ +CREATE OR REPLACE FUNCTION ams_index (my_user_id VARCHAR, my_locidispid BIGINT, my_audio_latency INTEGER) RETURNS VOID STRICT VOLATILE AS $$ + BEGIN + -- output table to hold tagged music sessions with latency + CREATE TEMPORARY TABLE ams_music_session_tmp (music_session_id VARCHAR(64) NOT NULL, tag INTEGER, latency INTEGER) ON COMMIT DROP; + + -- populate ams_music_session_tmp as all music sessions + INSERT INTO ams_music_session_tmp SELECT DISTINCT id, NULL::INTEGER AS tag, NULL::INTEGER AS latency + FROM active_music_sessions; + + -- TODO worry about active music session where my_user_id is the creator? + -- eh, maybe, but if the music session is active and you're the creator wouldn't you already be in it? + -- so maybe you're on another computer, so why care? plus seth is talking about auto rsvp'ing the session + -- for you, so maybe not a problem. + + -- tag accepted rsvp as 1 + UPDATE ams_music_session_tmp q SET tag = 1 FROM rsvp_slots s, rsvp_requests_rsvp_slots rrs, rsvp_requests r WHERE + q.music_session_id = s.music_session_id AND + s.id = rrs.rsvp_slot_id AND + rrs.rsvp_request_id = r.id AND + r.user_id = my_user_id AND + rrs.chosen = TRUE AND + q.tag is NULL; + + -- tag invitation as 2 + UPDATE ams_music_session_tmp q SET tag = 2 FROM invitations i WHERE + q.music_session_id = i.music_session_id AND + i.receiver_id = my_user_id AND + q.tag IS NULL; + + -- musician access as 3 + UPDATE ams_music_session_tmp q SET tag = 3 FROM music_sessions m WHERE + q.music_session_id = m.id AND + m.musician_access = TRUE AND + q.tag IS NULL; + + -- delete anything not tagged + DELETE FROM ams_music_session_tmp WHERE tag IS NULL; + + -- output table to hold users involved in the ams_music_session_tmp sessions and their latency + CREATE TEMPORARY TABLE ams_users_tmp (music_session_id VARCHAR(64) NOT NULL, user_id VARCHAR(64) NOT NULL, latency INTEGER) ON COMMIT DROP; + + -- populate ams_users_tmp as all musicians in the ams_music_session_tmp sessions with full latency and music session + INSERT INTO ams_users_tmp SELECT c.music_session_id, c.user_id, (s.score+my_audio_latency+c.last_jam_audio_latency)/2 AS latency + FROM ams_music_session_tmp q + INNER JOIN connections c ON c.music_session_id = q.music_session_id + LEFT OUTER JOIN current_scores s ON s.alocidispid = c.locidispid + WHERE s.blocidispid = my_locidispid; + + -- calculate the average latency + UPDATE ams_music_session_tmp q SET latency = (select AVG(u.latency) FROM ams_users_tmp u WHERE + q.music_session_id = u.music_session_id); + + RETURN; + END; +$$ LANGUAGE plpgsql; diff --git a/ruby/spec/jam_ruby/models/active_music_session_spec.rb b/ruby/spec/jam_ruby/models/active_music_session_spec.rb index effc53291..05fc301d7 100644 --- a/ruby/spec/jam_ruby/models/active_music_session_spec.rb +++ b/ruby/spec/jam_ruby/models/active_music_session_spec.rb @@ -385,10 +385,39 @@ describe ActiveMusicSession do end # todo we need more tests: - # rsvp'd user (chosen and not chosen) - # invited user - # creator (who should be automatically rsvp'd) - # musician_access and not + # + # the easiest collection of tests, not involving filtering, just tagging and latency, still result in many cases + # (given a creator, member, and observer): + # + # {not_rsvp, rsvp_not_chosen, rsvp_chosen} x + # {not_invited, invited} x + # {no_musicians, musicians_on_approval, musicians_freely_join} x + # {creator_not_member, creator_is_member} x + # {observer_not_member, observer_is_member} x + # {observer_member_not_scored, observer_member_scored} + # + # eh, that's 144 cases all told, and that doesn't cover the cases with multiple members... + # + # member is the user in the session + # creator is the user that created the session + # observer is the user making the call to ams_index + # + # the first two categories (rsvp and invited) are about the observer. + # + # i see this being written like this: + # + # test_ams([:not_rsvp, :not_invited, :no_musicians, :creator_not_member, :observer_not_member, :observer_member_not_scored], + # member_latency, observer_member_score, observer_latency, expected_count, expected_tag, expected_latency) + # + # ... repeat as above with all the various combinations by choosing one from each category and appropriate other + # values and then expected results ... + # + # expected_count is 0 for the above written case, and would be 1 in the cases where any of rsvp_chosen, invited, + # musicians_on_approval, or musicians_freely_join are specified. test_ams would know which session and user should + # appear in the results of ams_index and ams_users. + # + # there should be an additional active music session created and joined by a distinct user, other. it should never + # appear in results. end