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/querying.rdoc
CHANGED
|
@@ -10,7 +10,9 @@ aims to be a gentle introduction to Sequel's querying support.
|
|
|
10
10
|
|
|
11
11
|
While you can easily use raw SQL with Sequel, a large part of the
|
|
12
12
|
advantage you get from using Sequel is Sequel's ability to abstract
|
|
13
|
-
SQL from you and give you a much nicer interface.
|
|
13
|
+
SQL from you and give you a much nicer interface. Sequel also ships with
|
|
14
|
+
a {core_extensions extension}[link:files/doc/core_extensions_rdoc.html],
|
|
15
|
+
which better integrates Sequel's DSL into the ruby language.
|
|
14
16
|
|
|
15
17
|
== Retrieving Objects
|
|
16
18
|
|
|
@@ -57,7 +59,7 @@ Any options you pass to +first+ will be used as a filter:
|
|
|
57
59
|
# SELECT * FROM artists WHERE (name = 'YJM') LIMIT 1
|
|
58
60
|
=> #<Artist @values={:name=>"YJM", :id=>1}>
|
|
59
61
|
|
|
60
|
-
artist = Artist.first(
|
|
62
|
+
artist = Artist.first(Sequel.like(:name, 'Y%'))
|
|
61
63
|
# SELECT * FROM artists WHERE (name LIKE 'Y%') LIMIT 1
|
|
62
64
|
=> #<Artist @values={:name=>"YJM", :id=>1}>
|
|
63
65
|
|
|
@@ -69,12 +71,12 @@ requires an argument:
|
|
|
69
71
|
=> {:name=>"YJM", :id=>1}
|
|
70
72
|
|
|
71
73
|
Note that while Model.[] allows you to pass a primary key directly,
|
|
72
|
-
Dataset#[] does not.
|
|
74
|
+
Dataset#[] does not (unless it is a model dataset).
|
|
73
75
|
|
|
74
76
|
==== Using +last+
|
|
75
77
|
|
|
76
78
|
If you want the last record in the dataset,
|
|
77
|
-
<tt>Sequel::Dataset#last</tt> is an obvious method to use. Note
|
|
79
|
+
<tt>Sequel::Dataset#last</tt> is an obvious method to use. Note
|
|
78
80
|
that last requires that the dataset be ordered. Without an order, any
|
|
79
81
|
object can be considered the first as well as the last.
|
|
80
82
|
|
|
@@ -162,22 +164,38 @@ It's also common to want to order such a map, so Sequel provides a
|
|
|
162
164
|
# SELECT name FROM artists ORDER BY name
|
|
163
165
|
=> ["AS", "YJM"]
|
|
164
166
|
|
|
167
|
+
In all of these cases, you can provide an array of column symbols and
|
|
168
|
+
an array of arrays of values will be returned:
|
|
169
|
+
|
|
170
|
+
artist_names = Artist.select_map([:id, :name])
|
|
171
|
+
# SELECT id, name FROM artists
|
|
172
|
+
=> [[1, "YJM"], [2, "AS"]]
|
|
173
|
+
|
|
165
174
|
==== As a Hash
|
|
166
175
|
|
|
167
176
|
Sequel makes it easy to take an SQL query and return it as a ruby hash,
|
|
168
177
|
using the +to_hash+ method:
|
|
169
178
|
|
|
170
|
-
artist_names = Artist.to_hash(:
|
|
179
|
+
artist_names = Artist.to_hash(:id, :name)
|
|
171
180
|
# SELECT * FROM artists
|
|
172
|
-
=> {"YJM"
|
|
181
|
+
=> {1=>"YJM", 2=>"AS"}
|
|
173
182
|
|
|
174
183
|
As you can see, the +to_hash+ method uses the first symbol as the key
|
|
175
184
|
and the second symbol as the value. So if you swap the two arguments the hash
|
|
176
185
|
will have its keys and values transposed:
|
|
177
186
|
|
|
178
|
-
artist_names = Artist.to_hash(:
|
|
187
|
+
artist_names = Artist.to_hash(:name, :id)
|
|
179
188
|
# SELECT * FROM artists
|
|
180
|
-
=> {
|
|
189
|
+
=> {"YJM"=>1, "AS"=>2}
|
|
190
|
+
|
|
191
|
+
Now what if you have multiple values for the same key? By default, +to_hash+
|
|
192
|
+
will just have the last matching value. If you care about all matching values,
|
|
193
|
+
use +to_hash_groups+, which makes the values of the array an array of matching
|
|
194
|
+
values, in the order they were received:
|
|
195
|
+
|
|
196
|
+
artist_names = Artist.to_hash_groups(:name, :id)
|
|
197
|
+
# SELECT * FROM artists
|
|
198
|
+
=> {"YJM"=>[1, 10, ...], "AS"=>[2, 20, ...]}
|
|
181
199
|
|
|
182
200
|
If you only provide one argument to +to_hash+, it uses the entire hash
|
|
183
201
|
or model object as the value:
|
|
@@ -186,6 +204,12 @@ or model object as the value:
|
|
|
186
204
|
# SELECT * FROM artists
|
|
187
205
|
=> {"YJM"=>{:id=>1, :name=>"YJM"}, "AS"=>{:id=>2, :name=>"AS"}}
|
|
188
206
|
|
|
207
|
+
and +to_hash_groups+ works similarly:
|
|
208
|
+
|
|
209
|
+
artist_names = DB[:artists].to_hash_groups(:name)
|
|
210
|
+
# SELECT * FROM artists
|
|
211
|
+
=> {"YJM"=>[{:id=>1, :name=>"YJM"}, {:id=>10, :name=>"YJM"}], ...}
|
|
212
|
+
|
|
189
213
|
Model datasets have a +to_hash+ method that can be called without any
|
|
190
214
|
arguments, in which case it will use the primary key as the key and
|
|
191
215
|
the model object as the value. This can be used to easily create an
|
|
@@ -196,6 +220,9 @@ identity map:
|
|
|
196
220
|
=> {1=>#<Artist @values={:id=>1, :name=>"YGM"}>,
|
|
197
221
|
2=>#<Artist @values={:id=>2, :name=>"AS"}>}
|
|
198
222
|
|
|
223
|
+
There is no equivalent handling to +to_hash_groups+, since there would
|
|
224
|
+
only be one matching record, as the primary key must be unique.
|
|
225
|
+
|
|
199
226
|
Note that +to_hash+ never modifies the columns selected. However, just
|
|
200
227
|
like Sequel has a +select_map+ method to modify the columns selected and
|
|
201
228
|
return an array, Sequel also has a +select_hash+ method to modify the
|
|
@@ -205,6 +232,12 @@ columns selected and return a hash:
|
|
|
205
232
|
# SELECT name, id FROM artists
|
|
206
233
|
=> {"YJM"=>1, "AS"=>2}
|
|
207
234
|
|
|
235
|
+
Likewise, +select_hash_groups+ also exists:
|
|
236
|
+
|
|
237
|
+
artist_names = Artist.select_hash_groups(:name, :id)
|
|
238
|
+
# SELECT name, id FROM artists
|
|
239
|
+
=> {"YJM"=>[1, 10, ...], "AS"=>[2, 20, ...]}
|
|
240
|
+
|
|
208
241
|
== Modifying datasets
|
|
209
242
|
|
|
210
243
|
Note that the retrieval methods discussed above just return
|
|
@@ -232,7 +265,7 @@ table +artists+:
|
|
|
232
265
|
Let's say we are only interested in the artists whose names
|
|
233
266
|
start with "A":
|
|
234
267
|
|
|
235
|
-
ds2 = ds1.where(
|
|
268
|
+
ds2 = ds1.where(Sequel.like(:name, 'A%'))
|
|
236
269
|
# SELECT * FROM artists WHERE name LIKE 'A%'
|
|
237
270
|
|
|
238
271
|
Here we see that +where+ returns a dataset that adds a +WHERE+
|
|
@@ -282,47 +315,47 @@ of condition is used depends on the values in the hash.
|
|
|
282
315
|
Unless Sequel has special support for the value's class, it uses a simple
|
|
283
316
|
equality statement:
|
|
284
317
|
|
|
285
|
-
Artist.
|
|
318
|
+
Artist.where(:id=>1)
|
|
286
319
|
# SELECT * FROM artists WHERE id = 1
|
|
287
320
|
|
|
288
|
-
Artist.
|
|
321
|
+
Artist.where(:name=>'YJM')
|
|
289
322
|
# SELECT * FROM artists WHERE name = 'YJM'
|
|
290
323
|
|
|
291
324
|
For arrays, Sequel uses the IN operator.
|
|
292
325
|
|
|
293
|
-
Artist.
|
|
326
|
+
Artist.where(:id=>[1, 2])
|
|
294
327
|
# SELECT * FROM artists WHERE id IN (1, 2)
|
|
295
328
|
|
|
296
329
|
For datasets, Sequel uses the IN operator with a subselect:
|
|
297
330
|
|
|
298
|
-
Artist.
|
|
331
|
+
Artist.where(:id=>Album.select(:artist_id))
|
|
299
332
|
# SELECT * FROM artists WHERE id IN (
|
|
300
333
|
# SELECT artist_id FROM albums)
|
|
301
334
|
|
|
302
335
|
For boolean values such as nil, true, and false, Sequel uses the IS operator:
|
|
303
336
|
|
|
304
|
-
Artist.
|
|
337
|
+
Artist.where(:id=>nil)
|
|
305
338
|
# SELECT * FROM artists WHERE id IS NULL
|
|
306
339
|
|
|
307
340
|
For ranges, Sequel uses a pair of inequality statements:
|
|
308
341
|
|
|
309
|
-
Artist.
|
|
342
|
+
Artist.where(:id=>1..5)
|
|
310
343
|
# SELECT * FROM artists WHERE id >= 1 AND id <= 5
|
|
311
344
|
|
|
312
345
|
Finally, for regexps, Sequel uses an SQL regular expression. Note that this
|
|
313
346
|
is probably only supported on PostgreSQL and MySQL.
|
|
314
347
|
|
|
315
|
-
Artist.
|
|
348
|
+
Artist.where(:name=>/JM$/)
|
|
316
349
|
# SELECT * FROM artists WHERE name ~ 'JM$'
|
|
317
350
|
|
|
318
351
|
If there are multiple arguments in the hash, the filters are ANDed together:
|
|
319
352
|
|
|
320
|
-
Artist.
|
|
353
|
+
Artist.where(:id=>1, :name=>/JM$/)
|
|
321
354
|
# SELECT * FROM artists WHERE id = 1 AND name ~ 'JM$'
|
|
322
355
|
|
|
323
|
-
This works the same as if you used two separate
|
|
356
|
+
This works the same as if you used two separate +where+ calls:
|
|
324
357
|
|
|
325
|
-
Artist.
|
|
358
|
+
Artist.where(:id=>1).where(:name=>/JM$/)
|
|
326
359
|
# SELECT * FROM artists WHERE id = 1 AND name ~ 'JM$'
|
|
327
360
|
|
|
328
361
|
=== Array of Two Element Arrays
|
|
@@ -331,14 +364,14 @@ If you use an array of two element arrays, it is treated as a hash. The only
|
|
|
331
364
|
advantage to using an array of two element arrays is that it allows you to
|
|
332
365
|
duplicate keys, so you can do:
|
|
333
366
|
|
|
334
|
-
Artist.
|
|
367
|
+
Artist.where([[:name, /JM$/], [:name, /^YJ/]])
|
|
335
368
|
# SELECT * FROM artists WHERE name ~ 'JM$' AND name ~ '^YJ'
|
|
336
369
|
|
|
337
370
|
=== Virtual Row Blocks
|
|
338
371
|
|
|
339
|
-
If a block is passed to filter, it is treated as a virtual row block:
|
|
372
|
+
If a block is passed to a filter, it is treated as a virtual row block:
|
|
340
373
|
|
|
341
|
-
Artist.
|
|
374
|
+
Artist.where{id > 5}
|
|
342
375
|
# SELECT * FROM artists WHERE id > 5
|
|
343
376
|
|
|
344
377
|
You can learn more about virtual row blocks in the {"Virtual Rows" guide}[link:files/doc/virtual_rows_rdoc.html].
|
|
@@ -346,7 +379,7 @@ You can learn more about virtual row blocks in the {"Virtual Rows" guide}[link:f
|
|
|
346
379
|
You can provide both regular arguments and a block, in which case the results
|
|
347
380
|
will be ANDed together:
|
|
348
381
|
|
|
349
|
-
Artist.
|
|
382
|
+
Artist.where(:name=>'A'...'M'){id > 5}
|
|
350
383
|
# SELECT * FROM artists WHERE name >= 'A' AND name < 'M' AND id > 5
|
|
351
384
|
|
|
352
385
|
=== Symbols
|
|
@@ -363,28 +396,30 @@ Sequel has a DSL that allows easily creating SQL expressions. These SQL
|
|
|
363
396
|
expressions are instances of subclasses of Sequel::SQL::Expression. You've
|
|
364
397
|
already seen an example earlier:
|
|
365
398
|
|
|
366
|
-
Artist.
|
|
399
|
+
Artist.where(Sequel.like(:name, 'Y%'))
|
|
367
400
|
# SELECT * FROM artists WHERE name LIKE 'Y%'
|
|
368
401
|
|
|
369
|
-
In this case
|
|
402
|
+
In this case Sequel.like returns a Sequel::SQL::BooleanExpression object,
|
|
370
403
|
which is used directly in the filter.
|
|
371
404
|
|
|
372
405
|
You can use the DSL to create arbitrarily complex expressions. SQL::Expression
|
|
373
|
-
objects
|
|
374
|
-
|
|
406
|
+
objects can be created via singleton methods on the Sequel module. The most common
|
|
407
|
+
method is Sequel.expr, which takes any object and wraps it in a SQL::Expression
|
|
408
|
+
object. In most cases, the SQL::Expression returned supports the & operator for
|
|
409
|
+
+AND+, the | operator for +OR+, and the ~ operator for inversion:
|
|
375
410
|
|
|
376
|
-
Artist.
|
|
411
|
+
Artist.where(Sequel.like(:name, 'Y%') & (Sequel.expr(:b=>1) | Sequel.~(:c=>3)))
|
|
377
412
|
# SELECT * FROM artists WHERE name LIKE 'Y%' AND (b = 1 OR c != 3)
|
|
378
413
|
|
|
379
414
|
You can combine these expression operators with the virtual row support:
|
|
380
415
|
|
|
381
|
-
Artist.
|
|
416
|
+
Artist.where{(a > 1) & ~((b(c) < 1) | d)}
|
|
382
417
|
# SELECT * FROM artists WHERE a > 1 AND b(c) >= 1 AND NOT d
|
|
383
418
|
|
|
384
419
|
Note the use of parentheses when using the & and | operators, as they have lower
|
|
385
420
|
precedence than other operators. The following will not work:
|
|
386
421
|
|
|
387
|
-
Artist.
|
|
422
|
+
Artist.where{a > 1 & ~(b(c) < 1 | d)}
|
|
388
423
|
# Raises a TypeError, as it calls Integer#| with a Sequel::SQL::Identifier
|
|
389
424
|
|
|
390
425
|
=== Strings with Placeholders
|
|
@@ -392,24 +427,24 @@ precedence than other operators. The following will not work:
|
|
|
392
427
|
Assuming you want to get your hands dirty and write some SQL, Sequel allows you
|
|
393
428
|
to use strings using placeholders for the values:
|
|
394
429
|
|
|
395
|
-
Artist.
|
|
430
|
+
Artist.where("name LIKE ?", 'Y%')
|
|
396
431
|
# SELECT * FROM artists WHERE name LIKE 'Y%'
|
|
397
432
|
|
|
398
433
|
This is the most common type of placeholder, where each question mark is substituted
|
|
399
434
|
with the next argument:
|
|
400
435
|
|
|
401
|
-
Artist.
|
|
436
|
+
Artist.where("name LIKE ? AND id = ?", 'Y%', 5)
|
|
402
437
|
# SELECT * FROM artists WHERE name LIKE 'Y%' AND id = 5
|
|
403
438
|
|
|
404
439
|
You can also use named placeholders with a hash, where the named placeholders use
|
|
405
440
|
colons before the placeholder names:
|
|
406
441
|
|
|
407
|
-
Artist.
|
|
442
|
+
Artist.where("name LIKE :name AND id = :id", :name=>'Y%', :id=>5)
|
|
408
443
|
# SELECT * FROM artists WHERE name LIKE 'Y%' AND id = 5
|
|
409
444
|
|
|
410
445
|
You don't have to provide any placeholders if you don't want to:
|
|
411
446
|
|
|
412
|
-
Artist.
|
|
447
|
+
Artist.where("id = 2")
|
|
413
448
|
# SELECT * FROM artists WHERE id = 2
|
|
414
449
|
|
|
415
450
|
However, if you are using any untrusted input, you should definitely be using placeholders.
|
|
@@ -417,9 +452,9 @@ In general, unless you are hardcoding values in the strings, you should use plac
|
|
|
417
452
|
You should never pass a string that has been built using interpolation, unless you are
|
|
418
453
|
sure of what you are doing.
|
|
419
454
|
|
|
420
|
-
Artist.
|
|
421
|
-
Artist.
|
|
422
|
-
Artist.
|
|
455
|
+
Artist.where("id = #{params[:id]}") # Don't do this!
|
|
456
|
+
Artist.where("id = ?", params[:id]) # Do this instead
|
|
457
|
+
Artist.where(:id=>params[:id]) # Even better
|
|
423
458
|
|
|
424
459
|
=== Inverting
|
|
425
460
|
|
|
@@ -427,12 +462,12 @@ You may be wondering how to specify a not equals condition in Sequel, or the NOT
|
|
|
427
462
|
operator. Sequel has generic support for inverting conditions, so to write a not
|
|
428
463
|
equals condition, you write an equals condition, and invert it:
|
|
429
464
|
|
|
430
|
-
Artist.
|
|
465
|
+
Artist.where(:id=>5).invert
|
|
431
466
|
# SELECT * FROM artists WHERE id != 5
|
|
432
467
|
|
|
433
468
|
Note that +invert+ inverts the entire filter:
|
|
434
469
|
|
|
435
|
-
Artist.
|
|
470
|
+
Artist.where(:id=>5).where{name > 'A'}.invert
|
|
436
471
|
# SELECT * FROM artists WHERE id != 5 OR name <= 'A'
|
|
437
472
|
|
|
438
473
|
In general, +invert+ is used rarely, since +exclude+ allows you to invert only specific
|
|
@@ -441,7 +476,7 @@ filters:
|
|
|
441
476
|
Artist.exclude(:id=>5)
|
|
442
477
|
# SELECT * FROM artists WHERE id != 5
|
|
443
478
|
|
|
444
|
-
Artist.
|
|
479
|
+
Artist.where(:id=>5).exclude{name > 'A'}
|
|
445
480
|
# SELECT * FROM artists WHERE id = 5 OR name <= 'A'
|
|
446
481
|
|
|
447
482
|
So to do a NOT IN with an array:
|
|
@@ -451,14 +486,14 @@ So to do a NOT IN with an array:
|
|
|
451
486
|
|
|
452
487
|
Or to use the NOT LIKE operator:
|
|
453
488
|
|
|
454
|
-
Artist.exclude(
|
|
489
|
+
Artist.exclude(Sequel.like(:name, '%J%'))
|
|
455
490
|
# SELECT * FROM artists WHERE name NOT LIKE '%J%'
|
|
456
491
|
|
|
457
492
|
=== Removing
|
|
458
493
|
|
|
459
494
|
To remove all existing filters, use +unfiltered+:
|
|
460
495
|
|
|
461
|
-
Artist.
|
|
496
|
+
Artist.where(:id=>1).unfiltered
|
|
462
497
|
# SELECT * FROM artists
|
|
463
498
|
|
|
464
499
|
== Ordering
|
|
@@ -474,7 +509,7 @@ You can specify multiple arguments to order by more than one column:
|
|
|
474
509
|
Album.order(:artist_id, :id)
|
|
475
510
|
# SELECT * FROM album ORDER BY artist_id, id
|
|
476
511
|
|
|
477
|
-
Note that unlike +
|
|
512
|
+
Note that unlike +where+, +order+ replaces an existing order, it does not
|
|
478
513
|
append to an existing order:
|
|
479
514
|
|
|
480
515
|
Artist.order(:id).order(:name)
|
|
@@ -499,15 +534,15 @@ order, using +reverse+:
|
|
|
499
534
|
# SELECT FROM artists ORDER BY id DESC
|
|
500
535
|
|
|
501
536
|
As you might expect, +reverse+ is not used all that much. In general,
|
|
502
|
-
<tt>
|
|
537
|
+
<tt>Sequel.desc</tt> is used more commonly to specify a descending order
|
|
503
538
|
for columns:
|
|
504
539
|
|
|
505
|
-
Artist.order(:id
|
|
540
|
+
Artist.order(Sequel.desc(:id))
|
|
506
541
|
# SELECT FROM artists ORDER BY id DESC
|
|
507
542
|
|
|
508
543
|
This allows you to easily use both ascending and descending orders:
|
|
509
544
|
|
|
510
|
-
Artist.order(:name, :id
|
|
545
|
+
Artist.order(:name, Sequel.desc(:id))
|
|
511
546
|
# SELECT FROM artists ORDER BY name, id DESC
|
|
512
547
|
|
|
513
548
|
=== Removing
|
|
@@ -559,6 +594,12 @@ columns, use +select_all+:
|
|
|
559
594
|
Artist.select(:id).select_all
|
|
560
595
|
# SELECT * FROM artists
|
|
561
596
|
|
|
597
|
+
To select all columns from a given table, provide an argument to
|
|
598
|
+
+select_all+:
|
|
599
|
+
|
|
600
|
+
Artist.select_all(:artists)
|
|
601
|
+
# SELECT artists.* FROM artists
|
|
602
|
+
|
|
562
603
|
=== Distinct
|
|
563
604
|
|
|
564
605
|
To treat duplicate rows as a single row when retrieving the records,
|
|
@@ -613,6 +654,17 @@ and Sequel provides a +group_and_count+ method to make this easier:
|
|
|
613
654
|
|
|
614
655
|
This will return the number of albums for each artist_id.
|
|
615
656
|
|
|
657
|
+
If you want to select and group on the same columns, you can use +select_group+:
|
|
658
|
+
|
|
659
|
+
Album.select_group(:artist_id)
|
|
660
|
+
# SELECT artist_id FROM albums GROUP BY artist_id
|
|
661
|
+
|
|
662
|
+
Usually you would add a +select_append+ call after that, to add some sort of
|
|
663
|
+
aggregation:
|
|
664
|
+
|
|
665
|
+
Album.select_group(:artist_id).select_append{sum(num_tracks).as(tracks)}
|
|
666
|
+
# SELECT artist_id, sum(num_tracks) AS tracks FROM albums GROUP BY artist_id
|
|
667
|
+
|
|
616
668
|
== Having
|
|
617
669
|
|
|
618
670
|
The SQL HAVING clause is similar to the WHERE clause, except that
|
|
@@ -632,12 +684,9 @@ will add to the HAVING clause instead of the WHERE clause:
|
|
|
632
684
|
# SELECT artist_id, COUNT(*) AS count FROM albums
|
|
633
685
|
# GROUP BY artist_id HAVING count >= 10 AND count < 15
|
|
634
686
|
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
having{count >= 10}.where(:name.like('A%'))
|
|
639
|
-
# SELECT artist_id, COUNT(*) AS count FROM albums
|
|
640
|
-
# WHERE name LIKE 'A%' GROUP BY artist_id HAVING count >= 10
|
|
687
|
+
This can be confusing, so it is recommended that you always use
|
|
688
|
+
either +having+ or +where+ instead of +filter+, indicating which
|
|
689
|
+
clause that would want affected.
|
|
641
690
|
|
|
642
691
|
Both the WHERE clause and the HAVING clause are removed by +unfiltered+:
|
|
643
692
|
|
|
@@ -678,7 +727,7 @@ can also provide a model class:
|
|
|
678
727
|
|
|
679
728
|
Or a dataset, in which case a subselect is used:
|
|
680
729
|
|
|
681
|
-
Album.join(Artist.
|
|
730
|
+
Album.join(Artist.where{name < 'A'}, :id=>:artist_id)
|
|
682
731
|
# SELECT * FROM albums
|
|
683
732
|
# INNER JOIN (SELECT * FROM artists WHERE (name < 'A')) AS t1
|
|
684
733
|
# ON (t1.id = albums.artist_id)
|
|
@@ -746,6 +795,19 @@ as a hash, but allows for duplicate keys:
|
|
|
746
795
|
And just like in the hash case, unqualified symbol elements in the
|
|
747
796
|
array are implicitly qualified.
|
|
748
797
|
|
|
798
|
+
By default, Sequel only qualifies unqualified symbols in the conditions. However,
|
|
799
|
+
You can provide an options hash with a <tt>:qualify=>:deep</tt> option to do a deep
|
|
800
|
+
qualification, which can qualify subexpressions. For example, let's say you are doing
|
|
801
|
+
a JOIN using case insensitive string comparison:
|
|
802
|
+
|
|
803
|
+
Album.join(:artists, {Sequel.function(:lower, :name) =>
|
|
804
|
+
Sequel.function(:lower, :artist_name)},
|
|
805
|
+
:qualify => :deep)
|
|
806
|
+
# SELECT * FROM albums INNER JOIN artists
|
|
807
|
+
# ON (lower(artists.name) = lower(albums.artist_name))
|
|
808
|
+
|
|
809
|
+
Note how the arguments to lower were qualified correctly in both cases.
|
|
810
|
+
|
|
749
811
|
==== USING Joins
|
|
750
812
|
|
|
751
813
|
The most common type of join conditions is a JOIN ON, as displayed
|
|
@@ -788,7 +850,7 @@ and artists tables, but only want albums where the artist's name
|
|
|
788
850
|
comes before the album's name.
|
|
789
851
|
|
|
790
852
|
Album.join(:artists, :id=>:artist_id) do |j, lj, js|
|
|
791
|
-
|
|
853
|
+
Sequel.qualify(j, :name) < Sequel.qualify(lj, :name)
|
|
792
854
|
end
|
|
793
855
|
# SELECT * FROM albums INNER JOIN artists
|
|
794
856
|
# ON artists.id = albums.artist_id
|
|
@@ -888,6 +950,25 @@ With either of these methods, you can use placeholders:
|
|
|
888
950
|
DB[:albums].with_sql("SELECT * FROM artists WHERE id = :id", :id=>5)
|
|
889
951
|
# SELECT * FROM artists WHERE id = 5
|
|
890
952
|
|
|
953
|
+
Note that if you specify the dataset using custom SQL, you can still call the dataset
|
|
954
|
+
modification methods, but in many cases they will appear to have no affect:
|
|
955
|
+
|
|
956
|
+
DB["SELECT * FROM artists"].select(:name).order(:id)
|
|
957
|
+
# SELECT * FROM artists
|
|
958
|
+
|
|
959
|
+
If you must drop down to using custom SQL, it's recommended that you only do so for
|
|
960
|
+
specific parts of a query. For example, if the reason you are using custom SQL is
|
|
961
|
+
to use a custom operator in the database in the SELECT clause:
|
|
962
|
+
|
|
963
|
+
DB["SELECT name, (foo !@# ?) AS baz FROM artists", 'bar']
|
|
964
|
+
|
|
965
|
+
it's better to use Sequel's DSL, and use a literal string for the custom operator:
|
|
966
|
+
|
|
967
|
+
DB[:artists].select(:name, Sequel.lit("(foo !@# ?)", 'bar').as(:baz))
|
|
968
|
+
|
|
969
|
+
That way Sequel's method chaining still works, and it increases Sequel's ability to
|
|
970
|
+
introspect the code.
|
|
971
|
+
|
|
891
972
|
== Checking for Records
|
|
892
973
|
|
|
893
974
|
If you just want to know whether the current dataset would return any rows, use <tt>empty?</tt>:
|
|
@@ -896,11 +977,11 @@ If you just want to know whether the current dataset would return any rows, use
|
|
|
896
977
|
# SELECT 1 FROM albums LIMIT 1
|
|
897
978
|
=> false
|
|
898
979
|
|
|
899
|
-
Album.
|
|
980
|
+
Album.where(:id=>0).empty?
|
|
900
981
|
# SELECT 1 FROM albums WHERE id = 0 LIMIT 1
|
|
901
982
|
=> true
|
|
902
983
|
|
|
903
|
-
Album.
|
|
984
|
+
Album.where(Sequel.like(:name, 'R%')).empty?
|
|
904
985
|
# SELECT 1 FROM albums WHERE name LIKE 'R%' LIMIT 1
|
|
905
986
|
=> false
|
|
906
987
|
|
data/doc/reflection.rdoc
CHANGED
|
@@ -4,9 +4,9 @@ Sequel supports reflection information in multiple ways.
|
|
|
4
4
|
|
|
5
5
|
== Adapter in Use
|
|
6
6
|
|
|
7
|
-
You can get the adapter in use using Database
|
|
7
|
+
You can get the adapter in use using Database#adapter_scheme:
|
|
8
8
|
|
|
9
|
-
DB.
|
|
9
|
+
DB.adapter_scheme # e.g. :postgres, :jdbc, :odbc
|
|
10
10
|
|
|
11
11
|
== Database Connected To
|
|
12
12
|
|
|
@@ -16,28 +16,54 @@ In some cases, the adapter scheme will be the same as the database to which you
|
|
|
16
16
|
|
|
17
17
|
== Tables in the Database
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
Database#tables gives an array of table name symbols:
|
|
20
20
|
|
|
21
21
|
DB.tables # [:table1, :table2, :table3, ...]
|
|
22
22
|
|
|
23
|
+
== Views in the Database
|
|
24
|
+
|
|
25
|
+
Database#views and gives an array of view name symbols:
|
|
26
|
+
|
|
27
|
+
DB.views # [:view1, :view2, :view3, ...]
|
|
28
|
+
|
|
23
29
|
== Indexes on a table
|
|
24
30
|
|
|
25
|
-
|
|
31
|
+
Database#indexes takes a table name gives a hash of index information. Keys are index names, values are subhashes with the keys :columns and :unique :
|
|
26
32
|
|
|
27
33
|
DB.indexes(:table1) # {:index1=>{:columns=>[:column1], :unique=>false}, :index2=>{:columns=>[:column2, :column3], :unique=>true}}
|
|
28
34
|
|
|
29
35
|
Index information generally does not include partial indexes, functional indexes, or indexes on the primary key of the table.
|
|
30
36
|
|
|
37
|
+
== Foreign Key Information for a Table
|
|
38
|
+
|
|
39
|
+
Database#foreign_key_list takes a table name and gives an array of hashes of foreign key information:
|
|
40
|
+
|
|
41
|
+
DB.foreign_key_list(:table1) # [{:columns=>[:column1], :table=>:referenced_table, :key=>[:referenced_column1]}]
|
|
42
|
+
|
|
43
|
+
At least the following entries will be present in the hash:
|
|
44
|
+
|
|
45
|
+
:columns :: An array of columns in the given table
|
|
46
|
+
:table :: The table referenced by the columns
|
|
47
|
+
:key :: An array of columns referenced (in the table specified by :table), but can be nil on certain adapters
|
|
48
|
+
if the primary key is referenced.
|
|
49
|
+
|
|
50
|
+
The hash may also contain entries for:
|
|
51
|
+
|
|
52
|
+
:deferrable :: Whether the constraint is deferrable
|
|
53
|
+
:name :: The name of the constraint
|
|
54
|
+
:on_delete :: The action to take ON DELETE
|
|
55
|
+
:on_update :: The action to take ON UPDATE
|
|
56
|
+
|
|
31
57
|
== Column Information for a Table
|
|
32
58
|
|
|
33
59
|
Database#schema takes a table symbol and returns column information in an array with each element being an array with two elements. The first elements of the subarray is a column symbol, and the second element is a hash of information about that column. The hash should include the following keys:
|
|
34
60
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
61
|
+
:allow_null :: Whether NULL/nil is an allowed value for this column. Used by the Sequel::Model typecasting code.
|
|
62
|
+
:db_type :: The type of column the database provided, as a string. Used by the schema_dumper plugin for a more specific type translation.
|
|
63
|
+
:default :: The default value of the column, as either a string or nil. Uses a database specific format. Used by the schema_dumper plugin for converting to a ruby value.
|
|
64
|
+
:primary_key :: Whether this column is one of the primary key columns for the table. Used by the Sequel::Model code to determine primary key columns.
|
|
65
|
+
:ruby_default :: The default value of the column as a ruby object, or nil if there is no default or the default could not be successfully parsed into a ruby object.
|
|
66
|
+
:type :: The type of column, as a symbol (e.g. :string). Used by the Sequel::Model typecasting code.
|
|
41
67
|
|
|
42
68
|
Example:
|
|
43
69
|
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
= New Features
|
|
2
|
+
|
|
3
|
+
* Support COLLATE in column definitions. At least MySQL and Microsoft
|
|
4
|
+
SQL Server support them, and PostgreSQL 9.1 should as well.
|
|
5
|
+
|
|
6
|
+
* When connecting to Microsoft SQL Server, you can use the
|
|
7
|
+
mssql_unicode_strings accessor to turn of the default usage
|
|
8
|
+
of unicode strings (N'') and use regular strings (''). This
|
|
9
|
+
can improve performance, but changes the behavior. It's
|
|
10
|
+
set to true by default for backwards compatibility. You can
|
|
11
|
+
change it at both the dataset and database level:
|
|
12
|
+
|
|
13
|
+
DB.mssql_unicode_strings = false # default for datasets
|
|
14
|
+
dataset.mssql_unicode_strings = false # just this dataset
|
|
15
|
+
|
|
16
|
+
* In the oracle adapter, if Sequel.application_timezone is :utc, set
|
|
17
|
+
the timezone for the connection to use the 00:00 timezone.
|
|
18
|
+
|
|
19
|
+
= Other Improvements
|
|
20
|
+
|
|
21
|
+
* In the single_table_inheritance plugin, correctly handle a
|
|
22
|
+
multi-level class hierarchy so that loading instances from a
|
|
23
|
+
middle level of the hierarchy can return instances of subclasses.
|
|
24
|
+
|
|
25
|
+
* Don't use a schema when creating a temporary table, even if
|
|
26
|
+
default_schema is set.
|
|
27
|
+
|
|
28
|
+
* Fix the migrator when a default_schema is used.
|
|
29
|
+
|
|
30
|
+
* In the ado adapter, assume a connection to SQL Server if the
|
|
31
|
+
:conn_string is given and doesn't indicate Access/Jet.
|
|
32
|
+
|
|
33
|
+
* Fix fetching rows in the tinytds adapter when the
|
|
34
|
+
identifier_output_method is nil.
|
|
35
|
+
|
|
36
|
+
* The tinytds adapter now checks for disconnect errors, but it might
|
|
37
|
+
not be reliable until the next release of tiny_tds.
|
|
38
|
+
|
|
39
|
+
* The odbc adapter now handles ODBC::Time instances correctly.
|