sequel 4.21.0 → 4.22.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (104) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +32 -0
  3. data/README.rdoc +3 -4
  4. data/doc/opening_databases.rdoc +10 -75
  5. data/doc/release_notes/4.22.0.txt +72 -0
  6. data/lib/sequel/adapters/ado/access.rb +1 -1
  7. data/lib/sequel/adapters/cubrid.rb +3 -3
  8. data/lib/sequel/adapters/db2.rb +1 -0
  9. data/lib/sequel/adapters/dbi.rb +1 -0
  10. data/lib/sequel/adapters/fdbsql.rb +3 -2
  11. data/lib/sequel/adapters/firebird.rb +1 -0
  12. data/lib/sequel/adapters/ibmdb.rb +1 -21
  13. data/lib/sequel/adapters/informix.rb +1 -0
  14. data/lib/sequel/adapters/jdbc.rb +37 -49
  15. data/lib/sequel/adapters/jdbc/fdbsql.rb +1 -0
  16. data/lib/sequel/adapters/mysql.rb +5 -3
  17. data/lib/sequel/adapters/mysql2.rb +5 -2
  18. data/lib/sequel/adapters/odbc.rb +8 -4
  19. data/lib/sequel/adapters/openbase.rb +1 -0
  20. data/lib/sequel/adapters/oracle.rb +3 -46
  21. data/lib/sequel/adapters/postgres.rb +3 -36
  22. data/lib/sequel/adapters/shared/access.rb +1 -1
  23. data/lib/sequel/adapters/shared/fdbsql.rb +3 -3
  24. data/lib/sequel/adapters/shared/mssql.rb +1 -1
  25. data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +12 -44
  26. data/lib/sequel/adapters/shared/oracle.rb +6 -2
  27. data/lib/sequel/adapters/shared/postgres.rb +6 -6
  28. data/lib/sequel/adapters/shared/sqlite.rb +1 -1
  29. data/lib/sequel/adapters/sqlite.rb +3 -46
  30. data/lib/sequel/adapters/tinytds.rb +12 -28
  31. data/lib/sequel/adapters/utils/pg_types.rb +1 -1
  32. data/lib/sequel/connection_pool/sharded_threaded.rb +63 -16
  33. data/lib/sequel/connection_pool/threaded.rb +72 -18
  34. data/lib/sequel/core.rb +1 -1
  35. data/lib/sequel/database/connecting.rb +2 -2
  36. data/lib/sequel/database/misc.rb +5 -5
  37. data/lib/sequel/database/query.rb +3 -2
  38. data/lib/sequel/database/schema_generator.rb +19 -19
  39. data/lib/sequel/database/schema_methods.rb +2 -2
  40. data/lib/sequel/database/transactions.rb +3 -3
  41. data/lib/sequel/dataset/actions.rb +18 -8
  42. data/lib/sequel/dataset/graph.rb +2 -2
  43. data/lib/sequel/dataset/prepared_statements.rb +28 -1
  44. data/lib/sequel/dataset/query.rb +7 -7
  45. data/lib/sequel/exceptions.rb +27 -24
  46. data/lib/sequel/extensions/_pretty_table.rb +1 -1
  47. data/lib/sequel/extensions/constraint_validations.rb +2 -2
  48. data/lib/sequel/extensions/date_arithmetic.rb +2 -2
  49. data/lib/sequel/extensions/pg_array.rb +10 -1
  50. data/lib/sequel/extensions/pg_row.rb +1 -1
  51. data/lib/sequel/extensions/pg_static_cache_updater.rb +1 -1
  52. data/lib/sequel/extensions/schema_dumper.rb +8 -8
  53. data/lib/sequel/extensions/split_array_nil.rb +1 -1
  54. data/lib/sequel/model.rb +1 -1
  55. data/lib/sequel/model/associations.rb +18 -11
  56. data/lib/sequel/model/base.rb +15 -15
  57. data/lib/sequel/model/exceptions.rb +11 -2
  58. data/lib/sequel/plugins/accessed_columns.rb +1 -1
  59. data/lib/sequel/plugins/auto_validations.rb +1 -1
  60. data/lib/sequel/plugins/boolean_readers.rb +1 -1
  61. data/lib/sequel/plugins/class_table_inheritance.rb +4 -7
  62. data/lib/sequel/plugins/composition.rb +1 -1
  63. data/lib/sequel/plugins/constraint_validations.rb +2 -2
  64. data/lib/sequel/plugins/csv_serializer.rb +171 -0
  65. data/lib/sequel/plugins/dirty.rb +2 -2
  66. data/lib/sequel/plugins/hook_class_methods.rb +1 -1
  67. data/lib/sequel/plugins/instance_hooks.rb +1 -1
  68. data/lib/sequel/plugins/many_through_many.rb +1 -1
  69. data/lib/sequel/plugins/nested_attributes.rb +5 -5
  70. data/lib/sequel/plugins/pg_array_associations.rb +4 -4
  71. data/lib/sequel/plugins/prepared_statements.rb +2 -2
  72. data/lib/sequel/plugins/prepared_statements_safe.rb +1 -1
  73. data/lib/sequel/plugins/serialization.rb +6 -6
  74. data/lib/sequel/plugins/serialization_modification_detection.rb +1 -1
  75. data/lib/sequel/plugins/sharding.rb +3 -1
  76. data/lib/sequel/plugins/single_table_inheritance.rb +5 -13
  77. data/lib/sequel/plugins/static_cache.rb +2 -2
  78. data/lib/sequel/plugins/tactical_eager_loading.rb +1 -1
  79. data/lib/sequel/plugins/tree.rb +1 -1
  80. data/lib/sequel/plugins/validation_class_methods.rb +2 -2
  81. data/lib/sequel/plugins/validation_helpers.rb +4 -4
  82. data/lib/sequel/plugins/xml_serializer.rb +3 -3
  83. data/lib/sequel/sql.rb +1 -1
  84. data/lib/sequel/version.rb +1 -1
  85. data/spec/adapters/postgres_spec.rb +17 -0
  86. data/spec/core/connection_pool_spec.rb +1 -1
  87. data/spec/core/dataset_spec.rb +22 -0
  88. data/spec/extensions/auto_validations_spec.rb +1 -1
  89. data/spec/extensions/blacklist_security_spec.rb +2 -2
  90. data/spec/extensions/csv_serializer_spec.rb +173 -0
  91. data/spec/extensions/json_serializer_spec.rb +2 -2
  92. data/spec/extensions/nested_attributes_spec.rb +9 -9
  93. data/spec/extensions/pg_array_spec.rb +5 -0
  94. data/spec/extensions/single_table_inheritance_spec.rb +21 -0
  95. data/spec/extensions/touch_spec.rb +1 -1
  96. data/spec/extensions/tree_spec.rb +4 -0
  97. data/spec/extensions/xml_serializer_spec.rb +3 -3
  98. data/spec/integration/prepared_statement_test.rb +1 -1
  99. data/spec/integration/schema_test.rb +7 -0
  100. data/spec/integration/type_test.rb +2 -2
  101. data/spec/model/associations_spec.rb +108 -14
  102. data/spec/model/base_spec.rb +8 -8
  103. data/spec/model/record_spec.rb +7 -7
  104. metadata +6 -2
