sequel 5.33.0 → 5.58.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (191) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +318 -0
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +40 -9
  5. data/doc/association_basics.rdoc +77 -13
  6. data/doc/cheat_sheet.rdoc +13 -5
  7. data/doc/code_order.rdoc +0 -12
  8. data/doc/dataset_filtering.rdoc +2 -2
  9. data/doc/fork_safety.rdoc +84 -0
  10. data/doc/migration.rdoc +12 -6
  11. data/doc/model_plugins.rdoc +1 -1
  12. data/doc/opening_databases.rdoc +15 -3
  13. data/doc/postgresql.rdoc +9 -1
  14. data/doc/querying.rdoc +7 -5
  15. data/doc/release_notes/5.34.0.txt +40 -0
  16. data/doc/release_notes/5.35.0.txt +56 -0
  17. data/doc/release_notes/5.36.0.txt +60 -0
  18. data/doc/release_notes/5.37.0.txt +30 -0
  19. data/doc/release_notes/5.38.0.txt +28 -0
  20. data/doc/release_notes/5.39.0.txt +19 -0
  21. data/doc/release_notes/5.40.0.txt +40 -0
  22. data/doc/release_notes/5.41.0.txt +25 -0
  23. data/doc/release_notes/5.42.0.txt +136 -0
  24. data/doc/release_notes/5.43.0.txt +98 -0
  25. data/doc/release_notes/5.44.0.txt +32 -0
  26. data/doc/release_notes/5.45.0.txt +34 -0
  27. data/doc/release_notes/5.46.0.txt +87 -0
  28. data/doc/release_notes/5.47.0.txt +59 -0
  29. data/doc/release_notes/5.48.0.txt +14 -0
  30. data/doc/release_notes/5.49.0.txt +59 -0
  31. data/doc/release_notes/5.50.0.txt +78 -0
  32. data/doc/release_notes/5.51.0.txt +47 -0
  33. data/doc/release_notes/5.52.0.txt +87 -0
  34. data/doc/release_notes/5.53.0.txt +23 -0
  35. data/doc/release_notes/5.54.0.txt +27 -0
  36. data/doc/release_notes/5.55.0.txt +21 -0
  37. data/doc/release_notes/5.56.0.txt +51 -0
  38. data/doc/release_notes/5.57.0.txt +23 -0
  39. data/doc/release_notes/5.58.0.txt +31 -0
  40. data/doc/sql.rdoc +14 -2
  41. data/doc/testing.rdoc +10 -1
  42. data/doc/transactions.rdoc +0 -8
  43. data/doc/validations.rdoc +1 -1
  44. data/doc/virtual_rows.rdoc +1 -1
  45. data/lib/sequel/adapters/ado/access.rb +1 -1
  46. data/lib/sequel/adapters/ado.rb +17 -17
  47. data/lib/sequel/adapters/amalgalite.rb +3 -5
  48. data/lib/sequel/adapters/ibmdb.rb +2 -2
  49. data/lib/sequel/adapters/jdbc/derby.rb +8 -0
  50. data/lib/sequel/adapters/jdbc/h2.rb +60 -10
  51. data/lib/sequel/adapters/jdbc/hsqldb.rb +6 -0
  52. data/lib/sequel/adapters/jdbc/mysql.rb +4 -4
  53. data/lib/sequel/adapters/jdbc/postgresql.rb +4 -4
  54. data/lib/sequel/adapters/jdbc.rb +29 -19
  55. data/lib/sequel/adapters/mysql.rb +80 -67
  56. data/lib/sequel/adapters/mysql2.rb +54 -49
  57. data/lib/sequel/adapters/odbc.rb +8 -6
  58. data/lib/sequel/adapters/oracle.rb +5 -4
  59. data/lib/sequel/adapters/postgres.rb +27 -29
  60. data/lib/sequel/adapters/shared/access.rb +2 -0
  61. data/lib/sequel/adapters/shared/db2.rb +30 -0
  62. data/lib/sequel/adapters/shared/mssql.rb +84 -7
  63. data/lib/sequel/adapters/shared/mysql.rb +33 -2
  64. data/lib/sequel/adapters/shared/oracle.rb +82 -7
  65. data/lib/sequel/adapters/shared/postgres.rb +158 -20
  66. data/lib/sequel/adapters/shared/sqlanywhere.rb +3 -0
  67. data/lib/sequel/adapters/shared/sqlite.rb +102 -10
  68. data/lib/sequel/adapters/sqlanywhere.rb +1 -1
  69. data/lib/sequel/adapters/sqlite.rb +60 -18
  70. data/lib/sequel/adapters/tinytds.rb +2 -1
  71. data/lib/sequel/adapters/utils/columns_limit_1.rb +22 -0
  72. data/lib/sequel/adapters/utils/mysql_mysql2.rb +2 -1
  73. data/lib/sequel/ast_transformer.rb +6 -0
  74. data/lib/sequel/connection_pool/sharded_single.rb +9 -8
  75. data/lib/sequel/connection_pool/sharded_threaded.rb +10 -10
  76. data/lib/sequel/connection_pool/single.rb +7 -9
  77. data/lib/sequel/connection_pool/threaded.rb +1 -1
  78. data/lib/sequel/core.rb +33 -24
  79. data/lib/sequel/database/connecting.rb +3 -4
  80. data/lib/sequel/database/misc.rb +37 -12
  81. data/lib/sequel/database/query.rb +3 -1
  82. data/lib/sequel/database/schema_generator.rb +50 -53
  83. data/lib/sequel/database/schema_methods.rb +45 -23
  84. data/lib/sequel/database/transactions.rb +9 -6
  85. data/lib/sequel/dataset/actions.rb +61 -8
  86. data/lib/sequel/dataset/features.rb +15 -0
  87. data/lib/sequel/dataset/placeholder_literalizer.rb +3 -7
  88. data/lib/sequel/dataset/prepared_statements.rb +2 -0
  89. data/lib/sequel/dataset/query.rb +114 -11
  90. data/lib/sequel/dataset/sql.rb +172 -46
  91. data/lib/sequel/deprecated.rb +3 -1
  92. data/lib/sequel/exceptions.rb +2 -0
  93. data/lib/sequel/extensions/_pretty_table.rb +1 -2
  94. data/lib/sequel/extensions/any_not_empty.rb +1 -1
  95. data/lib/sequel/extensions/async_thread_pool.rb +438 -0
  96. data/lib/sequel/extensions/blank.rb +8 -0
  97. data/lib/sequel/extensions/columns_introspection.rb +1 -2
  98. data/lib/sequel/extensions/core_refinements.rb +38 -11
  99. data/lib/sequel/extensions/date_arithmetic.rb +36 -24
  100. data/lib/sequel/extensions/date_parse_input_handler.rb +67 -0
  101. data/lib/sequel/extensions/datetime_parse_to_time.rb +5 -1
  102. data/lib/sequel/extensions/duplicate_columns_handler.rb +3 -1
  103. data/lib/sequel/extensions/eval_inspect.rb +2 -0
  104. data/lib/sequel/extensions/inflector.rb +9 -1
  105. data/lib/sequel/extensions/is_distinct_from.rb +139 -0
  106. data/lib/sequel/extensions/migration.rb +13 -2
  107. data/lib/sequel/extensions/named_timezones.rb +5 -1
  108. data/lib/sequel/extensions/pagination.rb +1 -1
  109. data/lib/sequel/extensions/pg_array.rb +1 -0
  110. data/lib/sequel/extensions/pg_array_ops.rb +6 -2
  111. data/lib/sequel/extensions/pg_enum.rb +3 -1
  112. data/lib/sequel/extensions/pg_extended_date_support.rb +2 -2
  113. data/lib/sequel/extensions/pg_hstore.rb +1 -1
  114. data/lib/sequel/extensions/pg_hstore_ops.rb +55 -3
  115. data/lib/sequel/extensions/pg_inet.rb +2 -0
  116. data/lib/sequel/extensions/pg_inet_ops.rb +1 -1
  117. data/lib/sequel/extensions/pg_interval.rb +35 -8
  118. data/lib/sequel/extensions/pg_json.rb +3 -5
  119. data/lib/sequel/extensions/pg_json_ops.rb +119 -4
  120. data/lib/sequel/extensions/pg_loose_count.rb +3 -1
  121. data/lib/sequel/extensions/pg_multirange.rb +372 -0
  122. data/lib/sequel/extensions/pg_range.rb +7 -19
  123. data/lib/sequel/extensions/pg_range_ops.rb +39 -9
  124. data/lib/sequel/extensions/pg_row.rb +1 -1
  125. data/lib/sequel/extensions/pg_row_ops.rb +25 -1
  126. data/lib/sequel/extensions/query.rb +3 -0
  127. data/lib/sequel/extensions/run_transaction_hooks.rb +1 -1
  128. data/lib/sequel/extensions/s.rb +4 -1
  129. data/lib/sequel/extensions/schema_dumper.rb +16 -5
  130. data/lib/sequel/extensions/server_block.rb +8 -12
  131. data/lib/sequel/extensions/sql_comments.rb +110 -3
  132. data/lib/sequel/extensions/sql_log_normalizer.rb +108 -0
  133. data/lib/sequel/extensions/sqlite_json_ops.rb +255 -0
  134. data/lib/sequel/extensions/string_agg.rb +1 -1
  135. data/lib/sequel/extensions/string_date_time.rb +19 -23
  136. data/lib/sequel/extensions/symbol_aref_refinement.rb +2 -0
  137. data/lib/sequel/extensions/symbol_as_refinement.rb +2 -0
  138. data/lib/sequel/extensions/to_dot.rb +9 -3
  139. data/lib/sequel/model/associations.rb +342 -114
  140. data/lib/sequel/model/base.rb +45 -24
  141. data/lib/sequel/model/errors.rb +10 -1
  142. data/lib/sequel/model/inflections.rb +1 -1
  143. data/lib/sequel/model/plugins.rb +8 -3
  144. data/lib/sequel/model.rb +3 -1
  145. data/lib/sequel/plugins/association_pks.rb +60 -18
  146. data/lib/sequel/plugins/association_proxies.rb +3 -0
  147. data/lib/sequel/plugins/async_thread_pool.rb +39 -0
  148. data/lib/sequel/plugins/auto_restrict_eager_graph.rb +62 -0
  149. data/lib/sequel/plugins/auto_validations.rb +39 -5
  150. data/lib/sequel/plugins/auto_validations_constraint_validations_presence_message.rb +68 -0
  151. data/lib/sequel/plugins/blacklist_security.rb +1 -2
  152. data/lib/sequel/plugins/class_table_inheritance.rb +3 -8
  153. data/lib/sequel/plugins/column_encryption.rb +728 -0
  154. data/lib/sequel/plugins/composition.rb +8 -2
  155. data/lib/sequel/plugins/concurrent_eager_loading.rb +174 -0
  156. data/lib/sequel/plugins/constraint_validations.rb +2 -1
  157. data/lib/sequel/plugins/csv_serializer.rb +2 -0
  158. data/lib/sequel/plugins/dataset_associations.rb +4 -1
  159. data/lib/sequel/plugins/dirty.rb +44 -0
  160. data/lib/sequel/plugins/enum.rb +124 -0
  161. data/lib/sequel/plugins/forbid_lazy_load.rb +2 -0
  162. data/lib/sequel/plugins/insert_conflict.rb +4 -0
  163. data/lib/sequel/plugins/instance_specific_default.rb +113 -0
  164. data/lib/sequel/plugins/json_serializer.rb +39 -24
  165. data/lib/sequel/plugins/lazy_attributes.rb +4 -1
  166. data/lib/sequel/plugins/many_through_many.rb +108 -9
  167. data/lib/sequel/plugins/nested_attributes.rb +8 -3
  168. data/lib/sequel/plugins/pg_array_associations.rb +58 -41
  169. data/lib/sequel/plugins/pg_auto_constraint_validations.rb +2 -0
  170. data/lib/sequel/plugins/prepared_statements.rb +15 -12
  171. data/lib/sequel/plugins/prepared_statements_safe.rb +1 -3
  172. data/lib/sequel/plugins/rcte_tree.rb +37 -35
  173. data/lib/sequel/plugins/serialization.rb +9 -3
  174. data/lib/sequel/plugins/serialization_modification_detection.rb +2 -1
  175. data/lib/sequel/plugins/single_table_inheritance.rb +7 -0
  176. data/lib/sequel/plugins/sql_comments.rb +189 -0
  177. data/lib/sequel/plugins/static_cache.rb +1 -1
  178. data/lib/sequel/plugins/string_stripper.rb +1 -1
  179. data/lib/sequel/plugins/subclasses.rb +28 -11
  180. data/lib/sequel/plugins/tactical_eager_loading.rb +8 -2
  181. data/lib/sequel/plugins/timestamps.rb +1 -1
  182. data/lib/sequel/plugins/tree.rb +9 -4
  183. data/lib/sequel/plugins/unused_associations.rb +521 -0
  184. data/lib/sequel/plugins/update_or_create.rb +1 -1
  185. data/lib/sequel/plugins/validation_class_methods.rb +5 -1
  186. data/lib/sequel/plugins/validation_helpers.rb +18 -11
  187. data/lib/sequel/plugins/xml_serializer.rb +1 -1
  188. data/lib/sequel/sql.rb +1 -1
  189. data/lib/sequel/timezones.rb +20 -17
  190. data/lib/sequel/version.rb +1 -1
  191. metadata +93 -39
