mirror of
https://github.com/discourse/discourse.git
synced 2026-09-05 04:40:41 -05:00
DEV: remove all calls to SqlBuilder use DB.build instead
This is part of the migration to mini_sql, SqlBuilder.new is being deprecated and replaced with DB.build
This commit is contained in:
+47
-43
@@ -64,13 +64,13 @@ class CategoryUser < ActiveRecord::Base
|
||||
|
||||
def self.auto_track(opts = {})
|
||||
|
||||
builder = SqlBuilder.new <<SQL
|
||||
UPDATE topic_users tu
|
||||
SET notification_level = :tracking,
|
||||
notifications_reason_id = :auto_track_category
|
||||
FROM topics t, category_users cu
|
||||
/*where*/
|
||||
SQL
|
||||
builder = DB.build <<~SQL
|
||||
UPDATE topic_users tu
|
||||
SET notification_level = :tracking,
|
||||
notifications_reason_id = :auto_track_category
|
||||
FROM topics t, category_users cu
|
||||
/*where*/
|
||||
SQL
|
||||
|
||||
builder.where("tu.topic_id = t.id AND
|
||||
cu.category_id = t.category_id AND
|
||||
@@ -90,45 +90,47 @@ SQL
|
||||
builder.where("tu.user_id = :user_id", user_id: user_id)
|
||||
end
|
||||
|
||||
builder.exec(tracking: notification_levels[:tracking],
|
||||
regular: notification_levels[:regular],
|
||||
auto_track_category: TopicUser.notification_reasons[:auto_track_category])
|
||||
builder.exec(
|
||||
tracking: notification_levels[:tracking],
|
||||
regular: notification_levels[:regular],
|
||||
auto_track_category: TopicUser.notification_reasons[:auto_track_category]
|
||||
)
|
||||
end
|
||||
|
||||
def self.auto_watch(opts = {})
|
||||
|
||||
builder = SqlBuilder.new <<SQL
|
||||
UPDATE topic_users tu
|
||||
SET notification_level =
|
||||
CASE WHEN should_track THEN :tracking
|
||||
WHEN should_watch THEN :watching
|
||||
ELSE notification_level
|
||||
END,
|
||||
notifications_reason_id =
|
||||
CASE WHEN should_track THEN null
|
||||
WHEN should_watch THEN :auto_watch_category
|
||||
ELSE notifications_reason_id
|
||||
END
|
||||
FROM (
|
||||
SELECT tu1.topic_id,
|
||||
tu1.user_id,
|
||||
CASE WHEN
|
||||
cu.user_id IS NULL AND tu1.notification_level = :watching AND tu1.notifications_reason_id = :auto_watch_category THEN true
|
||||
builder = DB.build <<~SQL
|
||||
UPDATE topic_users tu
|
||||
SET notification_level =
|
||||
CASE WHEN should_track THEN :tracking
|
||||
WHEN should_watch THEN :watching
|
||||
ELSE notification_level
|
||||
END,
|
||||
notifications_reason_id =
|
||||
CASE WHEN should_track THEN null
|
||||
WHEN should_watch THEN :auto_watch_category
|
||||
ELSE notifications_reason_id
|
||||
END
|
||||
FROM (
|
||||
SELECT tu1.topic_id,
|
||||
tu1.user_id,
|
||||
CASE WHEN
|
||||
cu.user_id IS NULL AND tu1.notification_level = :watching AND tu1.notifications_reason_id = :auto_watch_category THEN true
|
||||
ELSE false
|
||||
END should_track,
|
||||
CASE WHEN
|
||||
cu.user_id IS NOT NULL AND tu1.notification_level in (:regular, :tracking) THEN true
|
||||
ELSE false
|
||||
END should_track,
|
||||
CASE WHEN
|
||||
cu.user_id IS NOT NULL AND tu1.notification_level in (:regular, :tracking) THEN true
|
||||
ELSE false
|
||||
END should_watch
|
||||
END should_watch
|
||||
|
||||
FROM topic_users tu1
|
||||
JOIN topics t ON t.id = tu1.topic_id
|
||||
LEFT JOIN category_users cu ON cu.category_id = t.category_id AND cu.user_id = tu1.user_id AND cu.notification_level = :watching
|
||||
/*where2*/
|
||||
) as X
|
||||
FROM topic_users tu1
|
||||
JOIN topics t ON t.id = tu1.topic_id
|
||||
LEFT JOIN category_users cu ON cu.category_id = t.category_id AND cu.user_id = tu1.user_id AND cu.notification_level = :watching
|
||||
/*where2*/
|
||||
) as X
|
||||
|
||||
/*where*/
|
||||
SQL
|
||||
/*where*/
|
||||
SQL
|
||||
|
||||
builder.where("X.topic_id = tu.topic_id AND X.user_id = tu.user_id")
|
||||
builder.where("should_watch OR should_track")
|
||||
@@ -147,10 +149,12 @@ SQL
|
||||
builder.where2("tu1.user_id = :user_id", user_id: user_id)
|
||||
end
|
||||
|
||||
builder.exec(watching: notification_levels[:watching],
|
||||
tracking: notification_levels[:tracking],
|
||||
regular: notification_levels[:regular],
|
||||
auto_watch_category: TopicUser.notification_reasons[:auto_watch_category])
|
||||
builder.exec(
|
||||
watching: notification_levels[:watching],
|
||||
tracking: notification_levels[:tracking],
|
||||
regular: notification_levels[:regular],
|
||||
auto_watch_category: TopicUser.notification_reasons[:auto_watch_category]
|
||||
)
|
||||
|
||||
end
|
||||
|
||||
|
||||
+4
-4
@@ -567,7 +567,7 @@ class Post < ActiveRecord::Base
|
||||
# each post.
|
||||
def self.calculate_avg_time(min_topic_age = nil)
|
||||
retry_lock_error do
|
||||
builder = SqlBuilder.new("UPDATE posts
|
||||
builder = DB.build("UPDATE posts
|
||||
SET avg_time = (x.gmean / 1000)
|
||||
FROM (SELECT post_timings.topic_id,
|
||||
post_timings.post_number,
|
||||
@@ -692,7 +692,7 @@ class Post < ActiveRecord::Base
|
||||
MAX_REPLY_LEVEL ||= 1000
|
||||
|
||||
def reply_ids(guardian = nil, only_replies_to_single_post: true)
|
||||
builder = SqlBuilder.new(<<~SQL, Post)
|
||||
builder = DB.build(<<~SQL)
|
||||
WITH RECURSIVE breadcrumb(id, level) AS (
|
||||
SELECT :post_id, 0
|
||||
UNION
|
||||
@@ -723,8 +723,8 @@ class Post < ActiveRecord::Base
|
||||
# for example it skips a post when it contains 2 quotes (which are replies) from different posts
|
||||
builder.where("count = 1") if only_replies_to_single_post
|
||||
|
||||
replies = builder.exec(post_id: id, max_reply_level: MAX_REPLY_LEVEL).to_a
|
||||
replies.map! { |r| { id: r["id"].to_i, level: r["level"].to_i } }
|
||||
replies = builder.query_hash(post_id: id, max_reply_level: MAX_REPLY_LEVEL)
|
||||
replies.each { |r| r.symbolize_keys! }
|
||||
|
||||
secured_ids = Post.secured(guardian).where(id: replies.map { |r| r[:id] }).pluck(:id).to_set
|
||||
|
||||
|
||||
+12
-11
@@ -101,18 +101,19 @@ class PostAction < ActiveRecord::Base
|
||||
#
|
||||
topic_ids = topics.map(&:id)
|
||||
map = {}
|
||||
builder = SqlBuilder.new <<SQL
|
||||
SELECT p.topic_id, p.post_number
|
||||
FROM post_actions pa
|
||||
JOIN posts p ON pa.post_id = p.id
|
||||
WHERE p.deleted_at IS NULL AND pa.deleted_at IS NULL AND
|
||||
pa.post_action_type_id = :post_action_type_id AND
|
||||
pa.user_id = :user_id AND
|
||||
p.topic_id IN (:topic_ids)
|
||||
ORDER BY p.topic_id, p.post_number
|
||||
SQL
|
||||
|
||||
builder.map_exec(OpenStruct, user_id: user.id, post_action_type_id: post_action_type_id, topic_ids: topic_ids).each do |row|
|
||||
builder = DB.build <<~SQL
|
||||
SELECT p.topic_id, p.post_number
|
||||
FROM post_actions pa
|
||||
JOIN posts p ON pa.post_id = p.id
|
||||
WHERE p.deleted_at IS NULL AND pa.deleted_at IS NULL AND
|
||||
pa.post_action_type_id = :post_action_type_id AND
|
||||
pa.user_id = :user_id AND
|
||||
p.topic_id IN (:topic_ids)
|
||||
ORDER BY p.topic_id, p.post_number
|
||||
SQL
|
||||
|
||||
builder.query(user_id: user.id, post_action_type_id: post_action_type_id, topic_ids: topic_ids).each do |row|
|
||||
(map[row.topic_id] ||= []) << row.post_number
|
||||
end
|
||||
|
||||
|
||||
+47
-48
@@ -66,40 +66,39 @@ class TagUser < ActiveRecord::Base
|
||||
end
|
||||
|
||||
def self.auto_watch(opts)
|
||||
builder = SqlBuilder.new <<SQL
|
||||
builder = DB.build <<~SQL
|
||||
UPDATE topic_users
|
||||
SET notification_level = CASE WHEN should_watch THEN :watching ELSE :tracking END,
|
||||
notifications_reason_id = CASE WHEN should_watch THEN :auto_watch_tag ELSE NULL END
|
||||
FROM
|
||||
(
|
||||
SELECT tu.topic_id, tu.user_id, CASE
|
||||
WHEN MAX(tag_users.notification_level) = :watching THEN true
|
||||
ELSE false
|
||||
END
|
||||
should_watch,
|
||||
|
||||
UPDATE topic_users
|
||||
SET notification_level = CASE WHEN should_watch THEN :watching ELSE :tracking END,
|
||||
notifications_reason_id = CASE WHEN should_watch THEN :auto_watch_tag ELSE NULL END
|
||||
FROM
|
||||
(
|
||||
SELECT tu.topic_id, tu.user_id, CASE
|
||||
WHEN MAX(tag_users.notification_level) = :watching THEN true
|
||||
ELSE false
|
||||
END
|
||||
should_watch,
|
||||
CASE WHEN MAX(tag_users.notification_level) IS NULL AND
|
||||
tu.notification_level = :watching AND
|
||||
tu.notifications_reason_id = :auto_watch_tag
|
||||
THEN true
|
||||
ELSE false
|
||||
END
|
||||
should_track
|
||||
|
||||
CASE WHEN MAX(tag_users.notification_level) IS NULL AND
|
||||
tu.notification_level = :watching AND
|
||||
tu.notifications_reason_id = :auto_watch_tag
|
||||
THEN true
|
||||
ELSE false
|
||||
END
|
||||
should_track
|
||||
FROM topic_users tu
|
||||
LEFT JOIN topic_tags ON tu.topic_id = topic_tags.topic_id
|
||||
LEFT JOIN tag_users ON tag_users.user_id = tu.user_id
|
||||
AND topic_tags.tag_id = tag_users.tag_id
|
||||
AND tag_users.notification_level = :watching
|
||||
/*where*/
|
||||
GROUP BY tu.topic_id, tu.user_id, tu.notification_level, tu.notifications_reason_id
|
||||
) AS X
|
||||
WHERE X.topic_id = topic_users.topic_id AND
|
||||
X.user_id = topic_users.user_id AND
|
||||
(should_track OR should_watch)
|
||||
|
||||
FROM topic_users tu
|
||||
LEFT JOIN topic_tags ON tu.topic_id = topic_tags.topic_id
|
||||
LEFT JOIN tag_users ON tag_users.user_id = tu.user_id
|
||||
AND topic_tags.tag_id = tag_users.tag_id
|
||||
AND tag_users.notification_level = :watching
|
||||
/*where*/
|
||||
GROUP BY tu.topic_id, tu.user_id, tu.notification_level, tu.notifications_reason_id
|
||||
) AS X
|
||||
WHERE X.topic_id = topic_users.topic_id AND
|
||||
X.user_id = topic_users.user_id AND
|
||||
(should_track OR should_watch)
|
||||
|
||||
SQL
|
||||
SQL
|
||||
|
||||
builder.where("tu.notification_level in (:tracking, :regular, :watching)")
|
||||
|
||||
@@ -120,23 +119,23 @@ SQL
|
||||
|
||||
def self.auto_track(opts)
|
||||
|
||||
builder = SqlBuilder.new <<SQL
|
||||
UPDATE topic_users
|
||||
SET notification_level = :tracking, notifications_reason_id = :auto_track_tag
|
||||
FROM (
|
||||
SELECT DISTINCT tu.topic_id, tu.user_id
|
||||
FROM topic_users tu
|
||||
JOIN topic_tags ON tu.topic_id = topic_tags.topic_id
|
||||
JOIN tag_users ON tag_users.user_id = tu.user_id
|
||||
AND topic_tags.tag_id = tag_users.tag_id
|
||||
AND tag_users.notification_level = :tracking
|
||||
/*where*/
|
||||
) as X
|
||||
WHERE
|
||||
topic_users.notification_level = :regular AND
|
||||
topic_users.topic_id = X.topic_id AND
|
||||
topic_users.user_id = X.user_id
|
||||
SQL
|
||||
builder = DB.build <<~SQL
|
||||
UPDATE topic_users
|
||||
SET notification_level = :tracking, notifications_reason_id = :auto_track_tag
|
||||
FROM (
|
||||
SELECT DISTINCT tu.topic_id, tu.user_id
|
||||
FROM topic_users tu
|
||||
JOIN topic_tags ON tu.topic_id = topic_tags.topic_id
|
||||
JOIN tag_users ON tag_users.user_id = tu.user_id
|
||||
AND topic_tags.tag_id = tag_users.tag_id
|
||||
AND tag_users.notification_level = :tracking
|
||||
/*where*/
|
||||
) as X
|
||||
WHERE
|
||||
topic_users.notification_level = :regular AND
|
||||
topic_users.topic_id = X.topic_id AND
|
||||
topic_users.user_id = X.user_id
|
||||
SQL
|
||||
|
||||
if topic_id = opts[:topic_id]
|
||||
builder.where("tu.topic_id = :topic_id", topic_id: topic_id)
|
||||
|
||||
+6
-6
@@ -1241,7 +1241,7 @@ class Topic < ActiveRecord::Base
|
||||
|
||||
def self.time_to_first_response(sql, opts = nil)
|
||||
opts ||= {}
|
||||
builder = SqlBuilder.new(sql)
|
||||
builder = DB.build(sql)
|
||||
builder.where("t.created_at >= :start_date", start_date: opts[:start_date]) if opts[:start_date]
|
||||
builder.where("t.created_at < :end_date", end_date: opts[:end_date]) if opts[:end_date]
|
||||
builder.where("t.category_id = :category_id", category_id: opts[:category_id]) if opts[:category_id]
|
||||
@@ -1253,7 +1253,7 @@ class Topic < ActiveRecord::Base
|
||||
builder.where("p.user_id in (:user_ids)", user_ids: opts[:user_ids]) if opts[:user_ids]
|
||||
builder.where("p.post_type = :post_type", post_type: Post.types[:regular])
|
||||
builder.where("EXTRACT(EPOCH FROM p.created_at - t.created_at) > 0")
|
||||
builder.exec
|
||||
builder.query_hash
|
||||
end
|
||||
|
||||
def self.time_to_first_response_per_day(start_date, end_date, opts = {})
|
||||
@@ -1280,13 +1280,13 @@ class Topic < ActiveRecord::Base
|
||||
SQL
|
||||
|
||||
def self.with_no_response_per_day(start_date, end_date, category_id = nil)
|
||||
builder = SqlBuilder.new(WITH_NO_RESPONSE_SQL)
|
||||
builder = DB.build(WITH_NO_RESPONSE_SQL)
|
||||
builder.where("t.created_at >= :start_date", start_date: start_date) if start_date
|
||||
builder.where("t.created_at < :end_date", end_date: end_date) if end_date
|
||||
builder.where("t.category_id = :category_id", category_id: category_id) if category_id
|
||||
builder.where("t.archetype <> '#{Archetype.private_message}'")
|
||||
builder.where("t.deleted_at IS NULL")
|
||||
builder.exec
|
||||
builder.query_hash
|
||||
end
|
||||
|
||||
WITH_NO_RESPONSE_TOTAL_SQL ||= <<-SQL
|
||||
@@ -1302,11 +1302,11 @@ class Topic < ActiveRecord::Base
|
||||
SQL
|
||||
|
||||
def self.with_no_response_total(opts = {})
|
||||
builder = SqlBuilder.new(WITH_NO_RESPONSE_TOTAL_SQL)
|
||||
builder = DB.build(WITH_NO_RESPONSE_TOTAL_SQL)
|
||||
builder.where("t.category_id = :category_id", category_id: opts[:category_id]) if opts[:category_id]
|
||||
builder.where("t.archetype <> '#{Archetype.private_message}'")
|
||||
builder.where("t.deleted_at IS NULL")
|
||||
builder.exec.first["count"].to_i
|
||||
builder.query_single.first.to_i
|
||||
end
|
||||
|
||||
def convert_to_public_topic(user)
|
||||
|
||||
@@ -174,8 +174,12 @@ class TopicTrackingState
|
||||
sql << "\nUNION ALL\n\n"
|
||||
sql << report_raw_sql(topic_id: topic_id, skip_new: true, skip_order: true, staff: user.staff?)
|
||||
|
||||
SqlBuilder.new(sql)
|
||||
.map_exec(TopicTrackingState, user_id: user.id, topic_id: topic_id, min_new_topic_date: Time.at(SiteSetting.min_new_topics_time).to_datetime)
|
||||
DB.query(
|
||||
sql,
|
||||
user_id: user.id,
|
||||
topic_id: topic_id,
|
||||
min_new_topic_date: Time.at(SiteSetting.min_new_topics_time).to_datetime
|
||||
)
|
||||
end
|
||||
|
||||
def self.report_raw_sql(opts = nil)
|
||||
|
||||
+46
-47
@@ -370,28 +370,28 @@ class TopicUser < ActiveRecord::Base
|
||||
return
|
||||
end
|
||||
|
||||
builder = SqlBuilder.new <<SQL
|
||||
UPDATE topic_users tu
|
||||
SET #{action_type_name} = x.state
|
||||
FROM (
|
||||
SELECT CASE WHEN EXISTS (
|
||||
SELECT 1
|
||||
FROM post_actions pa
|
||||
JOIN posts p on p.id = pa.post_id
|
||||
JOIN topics t ON t.id = p.topic_id
|
||||
WHERE pa.deleted_at IS NULL AND
|
||||
p.deleted_at IS NULL AND
|
||||
t.deleted_at IS NULL AND
|
||||
pa.post_action_type_id = :action_type_id AND
|
||||
tu2.topic_id = t.id AND
|
||||
tu2.user_id = pa.user_id
|
||||
LIMIT 1
|
||||
) THEN true ELSE false END state, tu2.topic_id, tu2.user_id
|
||||
FROM topic_users tu2
|
||||
/*where*/
|
||||
) x
|
||||
WHERE x.topic_id = tu.topic_id AND x.user_id = tu.user_id AND x.state != tu.#{action_type_name}
|
||||
SQL
|
||||
builder = DB.build <<~SQL
|
||||
UPDATE topic_users tu
|
||||
SET #{action_type_name} = x.state
|
||||
FROM (
|
||||
SELECT CASE WHEN EXISTS (
|
||||
SELECT 1
|
||||
FROM post_actions pa
|
||||
JOIN posts p on p.id = pa.post_id
|
||||
JOIN topics t ON t.id = p.topic_id
|
||||
WHERE pa.deleted_at IS NULL AND
|
||||
p.deleted_at IS NULL AND
|
||||
t.deleted_at IS NULL AND
|
||||
pa.post_action_type_id = :action_type_id AND
|
||||
tu2.topic_id = t.id AND
|
||||
tu2.user_id = pa.user_id
|
||||
LIMIT 1
|
||||
) THEN true ELSE false END state, tu2.topic_id, tu2.user_id
|
||||
FROM topic_users tu2
|
||||
/*where*/
|
||||
) x
|
||||
WHERE x.topic_id = tu.topic_id AND x.user_id = tu.user_id AND x.state != tu.#{action_type_name}
|
||||
SQL
|
||||
|
||||
if user_id
|
||||
builder.where("tu2.user_id = :user_id", user_id: user_id)
|
||||
@@ -440,32 +440,31 @@ SQL
|
||||
# we up these numbers so they are not in-sync
|
||||
# the simple fix is to add a column here, but table is already quite big
|
||||
# long term we want to split up topic_users and allow for this better
|
||||
builder = SqlBuilder.new <<SQL
|
||||
builder = DB.build <<~SQL
|
||||
UPDATE topic_users t
|
||||
SET
|
||||
last_read_post_number = LEAST(GREATEST(last_read, last_read_post_number), max_post_number),
|
||||
highest_seen_post_number = LEAST(max_post_number,GREATEST(t.highest_seen_post_number, last_read))
|
||||
FROM (
|
||||
SELECT topic_id, user_id, MAX(post_number) last_read
|
||||
FROM post_timings
|
||||
GROUP BY topic_id, user_id
|
||||
) as X
|
||||
JOIN (
|
||||
SELECT p.topic_id, MAX(p.post_number) max_post_number from posts p
|
||||
GROUP BY p.topic_id
|
||||
) as Y on Y.topic_id = X.topic_id
|
||||
/*where*/
|
||||
SQL
|
||||
|
||||
UPDATE topic_users t
|
||||
SET
|
||||
last_read_post_number = LEAST(GREATEST(last_read, last_read_post_number), max_post_number),
|
||||
highest_seen_post_number = LEAST(max_post_number,GREATEST(t.highest_seen_post_number, last_read))
|
||||
FROM (
|
||||
SELECT topic_id, user_id, MAX(post_number) last_read
|
||||
FROM post_timings
|
||||
GROUP BY topic_id, user_id
|
||||
) as X
|
||||
JOIN (
|
||||
SELECT p.topic_id, MAX(p.post_number) max_post_number from posts p
|
||||
GROUP BY p.topic_id
|
||||
) as Y on Y.topic_id = X.topic_id
|
||||
/*where*/
|
||||
SQL
|
||||
|
||||
builder.where <<SQL
|
||||
X.topic_id = t.topic_id AND
|
||||
X.user_id = t.user_id AND
|
||||
(
|
||||
last_read_post_number <> LEAST(GREATEST(last_read, last_read_post_number), max_post_number) OR
|
||||
highest_seen_post_number <> LEAST(max_post_number,GREATEST(t.highest_seen_post_number, last_read))
|
||||
)
|
||||
SQL
|
||||
builder.where <<~SQL
|
||||
X.topic_id = t.topic_id AND
|
||||
X.user_id = t.user_id AND
|
||||
(
|
||||
last_read_post_number <> LEAST(GREATEST(last_read, last_read_post_number), max_post_number) OR
|
||||
highest_seen_post_number <> LEAST(max_post_number,GREATEST(t.highest_seen_post_number, last_read))
|
||||
)
|
||||
SQL
|
||||
|
||||
if topic_id
|
||||
builder.where("t.topic_id = :topic_id", topic_id: topic_id)
|
||||
|
||||
@@ -28,7 +28,7 @@ class TopicViewItem < ActiveRecord::Base
|
||||
/*where*/
|
||||
)"
|
||||
|
||||
builder = SqlBuilder.new(sql)
|
||||
builder = DB.build(sql)
|
||||
|
||||
if !user_id
|
||||
builder.where("ip_address = :ip_address AND topic_id = :topic_id AND user_id IS NULL")
|
||||
@@ -41,7 +41,7 @@ class TopicViewItem < ActiveRecord::Base
|
||||
|
||||
Topic.where(id: topic_id).update_all 'views = views + 1'
|
||||
|
||||
if result.cmd_tuples > 0
|
||||
if result > 0
|
||||
UserStat.where(user_id: user_id).update_all 'topics_entered = topics_entered + 1' if user_id
|
||||
end
|
||||
|
||||
|
||||
+66
-44
@@ -39,16 +39,6 @@ class UserAction < ActiveRecord::Base
|
||||
ASSIGNED,
|
||||
].each_with_index.to_a.flatten]
|
||||
|
||||
# note, this is temporary until we upgrade to rails 4
|
||||
# in rails 4 types are mapped correctly so you dont end up
|
||||
# having strings where you would expect bools
|
||||
class UserActionRow < OpenStruct
|
||||
include ActiveModel::SerializerSupport
|
||||
|
||||
def as_json(options = nil)
|
||||
@table.as_json(options)
|
||||
end
|
||||
end
|
||||
|
||||
def self.last_action_in_topic(user_id, topic_id)
|
||||
UserAction.where(user_id: user_id,
|
||||
@@ -59,25 +49,24 @@ class UserAction < ActiveRecord::Base
|
||||
def self.stats(user_id, guardian)
|
||||
|
||||
# Sam: I tried this in AR and it got complex
|
||||
builder = UserAction.sql_builder <<SQL
|
||||
builder = DB.build <<~SQL
|
||||
|
||||
SELECT action_type, COUNT(*) count
|
||||
FROM user_actions a
|
||||
LEFT JOIN topics t ON t.id = a.target_topic_id
|
||||
LEFT JOIN posts p on p.id = a.target_post_id
|
||||
LEFT JOIN posts p2 on p2.topic_id = a.target_topic_id and p2.post_number = 1
|
||||
LEFT JOIN categories c ON c.id = t.category_id
|
||||
/*where*/
|
||||
GROUP BY action_type
|
||||
SQL
|
||||
SELECT action_type, COUNT(*) count
|
||||
FROM user_actions a
|
||||
LEFT JOIN topics t ON t.id = a.target_topic_id
|
||||
LEFT JOIN posts p on p.id = a.target_post_id
|
||||
LEFT JOIN posts p2 on p2.topic_id = a.target_topic_id and p2.post_number = 1
|
||||
LEFT JOIN categories c ON c.id = t.category_id
|
||||
/*where*/
|
||||
GROUP BY action_type
|
||||
SQL
|
||||
|
||||
builder.where('a.user_id = :user_id', user_id: user_id)
|
||||
|
||||
apply_common_filters(builder, user_id, guardian)
|
||||
|
||||
results = builder.exec.to_a
|
||||
results = builder.query
|
||||
results.sort! { |a, b| ORDER[a.action_type] <=> ORDER[b.action_type] }
|
||||
|
||||
results
|
||||
end
|
||||
|
||||
@@ -139,19 +128,50 @@ SQL
|
||||
stream(action_id: action_id, guardian: guardian).first
|
||||
end
|
||||
|
||||
NULL_QUEUED_STREAM_COLS = %i{
|
||||
cooked
|
||||
uploaded_avatar_id
|
||||
acting_name
|
||||
acting_username
|
||||
acting_user_id
|
||||
target_name
|
||||
target_username
|
||||
target_user_id
|
||||
post_number
|
||||
post_id
|
||||
deleted
|
||||
hidden
|
||||
post_type
|
||||
action_type
|
||||
action_code
|
||||
action_code_who
|
||||
topic_closed
|
||||
topic_id
|
||||
topic_archived
|
||||
}.map! { |s| "NULL as #{s}" }.join(", ")
|
||||
|
||||
def self.stream_queued(opts = nil)
|
||||
opts ||= {}
|
||||
|
||||
offset = opts[:offset] || 0
|
||||
limit = opts[:limit] || 60
|
||||
|
||||
builder = SqlBuilder.new <<-SQL
|
||||
# this is somewhat ugly, but the serializer wants all these columns
|
||||
# it is more correct to have an object with all the fields needed
|
||||
# cause then we can catch and change if we ever add columns
|
||||
builder = DB.build <<~SQL
|
||||
SELECT
|
||||
a.id,
|
||||
t.title, a.action_type, a.created_at, t.id topic_id,
|
||||
u.username, u.name, u.id AS user_id,
|
||||
t.title,
|
||||
a.action_type,
|
||||
a.created_at,
|
||||
t.id topic_id,
|
||||
u.username,
|
||||
u.name,
|
||||
u.id AS user_id,
|
||||
qp.raw,
|
||||
t.category_id
|
||||
t.category_id,
|
||||
#{NULL_QUEUED_STREAM_COLS}
|
||||
FROM user_actions as a
|
||||
JOIN queued_posts AS qp ON qp.id = a.queued_post_id
|
||||
LEFT OUTER JOIN topics t on t.id = qp.topic_id
|
||||
@@ -169,7 +189,7 @@ SQL
|
||||
.order_by("a.created_at desc")
|
||||
.offset(offset.to_i)
|
||||
.limit(limit.to_i)
|
||||
.map_exec(UserActionRow)
|
||||
.query
|
||||
end
|
||||
|
||||
def self.stream(opts = nil)
|
||||
@@ -197,7 +217,7 @@ SQL
|
||||
|
||||
# The weird thing is that target_post_id can be null, so it makes everything
|
||||
# ever so more complex. Should we allow this, not sure.
|
||||
builder = SqlBuilder.new <<-SQL
|
||||
builder = DB.build <<~SQL
|
||||
SELECT
|
||||
a.id,
|
||||
t.title, a.action_type, a.created_at, t.id topic_id,
|
||||
@@ -249,7 +269,7 @@ SQL
|
||||
.limit(limit.to_i)
|
||||
end
|
||||
|
||||
builder.map_exec(UserActionRow)
|
||||
builder.query
|
||||
end
|
||||
|
||||
def self.log_action!(hash)
|
||||
@@ -321,19 +341,19 @@ SQL
|
||||
def self.synchronize_target_topic_ids(post_ids = nil)
|
||||
|
||||
# nuke all dupes, using magic
|
||||
builder = SqlBuilder.new <<SQL
|
||||
DELETE FROM user_actions USING user_actions ua2
|
||||
/*where*/
|
||||
SQL
|
||||
builder = DB.build <<~SQL
|
||||
DELETE FROM user_actions USING user_actions ua2
|
||||
/*where*/
|
||||
SQL
|
||||
|
||||
builder.where <<SQL
|
||||
user_actions.action_type = ua2.action_type AND
|
||||
user_actions.user_id = ua2.user_id AND
|
||||
user_actions.acting_user_id = ua2.acting_user_id AND
|
||||
user_actions.target_post_id = ua2.target_post_id AND
|
||||
user_actions.target_post_id > 0 AND
|
||||
user_actions.id > ua2.id
|
||||
SQL
|
||||
builder.where <<~SQL
|
||||
user_actions.action_type = ua2.action_type AND
|
||||
user_actions.user_id = ua2.user_id AND
|
||||
user_actions.acting_user_id = ua2.acting_user_id AND
|
||||
user_actions.target_post_id = ua2.target_post_id AND
|
||||
user_actions.target_post_id > 0 AND
|
||||
user_actions.id > ua2.id
|
||||
SQL
|
||||
|
||||
if post_ids
|
||||
builder.where("user_actions.target_post_id in (:post_ids)", post_ids: post_ids)
|
||||
@@ -341,9 +361,11 @@ SQL
|
||||
|
||||
builder.exec
|
||||
|
||||
builder = SqlBuilder.new("UPDATE user_actions
|
||||
SET target_topic_id = (select topic_id from posts where posts.id = target_post_id)
|
||||
/*where*/")
|
||||
builder = DB.build <<~SQL
|
||||
UPDATE user_actions
|
||||
SET target_topic_id = (select topic_id from posts where posts.id = target_post_id)
|
||||
/*where*/
|
||||
SQL
|
||||
|
||||
builder.where("target_topic_id <> (select topic_id from posts where posts.id = target_post_id)")
|
||||
if post_ids
|
||||
|
||||
@@ -25,7 +25,7 @@ class UserProfileView < ActiveRecord::Base
|
||||
/*where*/
|
||||
)"
|
||||
|
||||
builder = SqlBuilder.new(sql)
|
||||
builder = DB.build(sql)
|
||||
|
||||
if !user_id
|
||||
builder.where("viewed_at = :viewed_at AND ip_address = :ip_address AND user_profile_id = :user_profile_id AND user_id IS NULL")
|
||||
@@ -35,7 +35,7 @@ class UserProfileView < ActiveRecord::Base
|
||||
|
||||
result = builder.exec(user_profile_id: user_profile_id, ip_address: ip, viewed_at: at, user_id: user_id)
|
||||
|
||||
if result.cmd_tuples > 0
|
||||
if result > 0
|
||||
UserProfile.find(user_profile_id).increment!(:views)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -54,7 +54,7 @@ class UserSearch
|
||||
users = users.includes(:user_search_data)
|
||||
.references(:user_search_data)
|
||||
.where("user_search_data.search_data @@ #{query}")
|
||||
.order(User.sql_fragment("CASE WHEN username_lower LIKE ? THEN 0 ELSE 1 END ASC", @term_like))
|
||||
.order(DB.sql_fragment("CASE WHEN username_lower LIKE ? THEN 0 ELSE 1 END ASC", @term_like))
|
||||
|
||||
else
|
||||
users = users.where("username_lower LIKE :term_like", term_like: @term_like)
|
||||
|
||||
@@ -184,7 +184,7 @@ class BadgeGranter
|
||||
|
||||
# hack to allow for params, otherwise sanitizer will trigger sprintf
|
||||
count_sql = "SELECT COUNT(*) count FROM (#{sql}) q WHERE :backfill = :backfill"
|
||||
grant_count = SqlBuilder.map_exec(OpenStruct, count_sql, params).first.count.to_i
|
||||
grant_count = DB.query_single(count_sql, params).first.to_i
|
||||
|
||||
grants_sql =
|
||||
if opts[:target_posts]
|
||||
|
||||
@@ -386,7 +386,7 @@ class UserMerger
|
||||
conditions = Array.wrap(opts[:conditions])
|
||||
updates = Array.wrap(opts[:updates])
|
||||
|
||||
builder = SqlBuilder.new(<<~SQL)
|
||||
builder = DB.build(<<~SQL)
|
||||
UPDATE #{table_name} AS x
|
||||
/*set*/
|
||||
WHERE x.#{user_id_column_name} = :source_user_id AND NOT EXISTS(
|
||||
|
||||
Reference in New Issue
Block a user