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
|
# File 'lib/quote_sql/deprecated.rb', line 22
def quote_sql(**options)
loop do
break unless gsub!(%r{(?<=^|\W)[:$](#{options.keys.join("|")})(?=\W|$)}) do |m|
key = m[1..].to_sym
next m unless options.key? key
sub = options[key]
case sub
when Arel::Nodes::SqlLiteral
next sub
when NilClass
next "NULL"
when TrueClass, FalseClass
next sub.to_s.upcase
when Time
sub = sub.strftime("%Y-%m-%d %H:%M:%S.%3N%z")
end
if sub.respond_to? :to_sql
next sub.to_sql
end
case m
when /^:(.+)_(FROM_CLAUSE)$/
name = conn.quote_column_name($1)
casts = sub.shift.transform_keys(&:to_s)
rv = quote_sql_values(sub, casts)
column_names = casts.map { conn.quote_column_name(_2.key?(:as) ? _2[:as] : _1) }
next "(VALUES \n(#{rv.join("),\n(")})\n ) #{name} (#{column_names.join(",") })"
when /^:(.+)_(as_select)$/i
name = conn.quote_column_name($1)
casts = sub.shift.transform_keys(&:to_s)
rv = quote_sql_values(sub, casts)
next "SELECT * FROM (VALUES \n(#{rv.join("),\n(")})\n ) #{name} (#{casts.keys.map { conn.quote_column_name(_1) }.join(",") })"
when /^:(.+)_(as_values)$/i
name = conn.quote_column_name($1)
casts = sub.shift.transform_keys(&:to_s)
rv = quote_sql_values(sub, casts)
next "#{name} (#{casts.keys.map { conn.quote_column_name(_1) }.join(",") }) AS ( VALUES \n(#{rv.join("),\n(")})\n )"
when /^:(.+)_(values)$/i
casts = sub.shift.transform_keys(&:to_sym)
rv = quote_sql_values(sub, casts)
next "VALUES \n(#{rv.join("),\n(")})\n"
when /_(LIST)$/i
next sub.map { conn.quote _1 }.join(",")
when /_(args)$/i
next sub.join(',')
when /_(raw|sql)$/i
next sub
when /_(ident|column)$/i, /table_name$/, /_?columns?$/, /column_names$/
if sub.is_a? Array
next sub.map do
_1[/^"[^"]+"\."[^"]+"$/] ? _1 : conn.quote_column_name(_1)
end.join(',')
else
next conn.quote_column_name(sub)
end
when /(?<=_)jsonb?$/i
next conn.quote(sub.to_json) + "::#{$MATCH}"
when /(?<=_)(uuid|int|text)$/i
cast = "::#{$MATCH}"
end
case sub
when Regexp
sub.to_postgres
when Array
dims = 1
dive = ->(ary) do
ary.map { |s| conn.quote s }.join(',')
end
sub = "[#{dive.call sub}]"
cast += "[]" * dims if cast.present?
"ARRAY#{sub}#{cast}"
else
"#{conn.quote(sub)}#{cast}"
end
end
end
Arel.sql self
end
|