@@ -0,0 +1,87 @@
1
+ = New Features
2
+
3
+ * When the sql_comments Database extension is used,
4
+ Database#with_comments is now added, which can be used for including
5
+ comments for all queries executed inside a given block. This can
6
+ be useful if you want to analyze database query logs, and want to
7
+ group all related queries:
8
+
9
+ DB.with_comments(model: Album, action: :all) do
10
+ DB[:albums].all
11
+ # SELECT * FROM albums -- model:Album,action:all
12
+ end
13
+
14
+ * An sql_comments plugin has been added, which will automatically
15
+ add SQL comments for all queries generated by model class, instance
16
+ and dataset methods:
17
+
18
+ Album.plugin :sql_comments
19
+
20
+ album = Album[1]
21
+ # SELECT * FROM albums WHERE (id = 1) LIMIT 1
22
+ # -- model:Album,method_type:class,method:[]
23
+
24
+ album.update(:name=>'A')
25
+ # UPDATE albums SET name = 'baz' WHERE (id = 1)
26
+ # -- model:Album,method_type:instance,method:update
27
+
28
+ Album.where(id: 1).delete
29
+ # DELETE FROM albums WHERE (id = 1)
30
+ # -- model:Album,method_type:dataset,method:delete
31
+
32
+ This plugin requires you have loaded the sql_comments Database
33
+ extension into the related Database before use.
34
+
35
+ * A date_parse_input_handler extension has been added to support
36
+ custom handling of input to date parsing methods. Among other
37
+ things, you can use this to limit the length of strings that
38
+ will be parsed, which can prevent ArgumentErrors in newer Ruby
39
+ versions:
40
+
41
+ Sequel.extension :date_parse_input_handler
42
+ Sequel.date_parse_input_handler do |string|
43
+ string.b[0, 128]
44
+ end
45
+
46
+ = Other Improvements
47
+
48
+ * On Ruby 3.1, the core_refinements extension now avoids the
49
+ deprecated Refinement#include, switching to
50
+ Refinement#import_methods.
51
+
52
+ * On Ruby 3.1, the subclasses plugin will use Ruby's native support
53
+ for Class#subclasses.
54
+
55
+ * The subclasses plugin has renamed descendents to descendants and
56
+ freeze_descendents to freeze_descendants. The previous method
57
+ names are still available as aliases.
58
+
59
+ * The :ruby_default schema entry for datetime/timestamp columns now
60
+ respects Sequel.datetime_class. Previously, the value for the
61
+ :ruby_default schema entry would always be a DateTime value for
62
+ such columns.
63
+
64
+ * The pg_interval extension now works with ActiveSupport 7.0.
65
+
66
+ * The shared postgres adapter now respects
67
+ Database#default_string_column_size for setting the size of string
68
+ columns that don't use text as the database type.
69
+
70
+ * Database#supports_check_constraints? now returns true on MySQL
71
+ 8.0.19+. This fixes drop_constraint in certain cases when combining
72
+ the constraint dropping with other changes in the same alter_table
73
+ block.
74
+
75
+ * The mysql adapter now supports the ruby-mysql 3 API (ruby-mysql
76
+ is a pure-ruby MySQL driver).
77
+
78
+ * The mysql adapter no longer uses the connection's server_version
79
+ method if it is defined, as the method does not return the
80
+ correct value when using the ruby-mysql driver with MariaDB.
81
+
82
+ * Comments added by the sql_comments extension no longer modify
83
+ cached SQL for a dataset.
84
+
85
+ = Other
86
+
87
+ * This is Sequel's 250th release!
@@ -0,0 +1,23 @@
1
+ = Improvements
2
+
3
+ * The jdbc/h2 subadapter now supports H2 version 2.0. It continues to
4
+ support H2 versions 1.3 and 1.4.
5
+
6
+ * The mysql2 adapter's prepared statement support now reuses existing
7
+ native prepared statements, instead of only binding variables on
8
+ newly prepared statements. This was the intended behavior
9
+ previously, and should result in increased performance in cases
10
+ where preparing a query takes significant time.
11
+
12
+ * The subclasses plugin now ignores an existing Class#subclasses
13
+ method if it is defined in Ruby. This fixes cases where usage of
14
+ ActiveSupport would break the subclasses plugin.
15
+
16
+ * Database#call_sproc in the jdbc adapter will now always close the
17
+ prepared call it creates. Before, if there was an exception raised
18
+ when setting the arguments for the prepared call, the prepared call
19
+ would not be closed.
20
+
21
+ * A more appropriate error is now issued if you try to use the
22
+ column_encryption plugin to encrypt a column without setting up an
23
+ encryption key.
@@ -0,0 +1,27 @@
1
+ = New Feature
2
+
3
+ * An enum plugin has been added. This plugin allows you to create
4
+ model-level enums, giving names to underlying values of a column.
5
+ For example:
6
+
7
+ Album.plugin :enum
8
+ Album.enum :status_id, good: 1, bad: 2
9
+
10
+ Adds Album#good! and Album#bad! for changing the status_id to 1 or
11
+ 2 respectively. It adds Album#good? and Album#bad? for checking
12
+ whether the status_id is 1 or 2 respectively. It overrides
13
+ Album#status_id to return :good or :bad instead of 1 or 2,
14
+ respectively, and overrides Album#status_id= to accept :good or
15
+ :bad instead of 1 or 2 respectively.
16
+
17
+ Additionally, it adds good and bad dataset methods for filtering
18
+ the model's dataset to records where status_id is 1 or 2
19
+ respectively. It also adds not_good and not_bad dataset methods
20
+ for filtering the model's dataset to records where status_id is not
21
+ 1 or not 2 respectively.
22
+
23
+ You can use :prefix and :suffix options when calling enum to
24
+ add a prefix or suffix to the method names created. You can
25
+ set the :override_accessors option to false to not override
26
+ the accessor methods for the column, and set the :dataset_methods
27
+ option to false to not add dataset methods.
@@ -0,0 +1,21 @@
1
+ = New Features
2
+
3
+ * An auto_restrict_eager_graph plugin has been added for automatically
4
+ disallowing the use of eager_graph with associations using blocks but
5
+ lacking graph_* options. This can prevent potentionally invalid usage,
6
+ as the restrictions added by the block are not used by eager_graph.
7
+
8
+ * The sqlite adapter now supports the :setup_regexp_function
9
+ Database option. This option will define a REGEXP function in the
10
+ database that will allow regexp support in queries, such as:
11
+
12
+ DB[:table].where(column: /(some|pattern)/)
13
+
14
+ Note that this creates a Ruby Regexp object per column value tested,
15
+ so it isn't the most optimal approach.
16
+
17
+ = Other Improvements
18
+
19
+ * Calling dataset aggregate methods such as #max on a model dataset now
20
+ works correctly. Previously, it could fail if called enough times to
21
+ optimize using a placeholder literalizer.
@@ -0,0 +1,51 @@
1
+ = New Features
2
+
3
+ * On SQLite, Database#create_table now supports a :strict option to
4
+ use the STRICT keyword when creating the table. When this option
5
+ is used, SQLite will enforce the types for each column. When using
6
+ this option, you are limited to using the following column types:
7
+ int, integer, real, text, blob, and any (any allows for dynamic
8
+ types).
9
+
10
+ * An sqlite_json_ops extension has been added, providing DSL support
11
+ for JSON functions and operators supported in SQLite 3.38.0. Usage
12
+ is similar to the pg_json_ops extension. First, you create an
13
+ appropriate object:
14
+
15
+ j = Sequel.sqlite_json_op(:json_column)
16
+ # or:
17
+ j = Sequel[:json_column].sqlite_json_op
18
+
19
+ Then, you call methods on that object to create expressions for the
20
+ JSON functions and operators:
21
+
22
+ j[1] # (json_column ->> 1)
23
+ j.get_text(1) # (json_column -> 1)
24
+ j.extract('$.a') # json_extract(json_column, '$.a')
25
+
26
+ j.array_length # json_array_length(json_column)
27
+ j.type # json_type(json_column)
28
+ j.valid # json_valid(json_column)
29
+ j.json # json(json_column)
30
+
31
+ j.insert('$.a', 1) # json_insert(json_column, '$.a', 1)
32
+ j.set('$.a', 1) # json_set(json_column, '$.a', 1)
33
+ j.replace('$.a', 1) # json_replace(json_column, '$.a', 1)
34
+ j.remove('$.a') # json_remove(json_column, '$.a')
35
+ j.patch('{"a":2}') # json_patch(json_column, '{"a":2}')
36
+
37
+ j.each # json_each(json_column)
38
+ j.tree # json_tree(json_column)
39
+
40
+ = Other Improvements
41
+
42
+ * The alter_table add_column and add_foreign_key methods now support
43
+ the :index option to create an index on the added column, for
44
+ compatibility with the :index option on the create_table column and
45
+ foreign_key methods.
46
+
47
+ * The schema_dumper extension now treats the "INTEGER" type the same
48
+ as the "integer" type. This fixes some behavior when using SQLite
49
+ 3.37.0+.
50
+
51
+ * Sequel's website has a much improved visual design.
@@ -0,0 +1,23 @@
1
+ = New Features
2
+
3
+ * An is_distinct_from extension has been added with support for the
4
+ SQL IS DISTINCT FROM operator. This operator is similar to the
5
+ not equals operator, except in terms of NULL handling. It returns
6
+ true if only one side is NULL, and false if both sides are NULL.
7
+ You can call is_distinct_from on Sequel itself or on Sequel objects:
8
+
9
+ Sequel.is_distinct_from(:column_a, :column_b)
10
+ Sequel[:column_a].is_distinct_from(:column_b)
11
+ # (column_a IS DISTINCT FROM column_b)
12
+
13
+ On databases not supporting IS DISTINCT FROM, support is emulated
14
+ using a CASE statement.
15
+
16
+ * Column definitions on MySQL can use the :on_update_current_timestamp
17
+ option for ON UPDATE CURRENT_TIMESTAMP, which creates a column that
18
+ will automatically have its value set to CURRENT_TIMESTAMP on every
19
+ update.
20
+
21
+ * Database#create_function on PostgreSQL now supports a :parallel
22
+ option to set the thread safety of the funciton. The value should
23
+ be :safe, :unsafe, or :restricted.
@@ -0,0 +1,31 @@
1
+ = New Features
2
+
3
+ * Dataset#merge and related #merge_* methods have been added for the
4
+ MERGE statement. MERGE is supported on PostgreSQL 15+, Oracle,
5
+ Microsoft SQL Server, DB2, H2, HSQLDB, and Derby. You can use MERGE
6
+ to insert, update, and/or delete in a single query. You call
7
+ the #merge_* methods to setup the MERGE statement, and #merge to
8
+ execute it on the database:
9
+
10
+ ds = DB[:m1]
11
+ merge_using(:m2, i1: :i2).
12
+ merge_insert(i1: :i2, a: Sequel[:b]+11).
13
+ merge_delete{a > 30}.
14
+ merge_update(i1: Sequel[:i1]+:i2+10, a: Sequel[:a]+:b+20)
15
+
16
+ ds.merge
17
+ # MERGE INTO m1 USING m2 ON (i1 = i2)
18
+ # WHEN NOT MATCHED THEN INSERT (i1, a) VALUES (i2, (b + 11))
19
+ # WHEN MATCHED AND (a > 30) THEN DELETE
20
+ # WHEN MATCHED THEN UPDATE SET i1 = (i1 + i2 + 10), a = (a + b + 20)
21
+
22
+ On PostgreSQL, the following additional MERGE related methods are
23
+ available:
24
+
25
+ * #merge_do_nothing_when_matched
26
+ * #merge_do_nothing_when_not_matched
27
+
28
+ * A :disable_split_materialized Database option is now supported on
29
+ MySQL. This disables split_materialized support in the optimizer,
30
+ working around a bug in MariaDB 10.5+ that causes failures in
31
+ Sequel's association tests.
data/doc/sql.rdoc CHANGED
@@ -428,6 +428,18 @@ As you can see, these literalize with ANDs by default. You can use the <tt>Sequ
428
428
 
