File: set_literalizer.rb

package info (click to toggle)
ruby-sequel 5.97.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 11,188 kB
  • sloc: ruby: 123,115; makefile: 3
file content (58 lines) | stat: -rw-r--r-- 1,731 bytes parent folder | download
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