sequel 5.24.0 → 5.29.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.
Files changed (79) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +58 -0
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +1 -1
  5. data/doc/cheat_sheet.rdoc +1 -0
  6. data/doc/postgresql.rdoc +2 -2
  7. data/doc/release_notes/5.25.0.txt +32 -0
  8. data/doc/release_notes/5.26.0.txt +35 -0
  9. data/doc/release_notes/5.27.0.txt +21 -0
  10. data/doc/release_notes/5.28.0.txt +16 -0
  11. data/doc/release_notes/5.29.0.txt +22 -0
  12. data/doc/testing.rdoc +11 -6
  13. data/lib/sequel/adapters/jdbc/postgresql.rb +6 -0
  14. data/lib/sequel/adapters/postgres.rb +5 -1
  15. data/lib/sequel/adapters/shared/mssql.rb +4 -2
  16. data/lib/sequel/adapters/shared/mysql.rb +1 -1
  17. data/lib/sequel/adapters/shared/postgres.rb +15 -0
  18. data/lib/sequel/adapters/shared/sqlite.rb +7 -2
  19. data/lib/sequel/adapters/tinytds.rb +1 -1
  20. data/lib/sequel/adapters/utils/mysql_mysql2.rb +1 -1
  21. data/lib/sequel/database/schema_generator.rb +1 -1
  22. data/lib/sequel/database/transactions.rb +3 -3
  23. data/lib/sequel/dataset/features.rb +6 -0
  24. data/lib/sequel/dataset/misc.rb +2 -2
  25. data/lib/sequel/dataset/query.rb +15 -2
  26. data/lib/sequel/dataset/sql.rb +17 -4
  27. data/lib/sequel/extensions/any_not_empty.rb +45 -0
  28. data/lib/sequel/extensions/exclude_or_null.rb +68 -0
  29. data/lib/sequel/extensions/pg_array_ops.rb +10 -6
  30. data/lib/sequel/extensions/pg_enum.rb +4 -1
  31. data/lib/sequel/extensions/pg_json.rb +1 -1
  32. data/lib/sequel/extensions/pg_json_ops.rb +124 -0
  33. data/lib/sequel/extensions/pg_range.rb +9 -0
  34. data/lib/sequel/extensions/sql_comments.rb +2 -2
  35. data/lib/sequel/model/base.rb +12 -5
  36. data/lib/sequel/plugins/association_multi_add_remove.rb +83 -0
  37. data/lib/sequel/plugins/caching.rb +3 -0
  38. data/lib/sequel/plugins/csv_serializer.rb +26 -9
  39. data/lib/sequel/plugins/dirty.rb +3 -9
  40. data/lib/sequel/plugins/empty_failure_backtraces.rb +38 -0
  41. data/lib/sequel/plugins/json_serializer.rb +15 -4
  42. data/lib/sequel/plugins/nested_attributes.rb +7 -0
  43. data/lib/sequel/plugins/sharding.rb +11 -5
  44. data/lib/sequel/plugins/throw_failures.rb +1 -1
  45. data/lib/sequel/plugins/typecast_on_load.rb +3 -2
  46. data/lib/sequel/sql.rb +4 -1
  47. data/lib/sequel/version.rb +1 -1
  48. data/spec/adapters/postgres_spec.rb +82 -17
  49. data/spec/adapters/sqlite_spec.rb +1 -1
  50. data/spec/bin_spec.rb +1 -1
  51. data/spec/core/database_spec.rb +1 -1
  52. data/spec/core/dataset_spec.rb +0 -3
  53. data/spec/core/expression_filters_spec.rb +26 -7
  54. data/spec/core/spec_helper.rb +1 -1
  55. data/spec/core_extensions_spec.rb +1 -1
  56. data/spec/extensions/any_not_empty_spec.rb +23 -0
  57. data/spec/extensions/association_multi_add_remove_spec.rb +1041 -0
  58. data/spec/extensions/caller_logging_spec.rb +1 -1
  59. data/spec/extensions/dirty_spec.rb +33 -0
  60. data/spec/extensions/empty_failure_backtraces_spec.rb +60 -0
  61. data/spec/extensions/exclude_or_null_spec.rb +15 -0
  62. data/spec/extensions/json_serializer_spec.rb +10 -0
  63. data/spec/extensions/named_timezones_spec.rb +5 -5
  64. data/spec/extensions/nested_attributes_spec.rb +48 -0
  65. data/spec/extensions/pg_array_ops_spec.rb +3 -3
  66. data/spec/extensions/pg_json_ops_spec.rb +67 -0
  67. data/spec/extensions/pg_range_spec.rb +35 -21
  68. data/spec/extensions/sharding_spec.rb +8 -0
  69. data/spec/extensions/spec_helper.rb +1 -1
  70. data/spec/guards_helper.rb +1 -1
  71. data/spec/integration/associations_test.rb +1 -1
  72. data/spec/integration/dataset_test.rb +57 -17
  73. data/spec/integration/plugin_test.rb +1 -1
  74. data/spec/integration/schema_test.rb +9 -0
  75. data/spec/integration/spec_helper.rb +7 -1
  76. data/spec/model/plugins_spec.rb +2 -2
  77. data/spec/model/spec_helper.rb +1 -1
  78. data/spec/sequel_warning.rb +1 -0
  79. metadata +35 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7ea0327d7fbbc76458fc9dc6a088069f04bd100b37f91288e9db9f37db84bbb7