@@ -1,5 +1,6 @@
1
1
  Sequel::JDBC.load_driver('com.foundationdb.sql.jdbc.Driver')
2
2
  Sequel.require 'adapters/shared/fdbsql'
3
+ Sequel::Deprecation.deprecate 'The jdbc/fdbsql adapter is deprecated and will be removed in a future version of Sequel.'
3
4
 
4
5
  module Sequel
5
6
  Fdbsql::CONVERTED_EXCEPTIONS << NativeException
@@ -303,7 +303,7 @@ module Sequel
303
303
  type_proc = f.type == 1 && cast_tinyint_integer?(f) ? cps[2] : cps[f.type]
304
304
  [output_identifier(f.name), type_proc, i+=1]
305
305
  end
306
- @columns = cols.map{|c| c.first}
306
+ @columns = cols.map(&:first)
307
307
  if opts[:split_multiple_result_sets]
308
308
  s = []
309
309
  yield_rows(r, cols){|h| s << h}
@@ -347,8 +347,10 @@ module Sequel
347
347
  end
348
348
 
349
349
  # Set the :type option to :select if it hasn't been set.
350
- def execute(sql, opts=OPTS, &block)
351
- super(sql, {:type=>:select}.merge(opts), &block)
350
+ def execute(sql, opts=OPTS)
351
+ opts = Hash[opts]
352
+ opts[:type] = :select
353
+ super
352
354
  end
