1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
# frozen_string_literal: true
module EvilQuery
class Base
include Diaspora::Logging
def fetch_ids!(relation, id_column)
#the relation should be ordered and limited by here
@class.connection.select_values(id_sql(relation, id_column))
end
def id_sql(relation, id_column)
@class.connection.unprepared_statement { relation.select(id_column).to_sql }
end
end
class Participation < Base
def initialize(user)
@user = user
@class = Post
end
def posts
author_id = @user.person_id
Post.joins("LEFT OUTER JOIN participations ON participations.target_id = posts.id AND " \
"participations.target_type = 'Post'")
.where(::Participation.arel_table[:author_id].eq(author_id).or(Post.arel_table[:author_id].eq(author_id)))
.order("posts.interacted_at DESC")
.distinct
end
end
class LikedPosts < Base
def initialize(user)
@user = user
end
def posts
Post.liked_by(@user.person)
end
end
class CommentedPosts < Base
def initialize(user)
@user = user
end
def posts
Post.commented_by(@user.person)
end
end
class MultiStream < Base
def initialize(user, order, max_time, include_spotlight)
@user = user
@class = Post
@order = order
@max_time = max_time
@include_spotlight = include_spotlight
end
def make_relation!
logger.debug("[EVIL-QUERY] make_relation!")
post_ids = aspects_post_ids! + ids!(followed_tags_posts!) + ids!(mentioned_posts)
post_ids += ids!(community_spotlight_posts!) if @include_spotlight
Post.where(:id => post_ids)
end
def aspects_post_ids!
logger.debug("[EVIL-QUERY] aspect_post_ids!")
@user.visible_shareable_ids(Post, limit: 15, order: "#{@order} DESC", max_time: @max_time, all_aspects?: true)
end
def followed_tags_posts!
logger.debug("[EVIL-QUERY] followed_tags_posts!")
StatusMessage.public_tag_stream(@user.followed_tag_ids).excluding_hidden_content(@user)
end
def mentioned_posts
logger.debug("[EVIL-QUERY] mentioned_posts")
StatusMessage.where_person_is_mentioned(@user.person)
end
def community_spotlight_posts!
Post.all_public.where(:author_id => fetch_ids!(Person.community_spotlight, 'people.id'))
end
def ids!(query)
fetch_ids!(query.for_a_stream(@max_time, @order), 'posts.id')
end
end
class VisibleShareableById < Base
def initialize(user, klass, key, id, conditions={})
@querent = user
@class = klass
@key = key
@id = id
@conditions = conditions
end
def post!
#small optimization - is this optimal order??
querent_has_visibility.first || querent_is_author.first || public_post.first
end
protected
def querent_has_visibility
@class.where(@key => @id).joins(:share_visibilities)
.where(share_visibilities: {user_id: @querent.id})
.where(@conditions)
.select(@class.table_name + ".*")
end
def querent_is_author
@class.where(@key => @id, :author_id => @querent.person.id).where(@conditions)
end
def public_post
@class.where(@key => @id, :public => true).where(@conditions)
end
end
end
|