From 94963f2ad160a4bc54183a5720cd00374e8b1428 Mon Sep 17 00:00:00 2001 From: Steven Miers Date: Tue, 7 Oct 2014 15:34:05 -0500 Subject: [PATCH] VRFS-2028 : Add videos to list_uploads, in addition to tracks. This is accomplished using a SQL union via arel. --- ruby/lib/jam_ruby/models/recording.rb | 93 ++++++++++++++++++++++----- 1 file changed, 76 insertions(+), 17 deletions(-) diff --git a/ruby/lib/jam_ruby/models/recording.rb b/ruby/lib/jam_ruby/models/recording.rb index a6d84bced..4368c3234 100644 --- a/ruby/lib/jam_ruby/models/recording.rb +++ b/ruby/lib/jam_ruby/models/recording.rb @@ -303,22 +303,82 @@ module JamRuby since = 0 unless since || since == '' # guard against nil uploads = [] - RecordedTrack - .joins(:recording) - .where(:user_id => user.id) - .where(:fully_uploaded => false) - .where('recorded_tracks.id > ?', since) - .where("upload_failures <= #{APP_CONFIG.max_track_upload_failures}") - .where("duration IS NOT NULL") - .where('all_discarded = false') - .order('recorded_tracks.id') - .limit(limit).each do |recorded_track| - uploads.push({ - :type => "recorded_track", - :client_track_id => recorded_track.client_track_id, - :recording_id => recorded_track.recording_id, - :next => recorded_track.id - }) + + # Uploads now include videos in addition to the tracks. + # This is accomplished using a SQL union via arel, as follows: + + # Select fields from track. Note the reorder, which removes + # the default scope sort as it b0rks the union. Also note the + # alias so that we can differentiate tracks and videos when + # processing the results: + track_arel = RecordedTrack.select([ + :id, + :recording_id, + :url, + :fully_uploaded, + :upload_failures, + :client_track_id, + Arel::Nodes::As.new('track', Arel.sql('item_type')) + ]).reorder("") + + # Select fields for video. Note that it must include + # the same number of fields as the track in order for + # the union to work: + vid_arel = RecordedVideo.select([ + :id, + :recording_id, + :url, + :fully_uploaded, + :upload_failures, + :client_video_source_id, + Arel::Nodes::As.new('video', Arel.sql('item_type')) + ]).reorder("") + + # Glue them together: + union = track_arel.union(vid_arel) + + # Create a table alias from the union so we can get back to arel: + utable = RecordedTrack.arel_table.create_table_alias(union, :recorded_items) + arel = track_arel.from(utable) + arel = arel.select([ + :id, + :recording_id, + :url, + :fully_uploaded, + :upload_failures, + :client_track_id, + :item_type + ]) + + # Further joining and criteria for the unioned object: + arel = arel.joins("INNER JOIN (SELECT id as rec_id, all_discarded, duration FROM recordings) recs ON rec_id=recorded_items.recording_id") \ + .where('recorded_items.fully_uploaded =?', false) \ + .where('recorded_items.id > ?', since) \ + .where("upload_failures <= #{APP_CONFIG.max_track_upload_failures}") \ + .where("duration IS NOT NULL") \ + .where('all_discarded = false') \ + .order('recorded_items.id') \ + .limit(limit) + + # Load into array: + arel.each do |recorded_item| + if(recorded_item.item_type=='video') + # A video: + uploads << ({ + :type => "recorded_video", + :client_video_source_id => recorded_item.client_track_id, + :recording_id => recorded_item.recording_id, + :next => recorded_item.id + }) + else + # A track: + uploads << ({ + :type => "recorded_track", + :client_track_id => recorded_item.client_track_id, + :recording_id => recorded_item.recording_id, + :next => recorded_item.id + }) + end end next_value = uploads.length > 0 ? uploads[-1][:next].to_s : nil @@ -326,7 +386,6 @@ module JamRuby next_value = since # echo back to the client the same value they passed in, if there are no results end - { "uploads" => uploads, "next" => next_value.to_s