353
355
 
354
356
  # Handle correct quoting of strings using ::MySQL.quote.
@@ -188,8 +188,11 @@ module Sequel
188
188
  end
189
189
 
190
190
  # Set the :type option to :select if it hasn't been set.
191
- def execute(sql, opts=OPTS, &block)
192
- super(sql, {:type=>:select, :stream=>@opts[:stream]}.merge(opts), &block)
191
+ def execute(sql, opts=OPTS)
192
+ opts = Hash[opts]
193
+ opts[:type] = :select
194
+ opts[:stream] = @opts[:stream]
195
+ super
193
196
  end
194
197
 
195
198
  # Handle correct quoting of strings using ::Mysql2::Client#escape.
@@ -94,13 +94,13 @@ module Sequel
94
94
  def fetch_rows(sql)
95
95
  execute(sql) do |s|
96
96
  i = -1
97
- cols = s.columns(true).map{|c| [output_identifier(c.name), i+=1]}
97
+ cols = s.columns(true).map{|c| [output_identifier(c.name), c.type, i+=1]}
98
98
  columns = cols.map{|c| c.at(0)}
99
99
  @columns = columns
100
100
  if rows = s.fetch_all
101
101
  rows.each do |row|
102
102
  hash = {}
103
- cols.each{|n,j| hash[n] = convert_odbc_value(row[j])}
103
+ cols.each{|n,t,j| hash[n] = convert_odbc_value(row[j], t)}
104
104
  yield hash
105
105
  end
106
106
  end
@@ -110,7 +110,7 @@ module Sequel
110
110
 
111
111
  private
112
112
 
113
- def convert_odbc_value(v)
113
+ def convert_odbc_value(v, t)
114
114
  # When fetching a result set, the Ruby ODBC driver converts all ODBC
115
115
  # SQL types to an equivalent Ruby type; with the exception of
116
116
  # SQL_TYPE_DATE, SQL_TYPE_TIME and SQL_TYPE_TIMESTAMP.
@@ -125,7 +125,11 @@ module Sequel
125
125
  when ::ODBC::Date
126
126
  Date.new(v.year, v.month, v.day)
127
127
  else
128
- v
128
+ if t == ::ODBC::SQL_BIT
129
+ v == 1
130
+ else
131
+ v
132
+ end
129
133
  end
130
134
  end
131
135
 
@@ -1,4 +1,5 @@
1
1
  require 'openbase'
2
+ Sequel::Deprecation.deprecate 'The openbase adapter is deprecated and will be removed in a future version of Sequel.'
2
3
 
3
4
  module Sequel
4
5
  module OpenBase
@@ -15,7 +15,7 @@ module Sequel
15
15
 
16
16
  ORACLE_TYPES = {
17
17
  :blob=>lambda{|b| Sequel::SQL::Blob.new(b.read)},
18
- :clob=>lambda{|b| b.read}
18
+ :clob=>lambda(&:read)
19
19
  }
20
20
 
21
21
  # Hash of conversion procs for this database.
@@ -348,52 +348,9 @@ module Sequel
348
348
  end
349
349
  end
350
350
 
351
- # Oracle prepared statement uses a new prepared statement each time
352
- # it is called, but it does use the bind arguments.
353
- module BindArgumentMethods
354
- include ArgumentMapper
351
+ BindArgumentMethods = prepared_statements_module(:bind, ArgumentMapper)
352
+ PreparedStatementMethods = prepared_statements_module(:prepare, BindArgumentMethods)
355
353
 
