sequel 4.34.0 → 4.35.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG +30 -0
- data/Rakefile +14 -17
- data/doc/object_model.rdoc +4 -4
- data/doc/release_notes/4.35.0.txt +130 -0
- data/doc/schema_modification.rdoc +8 -3
- data/doc/security.rdoc +3 -3
- data/lib/sequel/adapters/ado.rb +2 -2
- data/lib/sequel/adapters/ado/access.rb +6 -6
- data/lib/sequel/adapters/ado/mssql.rb +2 -2
- data/lib/sequel/adapters/amalgalite.rb +6 -6
- data/lib/sequel/adapters/cubrid.rb +4 -4
- data/lib/sequel/adapters/do.rb +2 -2
- data/lib/sequel/adapters/do/mysql.rb +1 -1
- data/lib/sequel/adapters/do/postgres.rb +1 -1
- data/lib/sequel/adapters/do/sqlite3.rb +1 -1
- data/lib/sequel/adapters/ibmdb.rb +6 -6
- data/lib/sequel/adapters/jdbc.rb +15 -15
- data/lib/sequel/adapters/jdbc/db2.rb +1 -1
- data/lib/sequel/adapters/jdbc/derby.rb +3 -3
- data/lib/sequel/adapters/jdbc/h2.rb +3 -3
- data/lib/sequel/adapters/jdbc/hsqldb.rb +2 -2
- data/lib/sequel/adapters/jdbc/mssql.rb +1 -1
- data/lib/sequel/adapters/jdbc/mysql.rb +1 -1
- data/lib/sequel/adapters/jdbc/oracle.rb +1 -1
- data/lib/sequel/adapters/jdbc/postgresql.rb +2 -2
- data/lib/sequel/adapters/jdbc/sqlanywhere.rb +1 -1
- data/lib/sequel/adapters/jdbc/sqlite.rb +1 -1
- data/lib/sequel/adapters/jdbc/transactions.rb +10 -10
- data/lib/sequel/adapters/mock.rb +1 -1
- data/lib/sequel/adapters/mysql.rb +2 -2
- data/lib/sequel/adapters/mysql2.rb +2 -2
- data/lib/sequel/adapters/odbc.rb +2 -2
- data/lib/sequel/adapters/odbc/mssql.rb +2 -2
- data/lib/sequel/adapters/oracle.rb +9 -9
- data/lib/sequel/adapters/postgres.rb +3 -3
- data/lib/sequel/adapters/shared/mssql.rb +36 -8
- data/lib/sequel/adapters/shared/oracle.rb +15 -0
- data/lib/sequel/adapters/shared/postgres.rb +22 -1
- data/lib/sequel/adapters/sqlanywhere.rb +1 -1
- data/lib/sequel/adapters/sqlite.rb +7 -7
- data/lib/sequel/adapters/swift.rb +3 -3
- data/lib/sequel/adapters/swift/mysql.rb +1 -1
- data/lib/sequel/adapters/swift/postgres.rb +1 -1
- data/lib/sequel/adapters/swift/sqlite.rb +1 -1
- data/lib/sequel/adapters/tinytds.rb +5 -7
- data/lib/sequel/database/logging.rb +18 -3
- data/lib/sequel/database/misc.rb +19 -8
- data/lib/sequel/database/schema_generator.rb +7 -2
- data/lib/sequel/database/schema_methods.rb +9 -2
- data/lib/sequel/database/transactions.rb +52 -18
- data/lib/sequel/dataset/actions.rb +24 -19
- data/lib/sequel/dataset/features.rb +5 -0
- data/lib/sequel/dataset/query.rb +6 -0
- data/lib/sequel/extensions/_pretty_table.rb +1 -1
- data/lib/sequel/extensions/error_sql.rb +3 -3
- data/lib/sequel/extensions/pg_range.rb +10 -1
- data/lib/sequel/extensions/schema_dumper.rb +8 -5
- data/lib/sequel/extensions/server_logging.rb +61 -0
- data/lib/sequel/extensions/sql_comments.rb +91 -0
- data/lib/sequel/model/associations.rb +40 -8
- data/lib/sequel/model/base.rb +19 -5
- data/lib/sequel/plugins/class_table_inheritance.rb +12 -0
- data/lib/sequel/plugins/delay_add_association.rb +1 -0
- data/lib/sequel/plugins/json_serializer.rb +10 -2
- data/lib/sequel/version.rb +1 -1
- data/spec/adapter_spec.rb +4 -0
- data/spec/adapters/mysql_spec.rb +1 -1
- data/spec/adapters/postgres_spec.rb +3 -2
- data/spec/core/connection_pool_spec.rb +2 -0
- data/spec/core/database_spec.rb +49 -0
- data/spec/core/dataset_spec.rb +25 -1
- data/spec/core/mock_adapter_spec.rb +3 -1
- data/spec/core/schema_generator_spec.rb +1 -1
- data/spec/core_model_spec.rb +2 -0
- data/spec/core_spec.rb +1 -0
- data/spec/extensions/delay_add_association_spec.rb +22 -0
- data/spec/extensions/json_serializer_spec.rb +6 -0
- data/spec/extensions/pg_range_spec.rb +30 -2
- data/spec/extensions/schema_dumper_spec.rb +3 -2
- data/spec/extensions/server_logging_spec.rb +45 -0
- data/spec/extensions/sql_comments_spec.rb +27 -0
- data/spec/files/reversible_migrations/006_reversible.rb +10 -0
- data/spec/files/reversible_migrations/007_reversible.rb +10 -0
- data/spec/integration/dataset_test.rb +28 -2
- data/spec/integration/migrator_test.rb +23 -1
- data/spec/integration/schema_test.rb +12 -32
- data/spec/integration/transaction_test.rb +10 -0
- data/spec/integration/type_test.rb +1 -1
- data/spec/model/eager_loading_spec.rb +16 -0
- data/spec/model/record_spec.rb +9 -0
- data/spec/model_no_assoc_spec.rb +1 -0
- data/spec/model_spec.rb +1 -0
- data/spec/plugin_spec.rb +1 -0
- metadata +16 -2
data/lib/sequel/database/misc.rb
CHANGED
@@ -116,31 +116,35 @@ module Sequel
|
|
116
116
|
# :sql_log_level :: Method to use to log SQL to a logger, :info by default.
|
117
117
|
#
|
118
118
|
# All options given are also passed to the connection pool.
|
119
|
-
def initialize(opts = OPTS
|
119
|
+
def initialize(opts = OPTS)
|
120
120
|
@opts ||= opts
|
121
121
|
@opts = connection_pool_default_options.merge(@opts)
|
122
122
|
@loggers = Array(@opts[:logger]) + Array(@opts[:loggers])
|
123
|
-
self.log_warn_duration = @opts[:log_warn_duration]
|
124
|
-
block ||= proc{|server| connect(server)}
|
125
123
|
@opts[:servers] = {} if @opts[:servers].is_a?(String)
|
126
124
|
@sharded = !!@opts[:servers]
|
127
125
|
@opts[:adapter_class] = self.class
|
128
|
-
|
129
126
|
@opts[:single_threaded] = @single_threaded = typecast_value_boolean(@opts.fetch(:single_threaded, Database.single_threaded))
|
130
|
-
@schemas = {}
|
131
127
|
@default_string_column_size = @opts[:default_string_column_size] || DEFAULT_STRING_COLUMN_SIZE
|
128
|
+
|
129
|
+
@schemas = {}
|
132
130
|
@prepared_statements = {}
|
133
131
|
@transactions = {}
|
132
|
+
@symbol_literal_cache = {}
|
133
|
+
|
134
134
|
@identifier_input_method = nil
|
135
135
|
@identifier_output_method = nil
|
136
136
|
@quote_identifiers = nil
|
137
137
|
@timezone = nil
|
138
|
+
|
138
139
|
@dataset_class = dataset_class_default
|
139
140
|
@cache_schema = typecast_value_boolean(@opts.fetch(:cache_schema, true))
|
140
141
|
@dataset_modules = []
|
141
|
-
@symbol_literal_cache = {}
|
142
142
|
@schema_type_classes = SCHEMA_TYPE_CLASSES.dup
|
143
|
+
|
143
144
|
self.sql_log_level = @opts[:sql_log_level] ? @opts[:sql_log_level].to_sym : :info
|
145
|
+
self.log_warn_duration = @opts[:log_warn_duration]
|
146
|
+
self.log_connection_info = typecast_value_boolean(@opts[:log_connection_info])
|
147
|
+
|
144
148
|
@pool = ConnectionPool.get_pool(self, @opts)
|
145
149
|
|
146
150
|
reset_identifier_mangling
|
@@ -166,7 +170,7 @@ module Sequel
|
|
166
170
|
synchronize(opts[:server]) do |conn|
|
167
171
|
if h = _trans(conn)
|
168
172
|
raise Error, "cannot call after_commit in a prepared transaction" if h[:prepare]
|
169
|
-
(
|
173
|
+
add_transaction_hook(conn, :after_commit, block)
|
170
174
|
else
|
171
175
|
yield
|
172
176
|
end
|
@@ -183,7 +187,7 @@ module Sequel
|
|
183
187
|
synchronize(opts[:server]) do |conn|
|
184
188
|
if h = _trans(conn)
|
185
189
|
raise Error, "cannot call after_rollback in a prepared transaction" if h[:prepare]
|
186
|
-
(
|
190
|
+
add_transaction_hook(conn, :after_rollback, block)
|
187
191
|
end
|
188
192
|
end
|
189
193
|
end
|
@@ -337,6 +341,13 @@ module Sequel
|
|
337
341
|
def adapter_initialize
|
338
342
|
end
|
339
343
|
|
344
|
+
# Set the given callable as a hook to be called. Type should be either
|
345
|
+
# :after_commit or :after_rollback.
|
346
|
+
def add_transaction_hook(conn, type, block)
|
347
|
+
hooks = _trans(conn)[type] ||= []
|
348
|
+
hooks << block
|
349
|
+
end
|
350
|
+
|
340
351
|
# Returns true when the object is considered blank.
|
341
352
|
# The only objects that are blank are nil, false,
|
342
353
|
# strings with all whitespace, and ones that respond
|
@@ -18,8 +18,7 @@ module Sequel
|
|
18
18
|
# the {"Schema Modification" guide}[rdoc-ref:doc/schema_modification.rdoc].
|
19
19
|
class CreateTableGenerator
|
20
20
|
# Classes specifying generic types that Sequel will convert to database-specific types.
|
21
|
-
GENERIC_TYPES
|
22
|
-
Date, DateTime, Time, File, TrueClass, FalseClass]
|
21
|
+
GENERIC_TYPES=%w'String Integer Fixnum Float Numeric BigDecimal Date DateTime Time File TrueClass FalseClass'
|
23
22
|
|
24
23
|
# Return the column hashes created by this generator
|
25
24
|
attr_reader :columns
|
@@ -41,6 +40,12 @@ module Sequel
|
|
41
40
|
instance_eval(&block) if block
|
42
41
|
@columns.unshift(@primary_key) if @primary_key && !has_column?(primary_key_name)
|
43
42
|
end
|
43
|
+
|
44
|
+
# Use custom Bignum method to use :Bignum instead of Bignum class, to work
|
45
|
+
# correctly in cases where Bignum is the same as Integer.
|
46
|
+
def Bignum(name, opts=OPTS)
|
47
|
+
column(name, :Bignum, opts)
|
48
|
+
end
|
44
49
|
|
45
50
|
# Add a method for each of the given types that creates a column
|
46
51
|
# with that type as a constant. Types given should either already
|
@@ -108,7 +108,7 @@ module Sequel
|
|
108
108
|
# be option hashes, so long as the option hashes have a :table
|
109
109
|
# entry giving the table referenced:
|
110
110
|
#
|
111
|
-
# create_join_table(:cat_id=>{:table=>:cats, :type
|
111
|
+
# create_join_table(:cat_id=>{:table=>:cats, :type=>:Bignum}, :dog_id=>:dogs)
|
112
112
|
#
|
113
113
|
# You can provide a second argument which is a table options hash:
|
114
114
|
#
|
@@ -884,7 +884,14 @@ module Sequel
|
|
884
884
|
|
885
885
|
# SQL fragment specifying the type of a given column.
|
886
886
|
def type_literal(column)
|
887
|
-
column[:type]
|
887
|
+
case column[:type]
|
888
|
+
when Class
|
889
|
+
type_literal_generic(column)
|
890
|
+
when :Bignum
|
891
|
+
type_literal_generic_bignum(column)
|
892
|
+
else
|
893
|
+
type_literal_specific(column)
|
894
|
+
end
|
888
895
|
end
|
889
896
|
|
890
897
|
# SQL fragment specifying the full type of a column,
|
@@ -80,11 +80,14 @@ module Sequel
|
|
80
80
|
# appropriately. Valid values true, :on, false, :off, :local (9.1+),
|
81
81
|
# and :remote_write (9.2+).
|
82
82
|
def transaction(opts=OPTS, &block)
|
83
|
+
opts = Hash[opts]
|
83
84
|
if retry_on = opts[:retry_on]
|
84
85
|
tot_retries = opts.fetch(:num_retries, 5)
|
85
86
|
num_retries = 0 unless tot_retries.nil?
|
86
87
|
begin
|
87
|
-
|
88
|
+
opts[:retry_on] = nil
|
89
|
+
opts[:retrying] = true
|
90
|
+
transaction(opts, &block)
|
88
91
|
rescue *retry_on => e
|
89
92
|
if num_retries
|
90
93
|
num_retries += 1
|
@@ -99,21 +102,40 @@ module Sequel
|
|
99
102
|
end
|
100
103
|
else
|
101
104
|
synchronize(opts[:server]) do |conn|
|
102
|
-
if opts[:savepoint] == :only
|
103
|
-
|
105
|
+
if opts[:savepoint] == :only
|
106
|
+
if supports_savepoints?
|
107
|
+
if _trans(conn)
|
108
|
+
opts[:savepoint] = true
|
109
|
+
else
|
110
|
+
return yield(conn)
|
111
|
+
end
|
112
|
+
else
|
113
|
+
opts[:savepoint] = false
|
114
|
+
end
|
104
115
|
end
|
116
|
+
|
105
117
|
if already_in_transaction?(conn, opts)
|
118
|
+
if opts[:rollback] == :always && !opts.has_key?(:savepoint)
|
119
|
+
if supports_savepoints?
|
120
|
+
opts[:savepoint] = true
|
121
|
+
else
|
122
|
+
raise Sequel::Error, "cannot set :rollback=>:always transaction option if already inside a transaction"
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
106
126
|
if opts[:savepoint] != false && (stack = _trans(conn)[:savepoints]) && stack.last
|
107
|
-
|
108
|
-
|
127
|
+
opts[:savepoint] = true
|
128
|
+
end
|
129
|
+
|
130
|
+
unless opts[:savepoint]
|
109
131
|
if opts[:retrying]
|
110
132
|
raise Sequel::Error, "cannot set :retry_on options if you are already inside a transaction"
|
111
133
|
end
|
112
134
|
return yield(conn)
|
113
135
|
end
|
114
|
-
else
|
115
|
-
_transaction(conn, opts, &block)
|
116
136
|
end
|
137
|
+
|
138
|
+
_transaction(conn, opts, &block)
|
117
139
|
end
|
118
140
|
end
|
119
141
|
end
|
@@ -174,12 +196,12 @@ module Sequel
|
|
174
196
|
|
175
197
|
# Add the current thread to the list of active transactions
|
176
198
|
def add_transaction(conn, opts)
|
177
|
-
hash =
|
199
|
+
hash = transaction_options(conn, opts)
|
178
200
|
|
179
201
|
if supports_savepoints?
|
180
|
-
if _trans(conn)
|
181
|
-
|
182
|
-
|
202
|
+
if t = _trans(conn)
|
203
|
+
t[:savepoints].push(opts[:auto_savepoint])
|
204
|
+
return
|
183
205
|
else
|
184
206
|
hash[:savepoints] = [opts[:auto_savepoint]]
|
185
207
|
if (prep = opts[:prepare]) && supports_prepared_transactions?
|
@@ -190,9 +212,7 @@ module Sequel
|
|
190
212
|
hash[:prepare] = prep
|
191
213
|
end
|
192
214
|
|
193
|
-
|
194
|
-
Sequel.synchronize{@transactions[conn] = hash}
|
195
|
-
end
|
215
|
+
Sequel.synchronize{@transactions[conn] = hash}
|
196
216
|
end
|
197
217
|
|
198
218
|
# Whether the current thread/connection is already inside a transaction
|
@@ -200,6 +220,12 @@ module Sequel
|
|
200
220
|
_trans(conn) && (!supports_savepoints? || !opts[:savepoint])
|
201
221
|
end
|
202
222
|
|
223
|
+
# Derive the transaction hash from the options passed to the transaction.
|
224
|
+
# Meant to be overridden.
|
225
|
+
def transaction_options(conn, opts)
|
226
|
+
{}
|
227
|
+
end
|
228
|
+
|
203
229
|
# Issue query to begin a new savepoint.
|
204
230
|
def begin_savepoint(conn, opts)
|
205
231
|
log_connection_execute(conn, begin_savepoint_sql(savepoint_level(conn)-1))
|
@@ -279,15 +305,23 @@ module Sequel
|
|
279
305
|
:execute
|
280
306
|
end
|
281
307
|
|
308
|
+
# Retrieve the transaction hooks that should be run for the given
|
309
|
+
# connection and commit status.
|
310
|
+
def transaction_hooks(conn, committed)
|
311
|
+
if !supports_savepoints? || savepoint_level(conn) == 1
|
312
|
+
_trans(conn)[committed ? :after_commit : :after_rollback]
|
313
|
+
end
|
314
|
+
end
|
315
|
+
|
282
316
|
# Remove the current thread from the list of active transactions
|
283
317
|
def remove_transaction(conn, committed)
|
318
|
+
callbacks = transaction_hooks(conn, committed)
|
319
|
+
|
284
320
|
if transaction_finished?(conn)
|
285
|
-
callbacks = _trans(conn)[committed ? :after_commit : :after_rollback]
|
286
321
|
Sequel.synchronize{@transactions.delete(conn)}
|
287
|
-
if callbacks
|
288
|
-
callbacks.each(&:call)
|
289
|
-
end
|
290
322
|
end
|
323
|
+
|
324
|
+
callbacks.each(&:call) if callbacks
|
291
325
|
end
|
292
326
|
|
293
327
|
# SQL to rollback to a savepoint
|
@@ -719,31 +719,33 @@ module Sequel
|
|
719
719
|
# DB[:table].to_hash([:id, :name]) # SELECT * FROM table
|
720
720
|
# # {[1, 'Jim']=>{:id=>1, :name=>'Jim'}, [2, 'Bob'=>{:id=>2, :name=>'Bob'}, ...}
|
721
721
|
#
|
722
|
-
#
|
723
|
-
#
|
724
|
-
#
|
725
|
-
#
|
722
|
+
# Options:
|
723
|
+
# :all :: Use all instead of each to retrieve the objects
|
724
|
+
# :hash :: The object into which the values will be placed. If this is not
|
725
|
+
# given, an empty hash is used. This can be used to use a hash with
|
726
|
+
# a default value or default proc.
|
726
727
|
def to_hash(key_column, value_column = nil, opts = OPTS)
|
727
728
|
h = opts[:hash] || {}
|
729
|
+
meth = opts[:all] ? :all : :each
|
728
730
|
if value_column
|
729
731
|
return naked.to_hash(key_column, value_column, opts) if row_proc
|
730
732
|
if value_column.is_a?(Array)
|
731
733
|
if key_column.is_a?(Array)
|
732
|
-
|
734
|
+
send(meth){|r| h[r.values_at(*key_column)] = r.values_at(*value_column)}
|
733
735
|
else
|
734
|
-
|
736
|
+
send(meth){|r| h[r[key_column]] = r.values_at(*value_column)}
|
735
737
|
end
|
736
738
|
else
|
737
739
|
if key_column.is_a?(Array)
|
738
|
-
|
740
|
+
send(meth){|r| h[r.values_at(*key_column)] = r[value_column]}
|
739
741
|
else
|
740
|
-
|
742
|
+
send(meth){|r| h[r[key_column]] = r[value_column]}
|
741
743
|
end
|
742
744
|
end
|
743
745
|
elsif key_column.is_a?(Array)
|
744
|
-
|
746
|
+
send(meth){|r| h[key_column.map{|k| r[k]}] = r}
|
745
747
|
else
|
746
|
-
|
748
|
+
send(meth){|r| h[r[key_column]] = r}
|
747
749
|
end
|
748
750
|
h
|
749
751
|
end
|
@@ -767,31 +769,34 @@ module Sequel
|
|
767
769
|
# DB[:table].to_hash_groups([:first, :middle]) # SELECT * FROM table
|
768
770
|
# # {['Jim', 'Bob']=>[{:id=>1, :first=>'Jim', :middle=>'Bob', :last=>'Smith'}, ...], ...}
|
769
771
|
#
|
770
|
-
#
|
771
|
-
#
|
772
|
-
#
|
772
|
+
# Options:
|
773
|
+
# :all :: Use all instead of each to retrieve the objects
|
774
|
+
# :hash :: The object into which the values will be placed. If this is not
|
775
|
+
# given, an empty hash is used. This can be used to use a hash with
|
776
|
+
# a default value or default proc.
|
773
777
|
# to start with a new, empty hash.
|
774
778
|
def to_hash_groups(key_column, value_column = nil, opts = OPTS)
|
775
779
|
h = opts[:hash] || {}
|
780
|
+
meth = opts[:all] ? :all : :each
|
776
781
|
if value_column
|
777
782
|
return naked.to_hash_groups(key_column, value_column, opts) if row_proc
|
778
783
|
if value_column.is_a?(Array)
|
779
784
|
if key_column.is_a?(Array)
|
780
|
-
|
785
|
+
send(meth){|r| (h[r.values_at(*key_column)] ||= []) << r.values_at(*value_column)}
|
781
786
|
else
|
782
|
-
|
787
|
+
send(meth){|r| (h[r[key_column]] ||= []) << r.values_at(*value_column)}
|
783
788
|
end
|
784
789
|
else
|
785
790
|
if key_column.is_a?(Array)
|
786
|
-
|
791
|
+
send(meth){|r| (h[r.values_at(*key_column)] ||= []) << r[value_column]}
|
787
792
|
else
|
788
|
-
|
793
|
+
send(meth){|r| (h[r[key_column]] ||= []) << r[value_column]}
|
789
794
|
end
|
790
795
|
end
|
791
796
|
elsif key_column.is_a?(Array)
|
792
|
-
|
797
|
+
send(meth){|r| (h[key_column.map{|k| r[k]}] ||= []) << r}
|
793
798
|
else
|
794
|
-
|
799
|
+
send(meth){|r| (h[r[key_column]] ||= []) << r}
|
795
800
|
end
|
796
801
|
h
|
797
802
|
end
|
@@ -157,6 +157,11 @@ module Sequel
|
|
157
157
|
false
|
158
158
|
end
|
159
159
|
|
160
|
+
# Whether the dataset supports skipping locked rows when returning data.
|
161
|
+
def supports_skip_locked?
|
162
|
+
false
|
163
|
+
end
|
164
|
+
|
160
165
|
# Whether the database supports SELECT *, column FROM table
|
161
166
|
def supports_select_all_and_column?
|
162
167
|
true
|
data/lib/sequel/dataset/query.rb
CHANGED
@@ -827,6 +827,12 @@ module Sequel
|
|
827
827
|
end
|
828
828
|
end
|
829
829
|
|
830
|
+
# Skip locked rows when returning results from this dataset.
|
831
|
+
def skip_locked
|
832
|
+
raise(Error, 'This dataset does not support skipping locked rows') unless supports_skip_locked?
|
833
|
+
clone(:skip_locked=>true)
|
834
|
+
end
|
835
|
+
|
830
836
|
# Unbind bound variables from this dataset's filter and return an array of two
|
831
837
|
# objects. The first object is a modified dataset where the filter has been
|
832
838
|
# replaced with one that uses bound variable placeholders. The second object
|
@@ -20,7 +20,7 @@
|
|
20
20
|
#
|
21
21
|
# This extension may not work correctly in the following cases:
|
22
22
|
#
|
23
|
-
# *
|
23
|
+
# * log_connection_yield is not used when executing the query.
|
24
24
|
# * The underlying exception is frozen or reused.
|
25
25
|
# * The underlying exception doesn't correctly record instance
|
26
26
|
# variables set on it (seems to happen on JRuby when underlying
|
@@ -57,12 +57,12 @@ module Sequel
|
|
57
57
|
# If there are no loggers for this database and an exception is raised
|
58
58
|
# store the SQL related to the exception with the exception, so it
|
59
59
|
# is available for DatabaseError#sql later.
|
60
|
-
def
|
60
|
+
def log_connection_yield(sql, conn, args=nil)
|
61
61
|
if @loggers.empty?
|
62
62
|
begin
|
63
63
|
yield
|
64
64
|
rescue => e
|
65
|
-
sql = "#{sql}; #{args.inspect}" if args
|
65
|
+
sql = "#{connection_info(conn) if conn && log_connection_info}#{sql}#{"; #{args.inspect}" if args}"
|
66
66
|
e.instance_variable_set(:@sequel_error_sql, sql)
|
67
67
|
raise
|
68
68
|
end
|
@@ -405,11 +405,20 @@ module Sequel
|
|
405
405
|
|
406
406
|
# Delegate to the ruby range object so that the object mostly acts like a range.
|
407
407
|
range_methods = %w'each last first step'
|
408
|
-
range_methods << 'cover?' if RUBY_VERSION >= '1.9'
|
409
408
|
range_methods.each do |m|
|
410
409
|
class_eval("def #{m}(*a, &block) to_range.#{m}(*a, &block) end", __FILE__, __LINE__)
|
411
410
|
end
|
412
411
|
|
412
|
+
# Return whether the value is inside the range.
|
413
|
+
def cover?(value)
|
414
|
+
return false if empty?
|
415
|
+
b = self.begin
|
416
|
+
return false if b && b.send(exclude_begin? ? :>= : :>, value)
|
417
|
+
e = self.end
|
418
|
+
return false if e && e.send(exclude_end? ? :<= : :<, value)
|
419
|
+
true
|
420
|
+
end
|
421
|
+
|
413
422
|
# Consider the receiver equal to other PGRange instances with the
|
414
423
|
# same beginning, ending, exclusions, and database type. Also consider
|
415
424
|
# it equal to Range instances if this PGRange can be converted to a
|
@@ -25,17 +25,17 @@ module Sequel
|
|
25
25
|
if !$1 && $2 && $2.to_i >= 10 && $3
|
26
26
|
# Unsigned integer type with 10 digits can potentially contain values which
|
27
27
|
# don't fit signed integer type, so use bigint type in target database.
|
28
|
-
{:type
|
28
|
+
{:type=>:Bignum}
|
29
29
|
else
|
30
30
|
{:type=>Integer}
|
31
31
|
end
|
32
32
|
when /\Atinyint(?:\((\d+)\))?(?: unsigned)?\z/o
|
33
33
|
{:type =>schema[:type] == :boolean ? TrueClass : Integer}
|
34
34
|
when /\Abigint(?:\((?:\d+)\))?(?: unsigned)?\z/o
|
35
|
-
{:type
|
35
|
+
{:type=>:Bignum}
|
36
36
|
when /\A(?:real|float|double(?: precision)?|double\(\d+,\d+\)(?: unsigned)?)\z/o
|
37
37
|
{:type=>Float}
|
38
|
-
when 'boolean', 'bit'
|
38
|
+
when 'boolean', 'bit', 'bool'
|
39
39
|
{:type=>TrueClass}
|
40
40
|
when /\A(?:(?:tiny|medium|long|n)?text|clob)\z/o
|
41
41
|
{:type=>String, :text=>true}
|
@@ -206,7 +206,7 @@ END_MIG
|
|
206
206
|
gen.foreign_key(name, table, col_opts)
|
207
207
|
else
|
208
208
|
gen.column(name, type, col_opts)
|
209
|
-
if [Integer, Bignum, Float].include?(type) && schema[:db_type] =~ / unsigned\z/io
|
209
|
+
if [Integer, :Bignum, Float].include?(type) && schema[:db_type] =~ / unsigned\z/io
|
210
210
|
gen.check(Sequel::SQL::Identifier.new(name) >= 0)
|
211
211
|
end
|
212
212
|
end
|
@@ -407,8 +407,11 @@ END_MIG
|
|
407
407
|
else
|
408
408
|
type = c.delete(:type)
|
409
409
|
opts = opts_inspect(c)
|
410
|
-
|
410
|
+
case type
|
411
|
+
when Class
|
411
412
|
"#{type.name} #{name.inspect}#{opts}"
|
413
|
+
when :Bignum
|
414
|
+
"Bignum #{name.inspect}#{opts}"
|
412
415
|
else
|
413
416
|
"column #{name.inspect}, #{type.inspect}#{opts}"
|
414
417
|
end
|