myexperiment-hackers
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[myexperiment-hackers] [2190] branches/event_logging/app/helpers/applica


From: noreply
Subject: [myexperiment-hackers] [2190] branches/event_logging/app/helpers/application_helper.rb: Minor reworking of news_from_log_for_contributor() to coalesce activity log
Date: Fri, 8 May 2009 12:07:44 -0400 (EDT)

Revision
2190
Author
dtm
Date
2009-05-08 12:07:44 -0400 (Fri, 08 May 2009)

Log Message

Minor reworking of news_from_log_for_contributor() to coalesce activity log
queries into one query.

Modified Paths

Diff

Modified: branches/event_logging/app/helpers/application_helper.rb (2189 => 2190)


--- branches/event_logging/app/helpers/application_helper.rb	2009-05-08 14:33:50 UTC (rev 2189)
+++ branches/event_logging/app/helpers/application_helper.rb	2009-05-08 16:07:44 UTC (rev 2190)
@@ -1539,6 +1539,8 @@
     # - members of networks, where current user is member of;
     # - members of networks, where current user is admin of;
     
+    # instead of accumulating events from queries to the activity log, we accumulate types of query and
+    # required parameters, and then form that into one query at the end
     events = []
     events_as_admin = []
     related_contributors = []
@@ -1555,7 +1557,7 @@
           
           # ..add networks AND members of networks, where contributor is admin AND where contributor is member of
           # (adding networks will provide with events like "network X credited for workflow Y", etc)
-          contributor.networks.concat(contributor.networks_owned).each do |network|
+          ( contributor.networks_owned + contributor.networks ).each do |network|
             related_contributors.concat([network])
             related_contributors.concat(network.members)
           end
@@ -1582,10 +1584,10 @@
           # NB! this db query is not the same as the one done when ALL network news are
           # generated - therefore, was not possible to make recursive call on each 
           # of the networks in turn
-          contributor.networks_owned.each do |network|
-            network_events = ActivityLog.find(:all, :conditions => ["created_at > ? AND created_at < ? AND (culprit_type = ? AND culprit_id = ?)", after, before, network.class.to_s, network.id]) 
-            events_as_admin.concat(network_events)
-          end
+          #network_events = ActivityLog.find(:all, :conditions => ["created_at > ? AND created_at < ? AND culprit_type = ? AND culprit_id IN (#{net_ids_owned.join(",")})", after,             before, net_owned[0].class.to_s]) 
+          events_as_admin.concat(
+            contributor.networks_owned.collect { |x| ["culprit", x.class.to_s, x.id] }
+            )
         end
       when "network"
         # UNCOMMENT THE NEXT LINE TO GET NEWS OF GROUP'S MEMBERS IN THE GROUP'S NEWS FEED
@@ -1601,10 +1603,15 @@
     # (no need to impose order on the DB query, as more queries will be run [for "related_contributors"]
     #  and subsequent sorting will be required anyway)
     unless contributor_news_only && contributor_initiated_actions_only
-      events = ActivityLog.find(:all, :conditions => ["created_at > ? AND created_at < ? AND ((activity_loggable_type = ? AND activity_loggable_id = ?) OR (culprit_type = ? AND culprit_id = ?) OR (referenced_type = ? AND referenced_id = ?))", after, before, contributor.class.to_s, contributor.id, contributor.class.to_s, contributor.id, contributor.class.to_s, contributor.id])
+#      events = ActivityLog.find(:all, :conditions => ["created_at > ? AND created_at < ? AND ((activity_loggable_type = ? AND activity_loggable_id = ?) OR (culprit_type = ? AND culprit_id = ?) OR (referenced_type = ? AND referenced_id = ?))", after, before, contributor.class.to_s, contributor.id, contributor.class.to_s, contributor.id, contributor.class.to_s, contributor.id])
+          events= [ ["activity", contributor.class.to_s, contributor.id],
+                    ["culprit", contributor.class.to_s, contributor.id],
+                    ["referenced", contributor.class.to_s, contributor.id]
+                  ]
     else
       # only fetch events where "contributor" is the 'culprit' of the action
-      events = ActivityLog.find(:all, :conditions => ["created_at > ? AND created_at < ? AND (culprit_type = ? AND culprit_id = ?)", after, before, contributor.class.to_s, contributor.id])
+#      events = ActivityLog.find(:all, :conditions => ["created_at > ? AND created_at < ? AND (culprit_type = ? AND culprit_id = ?)", after, before, contributor.class.to_s, contributor.id])
+          events= [ ["culprit", contributor.class.to_s, contributor.id] ]
     end
     events.concat(events_as_admin)
     
@@ -1638,45 +1645,110 @@
       #
       # don't show site announcements on profile page news feeds
       unless contributor_news_only
-        site_announcements = ActivityLog.find(:all, :conditions => ["created_at > ? AND created_at < ? AND activity_loggable_type = ?", after, before, "Announcement"]) 
-        events.concat(site_announcements)
+#        site_announcements = ActivityLog.find(:all, :conditions => ["created_at > ? AND created_at < ? AND activity_loggable_type = ?", after, before, "Announcement"]) 
+        events << ["announcements"]
       end
-      
 
       # ==== User's Items ====
       # get hold of all the items belonging to the current user