356
- private
357
-
358
- # Run execute_select on the database with the given SQL and the stored
359
- # bind arguments.
360
- def execute(sql, opts=OPTS, &block)
361
- super(prepared_sql, {:arguments=>bind_arguments}.merge(opts), &block)
362
- end
363
-
364
- # Same as execute, explicit due to intricacies of alias and super.
365
- def execute_dui(sql, opts=OPTS, &block)
366
- super(prepared_sql, {:arguments=>bind_arguments}.merge(opts), &block)
367
- end
368
-
369
- # Same as execute, explicit due to intricacies of alias and super.
370
- def execute_insert(sql, opts=OPTS, &block)
371
- super(prepared_sql, {:arguments=>bind_arguments}.merge(opts), &block)
372
- end
373
- end
374
-
375
- module PreparedStatementMethods
376
- include BindArgumentMethods
377
-
378
- private
379
-
380
- # Execute the stored prepared statement name and the stored bind
381
- # arguments instead of the SQL given.
382
- def execute(sql, opts=OPTS, &block)
383
- super(prepared_statement_name, opts, &block)
384
- end
385
-
386
- # Same as execute, explicit due to intricacies of alias and super.
387
- def execute_dui(sql, opts=OPTS, &block)
388
- super(prepared_statement_name, opts, &block)
389
- end
390
-
391
- # Same as execute, explicit due to intricacies of alias and super.
392
- def execute_insert(sql, opts=OPTS, &block)
393
- super(prepared_statement_name, opts, &block)
394
- end
395
- end
396
-
397
354
  # Execute the given type of statement with the hash of values.
398
355
  def call(type, bind_vars={}, *values, &block)
399
356
  ps = to_prepared_statement(type, values)
@@ -681,7 +681,7 @@ module Sequel
681
681
  # This is untested with the prepared statement/bound variable support,
682
682
  # and unlikely to work with either.
683
683
  def use_cursor(opts=OPTS)
684
- clone(:cursor=>{:rows_per_fetch=>1000}.merge(opts))
684
+ clone(:cursor=>{:rows_per_fetch=>1000}.merge!(opts))
685
685
  end
686
686
 
687
687
  # Replace the WHERE clause with one that uses CURRENT OF with the given
@@ -732,47 +732,14 @@ module Sequel
732
732
  end
733
733
  end
734
734
 
735
- # Allow use of bind arguments for PostgreSQL using the pg driver.
736
- module BindArgumentMethods
737
- include ArgumentMapper
738
- include ::Sequel::Postgres::DatasetMethods::PreparedStatementMethods
739
-
740
- private
741
-
742
- # Execute the given SQL with the stored bind arguments.
743
- def execute(sql, opts=OPTS, &block)
744
- super(sql, {:arguments=>bind_arguments}.merge(opts), &block)
745
- end
746
-
747
- # Same as execute, explicit due to intricacies of alias and super.
748
- def execute_dui(sql, opts=OPTS, &block)
749
- super(sql, {:arguments=>bind_arguments}.merge(opts), &block)
750
- end
751
- end
752
-
753
- # Allow use of server side prepared statements for PostgreSQL using the
754
- # pg driver.
755
- module PreparedStatementMethods
756
- include BindArgumentMethods
735
+ BindArgumentMethods = prepared_statements_module(:bind, [ArgumentMapper, ::Sequel::Postgres::DatasetMethods::PreparedStatementMethods], %w'execute execute_dui')
757
736
 
737
+ PreparedStatementMethods = prepared_statements_module(:prepare, BindArgumentMethods, %w'execute execute_dui') do
758
738
  # Raise a more obvious error if you attempt to call a unnamed prepared statement.
759
739
  def call(*)
760
740
  raise Error, "Cannot call prepared statement without a name" if prepared_statement_name.nil?
761
741
  super
762
742
  end
763
-
764
- private
765
-
766
- # Execute the stored prepared statement name and the stored bind
767
- # arguments instead of the SQL given.
768
- def execute(sql, opts=OPTS, &block)
769
- super(prepared_statement_name, opts, &block)
770
- end
771
-
772
- # Same as execute, explicit due to intricacies of alias and super.
773
- def execute_dui(sql, opts=OPTS, &block)
774
- super(prepared_statement_name, opts, &block)
775
- end
776
743
  end
777
744
 
778
745
  # Execute the given type of statement with the hash of values.
@@ -12,7 +12,7 @@ module Sequel
12
12
 
13
13
  # Doesn't work, due to security restrictions on MSysObjects
14
14
  #def tables
15
- # from(:MSysObjects).filter(:Type=>1, :Flags=>0).select_map(:Name).map{|x| x.to_sym}
15
+ # from(:MSysObjects).filter(:Type=>1, :Flags=>0).select_map(:Name).map(&:to_sym)
16
16
  #end
