sequel 5.24.0 → 5.29.0

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