module Sequel::Dataset::PreparedStatementMethods
Backbone of the prepared statement support. Grafts bind variable support into datasets by hijacking literal and using placeholders. By default, emulates prepared statements and bind variables by taking the hash of bind variables and directly substituting them into the query, which works on all databases, as it is no different from using the dataset without bind variables.
Constants
- PLACEHOLDER_RE
Public Instance Methods
Sets the #prepared_args to the given hash and runs the prepared statement.
# File lib/sequel/dataset/prepared_statements.rb, line 126 def call(bind_vars={}, &block) bind(bind_vars).run(&block) end
Send the columns to the original dataset, as calling it on the prepared statement can cause problems.
# File lib/sequel/dataset/prepared_statements.rb, line 139 def columns orig_dataset.columns end
Programmer friendly string showing this is a prepared statement, with the prepared SQL it represents (which in general won't have substituted variables).
# File lib/sequel/dataset/prepared_statements.rb, line 184 def inspect "<#{visible_class_name}/PreparedStatement #{prepared_sql.inspect}>" end
Changes the values of symbols if they start with $ and #prepared_args is present. If so, they are considered placeholders, and they are substituted using prepared_arg.
# File lib/sequel/dataset/prepared_statements.rb, line 168 def literal_symbol_append(sql, v) if @opts[:bind_vars] and match = PLACEHOLDER_RE.match(v.to_s) s = match[1].to_sym if prepared_arg?(s) literal_append(sql, prepared_arg(s)) else sql << v.to_s end else super end end
Whether to log the full SQL query. By default, just the prepared statement name is generally logged on adapters that support native prepared statements.
# File lib/sequel/dataset/prepared_statements.rb, line 98 def log_sql @opts[:log_sql] end
The dataset that created this prepared statement.
# File lib/sequel/dataset/prepared_statements.rb, line 114 def orig_dataset @opts[:orig_dataset] end
Raise an error if attempting to call prepare on an already prepared statement.
# File lib/sequel/dataset/prepared_statements.rb, line 132 def prepare(*) raise Error, "cannot prepare an already prepared statement" unless allow_preparing_prepared_statements? super end
The array/hash of bound variable placeholder names.
# File lib/sequel/dataset/prepared_statements.rb, line 109 def prepared_args @opts[:prepared_args] end
The argument to supply to insert and update, which may use placeholders specified by #prepared_args
# File lib/sequel/dataset/prepared_statements.rb, line 120 def prepared_modify_values @opts[:prepared_modify_values] end
Returns the SQL for the prepared statement, depending on the type of the statement and the prepared_modify_values.
# File lib/sequel/dataset/prepared_statements.rb, line 145 def prepared_sql case prepared_type when :select, :all, :each # Most common scenario, so listed first. select_sql when :first clone(:limit=>1).select_sql when :insert_select insert_select_sql(*prepared_modify_values) when :insert, :insert_pk insert_sql(*prepared_modify_values) when :update update_sql(*prepared_modify_values) when :delete delete_sql else select_sql end end
The type of prepared statement, should be one of :select, :first, :insert, :update, or :delete
# File lib/sequel/dataset/prepared_statements.rb, line 104 def prepared_type @opts[:prepared_type] end
Protected Instance Methods
Run the method based on the type of prepared statement, with :select running all to get all of the rows, and the other types running the method with the same name as the type.
# File lib/sequel/dataset/prepared_statements.rb, line 193 def run(&block) case prepared_type when :select, :all # Most common scenario, so listed first all(&block) when :each each(&block) when :insert_select with_sql(prepared_sql).first when :first first when :insert, :update, :delete if opts[:returning] && supports_returning?(prepared_type) returning_fetch_rows(prepared_sql) elsif prepared_type == :delete delete else send(prepared_type, *prepared_modify_values) end when :insert_pk fetch_rows(prepared_sql){|r| return r.values.first} when Array case prepared_type.at(0) when :map, :to_hash, :to_hash_groups send(*prepared_type, &block) end else Sequel::Deprecation.deprecate("Using an unsupported prepared statement type (#{prepared_type.inspect})", 'Switch to using :select as the prepared statement type') all(&block) end end
Private Instance Methods
Returns the value of the #prepared_args hash for the given key.
# File lib/sequel/dataset/prepared_statements.rb, line 228 def prepared_arg(k) @opts[:bind_vars][k] end
Whether there is a bound value for the given key.
# File lib/sequel/dataset/prepared_statements.rb, line 233 def prepared_arg?(k) @opts[:bind_vars].has_key?(k) end
The symbol cache should always be skipped, since placeholders are symbols.
# File lib/sequel/dataset/prepared_statements.rb, line 239 def skip_symbol_cache? true end
Use a clone of the dataset extended with prepared statement support and using the same argument hash so that you can use bind variables/prepared arguments in subselects.
# File lib/sequel/dataset/prepared_statements.rb, line 246 def subselect_sql_append(sql, ds) ds.clone(:append_sql=>sql, :prepared_args=>prepared_args, :bind_vars=>@opts[:bind_vars]). send(:to_prepared_statement, :select, nil, :extend=>prepared_statement_modules). prepared_sql end