17
17
 
18
18
  # Access doesn't support renaming tables from an SQL query,
@@ -265,9 +265,9 @@ module Sequel
265
265
  end
266
266
 
267
267
  STALE_STATEMENT_SQLSTATE = '0A50A'.freeze
268
- NOT_NULL_CONSTRAINT_SQLSTATES = %w'23502'.freeze.each{|s| s.freeze}
269
- FOREIGN_KEY_CONSTRAINT_SQLSTATES = %w'23503 23504'.freeze.each{|s| s.freeze}
270
- UNIQUE_CONSTRAINT_SQLSTATES = %w'23501'.freeze.each{|s| s.freeze}
268
+ NOT_NULL_CONSTRAINT_SQLSTATES = %w'23502'.freeze.each(&:freeze)
269
+ FOREIGN_KEY_CONSTRAINT_SQLSTATES = %w'23503 23504'.freeze.each(&:freeze)
270
+ UNIQUE_CONSTRAINT_SQLSTATES = %w'23501'.freeze.each(&:freeze)
271
271
 
272
272
  # Given the SQLState, return the appropriate DatabaseError subclass.
273
273
  def database_specific_error_class_from_sqlstate(sqlstate)
@@ -466,7 +466,7 @@ module Sequel
466
466
  else
467
467
  schema_column_type(row[:db_type])
468
468
  end
469
- row[:max_length] = row[:max_chars] if row[:type] == :string
469
+ row[:max_length] = row[:max_chars] if row[:type] == :string && row[:max_chars] >= 0
470
470
  [m.call(row.delete(:column)), row]
471
471
  end
472
472
  end
@@ -6,7 +6,7 @@ module Sequel
6
6
  # prepared statements and stored procedures.
7
7
  module PreparedStatements
8
8
  module DatabaseMethods
9
- disconnect_errors = <<-END.split("\n").map{|l| l.strip}
9
+ disconnect_errors = <<-END.split("\n").map(&:strip)
10
10
  Commands out of sync; you can't run this command now
11
11
  Can't connect to local MySQL server through socket
12
12
  MySQL server has gone away
@@ -100,51 +100,19 @@ module Sequel
100
100
  end
101
101
  end
102
102
 
103
- # Methods for MySQL prepared statements using the native driver.
104
- module PreparedStatementMethods
105
- include Sequel::Dataset::UnnumberedArgumentMapper
106
-
107
- # Raise a more obvious error if you attempt to call a unnamed prepared statement.
108
- def call(*)
109
- raise Error, "Cannot call prepared statement without a name" if prepared_statement_name.nil?
110
- super
111
- end
112
-
113
- private
114
-
115
- # Execute the prepared statement with the bind arguments instead of
116
- # the given SQL.
117
- def execute(sql, opts=OPTS, &block)
118
- super(prepared_statement_name, {:arguments=>bind_arguments}.merge(opts), &block)
119
- end
120
-
121
- # Same as execute, explicit due to intricacies of alias and super.
122
- def execute_dui(sql, opts=OPTS, &block)
123
- super(prepared_statement_name, {:arguments=>bind_arguments}.merge(opts), &block)
124
- end
125
-
126
- # Same as execute, explicit due to intricacies of alias and super.
127
- def execute_insert(sql, opts=OPTS, &block)
128
- super(prepared_statement_name, {:arguments=>bind_arguments}.merge(opts), &block)
129
- end
103
+ PreparedStatementMethods = Sequel::Dataset.send(:prepared_statements_module,
104
+ :prepare_bind,
105
+ Sequel::Dataset::UnnumberedArgumentMapper) do
106
+ # Raise a more obvious error if you attempt to call a unnamed prepared statement.
107
+ def call(*)
108
+ raise Error, "Cannot call prepared statement without a name" if prepared_statement_name.nil?
109
+ super
110
+ end
130
111
  end
131
112
 
