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
@@ -24,9 +24,9 @@ module Sequel
|
|
24
24
|
def execute_insert(sql, opts=OPTS)
|
25
25
|
synchronize(opts[:server]) do |conn|
|
26
26
|
begin
|
27
|
-
|
27
|
+
log_connection_yield(sql, conn){conn.do(sql)}
|
28
28
|
begin
|
29
|
-
s =
|
29
|
+
s = log_connection_yield(LAST_INSERT_ID_SQL, conn){conn.run(LAST_INSERT_ID_SQL)}
|
30
30
|
if (rows = s.fetch_all) and (row = rows.first) and (v = row.first)
|
31
31
|
Integer(v)
|
32
32
|
end
|
@@ -80,10 +80,10 @@ module Sequel
|
|
80
80
|
if args = opts[:arguments]
|
81
81
|
r = conn.parse(sql)
|
82
82
|
args = cursor_bind_params(conn, r, args)
|
83
|
-
nr =
|
83
|
+
nr = log_connection_yield(sql, conn, args){r.exec}
|
84
84
|
r = nr unless block_given?
|
85
85
|
else
|
86
|
-
r =
|
86
|
+
r = log_connection_yield(sql, conn){conn.exec(sql)}
|
87
87
|
end
|
88
88
|
if block_given?
|
89
89
|
begin
|
@@ -172,7 +172,7 @@ module Sequel
|
|
172
172
|
end
|
173
173
|
end
|
174
174
|
unless cursor
|
175
|
-
cursor =
|
175
|
+
cursor = log_connection_yield("PREPARE #{name}: #{sql}", conn){conn.parse(sql)}
|
176
176
|
conn.prepared_statements[name] = [cursor, sql]
|
177
177
|
end
|
178
178
|
args = cursor_bind_params(conn, cursor, opts[:arguments])
|
@@ -182,7 +182,7 @@ module Sequel
|
|
182
182
|
log_sql << sql
|
183
183
|
log_sql << ")"
|
184
184
|
end
|
185
|
-
r =
|
185
|
+
r = log_connection_yield(log_sql, conn, args){cursor.exec}
|
186
186
|
if block_given?
|
187
187
|
yield(cursor)
|
188
188
|
elsif type == :insert
|
@@ -201,7 +201,7 @@ module Sequel
|
|
201
201
|
if sequence
|
202
202
|
sql = "SELECT #{literal(sequence)}.currval FROM dual"
|
203
203
|
begin
|
204
|
-
cursor =
|
204
|
+
cursor = log_connection_yield(sql, conn){conn.exec(sql)}
|
205
205
|
row = cursor.fetch
|
206
206
|
row.each{|v| return (v.to_i if v)}
|
207
207
|
rescue OCIError
|
@@ -213,12 +213,12 @@ module Sequel
|
|
213
213
|
end
|
214
214
|
|
215
215
|
def begin_transaction(conn, opts=OPTS)
|
216
|
-
|
216
|
+
log_connection_yield(TRANSACTION_BEGIN, conn){conn.autocommit = false}
|
217
217
|
set_transaction_isolation(conn, opts)
|
218
218
|
end
|
219
219
|
|
220
220
|
def commit_transaction(conn, opts=OPTS)
|
221
|
-
|
221
|
+
log_connection_yield(TRANSACTION_COMMIT, conn){conn.commit}
|
222
222
|
end
|
223
223
|
|
224
224
|
def disconnect_error?(e, opts)
|
@@ -250,7 +250,7 @@ module Sequel
|
|
250
250
|
end
|
251
251
|
|
252
252
|
def rollback_transaction(conn, opts=OPTS)
|
253
|
-
|
253
|
+
log_connection_yield(TRANSACTION_ROLLBACK, conn){conn.rollback}
|
254
254
|
end
|
255
255
|
|
256
256
|
def schema_parse_table(table, opts=OPTS)
|
@@ -283,7 +283,7 @@ module Sequel
|
|
283
283
|
|
284
284
|
metadata = synchronize(opts[:server]) do |conn|
|
285
285
|
begin
|
286
|
-
|
286
|
+
log_connection_yield("Connection.describe_table", conn){conn.describe_table(schema_and_table)}
|
287
287
|
rescue OCIError => e
|
288
288
|
raise_error(e)
|
289
289
|
end
|
@@ -183,7 +183,7 @@ module Sequel
|
|
183
183
|
# Return the PGResult object that is returned by executing the given
|
184
184
|
# sql and args.
|
185
185
|
def execute_query(sql, args)
|
186
|
-
@db.
|
186
|
+
@db.log_connection_yield(sql, self, args){args ? async_exec(sql, args) : async_exec(sql)}
|
187
187
|
end
|
188
188
|
end
|
189
189
|
|
@@ -584,7 +584,7 @@ module Sequel
|
|
584
584
|
|
585
585
|
unless conn.prepared_statements[ps_name] == sql
|
586
586
|
conn.execute("DEALLOCATE #{ps_name}") if conn.prepared_statements.include?(ps_name)
|
587
|
-
conn.check_disconnect_errors{
|
587
|
+
conn.check_disconnect_errors{log_connection_yield("PREPARE #{ps_name} AS #{sql}", conn){conn.prepare(ps_name, sql)}}
|
588
588
|
conn.prepared_statements[ps_name] = sql
|
589
589
|
end
|
590
590
|
|
@@ -595,7 +595,7 @@ module Sequel
|
|
595
595
|
log_sql << ")"
|
596
596
|
end
|
597
597
|
|
598
|
-
q = conn.check_disconnect_errors{
|
598
|
+
q = conn.check_disconnect_errors{log_connection_yield(log_sql, conn, args){_execute_prepared_statement(conn, ps_name, args, opts)}}
|
599
599
|
begin
|
600
600
|
block_given? ? yield(q) : q.cmd_tuples
|
601
601
|
ensure
|
@@ -516,8 +516,10 @@ module Sequel
|
|
516
516
|
BOOL_TRUE = '1'.freeze
|
517
517
|
BOOL_FALSE = '0'.freeze
|
518
518
|
COMMA_SEPARATOR = ', '.freeze
|
519
|
-
|
520
|
-
|
519
|
+
TABLE_HINT = " WITH (".freeze
|
520
|
+
READPAST = "READPAST".freeze
|
521
|
+
NOLOCK = 'NOLOCK'.freeze
|
522
|
+
UPDLOCK = 'UPDLOCK'.freeze
|
521
523
|
WILDCARD = LiteralString.new('*').freeze
|
522
524
|
CONSTANT_MAP = {:CURRENT_DATE=>'CAST(CURRENT_TIMESTAMP AS DATE)'.freeze, :CURRENT_TIME=>'CAST(CURRENT_TIMESTAMP AS TIME)'.freeze}
|
523
525
|
EXTRACT_MAP = {:year=>"yy", :month=>"m", :day=>"d", :hour=>"hh", :minute=>"n", :second=>"s"}
|
@@ -732,7 +734,7 @@ module Sequel
|
|
732
734
|
is_2005_or_later?
|
733
735
|
end
|
734
736
|
|
735
|
-
# MSSQL
|
737
|
+
# MSSQL 2008+ supports GROUPING SETS
|
736
738
|
def supports_grouping_sets?
|
737
739
|
is_2008_or_later?
|
738
740
|
end
|
@@ -782,6 +784,11 @@ module Sequel
|
|
782
784
|
supports_insert_select?
|
783
785
|
end
|
784
786
|
|
787
|
+
# MSSQL uses READPAST to skip locked rows.
|
788
|
+
def supports_skip_locked?
|
789
|
+
true
|
790
|
+
end
|
791
|
+
|
785
792
|
# MSSQL 2005+ supports window functions
|
786
793
|
def supports_window_functions?
|
787
794
|
true
|
@@ -965,11 +972,32 @@ module Sequel
|
|
965
972
|
|
966
973
|
# Support different types of locking styles
|
967
974
|
def select_lock_sql(sql)
|
968
|
-
|
969
|
-
|
970
|
-
|
971
|
-
|
972
|
-
|
975
|
+
lock = @opts[:lock]
|
976
|
+
skip_locked = @opts[:skip_locked]
|
977
|
+
for_update = lock == :update
|
978
|
+
dirty = lock == :dirty
|
979
|
+
lock_hint = for_update || dirty
|
980
|
+
|
981
|
+
if lock_hint || skip_locked
|
982
|
+
sql << TABLE_HINT
|
983
|
+
|
984
|
+
if lock_hint
|
985
|
+
sql << if for_update
|
986
|
+
UPDLOCK
|
987
|
+
else
|
988
|
+
NOLOCK
|
989
|
+
end
|
990
|
+
end
|
991
|
+
|
992
|
+
if lock_hint && skip_locked
|
993
|
+
sql << COMMA_SEPARATOR
|
994
|
+
end
|
995
|
+
|
996
|
+
if skip_locked
|
997
|
+
sql << READPAST
|
998
|
+
end
|
999
|
+
|
1000
|
+
sql << PAREN_CLOSE
|
973
1001
|
else
|
974
1002
|
super
|
975
1003
|
end
|
@@ -287,6 +287,7 @@ module Sequel
|
|
287
287
|
HSTAR = "H*".freeze
|
288
288
|
DUAL = ' FROM DUAL'.freeze
|
289
289
|
BITAND_PROC = lambda{|a, b| Sequel.lit(["CAST(BITAND(", ", ", ") AS INTEGER)"], a, b)}
|
290
|
+
SKIP_LOCKED = " SKIP LOCKED".freeze
|
290
291
|
|
291
292
|
include(Module.new do
|
292
293
|
Dataset.def_sql_method(self, :select, %w'with select distinct columns from join where group having compounds order lock')
|
@@ -431,6 +432,11 @@ module Sequel
|
|
431
432
|
false
|
432
433
|
end
|
433
434
|
|
435
|
+
# Oracle supports SKIP LOCKED.
|
436
|
+
def supports_skip_locked?
|
437
|
+
true
|
438
|
+
end
|
439
|
+
|
434
440
|
# Oracle supports timezones in literal timestamps.
|
435
441
|
def supports_timestamp_timezones?
|
436
442
|
true
|
@@ -536,6 +542,15 @@ module Sequel
|
|
536
542
|
:union
|
537
543
|
end
|
538
544
|
|
545
|
+
# Use SKIP LOCKED if skipping locked rows.
|
546
|
+
def select_lock_sql(sql)
|
547
|
+
super
|
548
|
+
|
549
|
+
if @opts[:skip_locked]
|
550
|
+
sql << SKIP_LOCKED
|
551
|
+
end
|
552
|
+
end
|
553
|
+
|
539
554
|
# Oracle supports quoted function names.
|
540
555
|
def supports_quoted_function_names?
|
541
556
|
true
|
@@ -1214,6 +1214,7 @@ module Sequel
|
|
1214
1214
|
SELECT_VALUES = "VALUES ".freeze
|
1215
1215
|
EMPTY_STRING = ''.freeze
|
1216
1216
|
LOCK_MODES = ['ACCESS SHARE', 'ROW SHARE', 'ROW EXCLUSIVE', 'SHARE UPDATE EXCLUSIVE', 'SHARE', 'SHARE ROW EXCLUSIVE', 'EXCLUSIVE', 'ACCESS EXCLUSIVE'].each(&:freeze)
|
1217
|
+
SKIP_LOCKED = " SKIP LOCKED".freeze
|
1217
1218
|
|
1218
1219
|
Dataset.def_sql_method(self, :delete, [['if server_version >= 90100', %w'with delete from using where returning'], ['else', %w'delete from using where returning']])
|
1219
1220
|
Dataset.def_sql_method(self, :insert, [['if server_version >= 90500', %w'with insert into columns values conflict returning'], ['elsif server_version >= 90100', %w'with insert into columns values returning'], ['else', %w'insert into columns values returning']])
|
@@ -1305,6 +1306,8 @@ module Sequel
|
|
1305
1306
|
# of any of the terms in any of the cols.
|
1306
1307
|
#
|
1307
1308
|
# Options:
|
1309
|
+
# :headline :: Append a expression to the selected columns aliased to headline that
|
1310
|
+
# contains an extract of the matched text.
|
1308
1311
|
# :language :: The language to use for the search (default: 'simple')
|
1309
1312
|
# :plain :: Whether a plain search should be used (default: false). In this case,
|
1310
1313
|
# terms should be a single string, and it will do a search where cols
|
@@ -1341,6 +1344,10 @@ module Sequel
|
|
1341
1344
|
ds = ds.reverse{ts_rank_cd(cols, terms)}
|
1342
1345
|
end
|
1343
1346
|
|
1347
|
+
if opts[:headline]
|
1348
|
+
ds = ds.select_append{ts_headline(lang, phrase_cols, terms).as(:headline)}
|
1349
|
+
end
|
1350
|
+
|
1344
1351
|
ds
|
1345
1352
|
end
|
1346
1353
|
|
@@ -1504,6 +1511,11 @@ module Sequel
|
|
1504
1511
|
true
|
1505
1512
|
end
|
1506
1513
|
|
1514
|
+
# PostgreSQL 9.5+ supports SKIP LOCKED.
|
1515
|
+
def supports_skip_locked?
|
1516
|
+
server_version >= 90500
|
1517
|
+
end
|
1518
|
+
|
1507
1519
|
# PostgreSQL supports timezones in literal timestamps
|
1508
1520
|
def supports_timestamp_timezones?
|
1509
1521
|
true
|
@@ -1684,8 +1696,17 @@ module Sequel
|
|
1684
1696
|
end
|
1685
1697
|
|
1686
1698
|
# Support FOR SHARE locking when using the :share lock style.
|
1699
|
+
# Use SKIP LOCKED if skipping locked rows.
|
1687
1700
|
def select_lock_sql(sql)
|
1688
|
-
@opts[:lock] == :share
|
1701
|
+
if @opts[:lock] == :share
|
1702
|
+
sql << FOR_SHARE
|
1703
|
+
else
|
1704
|
+
super
|
1705
|
+
end
|
1706
|
+
|
1707
|
+
if @opts[:skip_locked]
|
1708
|
+
sql << SKIP_LOCKED
|
1709
|
+
end
|
1689
1710
|
end
|
1690
1711
|
|
1691
1712
|
# Support VALUES clause instead of the SELECT clause to return rows.
|
@@ -102,7 +102,7 @@ module Sequel
|
|
102
102
|
|
103
103
|
LAST_INSERT_ID = 'SELECT @@IDENTITY'.freeze
|
104
104
|
def _execute(conn, type, sql, opts)
|
105
|
-
unless rs =
|
105
|
+
unless rs = log_connection_yield(sql, conn){@api.sqlany_execute_direct(conn, sql)}
|
106
106
|
result, errstr = @api.sqlany_error(conn)
|
107
107
|
raise_error(SQLAnywhereException.new(errstr, result, sql))
|
108
108
|
end
|
@@ -109,7 +109,7 @@ module Sequel
|
|
109
109
|
db = ::SQLite3::Database.new(opts[:database].to_s, sqlite3_opts)
|
110
110
|
db.busy_timeout(opts.fetch(:timeout, 5000))
|
111
111
|
|
112
|
-
connection_pragmas.each{|s|
|
112
|
+
connection_pragmas.each{|s| log_connection_yield(s, db){db.execute_batch(s)}}
|
113
113
|
|
114
114
|
class << db
|
115
115
|
attr_reader :prepared_statements
|
@@ -184,12 +184,12 @@ module Sequel
|
|
184
184
|
opts.fetch(:arguments, {}).each{|k, v| args[k] = prepared_statement_argument(v)}
|
185
185
|
case type
|
186
186
|
when :select
|
187
|
-
|
187
|
+
log_connection_yield(sql, conn, log_args){conn.query(sql, args, &block)}
|
188
188
|
when :insert
|
189
|
-
|
189
|
+
log_connection_yield(sql, conn, log_args){conn.execute(sql, args)}
|
190
190
|
conn.last_insert_row_id
|
191
191
|
when :update
|
192
|
-
|
192
|
+
log_connection_yield(sql, conn, log_args){conn.execute_batch(sql, args)}
|
193
193
|
conn.changes
|
194
194
|
end
|
195
195
|
end
|
@@ -241,7 +241,7 @@ module Sequel
|
|
241
241
|
end
|
242
242
|
end
|
243
243
|
unless cps
|
244
|
-
cps =
|
244
|
+
cps = log_connection_yield("PREPARE #{name}: #{sql}", conn){conn.prepare(sql)}
|
245
245
|
conn.prepared_statements[name] = [cps, sql]
|
246
246
|
end
|
247
247
|
log_sql = String.new
|
@@ -252,9 +252,9 @@ module Sequel
|
|
252
252
|
log_sql << ")"
|
253
253
|
end
|
254
254
|
if block
|
255
|
-
|
255
|
+
log_connection_yield(log_sql, conn, args){cps.execute(ps_args, &block)}
|
256
256
|
else
|
257
|
-
|
257
|
+
log_connection_yield(log_sql, conn, args){cps.execute!(ps_args){|r|}}
|
258
258
|
case type
|
259
259
|
when :insert
|
260
260
|
conn.last_insert_row_id
|
@@ -50,7 +50,7 @@ module Sequel
|
|
50
50
|
def execute(sql, opts=OPTS)
|
51
51
|
synchronize(opts[:server]) do |conn|
|
52
52
|
begin
|
53
|
-
res =
|
53
|
+
res = log_connection_yield(sql, conn){conn.execute(sql)}
|
54
54
|
yield res if block_given?
|
55
55
|
nil
|
56
56
|
rescue ::Swift::Error => e
|
@@ -64,7 +64,7 @@ module Sequel
|
|
64
64
|
def execute_dui(sql, opts=OPTS)
|
65
65
|
synchronize(opts[:server]) do |conn|
|
66
66
|
begin
|
67
|
-
|
67
|
+
log_connection_yield(sql, conn){conn.execute(sql).affected_rows}
|
68
68
|
rescue ::Swift::Error => e
|
69
69
|
raise_error(e)
|
70
70
|
end
|
@@ -76,7 +76,7 @@ module Sequel
|
|
76
76
|
def execute_insert(sql, opts=OPTS)
|
77
77
|
synchronize(opts[:server]) do |conn|
|
78
78
|
begin
|
79
|
-
|
79
|
+
log_connection_yield(sql, conn){conn.execute(sql).insert_id}
|
80
80
|
rescue ::Swift::Error => e
|
81
81
|
raise_error(e)
|
82
82
|
end
|
@@ -27,7 +27,7 @@ module Sequel
|
|
27
27
|
|
28
28
|
# Apply the connectiong setting SQLs for every new connection.
|
29
29
|
def setup_connection(conn)
|
30
|
-
mysql_connection_setting_sqls.each{|sql|
|
30
|
+
mysql_connection_setting_sqls.each{|sql| log_connection_yield(sql, conn){conn.execute(sql)}}
|
31
31
|
super
|
32
32
|
end
|
33
33
|
end
|
@@ -38,7 +38,7 @@ module Sequel
|
|
38
38
|
def setup_connection(conn)
|
39
39
|
conn = super(conn)
|
40
40
|
conn.native_bind_format = true
|
41
|
-
connection_configuration_sqls.each{|sql|
|
41
|
+
connection_configuration_sqls.each{|sql| log_connection_yield(sql, conn){conn.execute(sql)}}
|
42
42
|
conn
|
43
43
|
end
|
44
44
|
end
|
@@ -18,7 +18,7 @@ module Sequel
|
|
18
18
|
|
19
19
|
if (ts = opts[:textsize])
|
20
20
|
sql = "SET TEXTSIZE #{typecast_value_integer(ts)}"
|
21
|
-
|
21
|
+
log_connection_yield(sql, c){c.execute(sql)}
|
22
22
|
end
|
23
23
|
|
24
24
|
c
|
@@ -52,12 +52,12 @@ module Sequel
|
|
52
52
|
single_value = true
|
53
53
|
end
|
54
54
|
sql = "EXEC sp_executesql N'#{c.escape(sql)}', N'#{c.escape(types.join(', '))}', #{values.join(', ')}"
|
55
|
-
|
55
|
+
log_connection_yield(sql, c) do
|
56
56
|
r = c.execute(sql)
|
57
57
|
r.each{|row| return row.values.first} if single_value
|
58
58
|
end
|
59
59
|
else
|
60
|
-
|
60
|
+
log_connection_yield(sql, c) do
|
61
61
|
r = c.execute(sql)
|
62
62
|
return r.send(m) if m
|
63
63
|
end
|
@@ -139,16 +139,14 @@ module Sequel
|
|
139
139
|
|
140
140
|
# Dispose of any possible results of execution.
|
141
141
|
def log_connection_execute(conn, sql)
|
142
|
-
|
142
|
+
log_connection_yield(sql, conn){conn.execute(sql).each}
|
143
143
|
end
|
144
144
|
|
145
145
|
# Return a 2 element array with the literal value and type to use
|
146
146
|
# in the prepared statement call for the given value and connection.
|
147
147
|
def ps_arg_type(v)
|
148
148
|
case v
|
149
|
-
when
|
150
|
-
[v, 'int']
|
151
|
-
when Bignum
|
149
|
+
when Integer
|
152
150
|
[v, 'bigint']
|
153
151
|
when Float
|
154
152
|
[v, 'double precision']
|
@@ -14,6 +14,9 @@ module Sequel
|
|
14
14
|
# Array of SQL loggers to use for this database.
|
15
15
|
attr_accessor :loggers
|
16
16
|
|
17
|
+
# Whether to include information about the connection in use when logging queries.
|
18
|
+
attr_accessor :log_connection_info
|
19
|
+
|
17
20
|
# Log level at which to log SQL queries. This is actually the method
|
18
21
|
# sent to the logger, so it should be the method name symbol. The default
|
19
22
|
# is :info, it can be set to :debug to log at DEBUG level.
|
@@ -31,9 +34,15 @@ module Sequel
|
|
31
34
|
|
32
35
|
# Yield to the block, logging any errors at error level to all loggers,
|
33
36
|
# and all other queries with the duration at warn or info level.
|
34
|
-
def log_yield(sql, args=nil)
|
37
|
+
def log_yield(sql, args=nil, &block)
|
38
|
+
log_connection_yield(sql, nil, args, &block)
|
39
|
+
end
|
40
|
+
|
41
|
+
# Yield to the block, logging any errors at error level to all loggers,
|
42
|
+
# and all other queries with the duration at warn or info level.
|
43
|
+
def log_connection_yield(sql, conn, args=nil)
|
35
44
|
return yield if @loggers.empty?
|
36
|
-
sql = "#{sql}; #{args.inspect}" if args
|
45
|
+
sql = "#{connection_info(conn) if conn && log_connection_info}#{sql}#{"; #{args.inspect}" if args}"
|
37
46
|
start = Time.now
|
38
47
|
begin
|
39
48
|
yield
|
@@ -53,11 +62,17 @@ module Sequel
|
|
53
62
|
end
|
54
63
|
|
55
64
|
private
|
65
|
+
|
66
|
+
# String including information about the connection, for use when logging
|
67
|
+
# connection info.
|
68
|
+
def connection_info(conn)
|
69
|
+
"(conn: #{conn.__id__}) "
|
70
|
+
end
|
56
71
|
|
57
72
|
# Log the given SQL and then execute it on the connection, used by
|
58
73
|
# the transaction code.
|
59
74
|
def log_connection_execute(conn, sql)
|
60
|
-
|
75
|
+
log_connection_yield(sql, conn){conn.send(connection_execute_method, sql)}
|
61
76
|
end
|
62
77
|
|
63
78
|
# Log message with message prefixed by duration at info level, or
|