429
429
  Sequel.or(column1: 1, column2: 2) # (("column1" = 1) OR ("column2" = 2))
430
430
 
431
+ As you can see in the above examples, <tt>Sequel.|</tt> and <tt>Sequel.or</tt> work differently.
432
+ <tt>Sequel.|</tt> is for combining an arbitrary number of expressions using OR. If you pass a single
433
+ argument, <tt>Sequel.|</tt> will just convert it to a Sequel expression, similar to <tt>Sequel.expr</tt>.
434
+ <tt>Sequel.or</tt> is for taking a single hash or array of two element arrays and combining the
435
+ elements of that single argument using OR instead of AND:
436
+
437
+ Sequel.|(column1: 1, column2: 2) # (("column1" = 1) AND ("column2" = 2))
438
+ Sequel.or(column1: 1, column2: 2) # (("column1" = 1) OR ("column2" = 2))
439
+
440
+ Sequel.|({column1: 1}, {column2: 2}) # (("column1" = 1) OR ("column2" = 2))
441
+ Sequel.or({column1: 1}, {column2: 2}) # ArgumentError
442
+
431
443
  You've already seen the <tt>Sequel.negate</tt> method, which will use ANDs if multiple entries are used:
432
444
 
433
445
  Sequel.negate(column1: 1, column2: 2) # (("column1" != 1) AND ("column2" != 2))