132
- # Methods for MySQL stored procedures using the native driver.
133
- module StoredProcedureMethods
134
- include Sequel::Dataset::StoredProcedureMethods
135
-
136
- private
137
-
138
- # Execute the database stored procedure with the stored arguments.
139
- def execute(sql, opts=OPTS, &block)
140
- super(@sproc_name, {:args=>@sproc_args, :sproc=>true}.merge(opts), &block)
141
- end
142
-
143
- # Same as execute, explicit due to intricacies of alias and super.
144
- def execute_dui(sql, opts=OPTS, &block)
145
- super(@sproc_name, {:args=>@sproc_args, :sproc=>true}.merge(opts), &block)
146
- end
147
- end
113
+ StoredProcedureMethods = Sequel::Dataset.send(:prepared_statements_module,
114
+ "sql = @sproc_name; opts = Hash[opts]; opts[:args] = @sproc_args; opts[:sproc] = true",
115
+ Sequel::Dataset::StoredProcedureMethods, %w'execute execute_dui')
148
116
 
149
117
  # MySQL is different in that it supports prepared statements but not bound
150
118
  # variables outside of prepared statements. The default implementation
@@ -474,8 +474,12 @@ module Sequel
474
474
  # If this dataset is associated with a sequence, return the most recently
475
475
  # inserted sequence value.
476
476
  def execute_insert(sql, opts=OPTS)
477
- f = @opts[:from]
478
- super(sql, {:table=>(f.first if f), :sequence=>@opts[:sequence]}.merge(opts))
477
+ opts = Hash[opts]
478
+ if f = @opts[:from]
479
+ opts[:table] = f.first
480
+ end
481
+ opts[:sequence] = @opts[:sequence]
482
+ super
479
483
  end
480
484
 
481
485
  # Use a colon for the timestamp offset, since Oracle appears to require it.
@@ -64,7 +64,7 @@ module Sequel
64
64
  # :where :: Create a partial exclusion constraint, which only affects
65
65
  # a subset of table rows, value should be a filter expression.
66
66
  def exclude(elements, opts=OPTS)
67
- constraints << {:type => :exclude, :elements => elements}.merge(opts)
67
+ constraints << {:type => :exclude, :elements => elements}.merge!(opts)
68
68
  end
69
69
  end
70
70
 
@@ -72,7 +72,7 @@ module Sequel
72
72
  # Adds an exclusion constraint to an existing table, see
73
73
  # CreateTableGenerator#exclude.
74
74
  def add_exclusion_constraint(elements, opts=OPTS)
75
- @operations << {:op => :add_constraint, :type => :exclude, :elements => elements}.merge(opts)
75
+ @operations << {:op => :add_constraint, :type => :exclude, :elements => elements}.merge!(opts)
76
76
  end
77
77
 
78
78
  # Validate the constraint with the given name, which should have
@@ -667,7 +667,7 @@ module Sequel
667
667
  if search_path = @opts[:search_path]
668
668
  case search_path
669
669
  when String
670
- search_path = search_path.split(",").map{|s| s.strip}
670
+ search_path = search_path.split(",").map(&:strip)
671
671
  when Array
672
672
  # nil
673
673
  else
@@ -706,7 +706,7 @@ module Sequel
706
706
  # Convert the hash of named conversion procs into a hash a oid conversion procs.
707
707
  def convert_named_procs_to_procs(named_procs)
708
708
  h = {}
709
- from(:pg_type).where(:typtype=>'b', :typname=>named_procs.keys.map{|t| t.to_s}).select_map([:oid, :typname]).each do |oid, name|
709
+ from(:pg_type).where(:typtype=>'b', :typname=>named_procs.keys.map(&:to_s)).select_map([:oid, :typname]).each do |oid, name|
710
710
  h[oid.to_i] = named_procs[name.untaint.to_sym]
711
711
  end
712
712
  h
@@ -1197,7 +1197,7 @@ module Sequel
1197
1197
  WINDOW = " WINDOW ".freeze
1198
1198
  SELECT_VALUES = "VALUES ".freeze
1199
1199
  EMPTY_STRING = ''.freeze
1200
- LOCK_MODES = ['ACCESS SHARE', 'ROW SHARE', 'ROW EXCLUSIVE', 'SHARE UPDATE EXCLUSIVE', 'SHARE', 'SHARE ROW EXCLUSIVE', 'EXCLUSIVE', 'ACCESS EXCLUSIVE'].each{|s| s.freeze}
1200
+ LOCK_MODES = ['ACCESS SHARE', 'ROW SHARE', 'ROW EXCLUSIVE', 'SHARE UPDATE EXCLUSIVE', 'SHARE', 'SHARE ROW EXCLUSIVE', 'EXCLUSIVE', 'ACCESS EXCLUSIVE'].each(&:freeze)
1201
1201
 
