Please sign in to comment.
Support literal strings with placeholders and subselects in prepared …
…statements Before, the following two types of prepared statements did not work: DB[:items].filter("id = ?", :$i).call(:select, :i=>1) DB[:items].filter(:id=>DB[:items].select(:id).filter(:id=>:$i)).call(:select, :i=>1) The first issue is because a placeholder string was literalized immediately, before the dataset was extended with the prepared statement code. The second issue is because the arguments given in the main prepared statements weren't passed into any subselects. This commit fixes both of those issues. It also makes the name argument to Dataset#prepare optional. Fixing the first issue is done by adding an SQL::PlaceholderLiteralString class that holds the string with placeholders as well as the arguments, and not literalizing them until the SQL string is needed. Fixing the second issue was a lot more work, It is done by adding a Dataset#subselect_sql private method that literal calls, and overriding it in the PreparedStatement module that extends the dataset, which takes the subselect dataset, turns it into a prepared statement, and does the magic necessary pass the args in (if the default emulated support is used). It required changes to the argument mappers so they didn't rely on instance variables. Instead of using a hash, they now use an array that is shared with any subselects. The mapping code is simpler and the code in general is more generic. This does away with prepared_args_hash, as it is no longer necessary.
- Loading branch information...
Showing with 162 additions and 72 deletions.
- +2 −0 CHANGELOG
- +1 −7 lib/sequel_core/adapters/jdbc.rb
- +32 −3 lib/sequel_core/adapters/mysql.rb
- +15 −19 lib/sequel_core/adapters/postgres.rb
- +1 −9 lib/sequel_core/adapters/sqlite.rb
- +2 −3 lib/sequel_core/database.rb
- +28 −27 lib/sequel_core/dataset/prepared_statements.rb
- +16 −3 lib/sequel_core/dataset/sql.rb
- +29 −1 lib/sequel_core/sql.rb
- +16 −0 spec/integration/prepared_statement_test.rb
- +20 −0 spec/sequel_core/dataset_spec.rb
Oops, something went wrong.