4
- data.tar.gz: 6195027a34de796b5109ee2b2ed57407ce9a58f75b1661a3be0ab9b2acbba885
3
+ metadata.gz: 014f4b025465c81d313d8ea8d5591d47165d84ee0e15906d3591992f63830e08
4
+ data.tar.gz: f0d19f67d618a2e7cbdf67b198f218cc765507d9de093934edfe1e30aa641e41
5
5
  SHA512:
6
- metadata.gz: aaa9a71ee0562ccedaeee6144c4764a8024699214dfd4fd7ce46e8a301d8df72f1a709d373f7f5d47c455ff70407b61e1e0bf05ee7f30e20c49a3be51a1bbea2
7
- data.tar.gz: d8343280ef3c09e930df1db0e12eeac349ce23f396fccf1dfcc055a5e760d5dbb50fd5d0a4f8ce591ac4d12644833b9afea6a94fa1b52991c580baba28c26926
6
+ metadata.gz: c1cda2787c781672dba64847f1524c0ae4120f0ee1eb412a9dbf814336941337b71b4bbc4bb481eb7d9fd847646ca657fcb2309f66030d6d51d28e96f787f073
7
+ data.tar.gz: 64a84a203bb795e586ca50f47d9ff865f9162bffae9d5f36c3d3dfc1baa3696f925bd474b2d4c74fc400f77f550c7fb7f74ea29ff4dfac9322db54a3c42a8732
data/CHANGELOG CHANGED
@@ -1,3 +1,61 @@
1
+ === 5.29.0 (2020-02-01)
2
+
3
+ * Recognize another disconnect error in the tinytds adapter (jeremyevans)
4
+
5
+ * Fix verbose warning in postgres adapter when using prepared statements and recent versions of ruby-pg (jeremyevans)
6
+
7
+ * Work correctly on Ruby 2.8+ by supporting second argument for initialize_clone (jeremyevans)
8
+
9
+ * Add empty_failure_backtraces plugin for empty backtraces for ValidationFailed and HookFailed exceptions, much faster on JRuby (jeremyevans)
10
+
11
+ * Add Dataset#json_serializer_opts to json_serializer plugin, allowing to set json_serializer options on a per-dataset basis (jeremyevans)
12
+
13
+ === 5.28.0 (2020-01-01)
14
+
15
+ * Warn when calling Sequel::JDBC::Postgres::Dataset#with_fetch_size (jeremyevans) (#1665)
16
+
17
+ * Add exclude_or_null extension, for filtering datasets where the condition is false or NULL (jeremyevans)
18
+
19
+ * Add any_not_empty extension, for making Dataset#any? without a block mean !empty? (jeremyevans)
20
+
21
+ === 5.27.0 (2019-12-01)
22
+
23
+ * Add Sequel::DEFAULT for a DEFAULT expression, useful for assigning to default values (jeremyevans)
24
+
25
+ * Make Postgres::ArrayOp#join in pg_array_ops extension work correctly on PostgreSQL <9.1 (jeremyevans)
26
+
27
+ * Make pg_enum extension work correctly on PostgreSQL 8.3-9.0 (jeremyevans)
28
+
29
+ * Emulate FILTER clause for aggregate functions using CASE on databases not supporting it directly (jeremyevans)
30
+
31
+ * Support ordering by NULLS FIRST/NULLS LAST without emulation on SQLite 3.30+ (jeremyevans)
32
+
33
+ === 5.26.0 (2019-11-01)
34
+
35
+ * Recognize two additional foreign key constraint violation codes on MySQL 8.0.13+ (rianmcguire) (#1657)
36
+
37
+ * Support table aliases for single-table INSERT statements on PostgreSQL 9.5+ (jeremyevans) (#1656)
38
+
39
+ * Implement Sequel::Postgres::PGRange#hash so instances work correctly in hashes (jeremyevans) (#1648)
40
+
41
+ * Make dirty plugin work correctly with typecast_on_load plugin (jeremyevans) (#1647)
42
+
43
+ * Add support for :require_modification option when setting up nested_attributes (jeremyevans)
44
+
45
+ * Add support for SQL/JSON path expressions to the pg_json_ops extension, supported by PostgreSQL 12+ (jeremyevans)
46
+
47
+ === 5.25.0 (2019-10-01)
48
+
49
+ * Fix Sequel::SQL::NumericMethods#coerce to not raise NoMethodError if super method is not defined (jeremyevans) (#1645)
50
+
51
+ * Allow setting a default for a column that already has a default on Microsoft SQL Server (jeremyevans)
52
+
53
+ * Fix keyword argument separation warnings on Ruby master branch in csv_serializer plugin (jeremyevans)
54
+
55
+ * Add association_multi_add_remove plugin for adding/removing multiple associated objects in a single method call (AlexWayfer, jeremyevans) (#1641, #1643)
56
+
57
+ * Make sharding plugin integrate with server_block extension (jeremyevans)
58
+
1
59
  === 5.24.0 (2019-09-01)
2
60
 
3
61
  * Add Database#skip_logging? private method designed for extensions to force query timing even if no logger is present (adam12) (#1640)
@@ -1,5 +1,5 @@
1
1
  Copyright (c) 2007-2008 Sharon Rosner
2
- Copyright (c) 2008-2019 Jeremy Evans
2
+ Copyright (c) 2008-2020 Jeremy Evans
3
3
 
4
4
  Permission is hereby granted, free of charge, to any person obtaining a copy
5
5
  of this software and associated documentation files (the "Software"), to
@@ -578,7 +578,7 @@ A single model instance can also be fetched by specifying a condition:
578
578
  post = Post.first(title: 'hello world')
579
579
  post = Post.first{num_comments < 10}
580
580
 
581
- The dataset for a model class returns rows a model instances instead of plain hashes:
581
+ The dataset for a model class returns rows of model instances instead of plain hashes:
582
582
 
583
583
  DB[:posts].first.class # => Hash
584
584
  Post.first.class # => Post
@@ -55,6 +55,7 @@ Without a filename argument, the sqlite adapter will setup a new sqlite database
55
55
 
56
56
  dataset.exclude(:active).delete
57
57
  dataset.where{price < 100}.update(:active => true)
58
+ dataset.where(:active).update(:price => Sequel[:price] * 0.90)
58
59
 
59
60
  == Datasets are Enumerable
60
61
 
@@ -341,12 +341,12 @@ Dataset#overriding_system_value and Dataset#overriding_user_value to use this ne
341
341
  syntax:
342
342
 
343
343
  DB.create_table(:table){primary_key :id}
344
- # Ignore the given value for id, using the identity's sequence value
344
+ # Ignore the given value for id, using the identity's sequence value.
345
345
  DB[:table].overriding_user_value.insert(:id=>1)
346
346
 
347
347
  DB.create_table(:table){primary_key :id, :identity=>:always}
348
348
  # Force the use of the given value for id, because otherwise the insert will
349
- # raise an error, since GENERATED ALWAYS was using when creating the column.
349
+ # raise an error, since GENERATED ALWAYS was used when creating the column.
350
350
  DB[:table].overriding_system_value.insert(:id=>1)
351
351
 
352
352
  === Distinct On Specific Columns
@@ -0,0 +1,32 @@
1
+ = New Features
2
+
3
+ * An association_multi_add_remove plugin has been added. This plugin
4
+ adds a shortcut for adding or removing multiple associated objects
5
+ in a single method call:
6
+
7
+ Artist.plugin :association_multi_add_remove
8
+ Artist.many_to_one :albums
9
+ Artist[1].add_albums([Album[2], Album[3]])
10
+ Artist[1].remove_albums([Album[4], Album[5]])
11
+
12
+ It also offers a setter method, which will add and remove associated
13
+ objects as necessary:
14
+
15
+ Artist[1].albums = [Album[3], Album[4]]
16
+
17
+ = Other Improvements
18
+
19
+ * The sharding plugin now integrates with the server_block extension.
20
+ This makes it so if you retrieve a model instance inside a
21
+ with_server block, saving the model instance will save it back to
22
+ the shard from which it was retrieved.
23
+
24
+ * Setting a default for a column on Microsoft SQL Server now works
25
+ correctly if the column already has a default.
26
+
27
+ * Sequel::SQL::NumericMethods#coerce no longer raises NoMethodError
28
+ if the super method is not defined. This fixes some cases when
29
+ comparing Date/DateTime instances to Sequel objects.
30
+
31
+ * The csv_serializer plugin now avoids keyword argument separation
32
+ issues on Ruby 2.7+.
@@ -0,0 +1,35 @@
1
+ = New Features
2
+
3
+ * Support for SQL/JSON path expressions has been added to the
4
+ pg_json_ops extension. These are supported in PostgreSQL 12+.
5
+ Examples:
6
+
7
+ j = Sequel.pg_json_op(:json_column)
8
+ j.path_exists('$.foo') # (jsonb_column @? '$.foo')
9
+ j.path_match('$.foo') # (jsonb_column @@ '$.foo')
10
+ j.path_exists!('$.foo') # jsonb_path_exists(jsonb_column, '$.foo')
11
+ j.path_match!('$.foo') # jsonb_path_match(jsonb_column, '$.foo')
12
+ j.path_query('$.foo') # jsonb_path_query(jsonb_column, '$.foo')
13
+ j.path_query_array('$.foo') # jsonb_path_query_array(jsonb_column, '$.foo')
14
+ j.path_query_first('$.foo') # jsonb_path_query_first(jsonb_column, '$.foo')
15
+
16
+ * The nested_attributes method in the nested_attributes plugin now
17
+ supports a :require_modification option, which can override the
18
+ default require_modification setting for the nested objects. This
19
+ can be useful to avoid errors if multiple requests are submitted
20
+ simultaneously to delete the same nested row.
21
+
22
+ = Other Improvements
23
+
24
+ * The dirty plugin now works correctly with the typecast_on_load
25
+ plugin.
26
+
27
+ * Sequel::Postgres::PGRange#hash has been added to the pg_range
28
+ extension, allowing PGRange instances to be usable as hash keys.
29
+
30
+ * Table aliases are now supported for single table INSERT
31
+ statements on PostgreSQL 9.5+, which can make some insert_conflict
32
+ usage easier.
33
+
34
+ * Two more foreign key constraint violation types are now recognized
35
+ on MySQL 8.0.13+.
@@ -0,0 +1,21 @@
1
+ = New Features
2
+
3
+ * Sequel::DEFAULT has been added a constant for the DEFAULT expression,
4
+ useful in inserts and especially updates:
5
+
6
+ DB[:a].where(:id=>1).update(:b=>Sequel::DEFAULT)
7
+ # UPDATE "a" SET "b" = DEFAULT WHERE "id" = 1
8
+
9
+ * SQL::Function#filter for filtered aggregate functions is now
10
+ supported on all databases. On databases not supporting it natively
11
+ (all except PostgreSQL 9.4+ and SQLite 3.30+), a CASE statement is
12
+ used to emulate the support.
13
+
14
+ = Other Improvements
15
+
16
+ * NULLS FIRST/LAST is now used without emulation on SQLite 3.30+.
17
+
18
+ * The pg_enum extension now works correctly on PostgreSQL 8.3-9.0.
19
+
20
+ * Postgres::ArrayOp#join in the pg_array_ops extension now works
21
+ correctly on PostgreSQL <9.1.
@@ -0,0 +1,16 @@
1
+ = New Features
2
+
3
+ * An any_not_empty extension has been added, for making Dataset#any?
4
+ without a block be the same as !empty?. This can result in a
5
+ much faster database query.
6
+
7
+ * An exclude_or_null extension has been added, adding a
8
+ Dataset#exclude_or_null method that returns rows where the given
9
+ expression is false or NULL. This extension is supported on
10
+ PostgreSQL, SQLite, MySQL, H2, and HSQLDB.
11
+
12
+ = Other Improvements
13
+
14
+ * When using the jdbc/postgresql adapter, calling with_fetch_size
15
+ on a dataset will emit a warning. This is because the driver
16
+ will ignore the setting.
@@ -0,0 +1,22 @@
1
+ = New Features
2
+
3
+ * An empty_failure_backtraces plugin has been added for using empty
4
+ backtraces for ValidationFailed and HookFailed exceptions. In many
5
+ cases, these exceptions are automatically handled (e.g. web form
6
+ submission handling to display appropriate error pages), and using
7
+ empty backtraces is 10-15x faster on JRuby 9.2.7.0+.
8
+
9
+ * Dataset#json_serializer_opts has been added to the json_serializer
10
+ plugin. This allows setting default options on a per-Dataset basis
11
+ for all Dataset#to_json calls.
12
+
13
+ = Other Improvements
14
+
15
+ * Another disconnect error is now recognized in the tinytds adapter.
16
+
17
+ * Using Sequel with the the CRuby master branch (what will be Ruby 3)
18
+ now works by supporting a second argument for
19
+ Dataset#initialize_clone.
20
+
21
+ * Sequel now avoids a warning in verbose mode when using the postgres
22
+ adapter, a recent version of ruby-pg, and bound variables.
@@ -8,17 +8,20 @@ These run each test in its own transaction, the recommended way to test.
8
8
 
9
9
  === minitest/spec
10
10
 
11
- ==== with minitest-hooks
12
-
11
+ ==== with minitest-hooks
13
12
  require 'minitest/hooks/default'
13
+
14
+ DB = Sequel.postgres # change if using sqlite etc
15
+
14
16
  class Minitest::HooksSpec
15
17
  def around
16
18
  DB.transaction(:rollback=>:always, :auto_savepoint=>true){super}
17
19
  end
18
20
  end
19
21
 
20
- ==== without minitest-hooks
21
-
22
+ ==== without minitest-hooks
23
+ DB = Sequel.postgres # change if using sqlite etc
24
+
22
25
  class Minitest::Spec
23
26
  def run(*args, &block)
24
27
  DB.transaction(:rollback=>:always, :auto_savepoint=>true){super}
@@ -26,7 +29,8 @@ These run each test in its own transaction, the recommended way to test.
26
29
  end
27
30
 
28
31
  === minitest/test
29
-
32
+ DB = Sequel.postgres # change if using sqlite etc
33
+
30
34
  # Use this class as the base class for your tests
31
35
  class SequelTestCase < Minitest::Test
32
36
  def run(*args, &block)
@@ -35,7 +39,8 @@ These run each test in its own transaction, the recommended way to test.
35
39
  end
36
40
 
37
41
  === rspec >= 2.8
38
-
42
+ DB = Sequel.postgres # change the database if you are using sqlite etc.
43
+
39
44
  RSpec.configure do |c|
40
45
  c.around(:each) do |example|
41
46
  DB.transaction(:rollback=>:always, :auto_savepoint=>true){example.run}
@@ -180,6 +180,12 @@ module Sequel
180
180
 
181
181
  class Dataset < JDBC::Dataset
182
182
  include Sequel::Postgres::DatasetMethods
183
+
184
+ # Warn when calling as the fetch size is ignored by the JDBC adapter currently.
185
+ def with_fetch_size(size)
186
+ warn("Sequel::JDBC::Postgres::Dataset#with_fetch_size does not currently have an effect.", :uplevel=>1)
187
+ super
188
+ end
183
189
 
184
190
  private
185
191
 
@@ -70,6 +70,10 @@ module Sequel
70
70
  # string names of the server side prepared statement, and values
71
71
  # are SQL strings.
72
72
  attr_reader :prepared_statements
73
+
74
+ unless public_method_defined?(:async_exec_params)
75
+ alias async_exec_params async_exec
76
+ end
73
77
  else
74
78
  # Make postgres-pr look like pg
75
79
  CONNECTION_OK = -1
@@ -149,7 +153,7 @@ module Sequel
149
153
 
150
154
  # Return the PGResult containing the query results.
151
155
  def execute_query(sql, args)
152
- @db.log_connection_yield(sql, self, args){args ? async_exec(sql, args) : async_exec(sql)}
156
+ @db.log_connection_yield(sql, self, args){args ? async_exec_params(sql, args) : async_exec(sql)}
153
157
  end
154
158
  end
155
159
 
@@ -279,7 +279,7 @@ module Sequel
279
279
  end
280
280
  end
281
281
  sqls << "ALTER TABLE #{quote_schema_table(table)} ALTER COLUMN #{column_definition_sql(op)}"
282
- sqls << alter_table_sql(table, op.merge(:op=>:set_column_default, :default=>default)) if default
282
+ sqls << alter_table_sql(table, op.merge(:op=>:set_column_default, :default=>default, :skip_drop_default=>true)) if default
283
283
  sqls
284
284
  when :set_column_null
285
285
  sch = schema(table).find{|k,v| k.to_s == op[:name].to_s}.last
@@ -290,7 +290,9 @@ module Sequel
290
290
  end
291
291
  "ALTER TABLE #{quote_schema_table(table)} ALTER COLUMN #{quote_identifier(op[:name])} #{type_literal(:type=>type)} #{'NOT ' unless op[:null]}NULL"
292
292
  when :set_column_default
293
- "ALTER TABLE #{quote_schema_table(table)} ADD CONSTRAINT #{quote_identifier("sequel_#{table}_#{op[:name]}_def")} DEFAULT #{literal(op[:default])} FOR #{quote_identifier(op[:name])}"
293
+ sqls = []
294
+ add_drop_default_constraint_sql(sqls, table, op[:name]) unless op[:skip_drop_default]
295
+ sqls << "ALTER TABLE #{quote_schema_table(table)} ADD CONSTRAINT #{quote_identifier("sequel_#{table}_#{op[:name]}_def")} DEFAULT #{literal(op[:default])} FOR #{quote_identifier(op[:name])}"
294
296
  else
295
297
  super(table, op)
296
298
  end
@@ -691,7 +691,7 @@ module Sequel
691
691
  end
692
692
 
693
693
  # Return the results of an EXPLAIN query as a string. Options:
694
- # :extended :: Use EXPLAIN EXPTENDED instead of EXPLAIN if true.
694
+ # :extended :: Use EXPLAIN EXTENDED instead of EXPLAIN if true.
695
695
  def explain(opts=OPTS)
696
696
  # Load the PrettyTable class, needed for explain output
697
697
  Sequel.extension(:_pretty_table) unless defined?(Sequel::PrettyTable)
@@ -1806,6 +1806,16 @@ module Sequel
1806
1806
  end
1807
1807
  end
1808
1808
 
1809
+ # Include aliases when inserting into a single table on PostgreSQL 9.5+.
1810
+ def insert_into_sql(sql)
1811
+ sql << " INTO "
1812
+ if (f = @opts[:from]) && f.length == 1
1813
+ identifier_append(sql, server_version >= 90500 ? f.first : unaliased_identifier(f.first))
1814
+ else
1815
+ source_list_append(sql, f)
1816
+ end
1817
+ end
1818
+
1809
1819
  # Return the primary key to use for RETURNING in an INSERT statement
1810
1820
  def insert_pk
1811
1821
  if (f = opts[:from]) && !f.empty?
@@ -1945,6 +1955,11 @@ module Sequel
1945
1955
  db.server_version(@opts[:server])
1946
1956
  end
1947
1957
 
1958
+ # PostgreSQL 9.4+ supports the FILTER clause for aggregate functions.
1959
+ def supports_filtered_aggregates?
1960
+ server_version >= 90400
1961
+ end
1962
+
1948
1963
  # PostgreSQL supports quoted function names.
1949
1964
  def supports_quoted_function_names?
1950
1965
  true
@@ -869,9 +869,9 @@ module Sequel
869
869
  end
870
870
  end
871
871
 
872
- # SQLite does not natively support NULLS FIRST/LAST.
872
+ # SQLite supports NULLS FIRST/LAST natively in 3.30+.
873
873
  def requires_emulating_nulls_first?
874
- true
874
+ db.sqlite_version < 33000
875
875
  end
876
876
 
877
877
  # SQLite does not support FOR UPDATE, but silently ignore it
@@ -897,6 +897,11 @@ module Sequel
897
897
  false
898
898
  end
899
899
 
900
+ # SQLite 3.30 supports the FILTER clause for aggregate functions.
901
+ def supports_filtered_aggregates?
902
+ db.sqlite_version >= 33000
903
+ end
904
+
900
905
  # SQLite supports quoted function names.
901
906
  def supports_quoted_function_names?
902
907
  true
@@ -145,7 +145,7 @@ module Sequel
145
145
 
146
146
  # Return true if the :conn argument is present and not active.
147
147
  def disconnect_error?(e, opts)
148
- super || (opts[:conn] && !opts[:conn].active?) || ((e.is_a?(::TinyTds::Error) && /\A(Attempt to initiate a new Adaptive Server operation with results pending|The request failed to run because the batch is aborted, this can be caused by abort signal sent from client|Adaptive Server connection timed out)/.match(e.message)))
148
+ super || (opts[:conn] && !opts[:conn].active?) || ((e.is_a?(::TinyTds::Error) && /\A(Attempt to initiate a new Adaptive Server operation with results pending|The request failed to run because the batch is aborted, this can be caused by abort signal sent from client|Adaptive Server connection timed out|DBPROCESS is dead or not enabled)/.match(e.message)))
149
149
  end
150
150
 
151
151
  # Dispose of any possible results of execution.
@@ -55,7 +55,7 @@ module Sequel
55
55
  NotNullConstraintViolation
56
56
  when 1062
57
57
  UniqueConstraintViolation
58
- when 1451, 1452
58
+ when 1451, 1452, 1216, 1217
59
59
  ForeignKeyConstraintViolation
60
60
  when 4025
61
61
  CheckConstraintViolation
@@ -126,7 +126,7 @@ module Sequel
126
126
  # :on_update :: Specify the behavior of this column when being updated
127
127
  # (:restrict, :cascade, :set_null, :set_default, :no_action).
128
128
  # :primary_key :: Make the column as a single primary key column. This should not
129
- # be used if you have a single, nonautoincrementing primary key column
129
+ # be used if you want a single autoincrementing primary key column
130
130
  # (use the primary_key method in that case).
131
131
  # :primary_key_constraint_name :: The name to give the primary key constraint
132
132
  # :primary_key_deferrable :: Similar to :deferrable, but for the primary key constraint
@@ -439,13 +439,12 @@ module Sequel
439
439
 
440
440
  # Remove the current thread from the list of active transactions
441
441
  def remove_transaction(conn, committed)
442
+ callbacks = transaction_hooks(conn, committed)
442
443
  if in_savepoint?(conn)
443
444
  savepoint_callbacks = savepoint_hooks(conn, committed)
444
445
  if committed
445
446
  savepoint_rollback_callbacks = savepoint_hooks(conn, false)
446
447
  end
447
- else
448
- callbacks = transaction_hooks(conn, committed)
449
448
  end
450
449
 
451
450
  if transaction_finished?(conn)
@@ -453,7 +452,6 @@ module Sequel
453
452
  rolled_back = !committed
454
453
  Sequel.synchronize{h[:rolled_back] = rolled_back}
455
454
  Sequel.synchronize{@transactions.delete(conn)}
456
- callbacks.each(&:call) if callbacks
457
455
  elsif savepoint_callbacks || savepoint_rollback_callbacks
458
456
  if committed
459
457
  meth = in_savepoint?(conn) ? :add_savepoint_hook : :add_transaction_hook
@@ -473,6 +471,8 @@ module Sequel
473
471
  savepoint_callbacks.each(&:call)
474
472
  end
475
473
  end
474
+
475
+ callbacks.each(&:call) if callbacks
476
476
  end
477
477
 
478
478
  # SQL to rollback to a savepoint