sequel 4.34.0 → 4.35.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|