sequel 3.21.0 → 3.41.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.
- data/CHANGELOG +1131 -3
- data/MIT-LICENSE +1 -1
- data/README.rdoc +106 -65
- data/Rakefile +59 -27
- data/bin/sequel +50 -26
- data/doc/active_record.rdoc +68 -52
- data/doc/advanced_associations.rdoc +201 -75
- data/doc/association_basics.rdoc +327 -79
- data/doc/bin_sequel.rdoc +144 -0
- data/doc/cheat_sheet.rdoc +21 -21
- data/doc/core_extensions.rdoc +374 -0
- data/doc/dataset_basics.rdoc +10 -10
- data/doc/dataset_filtering.rdoc +54 -42
- data/doc/mass_assignment.rdoc +56 -0
- data/doc/migration.rdoc +89 -557
- data/doc/model_hooks.rdoc +80 -29
- data/doc/object_model.rdoc +576 -0
- data/doc/opening_databases.rdoc +121 -53
- data/doc/prepared_statements.rdoc +41 -15
- data/doc/querying.rdoc +137 -56
- data/doc/reflection.rdoc +36 -10
- data/doc/release_notes/3.22.0.txt +39 -0
- data/doc/release_notes/3.23.0.txt +172 -0
- data/doc/release_notes/3.24.0.txt +420 -0
- data/doc/release_notes/3.25.0.txt +88 -0
- data/doc/release_notes/3.26.0.txt +88 -0
- data/doc/release_notes/3.27.0.txt +82 -0
- data/doc/release_notes/3.28.0.txt +304 -0
- data/doc/release_notes/3.29.0.txt +459 -0
- data/doc/release_notes/3.30.0.txt +135 -0
- data/doc/release_notes/3.31.0.txt +146 -0
- data/doc/release_notes/3.32.0.txt +202 -0
- data/doc/release_notes/3.33.0.txt +157 -0
- data/doc/release_notes/3.34.0.txt +671 -0
- data/doc/release_notes/3.35.0.txt +144 -0
- data/doc/release_notes/3.36.0.txt +245 -0
- data/doc/release_notes/3.37.0.txt +338 -0
- data/doc/release_notes/3.38.0.txt +234 -0
- data/doc/release_notes/3.39.0.txt +237 -0
- data/doc/release_notes/3.40.0.txt +73 -0
- data/doc/release_notes/3.41.0.txt +155 -0
- data/doc/schema_modification.rdoc +585 -0
- data/doc/sharding.rdoc +99 -8
- data/doc/sql.rdoc +154 -112
- data/doc/testing.rdoc +169 -0
- data/doc/thread_safety.rdoc +17 -0
- data/doc/transactions.rdoc +137 -0
- data/doc/validations.rdoc +1 -1
- data/doc/virtual_rows.rdoc +78 -43
- data/lib/sequel/adapters/ado/access.rb +334 -0
- data/lib/sequel/adapters/ado/mssql.rb +18 -12
- data/lib/sequel/adapters/ado.rb +69 -21
- data/lib/sequel/adapters/amalgalite.rb +17 -14
- data/lib/sequel/adapters/cubrid.rb +143 -0
- data/lib/sequel/adapters/db2.rb +178 -85
- data/lib/sequel/adapters/dbi.rb +19 -21
- data/lib/sequel/adapters/do/mysql.rb +17 -11
- data/lib/sequel/adapters/do/postgres.rb +2 -61
- data/lib/sequel/adapters/do/sqlite.rb +0 -10
- data/lib/sequel/adapters/do.rb +20 -39
- data/lib/sequel/adapters/firebird.rb +33 -210
- data/lib/sequel/adapters/ibmdb.rb +452 -0
- data/lib/sequel/adapters/informix.rb +6 -29
- data/lib/sequel/adapters/jdbc/as400.rb +16 -34
- data/lib/sequel/adapters/jdbc/cubrid.rb +52 -0
- data/lib/sequel/adapters/jdbc/db2.rb +78 -0
- data/lib/sequel/adapters/jdbc/derby.rb +325 -0
- data/lib/sequel/adapters/jdbc/firebird.rb +24 -0
- data/lib/sequel/adapters/jdbc/h2.rb +68 -31
- data/lib/sequel/adapters/jdbc/hsqldb.rb +189 -0
- data/lib/sequel/adapters/jdbc/informix.rb +21 -0
- data/lib/sequel/adapters/jdbc/jtds.rb +40 -0
- data/lib/sequel/adapters/jdbc/mssql.rb +3 -33
- data/lib/sequel/adapters/jdbc/mysql.rb +16 -28
- data/lib/sequel/adapters/jdbc/oracle.rb +88 -25
- data/lib/sequel/adapters/jdbc/postgresql.rb +77 -52
- data/lib/sequel/adapters/jdbc/progress.rb +21 -0
- data/lib/sequel/adapters/jdbc/sqlite.rb +20 -10
- data/lib/sequel/adapters/jdbc/sqlserver.rb +72 -0
- data/lib/sequel/adapters/jdbc/transactions.rb +83 -0
- data/lib/sequel/adapters/jdbc.rb +308 -114
- data/lib/sequel/adapters/mock.rb +372 -0
- data/lib/sequel/adapters/mysql.rb +130 -230
- data/lib/sequel/adapters/mysql2.rb +64 -63
- data/lib/sequel/adapters/odbc/mssql.rb +17 -9
- data/lib/sequel/adapters/odbc.rb +29 -10
- data/lib/sequel/adapters/openbase.rb +7 -11
- data/lib/sequel/adapters/oracle.rb +364 -57
- data/lib/sequel/adapters/postgres.rb +379 -145
- data/lib/sequel/adapters/shared/access.rb +236 -11
- data/lib/sequel/adapters/shared/cubrid.rb +216 -0
- data/lib/sequel/adapters/shared/db2.rb +353 -0
- data/lib/sequel/adapters/shared/firebird.rb +231 -0
- data/lib/sequel/adapters/shared/informix.rb +53 -0
- data/lib/sequel/adapters/shared/mssql.rb +412 -116
- data/lib/sequel/adapters/shared/mysql.rb +396 -89
- data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +166 -0
- data/lib/sequel/adapters/shared/oracle.rb +262 -45
- data/lib/sequel/adapters/shared/postgres.rb +688 -279
- data/lib/sequel/adapters/shared/progress.rb +5 -8
- data/lib/sequel/adapters/shared/sqlite.rb +317 -96
- data/lib/sequel/adapters/sqlite.rb +109 -46
- data/lib/sequel/adapters/swift/mysql.rb +10 -12
- data/lib/sequel/adapters/swift/postgres.rb +13 -79
- data/lib/sequel/adapters/swift/sqlite.rb +9 -6
- data/lib/sequel/adapters/swift.rb +31 -27
- data/lib/sequel/adapters/tinytds.rb +177 -25
- data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +77 -0
- data/lib/sequel/adapters/utils/pg_types.rb +81 -0
- data/lib/sequel/adapters/utils/split_alter_table.rb +36 -0
- data/lib/sequel/adapters/utils/stored_procedures.rb +1 -11
- data/lib/sequel/ast_transformer.rb +194 -0
- data/lib/sequel/connection_pool/sharded_single.rb +23 -13
- data/lib/sequel/connection_pool/sharded_threaded.rb +64 -13
- data/lib/sequel/connection_pool/single.rb +11 -3
- data/lib/sequel/connection_pool/threaded.rb +69 -20
- data/lib/sequel/connection_pool.rb +20 -18
- data/lib/sequel/core.rb +143 -11
- data/lib/sequel/database/connecting.rb +66 -29
- data/lib/sequel/database/dataset.rb +4 -4
- data/lib/sequel/database/dataset_defaults.rb +63 -2
- data/lib/sequel/database/logging.rb +7 -2
- data/lib/sequel/database/misc.rb +192 -51
- data/lib/sequel/database/query.rb +299 -114
- data/lib/sequel/database/schema_generator.rb +103 -36
- data/lib/sequel/database/schema_methods.rb +310 -69
- data/lib/sequel/dataset/actions.rb +344 -90
- data/lib/sequel/dataset/features.rb +101 -8
- data/lib/sequel/dataset/graph.rb +42 -15
- data/lib/sequel/dataset/misc.rb +52 -25
- data/lib/sequel/dataset/mutation.rb +12 -7
- data/lib/sequel/dataset/prepared_statements.rb +68 -30
- data/lib/sequel/dataset/query.rb +322 -68
- data/lib/sequel/dataset/sql.rb +716 -293
- data/lib/sequel/dataset.rb +8 -0
- data/lib/sequel/exceptions.rb +4 -0
- data/lib/sequel/extensions/_pretty_table.rb +83 -0
- data/lib/sequel/extensions/arbitrary_servers.rb +109 -0
- data/lib/sequel/extensions/blank.rb +4 -0
- data/lib/sequel/extensions/columns_introspection.rb +72 -0
- data/lib/sequel/extensions/connection_validator.rb +109 -0
- data/lib/sequel/extensions/constraint_validations.rb +451 -0
- data/lib/sequel/{core_sql.rb → extensions/core_extensions.rb} +30 -46
- data/lib/sequel/extensions/eval_inspect.rb +173 -0
- data/lib/sequel/extensions/inflector.rb +4 -0
- data/lib/sequel/extensions/looser_typecasting.rb +5 -4
- data/lib/sequel/extensions/migration.rb +100 -11
- data/lib/sequel/extensions/named_timezones.rb +9 -0
- data/lib/sequel/extensions/null_dataset.rb +94 -0
- data/lib/sequel/extensions/pagination.rb +4 -0
- data/lib/sequel/extensions/pg_array.rb +539 -0
- data/lib/sequel/extensions/pg_array_ops.rb +263 -0
- data/lib/sequel/extensions/pg_auto_parameterize.rb +175 -0
- data/lib/sequel/extensions/pg_hstore.rb +334 -0
- data/lib/sequel/extensions/pg_hstore_ops.rb +293 -0
- data/lib/sequel/extensions/pg_inet.rb +113 -0
- data/lib/sequel/extensions/pg_interval.rb +191 -0
- data/lib/sequel/extensions/pg_json.rb +212 -0
- data/lib/sequel/extensions/pg_range.rb +513 -0
- data/lib/sequel/extensions/pg_range_ops.rb +150 -0
- data/lib/sequel/extensions/pg_row.rb +576 -0
- data/lib/sequel/extensions/pg_row_ops.rb +182 -0
- data/lib/sequel/extensions/pg_statement_cache.rb +317 -0
- data/lib/sequel/extensions/pretty_table.rb +17 -72
- data/lib/sequel/extensions/query.rb +8 -4
- data/lib/sequel/extensions/query_literals.rb +79 -0
- data/lib/sequel/extensions/schema_caching.rb +76 -0
- data/lib/sequel/extensions/schema_dumper.rb +282 -76
- data/lib/sequel/extensions/select_remove.rb +39 -0
- data/lib/sequel/extensions/server_block.rb +140 -0
- data/lib/sequel/extensions/split_array_nil.rb +65 -0
- data/lib/sequel/extensions/sql_expr.rb +8 -110
- data/lib/sequel/extensions/string_date_time.rb +4 -0
- data/lib/sequel/extensions/thread_local_timezones.rb +10 -4
- data/lib/sequel/extensions/to_dot.rb +99 -83
- data/lib/sequel/model/associations.rb +1263 -409
- data/lib/sequel/model/base.rb +624 -171
- data/lib/sequel/model/errors.rb +1 -1
- data/lib/sequel/model/exceptions.rb +24 -2
- data/lib/sequel/model/inflections.rb +1 -1
- data/lib/sequel/model.rb +30 -11
- data/lib/sequel/no_core_ext.rb +2 -0
- data/lib/sequel/plugins/active_model.rb +13 -1
- data/lib/sequel/plugins/association_pks.rb +137 -16
- data/lib/sequel/plugins/caching.rb +25 -18
- data/lib/sequel/plugins/class_table_inheritance.rb +4 -4
- data/lib/sequel/plugins/composition.rb +44 -12
- data/lib/sequel/plugins/constraint_validations.rb +198 -0
- data/lib/sequel/plugins/dataset_associations.rb +100 -0
- data/lib/sequel/plugins/defaults_setter.rb +72 -0
- data/lib/sequel/plugins/dirty.rb +214 -0
- data/lib/sequel/plugins/eager_each.rb +59 -0
- data/lib/sequel/plugins/force_encoding.rb +6 -6
- data/lib/sequel/plugins/hook_class_methods.rb +1 -1
- data/lib/sequel/plugins/identity_map.rb +134 -15
- data/lib/sequel/plugins/instance_filters.rb +10 -0
- data/lib/sequel/plugins/instance_hooks.rb +1 -1
- data/lib/sequel/plugins/json_serializer.rb +77 -6
- data/lib/sequel/plugins/list.rb +13 -2
- data/lib/sequel/plugins/many_through_many.rb +103 -51
- data/lib/sequel/plugins/many_to_one_pk_lookup.rb +71 -0
- data/lib/sequel/plugins/nested_attributes.rb +150 -66
- data/lib/sequel/plugins/optimistic_locking.rb +8 -0
- data/lib/sequel/plugins/pg_row.rb +121 -0
- data/lib/sequel/plugins/pg_typecast_on_load.rb +65 -0
- data/lib/sequel/plugins/prepared_statements.rb +168 -0
- data/lib/sequel/plugins/prepared_statements_associations.rb +87 -0
- data/lib/sequel/plugins/prepared_statements_safe.rb +82 -0
- data/lib/sequel/plugins/prepared_statements_with_pk.rb +59 -0
- data/lib/sequel/plugins/rcte_tree.rb +31 -17
- data/lib/sequel/plugins/schema.rb +8 -3
- data/lib/sequel/plugins/serialization.rb +98 -49
- data/lib/sequel/plugins/serialization_modification_detection.rb +63 -0
- data/lib/sequel/plugins/sharding.rb +21 -54
- data/lib/sequel/plugins/single_table_inheritance.rb +57 -12
- data/lib/sequel/plugins/static_cache.rb +99 -0
- data/lib/sequel/plugins/subclasses.rb +29 -3
- data/lib/sequel/plugins/tactical_eager_loading.rb +7 -7
- data/lib/sequel/plugins/timestamps.rb +1 -1
- data/lib/sequel/plugins/touch.rb +18 -6
- data/lib/sequel/plugins/tree.rb +3 -3
- data/lib/sequel/plugins/typecast_on_load.rb +9 -12
- data/lib/sequel/plugins/update_primary_key.rb +2 -2
- data/lib/sequel/plugins/validation_class_methods.rb +2 -1
- data/lib/sequel/plugins/validation_helpers.rb +57 -4
- data/lib/sequel/plugins/xml_serializer.rb +15 -4
- data/lib/sequel/sql.rb +721 -141
- data/lib/sequel/timezones.rb +67 -40
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/db2_spec.rb +146 -0
- data/spec/adapters/firebird_spec.rb +53 -39
- data/spec/adapters/mssql_spec.rb +261 -66
- data/spec/adapters/mysql_spec.rb +597 -352
- data/spec/adapters/oracle_spec.rb +92 -117
- data/spec/adapters/postgres_spec.rb +2103 -341
- data/spec/adapters/spec_helper.rb +16 -6
- data/spec/adapters/sqlite_spec.rb +237 -76
- data/spec/core/connection_pool_spec.rb +270 -141
- data/spec/core/database_spec.rb +980 -524
- data/spec/core/dataset_spec.rb +1658 -1243
- data/spec/core/expression_filters_spec.rb +741 -334
- data/spec/core/mock_adapter_spec.rb +453 -0
- data/spec/core/object_graph_spec.rb +88 -129
- data/spec/core/schema_generator_spec.rb +4 -4
- data/spec/core/schema_spec.rb +556 -53
- data/spec/core/spec_helper.rb +7 -48
- data/spec/core_extensions_spec.rb +626 -0
- data/spec/extensions/active_model_spec.rb +13 -0
- data/spec/extensions/arbitrary_servers_spec.rb +110 -0
- data/spec/extensions/association_autoreloading_spec.rb +18 -10
- data/spec/extensions/association_dependencies_spec.rb +15 -25
- data/spec/extensions/association_pks_spec.rb +227 -33
- data/spec/extensions/association_proxies_spec.rb +4 -4
- data/spec/extensions/boolean_readers_spec.rb +25 -25
- data/spec/extensions/caching_spec.rb +47 -51
- data/spec/extensions/class_table_inheritance_spec.rb +31 -83
- data/spec/extensions/columns_introspection_spec.rb +91 -0
- data/spec/extensions/composition_spec.rb +18 -13
- data/spec/extensions/connection_validator_spec.rb +118 -0
- data/spec/extensions/constraint_validations_plugin_spec.rb +196 -0
- data/spec/extensions/constraint_validations_spec.rb +316 -0
- data/spec/extensions/dataset_associations_spec.rb +199 -0
- data/spec/extensions/defaults_setter_spec.rb +88 -0
- data/spec/extensions/dirty_spec.rb +155 -0
- data/spec/extensions/eager_each_spec.rb +34 -0
- data/spec/extensions/eval_inspect_spec.rb +67 -0
- data/spec/extensions/force_encoding_spec.rb +4 -2
- data/spec/extensions/hook_class_methods_spec.rb +97 -128
- data/spec/extensions/identity_map_spec.rb +142 -24
- data/spec/extensions/inflector_spec.rb +0 -4
- data/spec/extensions/instance_filters_spec.rb +11 -21
- data/spec/extensions/instance_hooks_spec.rb +72 -0
- data/spec/extensions/json_serializer_spec.rb +49 -12
- data/spec/extensions/lazy_attributes_spec.rb +16 -20
- data/spec/extensions/list_spec.rb +49 -40
- data/spec/extensions/looser_typecasting_spec.rb +7 -7
- data/spec/extensions/many_through_many_spec.rb +368 -254
- data/spec/extensions/many_to_one_pk_lookup_spec.rb +140 -0
- data/spec/extensions/migration_spec.rb +140 -35
- data/spec/extensions/named_timezones_spec.rb +29 -11
- data/spec/extensions/nested_attributes_spec.rb +268 -89
- data/spec/extensions/null_dataset_spec.rb +85 -0
- data/spec/extensions/optimistic_locking_spec.rb +24 -21
- data/spec/extensions/pg_array_ops_spec.rb +112 -0
- data/spec/extensions/pg_array_spec.rb +324 -0
- data/spec/extensions/pg_auto_parameterize_spec.rb +65 -0
- data/spec/extensions/pg_hstore_ops_spec.rb +140 -0
- data/spec/extensions/pg_hstore_spec.rb +200 -0
- data/spec/extensions/pg_inet_spec.rb +47 -0
- data/spec/extensions/pg_interval_spec.rb +72 -0
- data/spec/extensions/pg_json_spec.rb +99 -0
- data/spec/extensions/pg_range_ops_spec.rb +56 -0
- data/spec/extensions/pg_range_spec.rb +395 -0
- data/spec/extensions/pg_row_ops_spec.rb +58 -0
- data/spec/extensions/pg_row_plugin_spec.rb +49 -0
- data/spec/extensions/pg_row_spec.rb +340 -0
- data/spec/extensions/pg_statement_cache_spec.rb +208 -0
- data/spec/extensions/pg_typecast_on_load_spec.rb +58 -0
- data/spec/extensions/prepared_statements_associations_spec.rb +111 -0
- data/spec/extensions/prepared_statements_safe_spec.rb +61 -0
- data/spec/extensions/prepared_statements_spec.rb +87 -0
- data/spec/extensions/prepared_statements_with_pk_spec.rb +31 -0
- data/spec/extensions/pretty_table_spec.rb +7 -6
- data/spec/extensions/query_literals_spec.rb +167 -0
- data/spec/extensions/query_spec.rb +9 -3
- data/spec/extensions/rcte_tree_spec.rb +50 -43
- data/spec/extensions/schema_caching_spec.rb +41 -0
- data/spec/extensions/schema_dumper_spec.rb +434 -49
- data/spec/extensions/schema_spec.rb +30 -49
- data/spec/extensions/select_remove_spec.rb +38 -0
- data/spec/extensions/serialization_modification_detection_spec.rb +72 -0
- data/spec/extensions/serialization_spec.rb +86 -48
- data/spec/extensions/server_block_spec.rb +90 -0
- data/spec/extensions/sharding_spec.rb +69 -143
- data/spec/extensions/single_table_inheritance_spec.rb +65 -29
- data/spec/extensions/skip_create_refresh_spec.rb +1 -1
- data/spec/extensions/spec_helper.rb +34 -67
- data/spec/extensions/split_array_nil_spec.rb +24 -0
- data/spec/extensions/sql_expr_spec.rb +29 -60
- data/spec/extensions/static_cache_spec.rb +145 -0
- data/spec/extensions/subclasses_spec.rb +14 -0
- data/spec/extensions/tactical_eager_loading_spec.rb +17 -19
- data/spec/extensions/thread_local_timezones_spec.rb +22 -2
- data/spec/extensions/timestamps_spec.rb +6 -6
- data/spec/extensions/to_dot_spec.rb +8 -11
- data/spec/extensions/touch_spec.rb +53 -14
- data/spec/extensions/tree_spec.rb +11 -26
- data/spec/extensions/typecast_on_load_spec.rb +9 -6
- data/spec/extensions/update_primary_key_spec.rb +30 -24
- data/spec/extensions/validation_class_methods_spec.rb +77 -68
- data/spec/extensions/validation_helpers_spec.rb +48 -37
- data/spec/extensions/xml_serializer_spec.rb +29 -4
- data/spec/files/transaction_specified_migrations/001_create_alt_basic.rb +4 -0
- data/spec/files/transaction_specified_migrations/002_create_basic.rb +4 -0
- data/spec/files/transaction_unspecified_migrations/001_create_alt_basic.rb +3 -0
- data/spec/files/transaction_unspecified_migrations/002_create_basic.rb +3 -0
- data/spec/integration/associations_test.rb +659 -21
- data/spec/integration/database_test.rb +25 -5
- data/spec/integration/dataset_test.rb +729 -141
- data/spec/integration/eager_loader_test.rb +38 -54
- data/spec/integration/migrator_test.rb +2 -3
- data/spec/integration/model_test.rb +81 -2
- data/spec/integration/plugin_test.rb +871 -160
- data/spec/integration/prepared_statement_test.rb +272 -128
- data/spec/integration/schema_test.rb +377 -57
- data/spec/integration/spec_helper.rb +49 -32
- data/spec/integration/timezone_test.rb +38 -12
- data/spec/integration/transaction_test.rb +183 -8
- data/spec/integration/type_test.rb +40 -8
- data/spec/model/association_reflection_spec.rb +207 -8
- data/spec/model/associations_spec.rb +1206 -693
- data/spec/model/base_spec.rb +334 -100
- data/spec/model/dataset_methods_spec.rb +45 -27
- data/spec/model/eager_loading_spec.rb +828 -692
- data/spec/model/hooks_spec.rb +355 -67
- data/spec/model/model_spec.rb +251 -179
- data/spec/model/plugins_spec.rb +24 -13
- data/spec/model/record_spec.rb +506 -232
- data/spec/model/spec_helper.rb +16 -77
- data/spec/model/validations_spec.rb +38 -2
- data/spec/rcov.opts +2 -0
- metadata +223 -81
- data/spec/core/core_sql_spec.rb +0 -451
data/doc/dataset_filtering.rdoc
CHANGED
|
@@ -4,171 +4,183 @@ Sequel is very flexibile when it comes to filtering records. You can specify you
|
|
|
4
4
|
|
|
5
5
|
== Filtering using a custom filter string
|
|
6
6
|
|
|
7
|
-
If you wish to write your SQL by hand, you can just supply it to the dataset's #
|
|
7
|
+
If you wish to write your SQL by hand, you can just supply it to the dataset's #where method:
|
|
8
8
|
|
|
9
|
-
items.
|
|
9
|
+
items.where('x < 10').sql
|
|
10
10
|
#=> "SELECT * FROM items WHERE x < 10"
|
|
11
11
|
|
|
12
12
|
In order to prevent SQL injection, you can replace literal values with question marks and supply the values as additional arguments:
|
|
13
13
|
|
|
14
|
-
items.
|
|
14
|
+
items.where('category = ?', 'ruby').sql
|
|
15
15
|
#=> "SELECT * FROM items WHERE category = 'ruby'"
|
|
16
16
|
|
|
17
17
|
You can also use placeholders with :placeholder and a hash of placeholder values:
|
|
18
18
|
|
|
19
|
-
items.
|
|
19
|
+
items.where('category = :category', :category=>'ruby').sql
|
|
20
20
|
#=> "SELECT * FROM items WHERE category = 'ruby'"
|
|
21
21
|
|
|
22
22
|
=== Specifying SQL functions
|
|
23
23
|
|
|
24
|
-
Sequel also allows you to specify functions by using the
|
|
24
|
+
Sequel also allows you to specify functions by using the Sequel.function method:
|
|
25
25
|
|
|
26
|
-
items.literal(
|
|
26
|
+
items.literal(Sequel.function(:avg, :price)) #=> "avg(price)"
|
|
27
27
|
|
|
28
28
|
If you are specifying a filter/selection/order, you can use a virtual row block:
|
|
29
29
|
|
|
30
30
|
items.select{avg(price)}
|
|
31
31
|
|
|
32
|
+
You can also use the {core_extensions extension}[link:files/doc/core_extensions_rdoc.html] and the +sql_function+ method:
|
|
33
|
+
|
|
34
|
+
:avg.sql_function(:price)
|
|
35
|
+
|
|
32
36
|
== Filtering using a hash
|
|
33
37
|
|
|
34
38
|
If you just need to compare records against values, you can supply a hash:
|
|
35
39
|
|
|
36
|
-
items.
|
|
40
|
+
items.where(:category => 'ruby').sql
|
|
37
41
|
#=> "SELECT * FROM items WHERE (category = 'ruby')"
|
|
38
42
|
|
|
39
43
|
Sequel can check for null values:
|
|
40
44
|
|
|
41
|
-
items.
|
|
45
|
+
items.where(:category => nil).sql
|
|
42
46
|
#=> "SELECT * FROM items WHERE (category IS NULL)"
|
|
43
47
|
|
|
44
48
|
Or compare two columns:
|
|
45
49
|
|
|
46
|
-
items.
|
|
50
|
+
items.where(:x => :some_table__y).sql
|
|
47
51
|
#=> "SELECT * FROM items WHERE (x = some_table.y)"
|
|
48
52
|
|
|
49
53
|
And also compare against multiple values:
|
|
50
54
|
|
|
51
|
-
items.
|
|
55
|
+
items.where(:category => ['ruby', 'perl']).sql
|
|
52
56
|
#=> "SELECT * FROM items WHERE (category IN ('ruby', 'perl'))"
|
|
53
57
|
|
|
54
58
|
Ranges (both inclusive and exclusive) can also be used:
|
|
55
59
|
|
|
56
|
-
items.
|
|
60
|
+
items.where(:price => 100..200).sql
|
|
57
61
|
#=> "SELECT * FROM items WHERE (price >= 100 AND price <= 200)"
|
|
58
62
|
|
|
59
|
-
items.
|
|
63
|
+
items.where(:price => 100...200).sql
|
|
60
64
|
#=> "SELECT * FROM items WHERE (price >= 100 AND price < 200)"
|
|
61
65
|
|
|
66
|
+
== Filtering using an array
|
|
67
|
+
|
|
68
|
+
If you need to select multiple items from a dataset, you can supply an array:
|
|
69
|
+
|
|
70
|
+
item_array = [1, 38, 47, 99]
|
|
71
|
+
items.where(:id => item_array).sql
|
|
72
|
+
#=> "SELECT * FROM items WHERE (id IN (1, 38, 47, 99))"
|
|
73
|
+
|
|
62
74
|
== Filtering using expressions
|
|
63
75
|
|
|
64
|
-
|
|
76
|
+
You can pass a block to where, which is evaluated in a special context:
|
|
65
77
|
|
|
66
|
-
items.
|
|
78
|
+
items.where{price * 2 < 50}.sql
|
|
67
79
|
#=> "SELECT * FROM items WHERE ((price * 2) < 50)
|
|
68
80
|
|
|
69
|
-
This works for the standard inequality and arithmetic operators
|
|
81
|
+
This works for the standard inequality and arithmetic operators:
|
|
70
82
|
|
|
71
|
-
items.
|
|
83
|
+
items.where{price + 100 < 200}.sql
|
|
72
84
|
#=> "SELECT * FROM items WHERE ((price + 100) < 200)
|
|
73
85
|
|
|
74
|
-
items.
|
|
86
|
+
items.where{price - 100 > 200}.sql
|
|
75
87
|
#=> "SELECT * FROM items WHERE ((price - 100) > 200)
|
|
76
88
|
|
|
77
|
-
items.
|
|
89
|
+
items.where{price * 100 <= 200}.sql
|
|
78
90
|
#=> "SELECT * FROM items WHERE ((price * 100) <= 200)
|
|
79
91
|
|
|
80
|
-
items.
|
|
92
|
+
items.where{price / 100 >= 200}.sql
|
|
81
93
|
#=> "SELECT * FROM items WHERE ((price / 100) >= 200)
|
|
82
94
|
|
|
83
95
|
You use the overloaded bitwise and (&) and or (|) operators to combine expressions:
|
|
84
96
|
|
|
85
|
-
items.
|
|
97
|
+
items.where{(price + 100 < 200) & (price * 100 <= 200)}.sql
|
|
86
98
|
#=> "SELECT * FROM items WHERE (((price + 100) < 200) AND ((price * 100) <= 200))
|
|
87
99
|
|
|
88
|
-
items.
|
|
100
|
+
items.where{(price - 100 > 200) | (price / 100 >= 200)}.sql
|
|
89
101
|
#=> "SELECT * FROM items WHERE (((price - 100) > 200) OR ((price / 100) >= 200))
|
|
90
102
|
|
|
91
|
-
To filter by equality, you use the standard hash, which can be combined with other
|
|
103
|
+
To filter by equality, you use the standard hash, which can be combined with other expressions using Sequel.& and Sequel.|:
|
|
92
104
|
|
|
93
|
-
items.
|
|
105
|
+
items.where{Sequel.&({:category => 'ruby'}, (price + 100 < 200))}.sql
|
|
94
106
|
#=> "SELECT * FROM items WHERE ((category = 'ruby') AND ((price + 100) < 200))"
|
|
95
107
|
|
|
96
108
|
This works with other hash values, such as arrays and ranges:
|
|
97
109
|
|
|
98
|
-
items.
|
|
110
|
+
items.where{Sequel.|({:category => ['ruby', 'other']}, (:price - 100 > 200))}.sql
|
|
99
111
|
#=> "SELECT * FROM items WHERE ((category IN ('ruby', 'other')) OR ((price - 100) <= 200))"
|
|
100
112
|
|
|
101
|
-
items.
|
|
113
|
+
items.where{Sequel.&({:price => (100..200)}, :active)).sql
|
|
102
114
|
#=> "SELECT * FROM items WHERE ((price >= 100 AND price <= 200) AND active)"
|
|
103
115
|
|
|
104
116
|
=== Negating conditions
|
|
105
117
|
|
|
106
|
-
You can use the
|
|
118
|
+
You can use the exclude method to exclude conditions:
|
|
107
119
|
|
|
108
|
-
items.
|
|
120
|
+
items.exclude(:category => 'ruby').sql
|
|
109
121
|
#=> "SELECT * FROM items WHERE (category != 'ruby')"
|
|
110
122
|
|
|
111
|
-
items.
|
|
123
|
+
items.exclude(:active).sql
|
|
112
124
|
#=> "SELECT * FROM items WHERE NOT active"
|
|
113
125
|
|
|
114
|
-
items.
|
|
126
|
+
items.exclude{price / 100 >= 200}.sql
|
|
115
127
|
#=> "SELECT * FROM items WHERE ((price / 100) < 200)
|
|
116
128
|
|
|
117
129
|
=== Comparing against column references
|
|
118
130
|
|
|
119
131
|
You can also compare against other columns:
|
|
120
132
|
|
|
121
|
-
items.
|
|
133
|
+
items.where{credit > debit}.sql
|
|
122
134
|
#=> "SELECT * FROM items WHERE (credit > debit)
|
|
123
135
|
|
|
124
136
|
Or against SQL functions:
|
|
125
137
|
|
|
126
|
-
items.
|
|
138
|
+
items.where{price - 100 < max(price)}.sql
|
|
127
139
|
#=> "SELECT * FROM items WHERE ((price - 100) < max(price))"
|
|
128
140
|
|
|
129
141
|
== String search functions
|
|
130
142
|
|
|
131
|
-
You can search SQL strings using the
|
|
143
|
+
You can search SQL strings using the Sequel.like method:
|
|
132
144
|
|
|
133
|
-
items.
|
|
145
|
+
items.where(Sequel.like(:name, 'Acme%')).sql
|
|
134
146
|
#=> "SELECT * FROM items WHERE (name LIKE 'Acme%')"
|
|
135
147
|
|
|
136
148
|
You can specify a Regexp as a like argument, but this will probably only work
|
|
137
149
|
on PostgreSQL and MySQL:
|
|
138
150
|
|
|
139
|
-
items.
|
|
151
|
+
items.where(Sequel.like(:name, /Acme.*/)).sql
|
|
140
152
|
#=> "SELECT * FROM items WHERE (name ~ 'Acme.*')"
|
|
141
153
|
|
|
142
154
|
Like can also take more than one argument:
|
|
143
155
|
|
|
144
|
-
items.
|
|
156
|
+
items.where(Sequel.like(:name, 'Acme%', /Beta.*/)).sql
|
|
145
157
|
#=> "SELECT * FROM items WHERE ((name LIKE 'Acme%') OR (name ~ 'Beta.*'))"
|
|
146
158
|
|
|
147
159
|
== String concatenation
|
|
148
160
|
|
|
149
|
-
You can concatenate SQL strings using
|
|
161
|
+
You can concatenate SQL strings using Sequel.join:
|
|
150
162
|
|
|
151
|
-
items.
|
|
163
|
+
items.where(Sequel.join([:name, :comment]).like('%acme%')).sql
|
|
152
164
|
#=> "SELECT * FROM items WHERE ((name || comment) LIKE 'Acme%')"
|
|
153
165
|
|
|
154
166
|
Array#sql_string_join also takes a join argument:
|
|
155
167
|
|
|
156
|
-
items.filter([:name, :comment]
|
|
168
|
+
items.filter(Sequel.join([:name, :comment], ' ').like('%acme%')).sql
|
|
157
169
|
#=> "SELECT * FROM items WHERE ((name || ' ' || comment) LIKE 'Acme%')"
|
|
158
170
|
|
|
159
171
|
== Filtering using sub-queries
|
|
160
172
|
|
|
161
173
|
One of the best features of Sequel is the ability to use datasets as sub-queries. Sub-queries can be very useful for filtering records, and many times provide a simpler alternative to table joins. Sub-queries can be used in all forms of filters:
|
|
162
174
|
|
|
163
|
-
refs = consumer_refs.
|
|
164
|
-
consumers.
|
|
175
|
+
refs = consumer_refs.where(:logged_in).select(:consumer_id)
|
|
176
|
+
consumers.where(:id => refs).sql
|
|
165
177
|
#=> "SELECT * FROM consumers WHERE (id IN (SELECT consumer_id FROM consumer_refs WHERE logged_in))"
|
|
166
178
|
|
|
167
179
|
Note that if you are checking for the inclusion of a single column in a subselect, the subselect should only select a single column.
|
|
168
180
|
|
|
169
181
|
== Using OR instead of AND
|
|
170
182
|
|
|
171
|
-
By default, if you chain calls to +
|
|
183
|
+
By default, if you chain calls to +where+, the conditions get ANDed together. If you want to use an OR for a condition, you can use the +or+ method:
|
|
172
184
|
|
|
173
|
-
items.
|
|
185
|
+
items.where(:name=>'Food').or(:vendor=>1).sql
|
|
174
186
|
#=> "SELECT * FROM items WHERE ((name = 'Food') OR (vendor = 1))"
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
= Sequel::Model Mass Assignment
|
|
2
|
+
|
|
3
|
+
Most Model methods that take a hash of attribute keys and values, including <tt>Model.new</tt>, <tt>Model.create</tt>, <tt>Model#set</tt> and <tt>Model#update</tt> are subject to Sequel's mass assignment rules.
|
|
4
|
+
When you pass a hash to these methods, each key has an <tt>=</tt> appended to it (the setter method), and if the setter method exists and access to it is not restricted, Sequel will call the setter method with the hash value.
|
|
5
|
+
By default, there are two types of setter methods that are restricted.
|
|
6
|
+
The first is methods like <tt>typecast_on_assignment=</tt> and <tt>==</tt>, which don't affect columns.
|
|
7
|
+
These methods cannot be enabled for mass assignment.
|
|
8
|
+
The second is primary key setters.
|
|
9
|
+
To enable use of primary key setters, you need to call +unrestrict_primary_key+ for that model:
|
|
10
|
+
|
|
11
|
+
Post.unrestrict_primary_key
|
|
12
|
+
|
|
13
|
+
Since mass assignment by default allows modification of all column values except for primary key columns, it can be a security risk in some cases.
|
|
14
|
+
Sequel has multiple ways of securing mass assignment.
|
|
15
|
+
The first way is using +set_allowed_columns+:
|
|
16
|
+
|
|
17
|
+
Post.set_allowed_columns :title, :body, :category
|
|
18
|
+
|
|
19
|
+
This explicitly sets which methods are allowed (<tt>title=</tt>, <tt>body=</tt>, and <tt>category=</tt>), all other methods will not be allowed.
|
|
20
|
+
This method is useful in simple applications where the same columns are allowed in all cases, but not appropriate when different columns are allowed in different scenarios (e.g. admin access vs. user access).
|
|
21
|
+
To handle cases where different columns are allowed in different cases, you can use +set_only+ or +update_only+:
|
|
22
|
+
|
|
23
|
+
# user case
|
|
24
|
+
post.set_only(params[:post], :title, :body)
|
|
25
|
+
# admin case
|
|
26
|
+
post.set_only(params[:post], :title, :body, :deleted)
|
|
27
|
+
|
|
28
|
+
In this case, only the <tt>title=</tt> and <tt>body=</tt> methods will be allowed in the mass assignment in the user case, and only <tt>title=</tt>, <tt>body=</tt>, and <tt>deleted=</tt> will be allowed for mass assignment in the admin case.
|
|
29
|
+
|
|
30
|
+
By default, if an invalid setter method call is attempted, Sequel raises a <tt>Sequel::Error</tt> exception. You can have Sequel silently ignore invalid calls by doing:
|
|
31
|
+
|
|
32
|
+
# Global default
|
|
33
|
+
Sequel::Model.strict_param_setting = false
|
|
34
|
+
# Class level
|
|
35
|
+
Post.strict_param_setting = false
|
|
36
|
+
# Instance level
|
|
37
|
+
post.strict_param_setting = false
|
|
38
|
+
|
|
39
|
+
These mass assignment methods have been around a long time, but starting in Sequel 3.12.0, the +set_fields+ and +update_fields+ methods were added, and these may be a better mass assignment choice for most users.
|
|
40
|
+
These methods take two arguments, the attributes hash as the first argument, and a single array of valid field names as the second argument:
|
|
41
|
+
|
|
42
|
+
post.set_fields(params[:post], [:title, :body])
|
|
43
|
+
|
|
44
|
+
+set_fields+ and +update_fields+ differ in implementation from +set_only+ and +update_only+.
|
|
45
|
+
With +set_only+ and +update_only+, the hash is iterated over and it checks each method call attempt to see if it is valid.
|
|
46
|
+
With +set_fields+ and +update_fields+, the array is iterated over, and it just looks up the value in the hash and calls the appropriate setter method.
|
|
47
|
+
|
|
48
|
+
+set_fields+ and +update_fields+ are designed for the case where you are expecting specific fields in the input, and want to ignore the other fields.
|
|
49
|
+
They work great for things like HTML forms where the form fields are static.
|
|
50
|
+
+set_only+ and +update_only+ are designed for cases where you are not sure what fields are going to be present in the input, but still want to make sure only certain setter methods can be called.
|
|
51
|
+
They work great for flexible APIs.
|
|
52
|
+
|
|
53
|
+
Starting in Sequel 3.34.0, +set_fields+ and +update_fields+ take an optional argument hash, and currently handles the :missing option. With <tt>:missing=>:skip</tt>, +set_fields+ and +update_fields+ will just skip missing entries in the hash, allowing them to be used in flexible APIs. With <tt>:missing=>:raise</tt>, +set_fields+ and +update_fields+ will raise an error if one of the entries in the hash is missing, instead of just assigning the value to nil or whatever the hash's default value is. That allows stricter checks, similar to the :strict_param_checking setting for the default mass assignment methods.
|
|
54
|
+
|
|
55
|
+
In all of the mass assignment cases, methods starting with +set+ will set the attributes without saving the object, while methods starting with +update+ will set the attributes and then save the changes to the object.
|
|
56
|
+
|