@@ -516,7 +528,7 @@ Inverting the LIKE operator works like other inversions:
516
528
 
517
529
  ~Sequel.like(:name, 'A%') # ("name" NOT LIKE 'A%' ESCAPE '\')
518
530
 
519
- Sequel also supports SQL regular expressions on MySQL and PostgreSQL. You can use these by passing a Ruby regular expression to +like+ or +ilike+, or by making the regular expression a hash value:
531
+ Sequel also supports SQL regular expressions on MySQL and PostgreSQL (and SQLite when using the sqlite adapter with the :setup_regexp_function Database option). You can use these by passing a Ruby regular expression to +like+ or +ilike+, or by making the regular expression a hash value:
520
532
 
521
533
  Sequel.like(:name, /^A/) # ("name" ~ '^A')
522
534
  ~Sequel.ilike(:name, /^A/) # ("name" !~* '^A')
@@ -544,7 +556,7 @@ On some databases, you can specify null ordering:
544
556
 
545
557
  === All Columns (.*)
546
558
 
547
- To select all columns in a table, Sequel supports the * method on identifiers and qualified without an argument:
559
+ To select all columns in a table, Sequel supports the * method on identifiers and qualified identifiers without an argument:
548
560
 
549
561
  Sequel[:table].* # "table".*
