/usr/lib/ruby/vendor_ruby/sequel/extensions/eval_inspect.rb is in ruby-sequel 4.1.1-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
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 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 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 | # The eval_inspect extension changes #inspect for Sequel::SQL::Expression
# subclasses to return a string suitable for ruby's eval, such that
#
# eval(obj.inspect) == obj
#
# is true. The above code is true for most of ruby's simple classes such
# as String, Integer, Float, and Symbol, but it's not true for classes such
# as Time, Date, and BigDecimal. Sequel attempts to handle situations where
# instances of these classes are a component of a Sequel expression.
#
# To load the extension:
#
# Sequel.extension :eval_inspect
module Sequel
module EvalInspect
# Special case objects where inspect does not generally produce input
# suitable for eval. Used by Sequel::SQL::Expression#inspect so that
# it can produce a string suitable for eval even if components of the
# expression have inspect methods that do not produce strings suitable
# for eval.
def eval_inspect(obj)
case obj
when Sequel::SQL::Blob, Sequel::LiteralString, Sequel::SQL::ValueList
"#{obj.class}.new(#{obj.inspect})"
when Array
"[#{obj.map{|o| eval_inspect(o)}.join(', ')}]"
when Hash
"{#{obj.map{|k, v| "#{eval_inspect(k)} => #{eval_inspect(v)}"}.join(', ')}}"
when Time
datepart = "%Y-%m-%dT" unless obj.is_a?(Sequel::SQLTime)
if RUBY_VERSION < '1.9'
# :nocov:
# Time on 1.8 doesn't handle %N (or %z on Windows), manually set the usec value in the string
hours, mins = obj.utc_offset.divmod(3600)
mins /= 60
"#{obj.class}.parse(#{obj.strftime("#{datepart}%H:%M:%S.#{sprintf('%06i%+03i%02i', obj.usec, hours, mins)}").inspect})#{'.utc' if obj.utc?}"
# :nocov:
else
"#{obj.class}.parse(#{obj.strftime("#{datepart}%T.%N%z").inspect})#{'.utc' if obj.utc?}"
end
when DateTime
# Ignore date of calendar reform
"DateTime.parse(#{obj.strftime('%FT%T.%N%z').inspect})"
when Date
# Ignore offset and date of calendar reform
"Date.new(#{obj.year}, #{obj.month}, #{obj.day})"
when BigDecimal
"BigDecimal.new(#{obj.to_s.inspect})"
else
obj.inspect
end
end
end
extend EvalInspect
module SQL
class Expression
# Attempt to produce a string suitable for eval, such that:
#
# eval(obj.inspect) == obj
def inspect
# Assume by default that the object can be recreated by calling
# self.class.new with any attr_reader values defined on the class,
# in the order they were defined.
klass = self.class
args = inspect_args.map do |arg|
if arg.is_a?(String) && arg =~ /\A\*/
# Special case string arguments starting with *, indicating that
# they should return an array to be splatted as the remaining arguments
send(arg.sub('*', '')).map{|a| Sequel.eval_inspect(a)}.join(', ')
else
Sequel.eval_inspect(send(arg))
end
end
"#{klass}.new(#{args.join(', ')})"
end
private
# Which attribute values to use in the inspect string.
def inspect_args
self.class.comparison_attrs
end
end
class ComplexExpression
private
# ComplexExpression's initializer uses a splat for the operator arguments.
def inspect_args
[:op, "*args"]
end
end
class Constant
# Constants to lookup in the Sequel module.
INSPECT_LOOKUPS = [:CURRENT_DATE, :CURRENT_TIMESTAMP, :CURRENT_TIME, :SQLTRUE, :SQLFALSE, :NULL, :NOTNULL]
# Reference the constant in the Sequel module if there is
# one that matches.
def inspect
INSPECT_LOOKUPS.each do |c|
return "Sequel::#{c}" if Sequel.const_get(c) == self
end
super
end
end
class CaseExpression
private
# CaseExpression's initializer checks whether an argument was
# provided, to differentiate CASE WHEN from CASE NULL WHEN, so
# check if an expression was provided, and only include the
# expression in the inspect output if so.
def inspect_args
if expression?
[:conditions, :default, :expression]
else
[:conditions, :default]
end
end
end
class Function
private
# Function's initializer uses a splat for the function arguments.
def inspect_args
[:f, "*args"]
end
end
class JoinOnClause
private
# JoinOnClause's initializer takes the on argument as the first argument
# instead of the last.
def inspect_args
[:on, :join_type, :table, :table_alias]
end
end
class JoinUsingClause
private
# JoinOnClause's initializer takes the using argument as the first argument
# instead of the last.
def inspect_args
[:using, :join_type, :table, :table_alias]
end
end
class OrderedExpression
private
# OrderedExpression's initializer takes the :nulls information inside a hash,
# so if a NULL order was given, include a hash with that information.
def inspect_args
if nulls
[:expression, :descending, :opts_hash]
else
[:expression, :descending]
end
end
# A hash of null information suitable for passing to the initializer.
def opts_hash
{:nulls=>nulls}
end
end
end
end
|