-      # array initialization statement needed to avoid ActiveRecord::AssociationTypeMismatch exception
-      users_stuff = []
+
       # user's contributions will contain all workflows/files/packs where the user is original uploader
-      users_stuff.concat(contributor.contributions.collect { |c_ution| c_ution.contributable })
+##### users_stuff.concat(contributor.contributions.collect { |c_ution| c_ution.contributable })
+      c_utions=contributor.contributions
+
+      events.concat( c_utions.collect { |o| ["activity",   o.contributable_type, o.contributable_id] } )
+      events.concat( c_utions.collect { |o| ["referenced", o.contributable_type, o.contributable_id] } )
+       
       # workflows, where WF versions uploaded by the user (when they are not the original uploader) - these aren't included into user's contributions
-      users_stuff.concat(contributor.workflows_with_contributed_versions)
+      wfvs=contributor.workflows_with_contributed_versions
+      events.concat( wfvs.collect { |o| ["activity",   o.class.to_s, o.id] } )
+      events.concat( wfvs.collect { |o| ["referenced", o.class.to_s, o.id] } )
       
       # also, fetch user's favourites
-      contributor.bookmarks.each do |favourite|
-        users_stuff.concat([favourite.bookmarkable])
-      end
+#######contributor.bookmarks.each do |favourite|
+#######  users_stuff.concat([favourite.bookmarkable])
+#######end
+      bms=contributor.bookmarks
+      events.concat( bms.collect { |b| ["activity",   b.bookmarkable_type, b.bookmarkable_id] } )
+      events.concat( bms.collect { |b| ["referenced", b.bookmarkable_type, b.bookmarkable_id] } )
       
-      # there might be overlap between user's contributables and favourites
-      # (because it's allowed to favourite own contributables)
-      users_stuff = users_stuff.uniq
-      
-      # get events log entries for all the user's items
-      users_stuff.each do |thing|
-        users_stuff_events = ActivityLog.find(:all, :conditions => ["created_at > ? AND created_at < ? AND ((activity_loggable_type = ? AND activity_loggable_id = ?) OR (referenced_type = ? AND referenced_id = ?))", after, before, thing.class.to_s, thing.id, thing.class.to_s, thing.id])
-        events.concat(users_stuff_events)
-      end
-      
     end
     
     
     # ============================================================
     #  ALL RELEVANT EVENT LOG ENTRIES HAVE BEEN FETCHED UP TO NOW
     # ============================================================
-    rtn = news_entries_from_log_entries(events, limit, current_viewer, contributor, contributor_news_only)
+    rtn = news_entries_from_log_entries(activities_from_interest_array(before, after, events), limit, current_viewer, contributor, contributor_news_only)
     
     return rtn
   end
+
+  def activities_from_interest_array(before, after, events)
+    # Events is an array of items:
+    #   [ query_type, param1, param2 ]
+    #   where param1 is usually type and param2 is usually id
+    
+    conditions_sql=[]
+    conditions_args=[]
+
+    # group events by query_type
+    grouped_queries=group_arrays_by_first_element(events)
+
+    grouped_queries.each do |query_type,event_list|
+      case query_type
+      when "announcements"
+        conditions_sql << '(activity_loggable_type = "Announcement")'
+      when "activity"
+        # group items by type
+        grouped_events=group_arrays_by_first_element(event_list)
+        # for each type create an sql entry 
+        grouped_events.each do | type, remaining | 
+          conditions_sql << '(activity_loggable_type = ? AND activity_loggable_id IN (?))'
+          # add the parameters for this sql to the arguments
+          # note picking out the ids from remaining array which is of the form [[id1],[id2],[id3]..]
+          conditions_args.concat([type, remaining.collect {|x| x[0] }])
+          end
+      when "referenced"
+        # same structure as activity
+        grouped_events=group_arrays_by_first_element(event_list)
+        grouped_events.each do | type, remaining | 
+          conditions_sql << '(referenced_type = ? AND referenced_id IN (?))'
+          conditions_args.concat([type, remaining.collect {|x| x[0] }])
+          end
+      when "culprit"
+        # same structure as activity
+        grouped_events=group_arrays_by_first_element(event_list)
+        grouped_events.each do | type, remaining | 
+          conditions_sql << '(culprit_type = ? AND culprit_id IN (?))'
+          conditions_args.concat([type, remaining.collect {|x| x[0] }])
+          end
+       end
+    end
+
+    # form conditions_sql and conditions_arg
+    # - prepend the time constraint
+    # - OR all the accumulated sql statements together
+    # - add the args
+    activity_events=ActivityLog.find(:all,
+                                     :conditions => ( [ "created_at > ? AND created_at < ? AND ( #{conditions_sql.join(" OR ")} )" ] + [after,before] + conditions_args )
+                                    )
+
+    return activity_events
+  end
+
+  def group_arrays_by_first_element(l)
+    rtn = {}
+    
+    l.each do |el|
+      k=el.shift
+      if rtn[ k ].nil? 
+        rtn[ k ]=[ el ]
+      else
+        rtn[ k ] << el
+      end
+    end
+    return rtn
+  end
   
   
   # Produces an array of news items in a form of [timestamp, description string, news_category_string] from ActivityLog table.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]