550
562
  Sequel[:schema][:table].* # "schema"."table".*
data/doc/testing.rdoc CHANGED
@@ -113,7 +113,7 @@ The order in which you delete/truncate the tables is important if you are using
113
113
 
114
114
  = Testing Sequel Itself
115
115
 
116
- Sequel has multiple separate test suites. All test suites use minitest/spec, with the minitest-hooks and minitest-shared_description extensions.
116
+ Sequel has multiple separate test suites. All test suites use minitest/spec, with the minitest-hooks and minitest-global_expectations extensions. To install the dependencies necessary to test Sequel, run <tt>gem install --development sequel</tt>.
117
117
 
118
118
  == rake
119
119
 
@@ -145,6 +145,8 @@ The <tt>spec_<i>adapter</i></tt> specs run against a real database connection wi
145
145
 
146
146
  These specs are broken down into two parts. For each database, there are specific specs that only apply to that database, and these are called the adapter specs. There are also shared specs that apply to all (or almost all) databases, these are called the integration specs. For database types that don't have specific adapter tests, you can use <tt>rake spec_integration</tt> to just run the shared integration tests.
147
147
 
148
+ Each adapter needs a specific gem installed in order to run. Please see the {connecting to a database guide}[rdoc-ref:doc/opening_databases.rdoc] for which gem you need to install for the adapter you are testing.
149
+
148
150
  == Environment variables
