sequel 5.39.0 → 5.63.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG +308 -0
- data/MIT-LICENSE +1 -1
- data/README.rdoc +57 -25
- data/bin/sequel +11 -3
- data/doc/advanced_associations.rdoc +13 -13
- data/doc/association_basics.rdoc +89 -24
- data/doc/cheat_sheet.rdoc +11 -3
- data/doc/migration.rdoc +12 -6
- data/doc/model_hooks.rdoc +1 -1
- data/doc/object_model.rdoc +8 -8
- data/doc/opening_databases.rdoc +18 -11
- data/doc/postgresql.rdoc +16 -8
- data/doc/querying.rdoc +5 -3
- data/doc/release_notes/5.40.0.txt +40 -0
- data/doc/release_notes/5.41.0.txt +25 -0
- data/doc/release_notes/5.42.0.txt +136 -0
- data/doc/release_notes/5.43.0.txt +98 -0
- data/doc/release_notes/5.44.0.txt +32 -0
- data/doc/release_notes/5.45.0.txt +34 -0
- data/doc/release_notes/5.46.0.txt +87 -0
- data/doc/release_notes/5.47.0.txt +59 -0
- data/doc/release_notes/5.48.0.txt +14 -0
- data/doc/release_notes/5.49.0.txt +59 -0
- data/doc/release_notes/5.50.0.txt +78 -0
- data/doc/release_notes/5.51.0.txt +47 -0
- data/doc/release_notes/5.52.0.txt +87 -0
- data/doc/release_notes/5.53.0.txt +23 -0
- data/doc/release_notes/5.54.0.txt +27 -0
- data/doc/release_notes/5.55.0.txt +21 -0
- data/doc/release_notes/5.56.0.txt +51 -0
- data/doc/release_notes/5.57.0.txt +23 -0
- data/doc/release_notes/5.58.0.txt +31 -0
- data/doc/release_notes/5.59.0.txt +73 -0
- data/doc/release_notes/5.60.0.txt +22 -0
- data/doc/release_notes/5.61.0.txt +43 -0
- data/doc/release_notes/5.62.0.txt +132 -0
- data/doc/release_notes/5.63.0.txt +33 -0
- data/doc/schema_modification.rdoc +1 -1
- data/doc/security.rdoc +9 -9
- data/doc/sql.rdoc +27 -15
- data/doc/testing.rdoc +22 -11
- data/doc/transactions.rdoc +6 -6
- data/doc/virtual_rows.rdoc +2 -2
- data/lib/sequel/adapters/ado/access.rb +1 -1
- data/lib/sequel/adapters/ado.rb +17 -17
- data/lib/sequel/adapters/amalgalite.rb +3 -5
- data/lib/sequel/adapters/ibmdb.rb +2 -2
- data/lib/sequel/adapters/jdbc/derby.rb +8 -0
- data/lib/sequel/adapters/jdbc/h2.rb +60 -10
- data/lib/sequel/adapters/jdbc/hsqldb.rb +6 -0
- data/lib/sequel/adapters/jdbc/postgresql.rb +4 -4
- data/lib/sequel/adapters/jdbc.rb +16 -18
- data/lib/sequel/adapters/mysql.rb +80 -67
- data/lib/sequel/adapters/mysql2.rb +54 -49
- data/lib/sequel/adapters/odbc.rb +6 -2
- data/lib/sequel/adapters/oracle.rb +3 -3
- data/lib/sequel/adapters/postgres.rb +83 -40
- data/lib/sequel/adapters/shared/access.rb +11 -1
- data/lib/sequel/adapters/shared/db2.rb +30 -0
- data/lib/sequel/adapters/shared/mssql.rb +58 -7
- data/lib/sequel/adapters/shared/mysql.rb +40 -2
- data/lib/sequel/adapters/shared/oracle.rb +76 -0
- data/lib/sequel/adapters/shared/postgres.rb +418 -174
- data/lib/sequel/adapters/shared/sqlanywhere.rb +10 -0
- data/lib/sequel/adapters/shared/sqlite.rb +102 -11
- data/lib/sequel/adapters/sqlanywhere.rb +1 -1
- data/lib/sequel/adapters/sqlite.rb +60 -18
- data/lib/sequel/adapters/tinytds.rb +1 -1
- data/lib/sequel/adapters/utils/columns_limit_1.rb +22 -0
- data/lib/sequel/adapters/utils/mysql_mysql2.rb +1 -1
- data/lib/sequel/ast_transformer.rb +6 -0
- data/lib/sequel/connection_pool/sharded_single.rb +5 -7
- data/lib/sequel/connection_pool/sharded_threaded.rb +5 -1
- data/lib/sequel/connection_pool/single.rb +6 -8
- data/lib/sequel/connection_pool/threaded.rb +8 -8
- data/lib/sequel/connection_pool/timed_queue.rb +257 -0
- data/lib/sequel/connection_pool.rb +47 -30
- data/lib/sequel/core.rb +28 -18
- data/lib/sequel/database/connecting.rb +26 -2
- data/lib/sequel/database/misc.rb +69 -14
- data/lib/sequel/database/query.rb +38 -1
- data/lib/sequel/database/schema_generator.rb +45 -52
- data/lib/sequel/database/schema_methods.rb +17 -1
- data/lib/sequel/dataset/actions.rb +107 -13
- data/lib/sequel/dataset/features.rb +20 -0
- data/lib/sequel/dataset/misc.rb +1 -1
- data/lib/sequel/dataset/prepared_statements.rb +2 -0
- data/lib/sequel/dataset/query.rb +118 -16
- data/lib/sequel/dataset/sql.rb +177 -47
- data/lib/sequel/extensions/_model_pg_row.rb +0 -12
- data/lib/sequel/extensions/_pretty_table.rb +1 -1
- data/lib/sequel/extensions/any_not_empty.rb +1 -1
- data/lib/sequel/extensions/async_thread_pool.rb +438 -0
- data/lib/sequel/extensions/auto_literal_strings.rb +1 -1
- data/lib/sequel/extensions/blank.rb +8 -0
- data/lib/sequel/extensions/constraint_validations.rb +1 -1
- data/lib/sequel/extensions/core_refinements.rb +36 -11
- data/lib/sequel/extensions/date_arithmetic.rb +71 -31
- data/lib/sequel/extensions/date_parse_input_handler.rb +67 -0
- data/lib/sequel/extensions/datetime_parse_to_time.rb +5 -1
- data/lib/sequel/extensions/duplicate_columns_handler.rb +1 -1
- data/lib/sequel/extensions/eval_inspect.rb +2 -0
- data/lib/sequel/extensions/inflector.rb +9 -1
- data/lib/sequel/extensions/is_distinct_from.rb +141 -0
- data/lib/sequel/extensions/looser_typecasting.rb +3 -0
- data/lib/sequel/extensions/migration.rb +7 -2
- data/lib/sequel/extensions/named_timezones.rb +26 -6
- data/lib/sequel/extensions/pagination.rb +1 -1
- data/lib/sequel/extensions/pg_array.rb +23 -3
- data/lib/sequel/extensions/pg_array_ops.rb +2 -2
- data/lib/sequel/extensions/pg_auto_parameterize.rb +478 -0
- data/lib/sequel/extensions/pg_enum.rb +1 -1
- data/lib/sequel/extensions/pg_extended_date_support.rb +28 -25
- data/lib/sequel/extensions/pg_extended_integer_support.rb +116 -0
- data/lib/sequel/extensions/pg_hstore.rb +6 -1
- data/lib/sequel/extensions/pg_hstore_ops.rb +53 -3
- data/lib/sequel/extensions/pg_inet.rb +10 -11
- data/lib/sequel/extensions/pg_inet_ops.rb +1 -1
- data/lib/sequel/extensions/pg_interval.rb +45 -19
- data/lib/sequel/extensions/pg_json.rb +13 -15
- data/lib/sequel/extensions/pg_json_ops.rb +73 -2
- data/lib/sequel/extensions/pg_loose_count.rb +3 -1
- data/lib/sequel/extensions/pg_multirange.rb +367 -0
- data/lib/sequel/extensions/pg_range.rb +10 -23
- data/lib/sequel/extensions/pg_range_ops.rb +37 -9
- data/lib/sequel/extensions/pg_row.rb +19 -13
- data/lib/sequel/extensions/pg_row_ops.rb +1 -1
- data/lib/sequel/extensions/query.rb +2 -0
- data/lib/sequel/extensions/s.rb +2 -1
- data/lib/sequel/extensions/schema_dumper.rb +13 -2
- data/lib/sequel/extensions/server_block.rb +8 -12
- data/lib/sequel/extensions/sql_comments.rb +110 -3
- data/lib/sequel/extensions/sql_log_normalizer.rb +108 -0
- data/lib/sequel/extensions/sqlite_json_ops.rb +255 -0
- data/lib/sequel/extensions/string_agg.rb +1 -1
- data/lib/sequel/extensions/string_date_time.rb +19 -23
- data/lib/sequel/extensions/symbol_aref.rb +2 -0
- data/lib/sequel/model/associations.rb +325 -96
- data/lib/sequel/model/base.rb +51 -27
- data/lib/sequel/model/errors.rb +10 -1
- data/lib/sequel/model/inflections.rb +1 -1
- data/lib/sequel/model/plugins.rb +5 -0
- data/lib/sequel/plugins/association_proxies.rb +2 -0
- data/lib/sequel/plugins/async_thread_pool.rb +39 -0
- data/lib/sequel/plugins/auto_restrict_eager_graph.rb +62 -0
- data/lib/sequel/plugins/auto_validations.rb +87 -15
- data/lib/sequel/plugins/auto_validations_constraint_validations_presence_message.rb +68 -0
- data/lib/sequel/plugins/class_table_inheritance.rb +2 -2
- data/lib/sequel/plugins/column_encryption.rb +728 -0
- data/lib/sequel/plugins/composition.rb +10 -4
- data/lib/sequel/plugins/concurrent_eager_loading.rb +174 -0
- data/lib/sequel/plugins/constraint_validations.rb +2 -1
- data/lib/sequel/plugins/dataset_associations.rb +4 -1
- data/lib/sequel/plugins/dirty.rb +1 -1
- data/lib/sequel/plugins/enum.rb +124 -0
- data/lib/sequel/plugins/finder.rb +3 -1
- data/lib/sequel/plugins/insert_conflict.rb +4 -0
- data/lib/sequel/plugins/instance_specific_default.rb +1 -1
- data/lib/sequel/plugins/json_serializer.rb +39 -24
- data/lib/sequel/plugins/lazy_attributes.rb +3 -0
- data/lib/sequel/plugins/list.rb +3 -1
- data/lib/sequel/plugins/many_through_many.rb +108 -9
- data/lib/sequel/plugins/nested_attributes.rb +12 -7
- data/lib/sequel/plugins/pg_array_associations.rb +56 -38
- data/lib/sequel/plugins/pg_auto_constraint_validations.rb +3 -1
- data/lib/sequel/plugins/prepared_statements.rb +10 -1
- data/lib/sequel/plugins/primary_key_lookup_check_values.rb +154 -0
- data/lib/sequel/plugins/rcte_tree.rb +27 -19
- data/lib/sequel/plugins/require_valid_schema.rb +67 -0
- data/lib/sequel/plugins/serialization.rb +9 -3
- data/lib/sequel/plugins/serialization_modification_detection.rb +2 -1
- data/lib/sequel/plugins/single_table_inheritance.rb +8 -0
- data/lib/sequel/plugins/sql_comments.rb +189 -0
- data/lib/sequel/plugins/static_cache.rb +1 -1
- data/lib/sequel/plugins/subclasses.rb +28 -11
- data/lib/sequel/plugins/tactical_eager_loading.rb +23 -10
- data/lib/sequel/plugins/timestamps.rb +1 -1
- data/lib/sequel/plugins/unused_associations.rb +521 -0
- data/lib/sequel/plugins/update_or_create.rb +1 -1
- data/lib/sequel/plugins/validate_associated.rb +22 -12
- data/lib/sequel/plugins/validation_helpers.rb +38 -11
- data/lib/sequel/plugins/xml_serializer.rb +1 -1
- data/lib/sequel/sql.rb +1 -1
- data/lib/sequel/timezones.rb +12 -14
- data/lib/sequel/version.rb +1 -1
- metadata +97 -43
|
@@ -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.
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
= New Features
|
|
2
|
+
|
|
3
|
+
* A require_valid_schema plugin has been added, for checking that
|
|
4
|
+
model classes have schema parsed as expected. By default, model
|
|
5
|
+
classes are not required to have valid schema, because it is
|
|
6
|
+
allowed to have model classes based on arbitrary datasets (such
|
|
7
|
+
as those using joins or set-returning functions), and it is not
|
|
8
|
+
possible to determine the schema for arbitary datasets.
|
|
9
|
+
|
|
10
|
+
Sequel swallows non-connection errors when trying to parse schema
|
|
11
|
+
for a model's dataset, but if schema parsing fails when you would
|
|
12
|
+
expect it to succeed, it results in a model where typecasting does
|
|
13
|
+
not work as expected.
|
|
14
|
+
|
|
15
|
+
The require_valid_schema plugin will raise an error when setting
|
|
16
|
+
the dataset for a model if schema parsing fails and the dataset
|
|
17
|
+
uses a simple table where you would expect schema parsing to
|
|
18
|
+
succeed. You can also provide an argument of :warn when loading
|
|
19
|
+
the plugin, to warn instead of raising an error.
|
|
20
|
+
|
|
21
|
+
This plugin may not work correctly in all cases for all adapters,
|
|
22
|
+
especially external adapters. Adapters are not required to support
|
|
23
|
+
schema parsing. Even if supported, adapters may not support
|
|
24
|
+
parsing schema for qualified tables, or parsing schema for views.
|
|
25
|
+
You should consider this plugin as a possible safety net. Users
|
|
26
|
+
are encouraged to try using it and report any unexpected breakage,
|
|
27
|
+
as that may help improve schema parsing in adapters that Sequel
|
|
28
|
+
ships.
|
|
29
|
+
|
|
30
|
+
* is_json and is_not_json methods have been added to the pg_json_ops
|
|
31
|
+
extension, for the IS [NOT] JSON operator supported in PostgreSQL
|
|
32
|
+
15+.
|
|
33
|
+
|
|
34
|
+
* Index creation methods on PostgreSQL 15+ now support a
|
|
35
|
+
:nulls_distinct option, for NULLS [NOT] DISTINCT. This allows you
|
|
36
|
+
to create unique indexes where NULL values are not considered
|
|
37
|
+
distinct.
|
|
38
|
+
|
|
39
|
+
* View creation methods on PostgreSQL 15+ now support a
|
|
40
|
+
:security_invoker option to create a view where access is
|
|
41
|
+
determined by the permissions of the role that is accessing the
|
|
42
|
+
view, instead of the role that created the view.
|
|
43
|
+
|
|
44
|
+
= Other Improvements
|
|
45
|
+
|
|
46
|
+
* The :allow_eager association option is now set to false by default
|
|
47
|
+
for associations explicitly marked as :instance_specific, if the
|
|
48
|
+
:eager_loader association is not given.
|
|
49
|
+
|
|
50
|
+
* The postgres adapter now supports the sequel-postgres-pr driver.
|
|
51
|
+
The sequel-postgres-pr driver is a slimmed down fork of the
|
|
52
|
+
postgres-pr driver designed specifically for use by Sequel.
|
|
53
|
+
|
|
54
|
+
* Model code that explicitly does not swallow connection errors
|
|
55
|
+
will also now not swallow disconnect errors. This can fix issues
|
|
56
|
+
where model classes are being loaded at runtime, and the query to
|
|
57
|
+
get the columns/schema for the model uses a connection that has
|
|
58
|
+
been disconnected.
|
|
59
|
+
|
|
60
|
+
* Model classes created from aliased expressions and literal
|
|
61
|
+
strings no longer use the simple_table optimization, as there
|
|
62
|
+
are cases where doing so is not safe.
|
|
63
|
+
|
|
64
|
+
= Backwards Compatibility
|
|
65
|
+
|
|
66
|
+
* The change to not swallow disconnect errors when not swallowing
|
|
67
|
+
connection errors can result in exceptions being raised which
|
|
68
|
+
weren't raised previously. In most cases, this will alert you
|
|
69
|
+
to issues in your application that should be fixed, but it
|
|
70
|
+
potentially it can result in regressions if you were OK with
|
|
71
|
+
the errors being swallowed. If this does result in regressions
|
|
72
|
+
in your application, please file an issue and we can probably
|
|
73
|
+
add a setting controlling this feature.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
= New Features
|
|
2
|
+
|
|
3
|
+
* The date_arithmetic extension now supports arbitrary expressions
|
|
4
|
+
as interval values on PostgreSQL 9.4+. Previously, only integers
|
|
5
|
+
were supported for the interval values.
|
|
6
|
+
|
|
7
|
+
= Other Improvements
|
|
8
|
+
|
|
9
|
+
* Most Kernel#respond_to? calls have been converted to equivalent
|
|
10
|
+
defined? calls for better performance. defined? is a keyword
|
|
11
|
+
and is about 50% faster for the same behavior.
|
|
12
|
+
|
|
13
|
+
* The is_distinct_from extension now supports the IS DISTINCT FROM
|
|
14
|
+
syntax natively on SQLite 3.39+, instead of emulating it.
|
|
15
|
+
|
|
16
|
+
* HAVING without GROUP BY is now supported on SQLite 3.39+.
|
|
17
|
+
|
|
18
|
+
* Coverage testing has been significantly expanded. Previously,
|
|
19
|
+
the core, model, plugin, and extension code had 100% line/branch
|
|
20
|
+
coverage. 100% line/branch coverage has been added for the
|
|
21
|
+
core extensions, bin/sequel, and the postgres adapter with the
|
|
22
|
+
pg driver.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
= Improvements
|
|
2
|
+
|
|
3
|
+
* When typecasting strings to other types, Sequel::Database will now
|
|
4
|
+
by default not typecast strings that are much longer than expected
|
|
5
|
+
for the underlying type. Depending on the underlying type, there
|
|
6
|
+
is a limit of either 100 or 1000 bytes on the input string. This
|
|
7
|
+
avoids potential performance issues when trying to convert
|
|
8
|
+
arbitrary sized user input to specific types.
|
|
9
|
+
|
|
10
|
+
* The respond_to? to defined? change made in 5.60.0 was reverted in
|
|
11
|
+
5.60.1 as it broke cases on Ruby < 3 where the object had an unused
|
|
12
|
+
refinement that added the method.
|
|
13
|
+
|
|
14
|
+
* When typecasting strings to integer, strings such as -0xa are now
|
|
15
|
+
treated as negative hexidecimal strings, similar to how 0xa is
|
|
16
|
+
treated as a positive hexidecimal string.
|
|
17
|
+
|
|
18
|
+
* Database#foreign_key_list now returns results for partitioned
|
|
19
|
+
tables on PostgreSQL 11+.
|
|
20
|
+
|
|
21
|
+
* Timestamps before the date of calendar reform are now handled
|
|
22
|
+
correctly by the pg_extended_date_support extension when using
|
|
23
|
+
Ruby 3.2 preview 2+.
|
|
24
|
+
|
|
25
|
+
= Backwards Compatibility
|
|
26
|
+
|
|
27
|
+
* The change to not typecast strings that are too long can break
|
|
28
|
+
backwards compatibility for applications that expect typecasting
|
|
29
|
+
for input beyond Sequel's limits. You can disable the string
|
|
30
|
+
bytesize checking by setting:
|
|
31
|
+
|
|
32
|
+
DB.check_string_typecast_bytesize = false
|
|
33
|
+
|
|
34
|
+
or by passing the check_string_typecast_bytesize: false option when
|
|
35
|
+
creating the Database instance.
|
|
36
|
+
|
|
37
|
+
* Code to workaround a bug in JRuby 9.2.0.0 has been removed from the
|
|
38
|
+
pg_extended_date_support extension. Users of the extension should
|
|
39
|
+
upgrade to a newer JRuby version.
|
|
40
|
+
|
|
41
|
+
* The is_json and is_not_json methods have been removed from the
|
|
42
|
+
pg_json_ops extension, as the underlying support was removed in
|
|
43
|
+
PostgreSQL 15 beta 4.
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
= New Features
|
|
2
|
+
|
|
3
|
+
* The pg_auto_parameterize extension for automatically using bound
|
|
4
|
+
variables when using postgres adapter with the pg driver has been
|
|
5
|
+
added back to Sequel. This extension was originally added in Sequel
|
|
6
|
+
3.34.0, but was removed in 4.0.0 due to the many corner cases it
|
|
7
|
+
had. Almost all of the corner cases have now been fixed, and
|
|
8
|
+
the extension is now recommended for production use. Compared
|
|
9
|
+
to the original version in Sequel 3, the reintroduced version
|
|
10
|
+
of the extension includes the following changes:
|
|
11
|
+
|
|
12
|
+
* Handles integers used in LIMIT/ORDER
|
|
13
|
+
* Respects explicit CASTs
|
|
14
|
+
* Tries to convert column IN (int, ...) into column = ANY($) with an
|
|
15
|
+
array parameter
|
|
16
|
+
* Uses the same parameter for the same object used more than once in
|
|
17
|
+
a query
|
|
18
|
+
* Uses parameters when inserting multiple rows via Dataset#import
|
|
19
|
+
* Supports automatically parameterizing all of the
|
|
20
|
+
PostgreSQL-specific types that Sequel ships support for in pg_*
|
|
21
|
+
extensions (though some values of those types may not support
|
|
22
|
+
automatic parameterization).
|
|
23
|
+
* Supports skipping auto parameterization for specific values.
|
|
24
|
+
|
|
25
|
+
Automatic parameterization is generally slower than Sequel's default
|
|
26
|
+
behavior, since some optimizations Sequel uses by default do not
|
|
27
|
+
currently support automatic parameterization.
|
|
28
|
+
|
|
29
|
+
Applications may need changes to work correctly with the
|
|
30
|
+
pg_auto_parameterize extension, such as the addition of explicit
|
|
31
|
+
casts. Please read the extension documentation for more details.
|
|
32
|
+
|
|
33
|
+
* Integer column schema entries now include :min_value and :max_value
|
|
34
|
+
entries on most databases, indicating the minimum and maximum values
|
|
35
|
+
supported for the column.
|
|
36
|
+
|
|
37
|
+
The validation_helpers plugin now has validates_max_value and
|
|
38
|
+
validates_min_value for testing the column value is not greater
|
|
39
|
+
than the given maximum value and not less than the given minimum
|
|
40
|
+
value, respectively.
|
|
41
|
+
|
|
42
|
+
The auto_validations plugin now automatically uses the :min_value
|
|
43
|
+
and :max_value column schema entries with the new validation_helpers
|
|
44
|
+
methods to validate that the column values for integer columns are
|
|
45
|
+
in the allowed range.
|
|
46
|
+
|
|
47
|
+
* A primary_key_lookup_check_values plugin has been added for
|
|
48
|
+
automatically typecasting and checking the primary key values are
|
|
49
|
+
in the allowed range (given by :min_value and :max_value column
|
|
50
|
+
schema entries) during lookup. If typecasting fails or the value
|
|
51
|
+
is outside the allowed range, the primary key lookup will return
|
|
52
|
+
nil without issuing a query (or will raise a NoMatchingRow error
|
|
53
|
+
if using with_pk!).
|
|
54
|
+
|
|
55
|
+
Note that this can change behavior in some cases if you are
|
|
56
|
+
passing filter conditions during lookup instead of passing primary
|
|
57
|
+
key values. The plugin tries to support most common filter
|
|
58
|
+
conditions, but there are still cases that will break.
|
|
59
|
+
|
|
60
|
+
* Sequel now supports shard-specific :after_connect and :connect_sqls
|
|
61
|
+
Database options, allowing you to customize behavior for specific
|
|
62
|
+
shards:
|
|
63
|
+
|
|
64
|
+
DB = Sequel.connect('url', servers: {
|
|
65
|
+
:shard1 => {host: '...', after_connect: proc{|conn|}},
|
|
66
|
+
:shard2 => {host: '...', connect_sqls: ['...']},
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
Note that these shard-specific options will not be respected if you
|
|
70
|
+
are calling after_connect= or connect_sqls= on the Database's
|
|
71
|
+
connection pool.
|
|
72
|
+
|
|
73
|
+
= Other Improvements
|
|
74
|
+
|
|
75
|
+
* A Sequel::Postgres::IntegerOutsideBigintRange exception will now be
|
|
76
|
+
raised if trying to literalize an integer outside PostgreSQL bigint
|
|
77
|
+
range, to avoid PostgreSQL treating the integer as a numeric type
|
|
78
|
+
and not respecting indexes on the related column.
|
|
79
|
+
|
|
80
|
+
A pg_extended_integer_support extension has been added for
|
|
81
|
+
customizing the behavior when literalizing an integer outside
|
|
82
|
+
PostgreSQL bigint range, either quoting it or getting the
|
|
83
|
+
historical behavior of using it directly in the query.
|
|
84
|
+
|
|
85
|
+
* Dataset#import and #multi_insert no longer use transactions when
|
|
86
|
+
they only run a single query.
|
|
87
|
+
|
|
88
|
+
* Fractional seconds in timestamps are now respected in the
|
|
89
|
+
named_timezones extension.
|
|
90
|
+
|
|
91
|
+
* Using hstore[] types as bound variables now works on PostgreSQL.
|
|
92
|
+
|
|
93
|
+
* Using BC dates and timestamps in bound variables now works on
|
|
94
|
+
PostgreSQL.
|
|
95
|
+
|
|
96
|
+
* A corner case has been fixed in eager loading where the window
|
|
97
|
+
function eager limit strategy would be used without removing the
|
|
98
|
+
row_number entries from the result.
|
|
99
|
+
|
|
100
|
+
* The shared postgres adapter now caches reflection datasets, speeding
|
|
101
|
+
up Database#indexes and similar methods.
|
|
102
|
+
|
|
103
|
+
* The mock postgres adapter now assumes PostgreSQL 15 instead of
|
|
104
|
+
PostgreSQL 14 by default.
|
|
105
|
+
|
|
106
|
+
= Backwards Compatibility
|
|
107
|
+
|
|
108
|
+
* If you are using Ruby integers outside PostgreSQL bigint range when
|
|
109
|
+
dealing with PostgreSQL numeric column values, this version may
|
|
110
|
+
not be compatible. It is recommended you explicitly convert the
|
|
111
|
+
Ruby integers to BigDecimal objects if you are using them for
|
|
112
|
+
numeric column values. You can also use the
|
|
113
|
+
pg_extended_integer_support extension introduced in this version.
|
|
114
|
+
|
|
115
|
+
= Workaround for Older Versions
|
|
116
|
+
|
|
117
|
+
* If you cannot upgrade to Sequel 5.62.0, but still want to avoid the
|
|
118
|
+
problems that come from using literal large integers on PostgreSQL,
|
|
119
|
+
you can use the following code, where DB is your Sequel::Database
|
|
120
|
+
object:
|
|
121
|
+
|
|
122
|
+
DB.extend_datasets do
|
|
123
|
+
def literal_integer(v)
|
|
124
|
+
if v > 9223372036854775807 || v < -9223372036854775808
|
|
125
|
+
raise Sequel::InvalidValue, "PostgreSQL int too large: #{v}"
|
|
126
|
+
end
|
|
127
|
+
super
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
This workaround should work all the way back to Sequel 3.29.0,
|
|
132
|
+
released in November 2011.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
= New Features
|
|
2
|
+
|
|
3
|
+
* On Ruby 3.2, the pool_class: :timed_queue Database option can now
|
|
4
|
+
be used to use an alternative connection pool that stores
|
|
5
|
+
connections in a queue, and uses the new Queue#pop :timeout option
|
|
6
|
+
in Ruby 3.2 to implement the pool timeout. This new connection
|
|
7
|
+
pool is simpler than the default connection pool. It is not yet
|
|
8
|
+
the default connection pool on Ruby 3.2, but it may become the
|
|
9
|
+
default in a later version. Users of Ruby 3.2 are encouraged to
|
|
10
|
+
try out the pool_class: :timed_queue Database option and provide
|
|
11
|
+
feedback on how it works in their application.
|
|
12
|
+
|
|
13
|
+
= Other Improvements
|
|
14
|
+
|
|
15
|
+
* The tactical_eager_loading plugin now works in combination with the
|
|
16
|
+
single_table_inheritance and class_table_inheritance plugins, when
|
|
17
|
+
loading an association only defined in a specific subclass.
|
|
18
|
+
Previously, eager loading would be skipped in such a case. Now,
|
|
19
|
+
an eager load will be attempted for all instances supporting the
|
|
20
|
+
association.
|
|
21
|
+
|
|
22
|
+
* The validate_associated plugin now avoids database type errors for
|
|
23
|
+
non-integer association keys. In cases where the associated object
|
|
24
|
+
doesn't have a value for the associated key, and the current object
|
|
25
|
+
does not have a key value that can be set in the associated object,
|
|
26
|
+
validation errors in the associated object related to the associated
|
|
27
|
+
key will be ignored.
|
|
28
|
+
|
|
29
|
+
* Thread-keyed connection pool hashes now use compare_by_identity for
|
|
30
|
+
better performance.
|
|
31
|
+
|
|
32
|
+
* The JRuby workaround in the named_timezones extension is no longer
|
|
33
|
+
used on JRuby 9.3.9.0+, as JRuby fixed the related bug.
|
|
@@ -377,7 +377,7 @@ Sequel will not add a column, but will add a composite primary key constraint:
|
|
|
377
377
|
It is possible to specify a name for the primary key constraint: via the :name option:
|
|
378
378
|
|
|
379
379
|
alter_table(:albums_artists) do
|
|
380
|
-
add_primary_key [:album_id, :artist_id], :
|
|
380
|
+
add_primary_key [:album_id, :artist_id], name: :albums_artists_pkey
|
|
381
381
|
end
|
|
382
382
|
|
|
383
383
|
If you just want to take an existing single column and make it a primary key, call
|
data/doc/security.rdoc
CHANGED
|
@@ -127,8 +127,8 @@ a ruby string as raw SQL. For example:
|
|
|
127
127
|
DB.literal(Date.today) # "'2013-03-22'"
|
|
128
128
|
DB.literal('a') # "'a'"
|
|
129
129
|
DB.literal(Sequel.lit('a')) # "a"
|
|
130
|
-
DB.literal(:
|
|
131
|
-
DB.literal(:
|
|
130
|
+
DB.literal(a: 'a') # "(\"a\" = 'a')"
|
|
131
|
+
DB.literal(a: Sequel.lit('a')) # "(\"a\" = a)"
|
|
132
132
|
|
|
133
133
|
==== SQL Filter Fragments
|
|
134
134
|
|
|
@@ -178,7 +178,7 @@ user input for function names.
|
|
|
178
178
|
For backwards compatibility, Sequel supports regular strings in the
|
|
179
179
|
window function :frame option, which will be treated as a literal string:
|
|
180
180
|
|
|
181
|
-
DB[:table].select{fun(arg).over(:
|
|
181
|
+
DB[:table].select{fun(arg).over(frame: 'SQL Here')}
|
|
182
182
|
|
|
183
183
|
You should make sure the frame argument is not derived from user input,
|
|
184
184
|
or switch to using a hash as the :frame option value.
|
|
@@ -237,7 +237,7 @@ or:
|
|
|
237
237
|
|
|
238
238
|
Instead, you should do:
|
|
239
239
|
|
|
240
|
-
DB[:table].update(:
|
|
240
|
+
DB[:table].update(column: params[:value].to_s) # Safe
|
|
241
241
|
|
|
242
242
|
Because using the auto_literal_strings extension makes SQL injection
|
|
243
243
|
so much eaiser, it is recommended to not use it, and instead
|
|
@@ -402,29 +402,29 @@ This issue isn't necessarily specific to Sequel, but it is a good general practi
|
|
|
402
402
|
If you are using values derived from user input, it is best to be explicit about
|
|
403
403
|
their type. For example:
|
|
404
404
|
|
|
405
|
-
Album.where(:
|
|
405
|
+
Album.where(id: params[:id])
|
|
406
406
|
|
|
407
407
|
is probably a bad idea. Assuming you are using a web framework, <tt>params[:id]</tt> could
|
|
408
408
|
be a string, an array, a hash, nil, or potentially something else.
|
|
409
409
|
|
|
410
410
|
Assuming that +id+ is an integer field, you probably want to do:
|
|
411
411
|
|
|
412
|
-
Album.where(:
|
|
412
|
+
Album.where(id: params[:id].to_i)
|
|
413
413
|
|
|
414
414
|
If you are looking something up by name, you should try to enforce the value to be
|
|
415
415
|
a string:
|
|
416
416
|
|
|
417
|
-
Album.where(:
|
|
417
|
+
Album.where(name: params[:name].to_s)
|
|
418
418
|
|
|
419
419
|
If you are trying to use an IN clause with a list of id values based on input provided
|
|
420
420
|
on a web form:
|
|
421
421
|
|
|
422
|
-
Album.where(:
|
|
422
|
+
Album.where(id: params[:ids].to_a.map(&:to_i))
|
|
423
423
|
|
|
424
424
|
Basically, be as explicit as possible. While there aren't any known security issues
|
|
425
425
|
in Sequel when you do:
|
|
426
426
|
|
|
427
|
-
Album.where(:
|
|
427
|
+
Album.where(id: params[:id])
|
|
428
428
|
|
|
429
429
|
It allows the attacker to choose to do any of the following queries:
|
|
430
430
|
|