sequel 5.83.0 → 5.84.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/sequel/adapters/shared/sqlite.rb +3 -1
- data/lib/sequel/database/connecting.rb +1 -1
- data/lib/sequel/database/misc.rb +8 -3
- data/lib/sequel/database/schema_methods.rb +2 -0
- data/lib/sequel/extensions/pg_json_ops.rb +328 -1
- data/lib/sequel/sql.rb +8 -5
- data/lib/sequel/version.rb +1 -1
- metadata +2 -236
- data/CHANGELOG +0 -1393
- data/README.rdoc +0 -936
- data/doc/advanced_associations.rdoc +0 -884
- data/doc/association_basics.rdoc +0 -1859
- data/doc/bin_sequel.rdoc +0 -146
- data/doc/cheat_sheet.rdoc +0 -255
- data/doc/code_order.rdoc +0 -104
- data/doc/core_extensions.rdoc +0 -405
- data/doc/dataset_basics.rdoc +0 -96
- data/doc/dataset_filtering.rdoc +0 -222
- data/doc/extensions.rdoc +0 -77
- data/doc/fork_safety.rdoc +0 -84
- data/doc/mass_assignment.rdoc +0 -98
- data/doc/migration.rdoc +0 -660
- data/doc/model_dataset_method_design.rdoc +0 -129
- data/doc/model_hooks.rdoc +0 -254
- data/doc/model_plugins.rdoc +0 -270
- data/doc/mssql_stored_procedures.rdoc +0 -43
- data/doc/object_model.rdoc +0 -563
- data/doc/opening_databases.rdoc +0 -439
- data/doc/postgresql.rdoc +0 -611
- data/doc/prepared_statements.rdoc +0 -144
- data/doc/querying.rdoc +0 -1070
- data/doc/reflection.rdoc +0 -120
- data/doc/release_notes/5.0.0.txt +0 -159
- data/doc/release_notes/5.1.0.txt +0 -31
- data/doc/release_notes/5.10.0.txt +0 -84
- data/doc/release_notes/5.11.0.txt +0 -83
- data/doc/release_notes/5.12.0.txt +0 -141
- data/doc/release_notes/5.13.0.txt +0 -27
- data/doc/release_notes/5.14.0.txt +0 -63
- data/doc/release_notes/5.15.0.txt +0 -39
- data/doc/release_notes/5.16.0.txt +0 -110
- data/doc/release_notes/5.17.0.txt +0 -31
- data/doc/release_notes/5.18.0.txt +0 -69
- data/doc/release_notes/5.19.0.txt +0 -28
- data/doc/release_notes/5.2.0.txt +0 -33
- data/doc/release_notes/5.20.0.txt +0 -89
- data/doc/release_notes/5.21.0.txt +0 -87
- data/doc/release_notes/5.22.0.txt +0 -48
- data/doc/release_notes/5.23.0.txt +0 -56
- data/doc/release_notes/5.24.0.txt +0 -56
- data/doc/release_notes/5.25.0.txt +0 -32
- data/doc/release_notes/5.26.0.txt +0 -35
- data/doc/release_notes/5.27.0.txt +0 -21
- data/doc/release_notes/5.28.0.txt +0 -16
- data/doc/release_notes/5.29.0.txt +0 -22
- data/doc/release_notes/5.3.0.txt +0 -121
- data/doc/release_notes/5.30.0.txt +0 -20
- data/doc/release_notes/5.31.0.txt +0 -148
- data/doc/release_notes/5.32.0.txt +0 -46
- data/doc/release_notes/5.33.0.txt +0 -24
- data/doc/release_notes/5.34.0.txt +0 -40
- data/doc/release_notes/5.35.0.txt +0 -56
- data/doc/release_notes/5.36.0.txt +0 -60
- data/doc/release_notes/5.37.0.txt +0 -30
- data/doc/release_notes/5.38.0.txt +0 -28
- data/doc/release_notes/5.39.0.txt +0 -19
- data/doc/release_notes/5.4.0.txt +0 -80
- data/doc/release_notes/5.40.0.txt +0 -40
- data/doc/release_notes/5.41.0.txt +0 -25
- data/doc/release_notes/5.42.0.txt +0 -136
- data/doc/release_notes/5.43.0.txt +0 -98
- data/doc/release_notes/5.44.0.txt +0 -32
- data/doc/release_notes/5.45.0.txt +0 -34
- data/doc/release_notes/5.46.0.txt +0 -87
- data/doc/release_notes/5.47.0.txt +0 -59
- data/doc/release_notes/5.48.0.txt +0 -14
- data/doc/release_notes/5.49.0.txt +0 -59
- data/doc/release_notes/5.5.0.txt +0 -61
- data/doc/release_notes/5.50.0.txt +0 -78
- data/doc/release_notes/5.51.0.txt +0 -47
- data/doc/release_notes/5.52.0.txt +0 -87
- data/doc/release_notes/5.53.0.txt +0 -23
- data/doc/release_notes/5.54.0.txt +0 -27
- data/doc/release_notes/5.55.0.txt +0 -21
- data/doc/release_notes/5.56.0.txt +0 -51
- data/doc/release_notes/5.57.0.txt +0 -23
- data/doc/release_notes/5.58.0.txt +0 -31
- data/doc/release_notes/5.59.0.txt +0 -73
- data/doc/release_notes/5.6.0.txt +0 -31
- data/doc/release_notes/5.60.0.txt +0 -22
- data/doc/release_notes/5.61.0.txt +0 -43
- data/doc/release_notes/5.62.0.txt +0 -132
- data/doc/release_notes/5.63.0.txt +0 -33
- data/doc/release_notes/5.64.0.txt +0 -50
- data/doc/release_notes/5.65.0.txt +0 -21
- data/doc/release_notes/5.66.0.txt +0 -24
- data/doc/release_notes/5.67.0.txt +0 -32
- data/doc/release_notes/5.68.0.txt +0 -61
- data/doc/release_notes/5.69.0.txt +0 -26
- data/doc/release_notes/5.7.0.txt +0 -108
- data/doc/release_notes/5.70.0.txt +0 -35
- data/doc/release_notes/5.71.0.txt +0 -21
- data/doc/release_notes/5.72.0.txt +0 -33
- data/doc/release_notes/5.73.0.txt +0 -66
- data/doc/release_notes/5.74.0.txt +0 -45
- data/doc/release_notes/5.75.0.txt +0 -35
- data/doc/release_notes/5.76.0.txt +0 -86
- data/doc/release_notes/5.77.0.txt +0 -63
- data/doc/release_notes/5.78.0.txt +0 -67
- data/doc/release_notes/5.79.0.txt +0 -28
- data/doc/release_notes/5.8.0.txt +0 -170
- data/doc/release_notes/5.80.0.txt +0 -40
- data/doc/release_notes/5.81.0.txt +0 -31
- data/doc/release_notes/5.82.0.txt +0 -61
- data/doc/release_notes/5.83.0.txt +0 -56
- data/doc/release_notes/5.9.0.txt +0 -99
- data/doc/schema_modification.rdoc +0 -679
- data/doc/security.rdoc +0 -443
- data/doc/sharding.rdoc +0 -286
- data/doc/sql.rdoc +0 -648
- data/doc/testing.rdoc +0 -204
- data/doc/thread_safety.rdoc +0 -15
- data/doc/transactions.rdoc +0 -250
- data/doc/validations.rdoc +0 -558
- data/doc/virtual_rows.rdoc +0 -265
@@ -1,60 +0,0 @@
|
|
1
|
-
= New Features
|
2
|
-
|
3
|
-
* Dataset#with_ties has been added on PostgreSQL 13+ and Microsoft
|
4
|
-
SQL Server, which will have a limited dataset also return all
|
5
|
-
rows with the same order as the final row.
|
6
|
-
|
7
|
-
* In the pg_json_ops extension, the following methods have been
|
8
|
-
added to Postgres::JSONBOp, all of which require PostgreSQL 13+:
|
9
|
-
|
10
|
-
* #set_lax
|
11
|
-
* #path_exists_tz!
|
12
|
-
* #path_match_tz!
|
13
|
-
* #path_query_tz
|
14
|
-
* #path_query_array_tz
|
15
|
-
* #path_query_first_tz
|
16
|
-
|
17
|
-
* On Oracle, the Database#view_exists? method now accepts a
|
18
|
-
:current_schema option to limit the views returned to the
|
19
|
-
current schema, instead of all non-system schemas.
|
20
|
-
|
21
|
-
= Other Improvements
|
22
|
-
|
23
|
-
* Sequel will now pass keyword arguments through in the following
|
24
|
-
cases:
|
25
|
-
|
26
|
-
* When loading plugins (Model.plugin)
|
27
|
-
|
28
|
-
* Class methods automically defined for methods defined in a
|
29
|
-
Model.dataset_module block
|
30
|
-
|
31
|
-
* Methods defined by Plugins.def_dataset_method
|
32
|
-
|
33
|
-
* Database methods called inside migrations
|
34
|
-
|
35
|
-
* Methods called via an association proxy when using the
|
36
|
-
association_proxies plugin.
|
37
|
-
|
38
|
-
* Dataset methods called inside a Dataset#query block when using
|
39
|
-
the query extension.
|
40
|
-
|
41
|
-
Previously, keywords were not handled in these cases, which would
|
42
|
-
cause deprecation warnings in Ruby 2.7 and ArgumentErrors in Ruby
|
43
|
-
3.0. Note that Sequel itself does not use keyword arguments at
|
44
|
-
all, so all of these changes only affect cases where external
|
45
|
-
methods are defined that accept keywords, and Sequel methods are
|
46
|
-
called with keywords that end up being delegated to the external
|
47
|
-
methods.
|
48
|
-
|
49
|
-
* The odbc adapter will now stream result sets instead of loading
|
50
|
-
the entire result set in memory and then iterating over it.
|
51
|
-
|
52
|
-
* Sequel now recognizes another disconnect error in the mysql and
|
53
|
-
mysql2 adapters.
|
54
|
-
|
55
|
-
= Backwards Compatibility
|
56
|
-
|
57
|
-
* Due to the odbc adapter change to use streaming, issuing queries
|
58
|
-
inside a Dataset#each block will no longer work unless a different
|
59
|
-
shard or thread is used. The behavior of such code is considered
|
60
|
-
undefined on all Sequel adapters.
|
@@ -1,30 +0,0 @@
|
|
1
|
-
= New Features
|
2
|
-
|
3
|
-
* Model#column_previously_was and #column_previously_changed? have
|
4
|
-
been added to the dirty plugin, for getting the previous values
|
5
|
-
of the column before saving and for whether there were changes
|
6
|
-
before saving.
|
7
|
-
|
8
|
-
Model#column_previously_changed? accepts :from and :to options
|
9
|
-
to allow you to more easily determine if the value changed from
|
10
|
-
and/or to specific values.
|
11
|
-
|
12
|
-
This information was previously obtainable via
|
13
|
-
Model#previous_changes, but these new methods offer a friendlier
|
14
|
-
interface.
|
15
|
-
|
16
|
-
* Postgres::PGRow::{Array,Hash}Row#op has been added to the
|
17
|
-
pg_row_ops extension if the pg_row extension is loaded. This
|
18
|
-
is similar to how the pg_array_ops, pg_hstore_ops, and
|
19
|
-
pg_json_ops and #op method to their objects. This makes it
|
20
|
-
easier to perform row operations on literal rows.
|
21
|
-
|
22
|
-
= Other Improvements
|
23
|
-
|
24
|
-
* The schema_dumper extension now supports more unsigned numeric
|
25
|
-
types, such as "decimal(7,2) unsigned" and "real unsigned".
|
26
|
-
|
27
|
-
* IntegerMigrator now raises an Migrator::Error if attempting to
|
28
|
-
migrate down when there are migration files missing and needed for
|
29
|
-
the down migration. Previously, IntegerMigrator would not raise an
|
30
|
-
exception and would make no database changes in this case.
|
@@ -1,28 +0,0 @@
|
|
1
|
-
= New Features
|
2
|
-
|
3
|
-
* The jdbc/mysql adapter now supports the newer
|
4
|
-
com.mysql.cj.jdbc.Driver driver. The adapter will still attempt to
|
5
|
-
load the older com.mysql.jdbc.Driver if the com.mysql.cj.jdbc.Driver
|
6
|
-
is not found.
|
7
|
-
|
8
|
-
= Other Improvements
|
9
|
-
|
10
|
-
* When testing a connection after creating a new Database instance
|
11
|
-
raises an exception, the Database instance is removed from
|
12
|
-
Sequel::DATABASES.
|
13
|
-
|
14
|
-
* The single_table_inheritance and prepared_statements plugins now
|
15
|
-
work correctly if loaded into the same class.
|
16
|
-
|
17
|
-
* Database connect and disconnect errors are no longer swallowed when
|
18
|
-
calling Database#create_or_replace_view, Database#server_version
|
19
|
-
on PostgreSQL, or Database#create_table* on Oracle.
|
20
|
-
|
21
|
-
= Backwards Compatibility
|
22
|
-
|
23
|
-
* Previously, instantiating a new Database instance directly using
|
24
|
-
Sequel::Database.new did not test the connection by default. That
|
25
|
-
was instead handled by Sequel::Database.connect. The test
|
26
|
-
connection now happens inside Database#initialize. This should only
|
27
|
-
affect backwards compatibility for code that is calling
|
28
|
-
Sequel::Database.new directly.
|
@@ -1,19 +0,0 @@
|
|
1
|
-
= New Features
|
2
|
-
|
3
|
-
* On Microsoft SQL Server, the :clustered option is now supported
|
4
|
-
for primary key and unique constraints. You can use a true value
|
5
|
-
for CLUSTERED and a false value for NONCLUSTERED.
|
6
|
-
|
7
|
-
= Other Improvements
|
8
|
-
|
9
|
-
* Partitioned tables are now included in the result of
|
10
|
-
Database#tables on PostgreSQL.
|
11
|
-
|
12
|
-
* alter_table set_column_allow_null no longer drops the size of
|
13
|
-
binary columns on Microsoft SQL Server.
|
14
|
-
|
15
|
-
* In the tree plugin, the roots_dataset method now works correctly
|
16
|
-
with queries using joins by qualifying the parent column.
|
17
|
-
|
18
|
-
* A fork safety guide has been added, discussing fork safety issues
|
19
|
-
when using Sequel.
|
data/doc/release_notes/5.4.0.txt
DELETED
@@ -1,80 +0,0 @@
|
|
1
|
-
= New Features
|
2
|
-
|
3
|
-
* An index_caching extension has been added, which makes
|
4
|
-
Database#indexes use a cache similar to Database#schema, and also
|
5
|
-
offers methods for saving and loading the cache from a file, similar
|
6
|
-
to the schema_caching extension.
|
7
|
-
|
8
|
-
This can speed up model loaded in certain cases when the
|
9
|
-
auto_validations plugin is used.
|
10
|
-
|
11
|
-
* A datetime_parse_to_time extension has been added, which parses
|
12
|
-
strings without timezone offsets using DateTime.parse intead of
|
13
|
-
Time.parse. This can fix problems when the string being parsed
|
14
|
-
represents a time not valid in the local timezone due to daylight
|
15
|
-
savings time shifts. Time.parse silently shifts such times by 1
|
16
|
-
hour instead of raising an exception, resulting in incorrect
|
17
|
-
behavior in that case.
|
18
|
-
|
19
|
-
It only makes sense to use this extension when the times in the
|
20
|
-
database are stored in UTC but not returned with timezone
|
21
|
-
information, the timezone for the Database instance
|
22
|
-
(or Sequel.database_timezone) is set to :utc (not the default),
|
23
|
-
and Time is used as the datetime_class (the default).
|
24
|
-
|
25
|
-
* A pg_timestamptz extension has been added for switching the default
|
26
|
-
generic timestamp type from timestamp to timestamptz.
|
27
|
-
|
28
|
-
* Sequel.date_{add,sub} in the date_arithmetic extension now supports
|
29
|
-
a :cast option for setting the cast type. This value defaults to
|
30
|
-
Time for backwards compatibility, which uses the default generic
|
31
|
-
timestamp type for the database.
|
32
|
-
|
33
|
-
* The class_table_inheritance plugin now supports an
|
34
|
-
:ignore_subclass_columns option which takes an array of column
|
35
|
-
symbols to ignore in subclasses. This allows you to use
|
36
|
-
the plugin when your table inheritance hierarchy includes
|
37
|
-
non-primary key columns with the same name in different tables.
|
38
|
-
|
39
|
-
= Improvements
|
40
|
-
|
41
|
-
* Dataset#insert_select now returns false instead of nil if it runs
|
42
|
-
an INSERT statement but does not return a value on Microsoft SQL
|
43
|
-
Server or PostgreSQL. This can happen on both databases if triggers
|
44
|
-
are used.
|
45
|
-
|
46
|
-
Model#save now checks for a false value returned by
|
47
|
-
Dataset#insert_select, and does not issue another INSERT statement
|
48
|
-
in that case.
|
49
|
-
|
50
|
-
* Database#indexes now correctly handles SQL::Identifier arguments on
|
51
|
-
SQLite, Microsoft SQL Server, SQLAnywhere, and DB2.
|
52
|
-
|
53
|
-
* Dataset#to_json in the json_serializer plugin and Dataset#to_xml
|
54
|
-
in the xml_serializer plugin now both handle datasets that use
|
55
|
-
eager_graph.
|
56
|
-
|
57
|
-
* Dataset#nullify now caches the dataset it returns, for better
|
58
|
-
performance if it is called more than once on the same dataset.
|
59
|
-
|
60
|
-
* Database#synchronize is now optimized on ruby 2.5+ and is about
|
61
|
-
10% faster by relying on the new lazy proc allocation feature.
|
62
|
-
|
63
|
-
= Backwards Compatibility
|
64
|
-
|
65
|
-
* Fractional second timestamps are now enabled on DB2. If you are
|
66
|
-
connecting to a DB2 database that does not support fractional
|
67
|
-
seconds, you should add the following code (where DB is your
|
68
|
-
Sequel::Database instance):
|
69
|
-
|
70
|
-
DB.extend_datasets do
|
71
|
-
def supports_timestamp_usecs?
|
72
|
-
false
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
* Calling a filtering method with no argument and a virtual row
|
77
|
-
block that returns nil on a dataset with no existing filter now
|
78
|
-
adds a WHERE NULL filter, to match the behavior if given a nil
|
79
|
-
argument. Previously, a deprecation warning was issued and a
|
80
|
-
dataset with no filter was returned.
|
@@ -1,40 +0,0 @@
|
|
1
|
-
= New Features
|
2
|
-
|
3
|
-
* On SQLite 3.33.0+, the UPDATE FROM syntax is now supported. This
|
4
|
-
allows you to update one table based on a join to another table.
|
5
|
-
The SQLite syntax is based on the PostgreSQL syntax, and the
|
6
|
-
Sequel API is the same for both. You need to pass multiple tables
|
7
|
-
to Dataset#from. The first table is the table to update, and the
|
8
|
-
remaining tables are used to construct the UPDATE FROM clause:
|
9
|
-
|
10
|
-
DB[:a, :b].where{{a[:c]=>b[:d]}}.update(:e=>'f')
|
11
|
-
# UPDATE a SET e = 'f' FROM b WHERE (a.c = b.d)
|
12
|
-
|
13
|
-
Unlike PostgreSQL, SQLite does not support the deletion of joined
|
14
|
-
datasets. Related to this, the following methods for testing
|
15
|
-
database support for modifying joined datasets have been added:
|
16
|
-
|
17
|
-
* supports_updating_joins?
|
18
|
-
* supports_deleting_joins?
|
19
|
-
|
20
|
-
= Other Improvements
|
21
|
-
|
22
|
-
* The pg_interval and date_arithmetic extensions now support
|
23
|
-
ActiveSupport 6.1.
|
24
|
-
|
25
|
-
* Sequel no longer issues method redefinition warnings in verbose
|
26
|
-
mode. As Ruby 3 has dropped uninitialized instance variable
|
27
|
-
warnings, Sequel is now verbose warning free on Ruby 3.
|
28
|
-
|
29
|
-
= Backwards Compatibility
|
30
|
-
|
31
|
-
* Trying to truncate or insert into a joined dataset now correctly
|
32
|
-
raises an exception even if the joined dataset supports updates.
|
33
|
-
|
34
|
-
* The private Dataset#check_modification_allowed! method is now
|
35
|
-
deprecated, and users (custom adapters) should now switch to one
|
36
|
-
of the more specific methods introduced in this version:
|
37
|
-
|
38
|
-
* check_insert_allowed!
|
39
|
-
* check_update_allowed!
|
40
|
-
* check_delete_allowed!
|
@@ -1,25 +0,0 @@
|
|
1
|
-
= New Features
|
2
|
-
|
3
|
-
* The validation methods added by the validation_helpers plugin now
|
4
|
-
support the :skip_invalid option, which will not add a validation
|
5
|
-
error on a column if it already has a validation error. This can
|
6
|
-
be useful if you want to avoid having duplicate errors.
|
7
|
-
|
8
|
-
* The auto_validations plugin now supports a :skip_invalid plugin
|
9
|
-
option, which will pass the :skip_invalid option when calling
|
10
|
-
validation methods.
|
11
|
-
|
12
|
-
= Other Improvements
|
13
|
-
|
14
|
-
* The :adder, :remover, and :clearer association options now
|
15
|
-
support keyword arguments in Ruby 2.7+.
|
16
|
-
|
17
|
-
* In the pg_interval extension, Sequel now uses the same number of
|
18
|
-
seconds per month and seconds per year as active_support. It
|
19
|
-
originally used the same number, but active_support changed the
|
20
|
-
values in active_support 5.1. Sequel now uses the active_support
|
21
|
-
values if they are available.
|
22
|
-
|
23
|
-
* When adding a String column on PostgreSQL, an explicit text: true
|
24
|
-
option now takes precedence over an explicit :size option, as it
|
25
|
-
does in Sequel's default behavior.
|
@@ -1,136 +0,0 @@
|
|
1
|
-
= New Features
|
2
|
-
|
3
|
-
* An async_thread_pool Database extension has been added, which
|
4
|
-
executes queries and processes results using a separate thread
|
5
|
-
pool. This allows you do do things like:
|
6
|
-
|
7
|
-
foos = DB[:foos].async.all
|
8
|
-
bars = DB[:bars].async.select_map(:name)
|
9
|
-
foo_bars = DB[:foo_bars].async.each{|x| p x}
|
10
|
-
|
11
|
-
and have the three method calls (all, select_map, and each)
|
12
|
-
execute concurrently. On Ruby implementations without a global
|
13
|
-
VM lock, such as JRuby, it will allow for parallel execution of
|
14
|
-
the method calls. On CRuby, the main benefit will be for cases
|
15
|
-
where query execution takes a long time or there is significant
|
16
|
-
latency between the application and the database.
|
17
|
-
|
18
|
-
When you call a method on foos, bars, or foo_bars, if the thread
|
19
|
-
pool hasn't finished processing the method, the calling code will
|
20
|
-
block until the method call has finished.
|
21
|
-
|
22
|
-
By default, for consistency, calling code will not preempt the
|
23
|
-
async thread pool. For example, if you do:
|
24
|
-
|
25
|
-
DB[:foos].async.all.size
|
26
|
-
|
27
|
-
The calling code will always wait for the async thread pool to
|
28
|
-
run the all method, and then the calling code will call size on
|
29
|
-
the result. This ensures that async queries will not use the
|
30
|
-
same connection as the the calling thread, even if calling thread
|
31
|
-
has a connection checked out.
|
32
|
-
|
33
|
-
In some cases, such as when the async thread pool is very busy,
|
34
|
-
preemption is desired for performance reasons. If you set the
|
35
|
-
:preempt_async_thread Database option before loading the
|
36
|
-
async_thread_pool extension, preemption will be allowed. With
|
37
|
-
preemption allowed, if the async thread pool has not started the
|
38
|
-
processing of the method at the time the calling code needs the
|
39
|
-
results of the method, the calling code will preempt the async
|
40
|
-
thread pool, and run the method on the current thread.
|
41
|
-
|
42
|
-
By default, the async thread pool uses the same number of threads as
|
43
|
-
the Database objects :max_connections attribute (the default for
|
44
|
-
that is 4). You can modify the number of async threads by setting
|
45
|
-
the :num_async_threads Database option before loading the Database
|
46
|
-
async_thread_pool extension.
|
47
|
-
|
48
|
-
Most Dataset methods that execute queries on the database and return
|
49
|
-
results will operate asynchronously if the the dataset is set to be
|
50
|
-
asynchronous via the Dataset#async method. This includes most
|
51
|
-
methods available due to the inclusion in Enumerable, even if not
|
52
|
-
defined by Dataset itself.
|
53
|
-
|
54
|
-
There are multiple caveats when using the async_thread_pool
|
55
|
-
extension:
|
56
|
-
|
57
|
-
* Asynchronous behavior is harder to understand and harder to
|
58
|
-
debug. It would be wise to only use this support in cases where
|
59
|
-
it provides is significant performance benefit.
|
60
|
-
|
61
|
-
* Dataset methods executed asynchronously will use a separate
|
62
|
-
database connection than the calling thread, so they will not
|
63
|
-
respect transactions in the calling thread, or other cases where
|
64
|
-
the calling thread checks out a connection directly using
|
65
|
-
Database#synchronize. They will also not respect the use of
|
66
|
-
Database#with_server (from the server_block extension) in the
|
67
|
-
calling thread.
|
68
|
-
|
69
|
-
* Dataset methods executed asynchronously should never ignore their
|
70
|
-
return value. Code such as:
|
71
|
-
|
72
|
-
DB[:table].async.insert(1)
|
73
|
-
|
74
|
-
is probablematic because without storing the return value, you
|
75
|
-
have no way to block until the insert has been completed.
|
76
|
-
|
77
|
-
* The returned object for Dataset methods executed asynchronously is
|
78
|
-
a proxy object (promise). So you should never do:
|
79
|
-
|
80
|
-
row = DB[:table].async.first
|
81
|
-
# ...
|
82
|
-
if row
|
83
|
-
end
|
84
|
-
|
85
|
-
# or:
|
86
|
-
|
87
|
-
bool = DB[:table].async.get(:boolean_column)
|
88
|
-
# ...
|
89
|
-
if bool
|
90
|
-
end
|
91
|
-
|
92
|
-
because the if branches will always be taken as row and bool will
|
93
|
-
never be nil or false. If you want to get the underlying value,
|
94
|
-
call itself on the proxy object (or __value if using Ruby <2.2).
|
95
|
-
|
96
|
-
For the same reason, you should not use the proxy objects directly
|
97
|
-
in case expressions or as arguments to Class#===. Use itself or
|
98
|
-
__value in those cases.
|
99
|
-
|
100
|
-
* Dataset methods executed asynchronously that include blocks have the
|
101
|
-
block executed asynchronously as well, assuming that the method
|
102
|
-
calls the block. Because these blocks are executed in a separate
|
103
|
-
thread, you cannot use control flow modifiers such as break or
|
104
|
-
return in them.
|
105
|
-
|
106
|
-
* An async_thread_pool model plugin has been added. This requires the
|
107
|
-
async_thread_pool extension has been loaded into the model's Database
|
108
|
-
object, and allows you to call Model.async instead of
|
109
|
-
Model.dataset.async. It also adds async support to the destroy,
|
110
|
-
with_pk, and with_pk! model dataset methods.
|
111
|
-
|
112
|
-
* Model#to_json_data has been added to the json_serializer plugin, for
|
113
|
-
returning a hash of data that can be converted to JSON, instead of
|
114
|
-
a JSON string.
|
115
|
-
|
116
|
-
* A :reject_nil option has been added to the nested_attributes method
|
117
|
-
in the nested_attributes plugin. This will ignore calls to the
|
118
|
-
nested attributes setter method where nil is passed as the setter
|
119
|
-
method argument.
|
120
|
-
|
121
|
-
= Other Improvements
|
122
|
-
|
123
|
-
* Model#freeze now works in case where model validation modifies the
|
124
|
-
object beyond adding errors.
|
125
|
-
|
126
|
-
* Model#freeze in the composition, serialization, and
|
127
|
-
serialization_modification_detection plugins now works in cases
|
128
|
-
where validation would end up loading the composed or
|
129
|
-
serialized values.
|
130
|
-
|
131
|
-
* Database#extension now avoids a possible thread safety issue that
|
132
|
-
could result in the extension being loaded into the Database twice.
|
133
|
-
|
134
|
-
* The ado adapter now supports overriding the timestamp conversion
|
135
|
-
proc. Previously, unlike other conversion procs, the timestamp
|
136
|
-
conversion proc was hard coded and could not be overridden.
|
@@ -1,98 +0,0 @@
|
|
1
|
-
= New Features
|
2
|
-
|
3
|
-
* A column_encryption plugin has been added to support encrypting the
|
4
|
-
content of individual columns in a table.
|
5
|
-
|
6
|
-
Column values are encrypted with AES-256-GCM using a per-value
|
7
|
-
cipher key derived from a key provided in the configuration using
|
8
|
-
HMAC-SHA256.
|
9
|
-
|
10
|
-
If you would like to support encryption of columns in more than one
|
11
|
-
model, you should probably load the plugin into the parent class of
|
12
|
-
your models and specify the keys:
|
13
|
-
|
14
|
-
Sequel::Model.plugin :column_encryption do |enc|
|
15
|
-
enc.key 0, ENV["SEQUEL_COLUMN_ENCRYPTION_KEY"]
|
16
|
-
end
|
17
|
-
|
18
|
-
This specifies a single master encryption key. Unless you are
|
19
|
-
actively rotating keys, it is best to use a single master key.
|
20
|
-
|
21
|
-
In the above call, 0 is the id of the key, and
|
22
|
-
ENV["SEQUEL_COLUMN_ENCRYPTION_KEY"] is the content of the key, which
|
23
|
-
must be a string with exactly 32 bytes. As indicated, this key
|
24
|
-
should not be hardcoded or otherwise committed to the source control
|
25
|
-
repository.
|
26
|
-
|
27
|
-
For models that need encrypted columns, you load the plugin again,
|
28
|
-
but specify the columns to encrypt:
|
29
|
-
|
30
|
-
ConfidentialModel.plugin :column_encryption do |enc|
|
31
|
-
enc.column :encrypted_column_name
|
32
|
-
enc.column :searchable_column_name, searchable: true
|
33
|
-
enc.column :ci_searchable_column_name, searchable: :case_insensitive
|
34
|
-
end
|
35
|
-
|
36
|
-
With this, all three specified columns (encrypted_column_name,
|
37
|
-
searchable_column_name, and ci_searchable_column_name) will be
|
38
|
-
marked as encrypted columns. When you run the following code:
|
39
|
-
|
40
|
-
ConfidentialModel.create(
|
41
|
-
encrypted_column_name: 'These',
|
42
|
-
searchable_column_name: 'will be',
|
43
|
-
ci_searchable_column_name: 'Encrypted'
|
44
|
-
)
|
45
|
-
|
46
|
-
It will save encrypted versions to the database.
|
47
|
-
encrypted_column_name will not be searchable, searchable_column_name
|
48
|
-
will be searchable with an exact match, and
|
49
|
-
ci_searchable_column_name will be searchable with a case insensitive
|
50
|
-
match.
|
51
|
-
|
52
|
-
To search searchable encrypted columns, use with_encrypted_value.
|
53
|
-
This example code will return the model instance created in the code
|
54
|
-
example in the previous section:
|
55
|
-
|
56
|
-
ConfidentialModel.
|
57
|
-
with_encrypted_value(:searchable_column_name, "will be")
|
58
|
-
with_encrypted_value(:ci_searchable_column_name, "encrypted").
|
59
|
-
first
|
60
|
-
|
61
|
-
To rotate encryption keys, add a new key above the existing key,
|
62
|
-
with a new key ID:
|
63
|
-
|
64
|
-
Sequel::Model.plugin :column_encryption do |enc|
|
65
|
-
enc.key 1, ENV["SEQUEL_COLUMN_ENCRYPTION_KEY"]
|
66
|
-
enc.key 0, ENV["SEQUEL_OLD_COLUMN_ENCRYPTION_KEY"]
|
67
|
-
end
|
68
|
-
|
69
|
-
Newly encrypted data will then use the new key. Records encrypted
|
70
|
-
with the older key will still be decrypted correctly.
|
71
|
-
|
72
|
-
To force reencryption for existing records that are using the older
|
73
|
-
key, you can use the needing_reencryption dataset method and the
|
74
|
-
reencrypt instance method. For a small number of records, you can
|
75
|
-
probably do:
|
76
|
-
|
77
|
-
ConfidentialModel.needing_reencryption.all(&:reencrypt)
|
78
|
-
|
79
|
-
With more than a small number of records, you'll want to do this in
|
80
|
-
batches. It's possible you could use an approach such as:
|
81
|
-
|
82
|
-
ds = ConfidentialModel.needing_reencryption.limit(100)
|
83
|
-
true until ds.all(&:reencrypt).empty?
|
84
|
-
|
85
|
-
After all values have been reencrypted for all models, and no models
|
86
|
-
use the older encryption key, you can remove it from the
|
87
|
-
configuration:
|
88
|
-
|
89
|
-
Sequel::Model.plugin :column_encryption do |enc|
|
90
|
-
enc.key 1, ENV["SEQUEL_COLUMN_ENCRYPTION_KEY"]
|
91
|
-
end
|
92
|
-
|
93
|
-
The column_encryption plugin supports encrypting serialized data,
|
94
|
-
as well as enforcing uniquenss of searchable encrypted columns
|
95
|
-
(in the absence of key rotation). By design, it does not support
|
96
|
-
compression, mixing encrypted and unencrypted data in the same
|
97
|
-
column, or support arbitrary encryption ciphers. See the plugin
|
98
|
-
documentation for more details.
|
@@ -1,32 +0,0 @@
|
|
1
|
-
= New Features
|
2
|
-
|
3
|
-
* A concurrent_eager_loading plugin has been added. This plugin
|
4
|
-
builds on top of the async_thread_pool Database extension and
|
5
|
-
allows eager loading multiple associations concurrently in
|
6
|
-
separate threads. With this plugin, you can mark datasets for
|
7
|
-
concurrent eager loading using eager_load_concurrently:
|
8
|
-
|
9
|
-
Album.eager_load_concurrently.eager(:artist, :genre, :tracks).all
|
10
|
-
|
11
|
-
Datasets that are marked for concurrent eager loading will use
|
12
|
-
concurrent eager loading if they are eager loading more than one
|
13
|
-
association. If you would like to make concurrent eager loading
|
14
|
-
the default, you can load the plugin with the :always option.
|
15
|
-
|
16
|
-
All of the association types that ship with Sequel now support
|
17
|
-
concurrent eager loading when using this plugin. For custom eager
|
18
|
-
loaders using the :eager_loader association option, please see the
|
19
|
-
documentation for the plugin for how to enable custom eager loading
|
20
|
-
for them.
|
21
|
-
|
22
|
-
= Other Improvements
|
23
|
-
|
24
|
-
* The date_arithmetic extension now handles ActiveSupport::Duration
|
25
|
-
values with weeks, as well as :weeks as a key in a hash value. Weeks
|
26
|
-
are converted into 7 days internally.
|
27
|
-
|
28
|
-
* The shared SQLite adapter now emulates the dropping of non-composite
|
29
|
-
unique constraints. Non-composite unique constraints are now
|
30
|
-
treated similarly to composite unique constraints, in that dropping
|
31
|
-
any unique constraints on a table will drop all unique constraints
|
32
|
-
on that table.
|
@@ -1,34 +0,0 @@
|
|
1
|
-
= New Features
|
2
|
-
|
3
|
-
* A auto_validations_constraint_validations_presence_message plugin
|
4
|
-
has been added that provides integration for the auto_validations
|
5
|
-
and constraint_validations plugin in the following conditions:
|
6
|
-
|
7
|
-
* The column has a NOT NULL constraint
|
8
|
-
* The column has a presence constraint validation with both
|
9
|
-
the :message and :allow_nil options used.
|
10
|
-
|
11
|
-
In this case, when saving a nil value in the column, the plugin
|
12
|
-
will make it so the more specific message from the presence
|
13
|
-
constraint validation is used, instead of the generic message
|
14
|
-
from auto_validations.
|
15
|
-
|
16
|
-
= Other Improvements
|
17
|
-
|
18
|
-
* On SQLite 3.35.0+, Sequel now uses ALTER TABLE DROP COLUMN for
|
19
|
-
dropping columns, instead of emulating the dropped column by
|
20
|
-
recreating the table.
|
21
|
-
|
22
|
-
* The Dataset#with :materialized option is now supported on SQLite
|
23
|
-
3.35.0+ for specifying whether common table expressions should be
|
24
|
-
materialized.
|
25
|
-
|
26
|
-
* The odbc adapter now correct handles boolean columns with NULL
|
27
|
-
values. Previously, such values were returned as false instead
|
28
|
-
of nil.
|
29
|
-
|
30
|
-
= Backwards Compatibility
|
31
|
-
|
32
|
-
* The change to use ALTER TABLE DROP COLUMN on SQLite 3.35.0+ can
|
33
|
-
cause backwards compatibility issues if SQLite 3.35.0+ does
|
34
|
-
not allow dropping the column.
|
@@ -1,87 +0,0 @@
|
|
1
|
-
= New Features
|
2
|
-
|
3
|
-
* An unused_associations plugin has been added, which allows you to
|
4
|
-
determine which associations and association methods are not used.
|
5
|
-
You can use this to avoid defining the unused associations and
|
6
|
-
association methods, which can save memory.
|
7
|
-
|
8
|
-
This plugin is supported on Ruby 2.5+, and uses method coverage to
|
9
|
-
determine if the plugin's methods are called. Because Sequel::Model
|
10
|
-
adds association methods to an anonymous module included in the
|
11
|
-
class, directly using the method coverage data to determine which
|
12
|
-
associations are used is challenging.
|
13
|
-
|
14
|
-
This plugin is mostly designed for reporting. You can have a
|
15
|
-
test suite that runs with method coverage enabled, and use the
|
16
|
-
coverage information to get data on unused associations:
|
17
|
-
|
18
|
-
# Calls Coverage.result
|
19
|
-
cov_data = Sequel::Model.update_associations_coverage
|
20
|
-
unused_associations_data = Sequel::Model.update_unused_associations_data(coverage_data: cov_data)
|
21
|
-
Sequel::Model.unused_associations(unused_associations_data: unused_associations_data)
|
22
|
-
# => [["Class1", "assoc1"], ...]
|
23
|
-
|
24
|
-
unused_associations returns an array of two element arrays, where
|
25
|
-
the first element is the class name and the second element is the
|
26
|
-
association name. The returned values will be associations where
|
27
|
-
all of the association methods are not used.
|
28
|
-
|
29
|
-
In addition to determining which associations are not used, you can
|
30
|
-
also use this to determine if you are defining association methods
|
31
|
-
that are not used:
|
32
|
-
|
33
|
-
Sequel::Model.unused_association_options(unused_associations_data: unused_associations_data)
|
34
|
-
# => [["Class2", "assoc2", {:read_only=>true}], ...]
|
35
|
-
|
36
|
-
unused_association_options is similar to unused_associations, but
|
37
|
-
returns an array of three element arrays, where the third element
|
38
|
-
is a hash of association options that should be used to avoid
|
39
|
-
defining the unused association methods. It's common in Sequel to
|
40
|
-
define associations and only use them for reading data and not for
|
41
|
-
modifications, and you can use this to easily see which associations
|
42
|
-
are only used for reading data.
|
43
|
-
|
44
|
-
As the determination of whether associations are used is based on
|
45
|
-
method coverage, this will report as unused any associations that are
|
46
|
-
used but where the association methods are not called. These cases
|
47
|
-
are rare, but can happen if you have libraries that use the
|
48
|
-
association reflection metadata without calling the association
|
49
|
-
methods, or use the association only in combination with another
|
50
|
-
plugin such as dataset_associations. You can set the :is_used
|
51
|
-
association option to explicitly mark an association as used, and
|
52
|
-
have this plugin avoid reporting it as unused.
|
53
|
-
|
54
|
-
In addition to just reporting on unused associations, you can also
|
55
|
-
directly use the unused associations metadata to automatically avoid
|
56
|
-
defining unused associations or unused associations methods. You
|
57
|
-
can set a :file option when loading the plugin:
|
58
|
-
|
59
|
-
Sequel::Model.plugin :unused_associations, file: 'unused_associations.json'
|
60
|
-
|
61
|
-
Then run the method coverage testing. This will save the unused
|
62
|
-
associations metadata to the file. Then you can use this metadata
|
63
|
-
automatically by also setting the :modify_associations option:
|
64
|
-
|
65
|
-
Sequel::Model.plugin :unused_associations, file: 'unused_associations.json',
|
66
|
-
modify_associations: true
|
67
|
-
|
68
|
-
With the :modify_associations option, unused associations are
|
69
|
-
skipped instead of being defined, and the options returned by
|
70
|
-
unused_association_options are automatically used. Note that using
|
71
|
-
the :modify_associations option is risky unless you have complete
|
72
|
-
coverage and do not have cases where the associations are used
|
73
|
-
without calling methods.
|
74
|
-
|
75
|
-
It is common to have multiple test suites where you need to combine
|
76
|
-
coverage. The plugin supports this by using a :coverage_file option:
|
77
|
-
|
78
|
-
Sequel::Model.plugin :unused_associations, coverage_file: 'unused_associations_coverage.json'
|
79
|
-
|
80
|
-
In this case, you would run update_associations_coverage after each
|
81
|
-
test suite, and update_unused_associations_data only after all test
|
82
|
-
suites have been run.
|
83
|
-
|
84
|
-
* Passing nil as the value of the :setter, :adder, :remover, or
|
85
|
-
:clearer association options will cause the related method to not be
|
86
|
-
defined, instead of using the default value. This allows you to
|
87
|
-
only define the methods you will actually be using.
|