149
151
 
150
152
  Sequel uses environment variables when testing to specify either the database to be tested or specify how testing should be done. You can also specify the databases to test by copying <tt>spec/spec_config.rb.example</tt> to <tt>spec/spec_config.rb</tt> and modifying it. See that file for details. It may be necessary to use +spec_config.rb+ as opposed to an environment variable if your database connection cannot be specified by a connection string.
@@ -157,9 +159,12 @@ The SEQUEL_INTEGRATION_URL environment variable specifies the Database connectio
157
159
 
158
160
  === Other
159
161
 
162
+ SEQUEL_ASYNC_THREAD_POOL :: Use the async_thread_pool extension when running the specs
163
+ SEQUEL_ASYNC_THREAD_POOL_PREEMPT :: Use the async_thread_pool extension when running the specs, with the :preempt_async_thread option
160
164
  SEQUEL_COLUMNS_INTROSPECTION :: Use the columns_introspection extension when running the specs
161
165
  SEQUEL_CONNECTION_VALIDATOR :: Use the connection validator extension when running the specs
162
166
  SEQUEL_DUPLICATE_COLUMNS_HANDLER :: Use the duplicate columns handler extension with value given when running the specs
167
+ SEQUEL_CONCURRENT_EAGER_LOADING :: Use the async_thread_pool extension and concurrent_eager_loading plugin when running the specs
163
168
  SEQUEL_ERROR_SQL :: Use the error_sql extension when running the specs
164
169
  SEQUEL_INDEX_CACHING :: Use the index_caching extension when running the specs
165
170
  SEQUEL_FIBER_CONCURRENCY :: Use the fiber_concurrency extension when running the adapter and integration specs
@@ -172,6 +177,10 @@ SEQUEL_NO_CACHE_ASSOCIATIONS :: Don't cache association metadata when running th
172
177
  SEQUEL_CHECK_PENDING :: Try running all specs (note, can cause lockups for some adapters), and raise errors for skipped specs that don't fail
173
178
  SEQUEL_NO_PENDING :: Don't skip any specs, try running all specs (note, can cause lockups for some adapters)
174
179
  SEQUEL_PG_TIMESTAMPTZ :: Use the pg_timestamptz extension when running the postgres specs
180
+ SEQUEL_QUERY_PER_ASSOCIATION_DB_0_URL :: Run query-per-association integration tests with multiple databases (all 4 must be set to run)
181
+ SEQUEL_QUERY_PER_ASSOCIATION_DB_1_URL :: Run query-per-association integration tests with multiple databases (all 4 must be set to run)
182
+ SEQUEL_QUERY_PER_ASSOCIATION_DB_2_URL :: Run query-per-association integration tests with multiple databases (all 4 must be set to run)
183
+ SEQUEL_QUERY_PER_ASSOCIATION_DB_3_URL :: Run query-per-association integration tests with multiple databases (all 4 must be set to run)
175
184
  SEQUEL_SPLIT_SYMBOLS :: Turn on symbol splitting when running the adapter and integration specs
176
185
  SEQUEL_SYNCHRONIZE_SQL :: Use the synchronize_sql extension when running the specs
177
186
  SEQUEL_TZINFO_VERSION :: Force the given tzinfo version when running the specs (e.g. '>=2')
@@ -143,14 +143,6 @@ If you want the current savepoint to be rolled back when the savepoint block exi
143
143
  end # RELEASE SAVEPOINT
144
144
  end # COMMIT
145
145
 
146
- If you want the current savepoint to be rolled back when the savepoint block exits (even if an exception is not raised), use <tt>Database#rollback_on_exit(:savepoint=>true)</tt>
147
-
148
- DB.transaction do # BEGIN
149
- DB.transaction(savepoint: true) do # SAVEPOINT
150
- DB.rollback_on_exit(:savepoint=>true)
151
- end # ROLLBACK TO SAVEPOINT
152
- end # COMMIT
153
-
154
146
  If you want the current savepoint and potentially enclosing savepoints to be rolled back when the savepoint blocks exit (even if an exception is not raised), use <tt>Database#rollback_on_exit(:savepoint=>integer)</tt>
155
147
 
156
148
  DB.transaction do # BEGIN
data/doc/validations.rdoc CHANGED
@@ -232,7 +232,7 @@ These methods check that the specified attributes can be valid integers or valid
232
232
 
233
233
  === +validates_operator+
234
234
 
235
- +validates_operator+ checks that a given +operator+ method returns a truthy value when called on attribute with a specified value for comparison. Generally, this is used for inequality checks (>, >=, etc) but any method that can be called on the attribute that accepts an argument and returns a truthy value may be used.
235
+ +validates_operator+ checks that a given +operator+ method returns a truthy value when called on attribute with a specified value for comparison. Generally, this is used for inequality checks (>, >=, etc.) but any method that can be called on the attribute that accepts an argument and returns a truthy value may be used.
236
236
 
