mirror of
https://github.com/wahyd4/gitlabhq.git
synced 2026-08-10 13:16:09 +10:00
This class can be used to join multiple AcitveRecord::Relation objects together using a SQL UNION statement. ActiveRecord < 5.0 sadly doesn't support UNION and existing Gems out there don't handle prepared statements (e.g. they never incremented the variable bindings).
35 lines
1.0 KiB
Ruby
35 lines
1.0 KiB
Ruby
module Gitlab
|
|
module SQL
|
|
# Class for building SQL UNION statements.
|
|
#
|
|
# ORDER BYs are dropped from the relations as the final sort order is not
|
|
# guaranteed any way.
|
|
#
|
|
# Example usage:
|
|
#
|
|
# union = Gitlab::SQL::Union.new(user.personal_projects, user.projects)
|
|
# sql = union.to_sql
|
|
#
|
|
# Project.where("id IN (#{sql})")
|
|
class Union
|
|
def initialize(relations)
|
|
@relations = relations
|
|
end
|
|
|
|
def to_sql
|
|
# Some relations may include placeholders for prepared statements, these
|
|
# aren't incremented properly when joining relations together this way.
|
|
# By using "unprepared_statements" we remove the usage of placeholders
|
|
# (thus fixing this problem), at a slight performance cost.
|
|
fragments = ActiveRecord::Base.connection.unprepared_statement do
|
|
@relations.map do |rel|
|
|
"(#{rel.reorder(nil).to_sql})"
|
|
end
|
|
end
|
|
|
|
fragments.join(' UNION ')
|
|
end
|
|
end
|
|
end
|
|
end
|