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
|
# frozen-string-literal: true
#
# The set_literalizer extension allows for using Set instances in many of the
# same places that you would use Array instances:
#
# DB[:table].where(column: Set.new([1, 2, 3]))
# # SELECT FROM table WHERE (column IN (1, 2, 3))
#
# To load the extension into all datasets created from a given Database:
#
# DB.extension :set_literalizer
#
# Related module: Sequel::Dataset::SetLiteralizer
require 'set'
module Sequel
class Dataset
module SetLiteralizer
# Try to generate the same SQL for Set instances used in datasets
# that would be used for equivalent Array instances.
def complex_expression_sql_append(sql, op, args)
# Array instances are treated specially by
# Sequel::SQL::BooleanExpression.from_value_pairs. That cannot
# be modified by a dataset extension, so this tries to convert
# the complex expression values generated by default to what would
# be the complex expression values used for the equivalent array.
case op
when :'=', :'!='
if (set = args[1]).is_a?(Set)
op = op == :'=' ? :IN : :'NOT IN'
col = args[0]
array = set.to_a
if Sequel.condition_specifier?(array) && col.is_a?(Array)
array = Sequel.value_list(array)
end
args = [col, array]
end
end
super
end
private
# Literalize Set instances by converting the set to array.
def literal_other_append(sql, v)
if Set === v
literal_append(sql, v.to_a)
else
super
end
end
end
register_extension(:set_literalizer, SetLiteralizer)
end
end
|