237
237
  class Album < Sequel::Model
238
238
  def validate
@@ -54,7 +54,7 @@ methods in the surrounding scope. For example:
54
54
 
55
55
  # Regular block
56
56
  ds.where{|o| o.c > a - b + @d}
57
- # WHERE (c > 100)
57
+ # WHERE (c > 110)
58
58
 
59
59
  # Instance-evaled block
60
60
  ds.where{c > a - b + @d}
@@ -318,7 +318,7 @@ module Sequel
318
318
  conn.OpenSchema(ado_schema.type, ado_schema.criteria)
319
319
  end
320
320
  }
321
- yield(r) if block_given?
321
+ yield(r) if defined?(yield)
322
322
  rescue ::WIN32OLERuntimeError => e
323
323
  raise_error(e)
324
324
  end
@@ -161,7 +161,7 @@ module Sequel
161
161
  begin
162
162
  r = log_connection_yield(sql, conn){conn.Execute(sql)}
163
163
  begin
164
- yield r if block_given?
164
+ yield r if defined?(yield)
165
165
  ensure
166
166
  begin
167
167
  r.close
@@ -195,10 +195,25 @@ module Sequel
195
195
  end
196
196
 
197
197
  @conversion_procs = CONVERSION_PROCS.dup
198
+ @conversion_procs[AdDBTimeStamp] = method(:adb_timestamp_to_application_timestamp)
198
199
 
199
200
  super
200
201
  end
201
202
 
203
+ def adb_timestamp_to_application_timestamp(v)
204
+ # This hard codes a timestamp_precision of 6 when converting.
205
+ # That is the default timestamp_precision, but the ado/mssql adapter uses a timestamp_precision
206
+ # of 3. However, timestamps returned by ado/mssql have nsec values that end up rounding to a
207
+ # the same value as if a timestamp_precision of 3 was hard coded (either xxx999yzz, where y is
208
+ # 5-9 or xxx000yzz where y is 0-4).
209
+ #
210
+ # ADO subadapters should override this they would like a different timestamp precision and the
211
+ # this code does not work for them (for example, if they provide full nsec precision).
212
+ #
213
+ # Note that fractional second handling for WIN32OLE objects is not correct on ruby <2.2
214
+ to_application_timestamp([v.year, v.month, v.day, v.hour, v.min, v.sec, (v.nsec/1000.0).round * 1000])
215
+ end
216
+
202
217
  def dataset_class_default
203
218
  Dataset
204
219
  end
@@ -233,23 +248,8 @@ module Sequel
233
248
  cols = []
234
249
  conversion_procs = db.conversion_procs
235
250
 
236
- ts_cp = nil
237
251
  recordset.Fields.each do |field|
238
- type = field.Type
239
- cp = if type == AdDBTimeStamp
240
- ts_cp ||= begin
241
- nsec_div = 1000000000.0/(10**(timestamp_precision))
242
- nsec_mul = 10**(timestamp_precision+3)
243
- meth = db.method(:to_application_timestamp)
244
- lambda do |v|
245
- # Fractional second handling is not correct on ruby <2.2
246
- meth.call([v.year, v.month, v.day, v.hour, v.min, v.sec, (v.nsec/nsec_div).round * nsec_mul])
247
- end
248
- end
249
- else
250
- conversion_procs[type]
251
- end
252
- cols << [output_identifier(field.Name), cp]
252
+ cols << [output_identifier(field.Name), conversion_procs[field.Type]]
253
253
  end
254
254
 
255
255
  self.columns = cols.map(&:first)
@@ -118,11 +118,9 @@ module Sequel
118
118
  # Yield an available connection. Rescue
119
119
  # any Amalgalite::Errors and turn them into DatabaseErrors.
120
120
  def _execute(sql, opts)
121
- begin
122
- synchronize(opts[:server]){|conn| yield conn}
123
- rescue ::Amalgalite::Error, ::Amalgalite::SQLite3::Error => e
124
- raise_error(e)
125
- end
121
+ synchronize(opts[:server]){|conn| yield conn}
122
+ rescue ::Amalgalite::Error, ::Amalgalite::SQLite3::Error => e
123
+ raise_error(e)
126
124
  end
127
125
 
128
126
  # The Amagalite adapter does not need the pool to convert exceptions.
@@ -246,7 +246,7 @@ module Sequel
246
246
  end
247
247
  begin
248
248
  stmt = log_connection_yield(log_sql, conn, args){conn.execute_prepared(ps_name, *args)}
249
- if block_given?
249
+ if defined?(yield)
250
250
  yield(stmt)
251
251
  else
252
252
  stmt.affected
@@ -268,7 +268,7 @@ module Sequel
268
268
  # is given or returning the number of affected rows if not, and ensuring the statement is freed.
269
269
  def _execute(conn, sql, opts)
270
270
  stmt = log_connection_yield(sql, conn){conn.execute(sql)}
271
- if block_given?
271
+ if defined?(yield)
272
272
  yield(stmt)
273
273
  else
274
274
  stmt.affected
@@ -2,6 +2,7 @@
2
2
 
3
3
  Sequel::JDBC.load_driver('org.apache.derby.jdbc.EmbeddedDriver', :Derby)
4
4
  require_relative 'transactions'
5
+ require_relative '../utils/columns_limit_1'
5
6
 
6
7
  module Sequel
7
8
  module JDBC
@@ -182,6 +183,8 @@ module Sequel
182
183
  end
183
184
 
184
185
  class Dataset < JDBC::Dataset
186
+ include ::Sequel::Dataset::ColumnsLimit1
187
+
185
188
  # Derby doesn't support an expression between CASE and WHEN,
186
189
  # so remove conditions.
187
190
  def case_expression_sql_append(sql, ce)
