sequel 4.21.0 → 4.22.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +32 -0
- data/README.rdoc +3 -4
- data/doc/opening_databases.rdoc +10 -75
- data/doc/release_notes/4.22.0.txt +72 -0
- data/lib/sequel/adapters/ado/access.rb +1 -1
- data/lib/sequel/adapters/cubrid.rb +3 -3
- data/lib/sequel/adapters/db2.rb +1 -0
- data/lib/sequel/adapters/dbi.rb +1 -0
- data/lib/sequel/adapters/fdbsql.rb +3 -2
- data/lib/sequel/adapters/firebird.rb +1 -0
- data/lib/sequel/adapters/ibmdb.rb +1 -21
- data/lib/sequel/adapters/informix.rb +1 -0
- data/lib/sequel/adapters/jdbc.rb +37 -49
- data/lib/sequel/adapters/jdbc/fdbsql.rb +1 -0
- data/lib/sequel/adapters/mysql.rb +5 -3
- data/lib/sequel/adapters/mysql2.rb +5 -2
- data/lib/sequel/adapters/odbc.rb +8 -4
- data/lib/sequel/adapters/openbase.rb +1 -0
- data/lib/sequel/adapters/oracle.rb +3 -46
- data/lib/sequel/adapters/postgres.rb +3 -36
- data/lib/sequel/adapters/shared/access.rb +1 -1
- data/lib/sequel/adapters/shared/fdbsql.rb +3 -3
- data/lib/sequel/adapters/shared/mssql.rb +1 -1
- data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +12 -44
- data/lib/sequel/adapters/shared/oracle.rb +6 -2
- data/lib/sequel/adapters/shared/postgres.rb +6 -6
- data/lib/sequel/adapters/shared/sqlite.rb +1 -1
- data/lib/sequel/adapters/sqlite.rb +3 -46
- data/lib/sequel/adapters/tinytds.rb +12 -28
- data/lib/sequel/adapters/utils/pg_types.rb +1 -1
- data/lib/sequel/connection_pool/sharded_threaded.rb +63 -16
- data/lib/sequel/connection_pool/threaded.rb +72 -18
- data/lib/sequel/core.rb +1 -1
- data/lib/sequel/database/connecting.rb +2 -2
- data/lib/sequel/database/misc.rb +5 -5
- data/lib/sequel/database/query.rb +3 -2
- data/lib/sequel/database/schema_generator.rb +19 -19
- data/lib/sequel/database/schema_methods.rb +2 -2
- data/lib/sequel/database/transactions.rb +3 -3
- data/lib/sequel/dataset/actions.rb +18 -8
- data/lib/sequel/dataset/graph.rb +2 -2
- data/lib/sequel/dataset/prepared_statements.rb +28 -1
- data/lib/sequel/dataset/query.rb +7 -7
- data/lib/sequel/exceptions.rb +27 -24
- data/lib/sequel/extensions/_pretty_table.rb +1 -1
- data/lib/sequel/extensions/constraint_validations.rb +2 -2
- data/lib/sequel/extensions/date_arithmetic.rb +2 -2
- data/lib/sequel/extensions/pg_array.rb +10 -1
- data/lib/sequel/extensions/pg_row.rb +1 -1
- data/lib/sequel/extensions/pg_static_cache_updater.rb +1 -1
- data/lib/sequel/extensions/schema_dumper.rb +8 -8
- data/lib/sequel/extensions/split_array_nil.rb +1 -1
- data/lib/sequel/model.rb +1 -1
- data/lib/sequel/model/associations.rb +18 -11
- data/lib/sequel/model/base.rb +15 -15
- data/lib/sequel/model/exceptions.rb +11 -2
- data/lib/sequel/plugins/accessed_columns.rb +1 -1
- data/lib/sequel/plugins/auto_validations.rb +1 -1
- data/lib/sequel/plugins/boolean_readers.rb +1 -1
- data/lib/sequel/plugins/class_table_inheritance.rb +4 -7
- data/lib/sequel/plugins/composition.rb +1 -1
- data/lib/sequel/plugins/constraint_validations.rb +2 -2
- data/lib/sequel/plugins/csv_serializer.rb +171 -0
- data/lib/sequel/plugins/dirty.rb +2 -2
- data/lib/sequel/plugins/hook_class_methods.rb +1 -1
- data/lib/sequel/plugins/instance_hooks.rb +1 -1
- data/lib/sequel/plugins/many_through_many.rb +1 -1
- data/lib/sequel/plugins/nested_attributes.rb +5 -5
- data/lib/sequel/plugins/pg_array_associations.rb +4 -4
- data/lib/sequel/plugins/prepared_statements.rb +2 -2
- data/lib/sequel/plugins/prepared_statements_safe.rb +1 -1
- data/lib/sequel/plugins/serialization.rb +6 -6
- data/lib/sequel/plugins/serialization_modification_detection.rb +1 -1
- data/lib/sequel/plugins/sharding.rb +3 -1
- data/lib/sequel/plugins/single_table_inheritance.rb +5 -13
- data/lib/sequel/plugins/static_cache.rb +2 -2
- data/lib/sequel/plugins/tactical_eager_loading.rb +1 -1
- data/lib/sequel/plugins/tree.rb +1 -1
- data/lib/sequel/plugins/validation_class_methods.rb +2 -2
- data/lib/sequel/plugins/validation_helpers.rb +4 -4
- data/lib/sequel/plugins/xml_serializer.rb +3 -3
- data/lib/sequel/sql.rb +1 -1
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/postgres_spec.rb +17 -0
- data/spec/core/connection_pool_spec.rb +1 -1
- data/spec/core/dataset_spec.rb +22 -0
- data/spec/extensions/auto_validations_spec.rb +1 -1
- data/spec/extensions/blacklist_security_spec.rb +2 -2
- data/spec/extensions/csv_serializer_spec.rb +173 -0
- data/spec/extensions/json_serializer_spec.rb +2 -2
- data/spec/extensions/nested_attributes_spec.rb +9 -9
- data/spec/extensions/pg_array_spec.rb +5 -0
- data/spec/extensions/single_table_inheritance_spec.rb +21 -0
- data/spec/extensions/touch_spec.rb +1 -1
- data/spec/extensions/tree_spec.rb +4 -0
- data/spec/extensions/xml_serializer_spec.rb +3 -3
- data/spec/integration/prepared_statement_test.rb +1 -1
- data/spec/integration/schema_test.rb +7 -0
- data/spec/integration/type_test.rb +2 -2
- data/spec/model/associations_spec.rb +108 -14
- data/spec/model/base_spec.rb +8 -8
- data/spec/model/record_spec.rb +7 -7
- 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
|
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
|
351
|
-
|
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
|
192
|
-
|
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.
|
data/lib/sequel/adapters/odbc.rb
CHANGED
@@ -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
|
-
|
128
|
+
if t == ::ODBC::SQL_BIT
|
129
|
+
v == 1
|
130
|
+
else
|
131
|
+
v
|
132
|
+
end
|
129
133
|
end
|
130
134
|
end
|
131
135
|
|
@@ -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
|
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
|
-
|
352
|
-
|
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
|
-
|
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
|
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
|
269
|
-
FOREIGN_KEY_CONSTRAINT_SQLSTATES = %w'23503 23504'.freeze.each
|
270
|
-
UNIQUE_CONSTRAINT_SQLSTATES = %w'23501'.freeze.each
|
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
|
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
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
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
|
-
|
133
|
-
|
134
|
-
|
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
|
-
|
478
|
-
|
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
|
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
|
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
|
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
|
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
|
-
|
308
|
-
|
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
|
324
|
+
@columns = cols.map(&:first)
|
368
325
|
result.each do |values|
|
369
326
|
row = {}
|
370
327
|
cols.each do |name,id,type_proc|
|