Unbinder is used to take a dataset filter and return a modified version that unbinds already bound values and returns a dataset with bound value placeholders and a hash of bind values. You can then prepare the dataset and use the bound variables to execute it with the same values.
This class only does a limited form of unbinding where the variable names and values can be associated unambiguously. The only cases it handles are SQL::ComplexExpression with an operator in UNBIND_OPS, a first argument that’s an instance of a member of UNBIND_KEY_CLASSES, and a second argument that’s an instance of a member of UNBIND_VALUE_CLASSES.
So it can handle cases like:
DB.filter(:a=>1).exclude(:b=>2).where{c > 3}
But it cannot handle cases like:
DB.filter(:a + 1 < 0)
The SQL::ComplexExpression operates that will be considered for transformation.
The key classes (first argument of the ComplexExpression) that will considered for transformation.
The value classes (second argument of the ComplexExpression) that will be considered for transformation.
Create a suitable bound variable key for the object, which should be an instance of one of the UNBIND_KEY_CLASSES.
# File lib/sequel/ast_transformer.rb, line 158 158: def bind_key(obj) 159: case obj 160: when Symbol, String 161: obj 162: when SQL::Identifier 163: bind_key(obj.value) 164: when SQL::QualifiedIdentifier 165: :"#{bind_key(obj.table)}.#{bind_key(obj.column)}" 166: else 167: raise Error, "unhandled object in Sequel::Unbinder#bind_key: #{obj}" 168: end 169: end
Handle SQL::ComplexExpression instances with suitable ops and arguments, substituting the value with a bound variable placeholder and assigning it an entry in the binds hash with a matching key.
# File lib/sequel/ast_transformer.rb, line 174 174: def v(o) 175: if o.is_a?(SQL::ComplexExpression) && UNBIND_OPS.include?(o.op) 176: l, r = o.args 177: l = l.value if l.is_a?(Sequel::SQL::Wrapper) 178: r = r.value if r.is_a?(Sequel::SQL::Wrapper) 179: if UNBIND_KEY_CLASSES.any?{|c| l.is_a?(c)} && UNBIND_VALUE_CLASSES.any?{|c| r.is_a?(c)} && !r.is_a?(LiteralString) 180: key = bind_key(l) 181: if (old = binds[key]) && old != r 182: raise UnbindDuplicate, "two different values for #{key.inspect}: #{[r, old].inspect}" 183: end 184: binds[key] = r 185: SQL::ComplexExpression.new(o.op, l, :"$#{key}") 186: else 187: super 188: end 189: else 190: super 191: end 192: end
Disabled; run with --debug to generate this.
Generated with the Darkfish Rdoc Generator 1.1.6.