1202
1202
  Dataset.def_sql_method(self, :delete, [['if server_version >= 90100', %w'with delete from using where returning'], ['else', %w'delete from using where returning']])
1203
1203
  Dataset.def_sql_method(self, :insert, [['if server_version >= 90100', %w'with insert into columns values returning'], ['else', %w'insert into columns values returning']])
@@ -1468,7 +1468,7 @@ module Sequel
1468
1468
  def _import(columns, values, opts=OPTS)
1469
1469
  if @opts[:returning]
1470
1470
  statements = multi_insert_sql(columns, values)
1471
- @db.transaction(opts.merge(:server=>@opts[:server])) do
1471
+ @db.transaction(Hash[opts].merge!(:server=>@opts[:server])) do
1472
1472
  statements.map{|st| returning_fetch_rows(st)}
1473
1473
  end.first.map{|v| v.length == 1 ? v.values.first : v}
1474
1474
  elsif opts[:return] == :primary_key
@@ -416,7 +416,7 @@ module Sequel
416
416
  "DROP TABLE #{bt}"
417
417
  ]
418
418
  indexes(table).each do |name, h|
419
- if (h[:columns].map{|x| x.to_s} - new_columns).empty?
419
+ if (h[:columns].map(&:to_s) - new_columns).empty?
420
420
  a << alter_table_sql(table, h.merge(:op=>:add_index, :name=>name))
421
421
  end
422
422
  end
@@ -304,52 +304,9 @@ module Sequel
304
304
  end
305
305
  end
306
306
 
307
- # SQLite prepared statement uses a new prepared statement each time
308
- # it is called, but it does use the bind arguments.
309
- module BindArgumentMethods
310
- include ArgumentMapper
311
-
312
- private
313
-
314
- # Run execute_select on the database with the given SQL and the stored
315
- # bind arguments.
316
- def execute(sql, opts=OPTS, &block)
317
- super(sql, {:arguments=>bind_arguments}.merge(opts), &block)
318
- end
319
-
320
- # Same as execute, explicit due to intricacies of alias and super.
321
- def execute_dui(sql, opts=OPTS, &block)
322
- super(sql, {:arguments=>bind_arguments}.merge(opts), &block)
323
- end
324
-
325
- # Same as execute, explicit due to intricacies of alias and super.
326
- def execute_insert(sql, opts=OPTS, &block)
327
- super(sql, {:arguments=>bind_arguments}.merge(opts), &block)
328
- end
329
- end
307
+ BindArgumentMethods = prepared_statements_module(:bind, ArgumentMapper)
308
+ PreparedStatementMethods = prepared_statements_module(:prepare, BindArgumentMethods)
330
309
 
331
- module PreparedStatementMethods
332
- include BindArgumentMethods
333
-
334
- private
335
-
336
- # Execute the stored prepared statement name and the stored bind
337
- # arguments instead of the SQL given.
338
- def execute(sql, opts=OPTS, &block)
339
- super(prepared_statement_name, opts, &block)
340
- end
341
-
342
- # Same as execute, explicit due to intricacies of alias and super.
343
- def execute_dui(sql, opts=OPTS, &block)
344
- super(prepared_statement_name, opts, &block)
345
- end
346
-
347
- # Same as execute, explicit due to intricacies of alias and super.
348
- def execute_insert(sql, opts=OPTS, &block)
349
- super(prepared_statement_name, opts, &block)
350
- end
351
- end
352
-
353
310
  # Execute the given type of statement with the hash of values.
354
311
  def call(type, bind_vars={}, *values, &block)
355
312
  ps = to_prepared_statement(type, values)
@@ -364,7 +321,7 @@ module Sequel
364
321
  cps = db.conversion_procs
365
322
  type_procs = result.types.map{|t| cps[base_type_name(t)]}
366
323
  cols = result.columns.map{|c| i+=1; [output_identifier(c), i, type_procs[i]]}
367
- @columns = cols.map{|c| c.first}
324
+ @columns = cols.map(&:first)
368
325
  result.each do |values|
369
326
  row = {}
370
327
  cols.each do |name,id,type_proc|