33import static org .mamute .model .EventType .ANSWERER_RELATED_EVENTS ;
44import static org .mamute .model .EventType .ASKER_RELATED_EVENTS ;
55
6+ import java .util .ArrayList ;
7+ import java .util .HashMap ;
68import java .util .List ;
9+ import java .util .Map ;
710
811import javax .inject .Inject ;
912
13+ import com .google .common .collect .ArrayListMultimap ;
14+ import com .google .common .collect .ListMultimap ;
1015import org .hibernate .Criteria ;
1116import org .hibernate .Query ;
1217import org .hibernate .Session ;
1318import org .joda .time .DateTime ;
19+ import org .joda .time .format .DateTimeFormat ;
20+ import org .joda .time .format .DateTimeFormatter ;
1421import org .mamute .dto .KarmaByContextHistory ;
1522import org .mamute .dto .UserSummaryForTag ;
1623import org .mamute .model .ReputationEvent ;
24+ import org .mamute .model .ReputationEventContext ;
1725import org .mamute .model .Tag ;
1826import org .mamute .model .User ;
1927
2028public class ReputationEventDAO {
2129 private static final int TOP_ANSWERERS = 20 ;
22-
30+ private static final DateTimeFormatter DATE_FMT = DateTimeFormat .forPattern ("yyyy/MM/dd" );
31+
2332 private Session session ;
2433 private InvisibleForUsersRule invisible ;
2534
@@ -49,44 +58,78 @@ public void delete(ReputationEvent event) {
4958
5059 @ SuppressWarnings ("unchecked" )
5160 public KarmaByContextHistory karmaWonByQuestion (User user , DateTime after , Integer maxResults ) {
52- Query query = karmaByContextQuery (user , after ).setMaxResults (maxResults );
53- return new KarmaByContextHistory (query .list ());
61+ return karmaByContext (user , after , maxResults );
5462 }
5563
5664 @ SuppressWarnings ("unchecked" )
57- public KarmaByContextHistory karmaWonByQuestion (User user ,
58- DateTime after ) {
59- Query query = karmaByContextQuery (user , after );
60- return new KarmaByContextHistory (query .list ());
65+ public KarmaByContextHistory karmaWonByQuestion (User user , DateTime after ) {
66+ return karmaByContext (user , after , null );
6167 }
62-
63- private Query karmaByContextQuery (User user , DateTime after ) {
64- String hql = "select e.context, sum(e.karmaReward), e.date from ReputationEvent e " +
65- "where e.user=:user and e.date > :after " +
66- "group by e.context, day(e.date) " +
67- "order by e.date desc" ;
68-
68+
69+ @ SuppressWarnings ("unchecked" )
70+ private KarmaByContextHistory karmaByContext (User user , DateTime after , Integer maxResult ) {
71+ String hql = "select e.context.class, e.context.id, sum(e.karmaReward), " +
72+ "concat(concat(year(e.date), '/', month(e.date)), '/', day(e.date)) " +
73+ "from ReputationEvent e " +
74+ "where e.user = :user and e.date > :after " +
75+ "group by e.context.class, e.context.id, concat(concat(year(e.date), '/', month(e.date)), '/', day(e.date)) " +
76+ "order by concat(concat(year(e.date), '/', month(e.date)), '/', day(e.date)) desc" ;
77+
78+ //get aggregate list
6979 Query query = session .createQuery (hql ).setParameter ("user" , user ).setParameter ("after" , after );
70- return query ;
80+ if (maxResult != null ){
81+ query .setMaxResults (maxResult );
82+ }
83+ return new KarmaByContextHistory (fetchContextData (query .list ()));
7184 }
7285
73-
86+ @ SuppressWarnings ("unchecked" )
87+ private List <Object []> fetchContextData (List <Object []> rows ){
88+ //separate id lists by class
89+ ListMultimap <String , Long > ids = ArrayListMultimap .create ();
90+ for (Object [] row : rows ){
91+ ids .put ((String ) row [0 ], (Long ) row [1 ]);
92+ }
93+
94+ //query for objects from their respective tables
95+ Map <String , ReputationEventContext > contexts = new HashMap <>();
96+ for (String key : ids .keySet ()){
97+ List <ReputationEventContext > ctx = session .createQuery ("from " +key +" where id in (:ids)" ).setParameterList ("ids" , ids .get (key )).list ();
98+ for (ReputationEventContext c : ctx ){
99+ contexts .put (key +":" +c .getId (), c );
100+ }
101+ }
102+
103+ //create formatted row data
104+ List <Object []> data = new ArrayList <>();
105+ for (Object [] row : rows ){
106+ data .add (new Object []{
107+ contexts .get (row [0 ] + ":" + row [1 ]),
108+ row [2 ],
109+ DATE_FMT .parseDateTime ((String ) row [3 ])
110+ });
111+ }
112+
113+ return data ;
114+ }
115+
116+
74117 @ SuppressWarnings ("unchecked" )
75118 public KarmaByContextHistory karmaWonByQuestion (User user ) {
76119 String hql = "select e.context, sum(e.karmaReward), e.date from ReputationEvent e " +
77120 "where e.user=:user " +
78121 "group by e.context, day(e.date) " +
79122 "order by e.date desc" ;
80-
123+
81124 Query query = session .createQuery (hql ).setParameter ("user" , user );
82125 return new KarmaByContextHistory (query .list ());
83126 }
84-
127+
85128 @ SuppressWarnings ("unchecked" )
86129 public List <UserSummaryForTag > getTopAnswerersSummaryAllTime (Tag tag ) {
87130 return getTopAnswerersSummary (tag , null ).list ();
88131 }
89-
132+
90133 @ SuppressWarnings ("unchecked" )
91134 public List <UserSummaryForTag > getTopAnswerersSummaryAfter (Tag tag , DateTime after ) {
92135 return getTopAnswerersSummary (tag , after ).setParameter ("after" , after ).list ();
@@ -99,42 +142,47 @@ private Query getTopAnswerersSummary(Tag tag, DateTime after) {
99142 "join e.user user " +
100143 "join q.answers a " +
101144 "join q.information.tags t " +
102- "where user=a.author and e.type in (:events)" +
103- where +
145+ "where user=a.author and e.type in (:events)" +
146+ where +
104147 "and t=:tag " +
105- "and q.id=e.context.id and e.context.class='Question '" +
148+ "and q.id=e.context.id and e.context.class='QUESTION '" +
106149 "group by user " +
107150 "order by karmaSum desc" ;
108-
109- return session .createQuery (hql ).setParameterList ("events" , ANSWERER_RELATED_EVENTS ()).setParameter ("tag" , tag ).setMaxResults (TOP_ANSWERERS );
151+
152+ return session .createQuery (hql )
153+ .setParameterList ("events" , ANSWERER_RELATED_EVENTS ())
154+ .setParameter ("tag" , tag ).setMaxResults (TOP_ANSWERERS );
110155 }
111-
156+
112157 @ SuppressWarnings ("unchecked" )
113158 public List <UserSummaryForTag > getTopAskersSummaryAllTime (Tag tag ) {
114159 return getTopAskersSummary (tag , null ).list ();
115160 }
116-
161+
117162 @ SuppressWarnings ("unchecked" )
118163 public List <UserSummaryForTag > getTopAskersSummaryAfter (Tag tag , DateTime after ) {
119164 return getTopAskersSummary (tag , after ).setParameter ("after" , after ).list ();
120165 }
121-
166+
122167 private Query getTopAskersSummary (Tag tag , DateTime after ) {
123168 String where = after == null ? "" : "and e.date > :after " ;
124169 String hql = "select new "
125170 + "org.mamute.dto.UserSummaryForTag(sum(e.karmaReward) as karmaSum, count(distinct q), user) "
126171 + "from ReputationEvent e, Question q " +
127172 "join e.user user " +
128173 "join q.information.tags t " +
129- "where e.type in (:events)" + where + "and t=:tag and e.context.id = q.id and e.context.class='Question ' " +
174+ "where e.type in (:events)" + where + "and t=:tag and e.context.id = q.id and e.context.class='QUESTION ' " +
130175 "group by user " +
131176 "order by karmaSum desc" ;
132-
133- return session .createQuery (hql ).setParameterList ("events" , ASKER_RELATED_EVENTS ()).setParameter ("tag" , tag ).setMaxResults (TOP_ANSWERERS );
177+
178+ return session .createQuery (hql )
179+ .setParameterList ("events" , ASKER_RELATED_EVENTS ())
180+ .setParameter ("tag" , tag )
181+ .setMaxResults (TOP_ANSWERERS );
134182 }
135-
183+
136184 private Criteria addInvisibleFilter (Criteria criteria ){
137185 return invisible .addFilter ("q" , criteria );
138186 }
139-
187+
140188}
0 commit comments