@@ -232,6 +235,11 @@ module Sequel
232
235
  false
233
236
  end
234
237
 
238
+ # Derby 10.11+ supports MERGE.
239
+ def supports_merge?
240
+ db.svn_version >= 1616546
241
+ end
242
+
235
243
  # Derby does not support IN/NOT IN with multiple columns
236
244
  def supports_multiple_column_in?
237
245
  false
@@ -24,6 +24,7 @@ module Sequel
24
24
 
25
25
  def freeze
26
26
  h2_version
27
+ version2?
27
28
  super
28
29
  end
29
30
 
@@ -140,13 +141,36 @@ module Sequel
140
141
  DATABASE_ERROR_REGEXPS
141
142
  end
142
143
 
143
- # Use IDENTITY() to get the last inserted id.
144
+ def execute_statement_insert(stmt, sql)
145
+ stmt.executeUpdate(sql, JavaSQL::Statement::RETURN_GENERATED_KEYS)
146
+ end
147
+
148
+ def prepare_jdbc_statement(conn, sql, opts)
149
+ opts[:type] == :insert ? conn.prepareStatement(sql, JavaSQL::Statement::RETURN_GENERATED_KEYS) : super
150
+ end
151
+
152
+ # Get the last inserted id using getGeneratedKeys, scope_identity, or identity.
144
153
  def last_insert_id(conn, opts=OPTS)
145
- statement(conn) do |stmt|
146
- sql = 'SELECT IDENTITY();'
147
- rs = log_connection_yield(sql, conn){stmt.executeQuery(sql)}
148
- rs.next
149
- rs.getLong(1)
154
+ if stmt = opts[:stmt]
155
+ rs = stmt.getGeneratedKeys
156
+ begin
157
+ if rs.next
158
+ begin
159
+ rs.getLong(1)
160
+ rescue
161
+ rs.getObject(1) rescue nil
162
+ end
163
+ end
164
+ ensure
165
+ rs.close
166
+ end
167
+ elsif !version2?
168
+ statement(conn) do |stmt|
169
+ sql = 'SELECT IDENTITY()'
170
+ rs = log_connection_yield(sql, conn){stmt.executeQuery(sql)}
171
+ rs.next
172
+ rs.getLong(1)
173
+ end
150
174
  end
151
175
  end
152
176
 
@@ -161,7 +185,12 @@ module Sequel
161
185
 
162
186
  # Use BIGINT IDENTITY for identity columns that use :Bignum type
163
187
  def type_literal_generic_bignum_symbol(column)
164
- column[:identity] ? 'BIGINT IDENTITY' : super
188
+ column[:identity] ? 'BIGINT AUTO_INCREMENT' : super
189
+ end
190
+
191
+ def version2?
192
+ return @version2 if defined?(@version2)
193
+ @version2 = h2_version.to_i >= 2
165
194
  end
166
195
  end
167
196
 
@@ -200,6 +229,11 @@ module Sequel
200
229
  false
201
230
  end
202
231
 
232
+ # H2 supports MERGE
233
+ def supports_merge?
234
+ true
235
+ end
236
+
203
237
  # H2 doesn't support multiple columns in IN/NOT IN
204
238
  def supports_multiple_column_in?
205
239
  false
@@ -209,9 +243,21 @@ module Sequel
209
243
 
210
244
  # H2 expects hexadecimal strings for blob values
211
245
  def literal_blob_append(sql, v)
212
- sql << "'" << v.unpack("H*").first << "'"
246
+ if db.send(:version2?)
247
+ super
248
+ else
249
+ sql << "'" << v.unpack("H*").first << "'"
250
+ end
251
+ end
252
+
253
+ def literal_false
254
+ 'FALSE'
213
255
  end
214
256
 
257
+ def literal_true
258
+ 'TRUE'
259
+ end
260
+
215
261
  # H2 handles fractional seconds in timestamps, but not in times
216
262
  def literal_sqltime(v)
217
263
  v.strftime("'%H:%M:%S'")
@@ -223,8 +269,12 @@ module Sequel
223
269
  end
224
270
 
225
271
  def select_only_offset_sql(sql)
226
- sql << " LIMIT -1 OFFSET "
227
- literal_append(sql, @opts[:offset])
272
+ if db.send(:version2?)
273
+ super
274
+ else
275
+ sql << " LIMIT -1 OFFSET "
276
+ literal_append(sql, @opts[:offset])
277
+ end
228
278
  end
229
279
 
230
280
  # H2 supports quoted function names.
@@ -179,6 +179,12 @@ module Sequel
179
179
  true
180
180
  end
181
181
 
182
+ # HSQLDB 2.3.4+ supports MERGE. Older versions also support MERGE, but not all
183
+ # features that are in Sequel's tests.
184
+ def supports_merge?
185
+ db.db_version >= 20304
186
+ end
187
+
182
188
  private
183
189
 
184
190
  def empty_from_sql
@@ -1,15 +1,15 @@
1
1
  # frozen-string-literal: true
2
2
 
3
- Sequel::JDBC.load_driver('com.mysql.jdbc.Driver', :MySQL)
4
- require_relative '../shared/mysql'
5
-
6
3
  module Sequel
7
4
  module JDBC
5
+ driver = Sequel::JDBC.load_driver(%w'com.mysql.cj.jdbc.Driver com.mysql.jdbc.Driver', :MySQL)
6
+ require_relative '../shared/mysql'
7
+
8
8
  Sequel.synchronize do
9
9
  DATABASE_SETUP[:mysql] = proc do |db|
10
10
  db.extend(Sequel::JDBC::MySQL::DatabaseMethods)
11
11
  db.extend_datasets Sequel::MySQL::DatasetMethods
12
- com.mysql.jdbc.Driver
12
+ driver
13
13
  end
14
14
  end
15
15