sequel 4.26.0 → 5.37.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/CHANGELOG +405 -5656
- data/MIT-LICENSE +1 -1
- data/README.rdoc +232 -157
- data/bin/sequel +32 -9
- data/doc/advanced_associations.rdoc +252 -188
- data/doc/association_basics.rdoc +231 -273
- data/doc/bin_sequel.rdoc +5 -3
- data/doc/cheat_sheet.rdoc +75 -48
- data/doc/code_order.rdoc +28 -10
- data/doc/core_extensions.rdoc +104 -63
- data/doc/dataset_basics.rdoc +12 -21
- data/doc/dataset_filtering.rdoc +99 -86
- data/doc/extensions.rdoc +3 -10
- data/doc/mass_assignment.rdoc +74 -31
- data/doc/migration.rdoc +72 -46
- data/doc/model_dataset_method_design.rdoc +129 -0
- data/doc/model_hooks.rdoc +15 -25
- data/doc/model_plugins.rdoc +12 -12
- data/doc/mssql_stored_procedures.rdoc +3 -3
- data/doc/object_model.rdoc +59 -69
- data/doc/opening_databases.rdoc +84 -94
- data/doc/postgresql.rdoc +268 -38
- data/doc/prepared_statements.rdoc +29 -24
- data/doc/querying.rdoc +184 -164
- data/doc/reflection.rdoc +5 -6
- data/doc/release_notes/5.0.0.txt +159 -0
- data/doc/release_notes/5.1.0.txt +31 -0
- data/doc/release_notes/5.10.0.txt +84 -0
- data/doc/release_notes/5.11.0.txt +83 -0
- data/doc/release_notes/5.12.0.txt +141 -0
- data/doc/release_notes/5.13.0.txt +27 -0
- data/doc/release_notes/5.14.0.txt +63 -0
- data/doc/release_notes/5.15.0.txt +39 -0
- data/doc/release_notes/5.16.0.txt +110 -0
- data/doc/release_notes/5.17.0.txt +31 -0
- data/doc/release_notes/5.18.0.txt +69 -0
- data/doc/release_notes/5.19.0.txt +28 -0
- data/doc/release_notes/5.2.0.txt +33 -0
- data/doc/release_notes/5.20.0.txt +89 -0
- data/doc/release_notes/5.21.0.txt +87 -0
- data/doc/release_notes/5.22.0.txt +48 -0
- data/doc/release_notes/5.23.0.txt +56 -0
- data/doc/release_notes/5.24.0.txt +56 -0
- data/doc/release_notes/5.25.0.txt +32 -0
- data/doc/release_notes/5.26.0.txt +35 -0
- data/doc/release_notes/5.27.0.txt +21 -0
- data/doc/release_notes/5.28.0.txt +16 -0
- data/doc/release_notes/5.29.0.txt +22 -0
- data/doc/release_notes/5.3.0.txt +121 -0
- data/doc/release_notes/5.30.0.txt +20 -0
- data/doc/release_notes/5.31.0.txt +148 -0
- data/doc/release_notes/5.32.0.txt +46 -0
- data/doc/release_notes/5.33.0.txt +24 -0
- data/doc/release_notes/5.34.0.txt +40 -0
- data/doc/release_notes/5.35.0.txt +56 -0
- data/doc/release_notes/5.36.0.txt +60 -0
- data/doc/release_notes/5.37.0.txt +30 -0
- data/doc/release_notes/5.4.0.txt +80 -0
- data/doc/release_notes/5.5.0.txt +61 -0
- data/doc/release_notes/5.6.0.txt +31 -0
- data/doc/release_notes/5.7.0.txt +108 -0
- data/doc/release_notes/5.8.0.txt +170 -0
- data/doc/release_notes/5.9.0.txt +99 -0
- data/doc/schema_modification.rdoc +102 -77
- data/doc/security.rdoc +160 -87
- data/doc/sharding.rdoc +74 -47
- data/doc/sql.rdoc +135 -122
- data/doc/testing.rdoc +34 -18
- data/doc/thread_safety.rdoc +2 -4
- data/doc/transactions.rdoc +101 -19
- data/doc/validations.rdoc +64 -51
- data/doc/virtual_rows.rdoc +90 -109
- data/lib/sequel.rb +3 -1
- data/lib/sequel/adapters/ado.rb +154 -22
- data/lib/sequel/adapters/ado/access.rb +21 -21
- data/lib/sequel/adapters/ado/mssql.rb +8 -15
- data/lib/sequel/adapters/amalgalite.rb +17 -25
- data/lib/sequel/adapters/ibmdb.rb +52 -58
- data/lib/sequel/adapters/jdbc.rb +149 -127
- data/lib/sequel/adapters/jdbc/db2.rb +32 -40
- data/lib/sequel/adapters/jdbc/derby.rb +56 -58
- data/lib/sequel/adapters/jdbc/h2.rb +40 -30
- data/lib/sequel/adapters/jdbc/hsqldb.rb +22 -33
- data/lib/sequel/adapters/jdbc/jtds.rb +4 -10
- data/lib/sequel/adapters/jdbc/mssql.rb +6 -12
- data/lib/sequel/adapters/jdbc/mysql.rb +17 -18
- data/lib/sequel/adapters/jdbc/oracle.rb +25 -19
- data/lib/sequel/adapters/jdbc/postgresql.rb +90 -69
- data/lib/sequel/adapters/jdbc/sqlanywhere.rb +14 -24
- data/lib/sequel/adapters/jdbc/sqlite.rb +50 -12
- data/lib/sequel/adapters/jdbc/sqlserver.rb +36 -9
- data/lib/sequel/adapters/jdbc/transactions.rb +25 -39
- data/lib/sequel/adapters/mock.rb +104 -113
- data/lib/sequel/adapters/mysql.rb +42 -61
- data/lib/sequel/adapters/mysql2.rb +126 -35
- data/lib/sequel/adapters/odbc.rb +21 -28
- data/lib/sequel/adapters/odbc/db2.rb +3 -1
- data/lib/sequel/adapters/odbc/mssql.rb +11 -15
- data/lib/sequel/adapters/odbc/oracle.rb +11 -0
- data/lib/sequel/adapters/oracle.rb +62 -68
- data/lib/sequel/adapters/postgres.rb +257 -311
- data/lib/sequel/adapters/postgresql.rb +3 -1
- data/lib/sequel/adapters/shared/access.rb +75 -79
- data/lib/sequel/adapters/shared/db2.rb +96 -74
- data/lib/sequel/adapters/shared/mssql.rb +258 -213
- data/lib/sequel/adapters/shared/mysql.rb +284 -216
- data/lib/sequel/adapters/shared/oracle.rb +175 -60
- data/lib/sequel/adapters/shared/postgres.rb +829 -383
- data/lib/sequel/adapters/shared/sqlanywhere.rb +105 -127
- data/lib/sequel/adapters/shared/sqlite.rb +382 -159
- data/lib/sequel/adapters/sqlanywhere.rb +53 -38
- data/lib/sequel/adapters/sqlite.rb +111 -105
- data/lib/sequel/adapters/tinytds.rb +38 -46
- data/lib/sequel/adapters/utils/emulate_offset_with_reverse_and_count.rb +8 -9
- data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +7 -5
- data/lib/sequel/adapters/utils/mysql_mysql2.rb +87 -0
- data/lib/sequel/adapters/utils/mysql_prepared_statements.rb +56 -0
- data/lib/sequel/adapters/utils/replace.rb +3 -4
- data/lib/sequel/adapters/utils/split_alter_table.rb +2 -0
- data/lib/sequel/adapters/utils/stored_procedures.rb +9 -22
- data/lib/sequel/adapters/utils/unmodified_identifiers.rb +28 -0
- data/lib/sequel/ast_transformer.rb +13 -89
- data/lib/sequel/connection_pool.rb +54 -26
- data/lib/sequel/connection_pool/sharded_single.rb +19 -12
- data/lib/sequel/connection_pool/sharded_threaded.rb +160 -111
- data/lib/sequel/connection_pool/single.rb +21 -12
- data/lib/sequel/connection_pool/threaded.rb +137 -119
- data/lib/sequel/core.rb +352 -320
- data/lib/sequel/database.rb +19 -2
- data/lib/sequel/database/connecting.rb +70 -55
- data/lib/sequel/database/dataset.rb +15 -5
- data/lib/sequel/database/dataset_defaults.rb +20 -102
- data/lib/sequel/database/features.rb +20 -4
- data/lib/sequel/database/logging.rb +25 -7
- data/lib/sequel/database/misc.rb +132 -118
- data/lib/sequel/database/query.rb +51 -28
- data/lib/sequel/database/schema_generator.rb +188 -75
- data/lib/sequel/database/schema_methods.rb +161 -92
- data/lib/sequel/database/transactions.rb +260 -58
- data/lib/sequel/dataset.rb +28 -12
- data/lib/sequel/dataset/actions.rb +354 -170
- data/lib/sequel/dataset/dataset_module.rb +46 -0
- data/lib/sequel/dataset/features.rb +81 -34
- data/lib/sequel/dataset/graph.rb +82 -58
- data/lib/sequel/dataset/misc.rb +139 -47
- data/lib/sequel/dataset/placeholder_literalizer.rb +66 -26
- data/lib/sequel/dataset/prepared_statements.rb +188 -85
- data/lib/sequel/dataset/query.rb +428 -214
- data/lib/sequel/dataset/sql.rb +446 -339
- data/lib/sequel/deprecated.rb +14 -2
- data/lib/sequel/exceptions.rb +48 -16
- data/lib/sequel/extensions/_model_constraint_validations.rb +16 -0
- data/lib/sequel/extensions/_model_pg_row.rb +43 -0
- data/lib/sequel/extensions/_pretty_table.rb +10 -9
- data/lib/sequel/extensions/any_not_empty.rb +45 -0
- data/lib/sequel/extensions/arbitrary_servers.rb +15 -11
- data/lib/sequel/extensions/auto_literal_strings.rb +74 -0
- data/lib/sequel/extensions/blank.rb +2 -0
- data/lib/sequel/extensions/caller_logging.rb +79 -0
- data/lib/sequel/extensions/columns_introspection.rb +9 -4
- data/lib/sequel/extensions/connection_expiration.rb +99 -0
- data/lib/sequel/extensions/connection_validator.rb +26 -13
- data/lib/sequel/extensions/constant_sql_override.rb +65 -0
- data/lib/sequel/extensions/constraint_validations.rb +93 -38
- data/lib/sequel/extensions/core_extensions.rb +45 -53
- data/lib/sequel/extensions/core_refinements.rb +44 -46
- data/lib/sequel/extensions/current_datetime_timestamp.rb +5 -4
- data/lib/sequel/extensions/dataset_source_alias.rb +4 -0
- data/lib/sequel/extensions/date_arithmetic.rb +42 -16
- data/lib/sequel/extensions/datetime_parse_to_time.rb +37 -0
- data/lib/sequel/extensions/duplicate_columns_handler.rb +94 -0
- data/lib/sequel/extensions/empty_array_consider_nulls.rb +7 -3
- data/lib/sequel/extensions/error_sql.rb +7 -3
- data/lib/sequel/extensions/escaped_like.rb +100 -0
- data/lib/sequel/extensions/eval_inspect.rb +14 -15
- data/lib/sequel/extensions/exclude_or_null.rb +68 -0
- data/lib/sequel/extensions/fiber_concurrency.rb +24 -0
- data/lib/sequel/extensions/freeze_datasets.rb +3 -0
- data/lib/sequel/extensions/from_block.rb +2 -31
- data/lib/sequel/extensions/graph_each.rb +19 -6
- data/lib/sequel/extensions/identifier_mangling.rb +180 -0
- data/lib/sequel/extensions/implicit_subquery.rb +48 -0
- data/lib/sequel/extensions/index_caching.rb +109 -0
- data/lib/sequel/extensions/inflector.rb +8 -4
- data/lib/sequel/extensions/integer64.rb +32 -0
- data/lib/sequel/extensions/looser_typecasting.rb +19 -9
- data/lib/sequel/extensions/migration.rb +132 -80
- data/lib/sequel/extensions/mssql_emulate_lateral_with_apply.rb +4 -0
- data/lib/sequel/extensions/named_timezones.rb +88 -23
- data/lib/sequel/extensions/no_auto_literal_strings.rb +4 -0
- data/lib/sequel/extensions/null_dataset.rb +12 -8
- data/lib/sequel/extensions/pagination.rb +35 -28
- data/lib/sequel/extensions/pg_array.rb +227 -316
- data/lib/sequel/extensions/pg_array_ops.rb +19 -7
- data/lib/sequel/extensions/pg_enum.rb +69 -24
- data/lib/sequel/extensions/pg_extended_date_support.rb +250 -0
- data/lib/sequel/extensions/pg_hstore.rb +50 -59
- data/lib/sequel/extensions/pg_hstore_ops.rb +9 -3
- data/lib/sequel/extensions/pg_inet.rb +34 -15
- data/lib/sequel/extensions/pg_inet_ops.rb +5 -1
- data/lib/sequel/extensions/pg_interval.rb +26 -26
- data/lib/sequel/extensions/pg_json.rb +422 -141
- data/lib/sequel/extensions/pg_json_ops.rb +248 -9
- data/lib/sequel/extensions/pg_loose_count.rb +5 -1
- data/lib/sequel/extensions/pg_range.rb +162 -146
- data/lib/sequel/extensions/pg_range_ops.rb +10 -5
- data/lib/sequel/extensions/pg_row.rb +53 -87
- data/lib/sequel/extensions/pg_row_ops.rb +36 -13
- data/lib/sequel/extensions/pg_static_cache_updater.rb +6 -2
- data/lib/sequel/extensions/pg_timestamptz.rb +28 -0
- data/lib/sequel/extensions/pretty_table.rb +4 -0
- data/lib/sequel/extensions/query.rb +12 -7
- data/lib/sequel/extensions/round_timestamps.rb +6 -9
- data/lib/sequel/extensions/run_transaction_hooks.rb +72 -0
- data/lib/sequel/extensions/s.rb +59 -0
- data/lib/sequel/extensions/schema_caching.rb +14 -1
- data/lib/sequel/extensions/schema_dumper.rb +83 -55
- data/lib/sequel/extensions/select_remove.rb +8 -4
- data/lib/sequel/extensions/sequel_4_dataset_methods.rb +85 -0
- data/lib/sequel/extensions/server_block.rb +50 -17
- data/lib/sequel/extensions/server_logging.rb +61 -0
- data/lib/sequel/extensions/split_array_nil.rb +8 -4
- data/lib/sequel/extensions/sql_comments.rb +96 -0
- data/lib/sequel/extensions/sql_expr.rb +4 -1
- data/lib/sequel/extensions/string_agg.rb +181 -0
- data/lib/sequel/extensions/string_date_time.rb +2 -0
- data/lib/sequel/extensions/symbol_aref.rb +53 -0
- data/lib/sequel/extensions/symbol_aref_refinement.rb +43 -0
- data/lib/sequel/extensions/symbol_as.rb +23 -0
- data/lib/sequel/extensions/symbol_as_refinement.rb +37 -0
- data/lib/sequel/extensions/synchronize_sql.rb +45 -0
- data/lib/sequel/extensions/thread_local_timezones.rb +4 -0
- data/lib/sequel/extensions/to_dot.rb +15 -5
- data/lib/sequel/extensions/virtual_row_method_block.rb +44 -0
- data/lib/sequel/model.rb +36 -126
- data/lib/sequel/model/associations.rb +850 -257
- data/lib/sequel/model/base.rb +652 -764
- data/lib/sequel/model/dataset_module.rb +13 -10
- data/lib/sequel/model/default_inflections.rb +3 -1
- data/lib/sequel/model/errors.rb +3 -3
- data/lib/sequel/model/exceptions.rb +12 -12
- data/lib/sequel/model/inflections.rb +8 -19
- data/lib/sequel/model/plugins.rb +111 -0
- data/lib/sequel/plugins/accessed_columns.rb +2 -0
- data/lib/sequel/plugins/active_model.rb +32 -7
- data/lib/sequel/plugins/after_initialize.rb +3 -1
- data/lib/sequel/plugins/association_dependencies.rb +27 -18
- data/lib/sequel/plugins/association_lazy_eager_option.rb +66 -0
- data/lib/sequel/plugins/association_multi_add_remove.rb +85 -0
- data/lib/sequel/plugins/association_pks.rb +181 -83
- data/lib/sequel/plugins/association_proxies.rb +33 -9
- data/lib/sequel/plugins/auto_validations.rb +58 -23
- data/lib/sequel/plugins/before_after_save.rb +8 -0
- data/lib/sequel/plugins/blacklist_security.rb +23 -12
- data/lib/sequel/plugins/boolean_readers.rb +9 -6
- data/lib/sequel/plugins/boolean_subsets.rb +64 -0
- data/lib/sequel/plugins/caching.rb +27 -16
- data/lib/sequel/plugins/class_table_inheritance.rb +192 -94
- data/lib/sequel/plugins/column_conflicts.rb +18 -3
- data/lib/sequel/plugins/column_select.rb +9 -5
- data/lib/sequel/plugins/columns_updated.rb +42 -0
- data/lib/sequel/plugins/composition.rb +36 -24
- data/lib/sequel/plugins/constraint_validations.rb +37 -16
- data/lib/sequel/plugins/csv_serializer.rb +58 -35
- data/lib/sequel/plugins/dataset_associations.rb +60 -18
- data/lib/sequel/plugins/def_dataset_method.rb +90 -0
- data/lib/sequel/plugins/defaults_setter.rb +74 -13
- data/lib/sequel/plugins/delay_add_association.rb +4 -1
- data/lib/sequel/plugins/dirty.rb +65 -24
- data/lib/sequel/plugins/eager_each.rb +27 -3
- data/lib/sequel/plugins/eager_graph_eager.rb +139 -0
- data/lib/sequel/plugins/empty_failure_backtraces.rb +38 -0
- data/lib/sequel/plugins/error_splitter.rb +19 -12
- data/lib/sequel/plugins/finder.rb +246 -0
- data/lib/sequel/plugins/forbid_lazy_load.rb +216 -0
- data/lib/sequel/plugins/force_encoding.rb +9 -12
- data/lib/sequel/plugins/hook_class_methods.rb +39 -54
- data/lib/sequel/plugins/input_transformer.rb +20 -10
- data/lib/sequel/plugins/insert_conflict.rb +72 -0
- data/lib/sequel/plugins/insert_returning_select.rb +4 -2
- data/lib/sequel/plugins/instance_filters.rb +12 -8
- data/lib/sequel/plugins/instance_hooks.rb +36 -17
- data/lib/sequel/plugins/instance_specific_default.rb +113 -0
- data/lib/sequel/plugins/inverted_subsets.rb +24 -13
- data/lib/sequel/plugins/json_serializer.rb +123 -47
- data/lib/sequel/plugins/lazy_attributes.rb +20 -14
- data/lib/sequel/plugins/list.rb +40 -26
- data/lib/sequel/plugins/many_through_many.rb +28 -12
- data/lib/sequel/plugins/modification_detection.rb +17 -5
- data/lib/sequel/plugins/mssql_optimistic_locking.rb +8 -5
- data/lib/sequel/plugins/nested_attributes.rb +55 -28
- data/lib/sequel/plugins/optimistic_locking.rb +5 -3
- data/lib/sequel/plugins/pg_array_associations.rb +52 -18
- data/lib/sequel/plugins/pg_auto_constraint_validations.rb +348 -0
- data/lib/sequel/plugins/pg_row.rb +7 -51
- data/lib/sequel/plugins/prepared_statements.rb +53 -72
- data/lib/sequel/plugins/prepared_statements_safe.rb +13 -5
- data/lib/sequel/plugins/rcte_tree.rb +43 -63
- data/lib/sequel/plugins/serialization.rb +37 -44
- data/lib/sequel/plugins/serialization_modification_detection.rb +3 -1
- data/lib/sequel/plugins/sharding.rb +17 -10
- data/lib/sequel/plugins/single_table_inheritance.rb +62 -28
- data/lib/sequel/plugins/singular_table_names.rb +2 -0
- data/lib/sequel/plugins/skip_create_refresh.rb +5 -3
- data/lib/sequel/plugins/skip_saving_columns.rb +108 -0
- data/lib/sequel/plugins/split_values.rb +13 -6
- data/lib/sequel/plugins/static_cache.rb +79 -53
- data/lib/sequel/plugins/static_cache_cache.rb +53 -0
- data/lib/sequel/plugins/string_stripper.rb +5 -3
- data/lib/sequel/plugins/subclasses.rb +20 -2
- data/lib/sequel/plugins/subset_conditions.rb +48 -0
- data/lib/sequel/plugins/table_select.rb +4 -2
- data/lib/sequel/plugins/tactical_eager_loading.rb +120 -6
- data/lib/sequel/plugins/throw_failures.rb +110 -0
- data/lib/sequel/plugins/timestamps.rb +22 -8
- data/lib/sequel/plugins/touch.rb +21 -8
- data/lib/sequel/plugins/tree.rb +57 -30
- data/lib/sequel/plugins/typecast_on_load.rb +14 -4
- data/lib/sequel/plugins/unlimited_update.rb +3 -7
- data/lib/sequel/plugins/update_or_create.rb +6 -4
- data/lib/sequel/plugins/update_primary_key.rb +3 -1
- data/lib/sequel/plugins/update_refresh.rb +28 -15
- data/lib/sequel/plugins/uuid.rb +70 -0
- data/lib/sequel/plugins/validate_associated.rb +20 -0
- data/lib/sequel/plugins/validation_class_methods.rb +40 -19
- data/lib/sequel/plugins/validation_contexts.rb +49 -0
- data/lib/sequel/plugins/validation_helpers.rb +49 -31
- data/lib/sequel/plugins/whitelist_security.rb +122 -0
- data/lib/sequel/plugins/xml_serializer.rb +31 -30
- data/lib/sequel/sql.rb +479 -329
- data/lib/sequel/timezones.rb +62 -32
- data/lib/sequel/version.rb +10 -3
- metadata +177 -477
- data/Rakefile +0 -165
- data/doc/active_record.rdoc +0 -912
- data/doc/release_notes/1.0.txt +0 -38
- data/doc/release_notes/1.1.txt +0 -143
- data/doc/release_notes/1.3.txt +0 -101
- data/doc/release_notes/1.4.0.txt +0 -53
- data/doc/release_notes/1.5.0.txt +0 -155
- data/doc/release_notes/2.0.0.txt +0 -298
- data/doc/release_notes/2.1.0.txt +0 -271
- data/doc/release_notes/2.10.0.txt +0 -328
- data/doc/release_notes/2.11.0.txt +0 -215
- data/doc/release_notes/2.12.0.txt +0 -534
- data/doc/release_notes/2.2.0.txt +0 -253
- data/doc/release_notes/2.3.0.txt +0 -88
- data/doc/release_notes/2.4.0.txt +0 -106
- data/doc/release_notes/2.5.0.txt +0 -137
- data/doc/release_notes/2.6.0.txt +0 -157
- data/doc/release_notes/2.7.0.txt +0 -166
- data/doc/release_notes/2.8.0.txt +0 -171
- data/doc/release_notes/2.9.0.txt +0 -97
- data/doc/release_notes/3.0.0.txt +0 -221
- data/doc/release_notes/3.1.0.txt +0 -406
- data/doc/release_notes/3.10.0.txt +0 -286
- data/doc/release_notes/3.11.0.txt +0 -254
- data/doc/release_notes/3.12.0.txt +0 -304
- data/doc/release_notes/3.13.0.txt +0 -210
- data/doc/release_notes/3.14.0.txt +0 -118
- data/doc/release_notes/3.15.0.txt +0 -78
- data/doc/release_notes/3.16.0.txt +0 -45
- data/doc/release_notes/3.17.0.txt +0 -58
- data/doc/release_notes/3.18.0.txt +0 -120
- data/doc/release_notes/3.19.0.txt +0 -67
- data/doc/release_notes/3.2.0.txt +0 -268
- data/doc/release_notes/3.20.0.txt +0 -41
- data/doc/release_notes/3.21.0.txt +0 -87
- data/doc/release_notes/3.22.0.txt +0 -39
- data/doc/release_notes/3.23.0.txt +0 -172
- data/doc/release_notes/3.24.0.txt +0 -420
- data/doc/release_notes/3.25.0.txt +0 -88
- data/doc/release_notes/3.26.0.txt +0 -88
- data/doc/release_notes/3.27.0.txt +0 -82
- data/doc/release_notes/3.28.0.txt +0 -304
- data/doc/release_notes/3.29.0.txt +0 -459
- data/doc/release_notes/3.3.0.txt +0 -192
- data/doc/release_notes/3.30.0.txt +0 -135
- data/doc/release_notes/3.31.0.txt +0 -146
- data/doc/release_notes/3.32.0.txt +0 -202
- data/doc/release_notes/3.33.0.txt +0 -157
- data/doc/release_notes/3.34.0.txt +0 -671
- data/doc/release_notes/3.35.0.txt +0 -144
- data/doc/release_notes/3.36.0.txt +0 -245
- data/doc/release_notes/3.37.0.txt +0 -338
- data/doc/release_notes/3.38.0.txt +0 -234
- data/doc/release_notes/3.39.0.txt +0 -237
- data/doc/release_notes/3.4.0.txt +0 -325
- data/doc/release_notes/3.40.0.txt +0 -73
- data/doc/release_notes/3.41.0.txt +0 -155
- data/doc/release_notes/3.42.0.txt +0 -74
- data/doc/release_notes/3.43.0.txt +0 -105
- data/doc/release_notes/3.44.0.txt +0 -152
- data/doc/release_notes/3.45.0.txt +0 -179
- data/doc/release_notes/3.46.0.txt +0 -122
- data/doc/release_notes/3.47.0.txt +0 -270
- data/doc/release_notes/3.48.0.txt +0 -477
- data/doc/release_notes/3.5.0.txt +0 -510
- data/doc/release_notes/3.6.0.txt +0 -366
- data/doc/release_notes/3.7.0.txt +0 -179
- data/doc/release_notes/3.8.0.txt +0 -151
- data/doc/release_notes/3.9.0.txt +0 -233
- data/doc/release_notes/4.0.0.txt +0 -262
- data/doc/release_notes/4.1.0.txt +0 -85
- data/doc/release_notes/4.10.0.txt +0 -226
- data/doc/release_notes/4.11.0.txt +0 -147
- data/doc/release_notes/4.12.0.txt +0 -105
- data/doc/release_notes/4.13.0.txt +0 -169
- data/doc/release_notes/4.14.0.txt +0 -68
- data/doc/release_notes/4.15.0.txt +0 -56
- data/doc/release_notes/4.16.0.txt +0 -36
- data/doc/release_notes/4.17.0.txt +0 -38
- data/doc/release_notes/4.18.0.txt +0 -36
- data/doc/release_notes/4.19.0.txt +0 -45
- data/doc/release_notes/4.2.0.txt +0 -129
- data/doc/release_notes/4.20.0.txt +0 -79
- data/doc/release_notes/4.21.0.txt +0 -94
- data/doc/release_notes/4.22.0.txt +0 -72
- data/doc/release_notes/4.23.0.txt +0 -65
- data/doc/release_notes/4.24.0.txt +0 -99
- data/doc/release_notes/4.25.0.txt +0 -181
- data/doc/release_notes/4.26.0.txt +0 -44
- data/doc/release_notes/4.3.0.txt +0 -40
- data/doc/release_notes/4.4.0.txt +0 -92
- data/doc/release_notes/4.5.0.txt +0 -34
- data/doc/release_notes/4.6.0.txt +0 -30
- data/doc/release_notes/4.7.0.txt +0 -103
- data/doc/release_notes/4.8.0.txt +0 -175
- data/doc/release_notes/4.9.0.txt +0 -190
- data/lib/sequel/adapters/cubrid.rb +0 -142
- data/lib/sequel/adapters/do.rb +0 -156
- data/lib/sequel/adapters/do/mysql.rb +0 -64
- data/lib/sequel/adapters/do/postgres.rb +0 -42
- data/lib/sequel/adapters/do/sqlite3.rb +0 -40
- data/lib/sequel/adapters/jdbc/as400.rb +0 -82
- data/lib/sequel/adapters/jdbc/cubrid.rb +0 -62
- data/lib/sequel/adapters/jdbc/firebirdsql.rb +0 -34
- data/lib/sequel/adapters/jdbc/informix-sqli.rb +0 -31
- data/lib/sequel/adapters/jdbc/jdbcprogress.rb +0 -31
- data/lib/sequel/adapters/odbc/progress.rb +0 -8
- data/lib/sequel/adapters/shared/cubrid.rb +0 -243
- data/lib/sequel/adapters/shared/firebird.rb +0 -245
- data/lib/sequel/adapters/shared/informix.rb +0 -52
- data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +0 -150
- data/lib/sequel/adapters/shared/progress.rb +0 -38
- data/lib/sequel/adapters/swift.rb +0 -158
- data/lib/sequel/adapters/swift/mysql.rb +0 -47
- data/lib/sequel/adapters/swift/postgres.rb +0 -45
- data/lib/sequel/adapters/swift/sqlite.rb +0 -47
- data/lib/sequel/adapters/utils/pg_types.rb +0 -68
- data/lib/sequel/dataset/mutation.rb +0 -109
- data/lib/sequel/extensions/empty_array_ignore_nulls.rb +0 -3
- data/lib/sequel/extensions/filter_having.rb +0 -59
- data/lib/sequel/extensions/hash_aliases.rb +0 -45
- data/lib/sequel/extensions/meta_def.rb +0 -31
- data/lib/sequel/extensions/query_literals.rb +0 -80
- data/lib/sequel/extensions/ruby18_symbol_extensions.rb +0 -22
- data/lib/sequel/extensions/sequel_3_dataset_methods.rb +0 -118
- data/lib/sequel/extensions/set_overrides.rb +0 -72
- data/lib/sequel/no_core_ext.rb +0 -1
- data/lib/sequel/plugins/association_autoreloading.rb +0 -7
- data/lib/sequel/plugins/many_to_one_pk_lookup.rb +0 -7
- data/lib/sequel/plugins/pg_typecast_on_load.rb +0 -78
- data/lib/sequel/plugins/prepared_statements_associations.rb +0 -117
- data/lib/sequel/plugins/prepared_statements_with_pk.rb +0 -59
- data/lib/sequel/plugins/schema.rb +0 -80
- data/lib/sequel/plugins/scissors.rb +0 -33
- data/spec/adapters/db2_spec.rb +0 -160
- data/spec/adapters/firebird_spec.rb +0 -411
- data/spec/adapters/informix_spec.rb +0 -100
- data/spec/adapters/mssql_spec.rb +0 -706
- data/spec/adapters/mysql_spec.rb +0 -1287
- data/spec/adapters/oracle_spec.rb +0 -313
- data/spec/adapters/postgres_spec.rb +0 -3725
- data/spec/adapters/spec_helper.rb +0 -43
- data/spec/adapters/sqlanywhere_spec.rb +0 -170
- data/spec/adapters/sqlite_spec.rb +0 -653
- data/spec/bin_spec.rb +0 -254
- data/spec/core/connection_pool_spec.rb +0 -1016
- data/spec/core/database_spec.rb +0 -2531
- data/spec/core/dataset_spec.rb +0 -5098
- data/spec/core/deprecated_spec.rb +0 -70
- data/spec/core/expression_filters_spec.rb +0 -1243
- data/spec/core/mock_adapter_spec.rb +0 -462
- data/spec/core/object_graph_spec.rb +0 -303
- data/spec/core/placeholder_literalizer_spec.rb +0 -163
- data/spec/core/schema_generator_spec.rb +0 -179
- data/spec/core/schema_spec.rb +0 -1659
- data/spec/core/spec_helper.rb +0 -34
- data/spec/core/version_spec.rb +0 -7
- data/spec/core_extensions_spec.rb +0 -699
- data/spec/extensions/accessed_columns_spec.rb +0 -51
- data/spec/extensions/active_model_spec.rb +0 -123
- data/spec/extensions/after_initialize_spec.rb +0 -24
- data/spec/extensions/arbitrary_servers_spec.rb +0 -109
- data/spec/extensions/association_dependencies_spec.rb +0 -117
- data/spec/extensions/association_pks_spec.rb +0 -365
- data/spec/extensions/association_proxies_spec.rb +0 -86
- data/spec/extensions/auto_validations_spec.rb +0 -192
- data/spec/extensions/blacklist_security_spec.rb +0 -88
- data/spec/extensions/blank_spec.rb +0 -69
- data/spec/extensions/boolean_readers_spec.rb +0 -93
- data/spec/extensions/caching_spec.rb +0 -270
- data/spec/extensions/class_table_inheritance_spec.rb +0 -420
- data/spec/extensions/column_conflicts_spec.rb +0 -60
- data/spec/extensions/column_select_spec.rb +0 -108
- data/spec/extensions/columns_introspection_spec.rb +0 -91
- data/spec/extensions/composition_spec.rb +0 -242
- data/spec/extensions/connection_validator_spec.rb +0 -120
- data/spec/extensions/constraint_validations_plugin_spec.rb +0 -274
- data/spec/extensions/constraint_validations_spec.rb +0 -325
- data/spec/extensions/core_refinements_spec.rb +0 -519
- data/spec/extensions/csv_serializer_spec.rb +0 -173
- data/spec/extensions/current_datetime_timestamp_spec.rb +0 -27
- data/spec/extensions/dataset_associations_spec.rb +0 -311
- data/spec/extensions/dataset_source_alias_spec.rb +0 -51
- data/spec/extensions/date_arithmetic_spec.rb +0 -150
- data/spec/extensions/defaults_setter_spec.rb +0 -101
- data/spec/extensions/delay_add_association_spec.rb +0 -52
- data/spec/extensions/dirty_spec.rb +0 -180
- data/spec/extensions/eager_each_spec.rb +0 -42
- data/spec/extensions/empty_array_consider_nulls_spec.rb +0 -24
- data/spec/extensions/error_splitter_spec.rb +0 -18
- data/spec/extensions/error_sql_spec.rb +0 -20
- data/spec/extensions/eval_inspect_spec.rb +0 -73
- data/spec/extensions/filter_having_spec.rb +0 -40
- data/spec/extensions/force_encoding_spec.rb +0 -114
- data/spec/extensions/from_block_spec.rb +0 -21
- data/spec/extensions/graph_each_spec.rb +0 -109
- data/spec/extensions/hash_aliases_spec.rb +0 -24
- data/spec/extensions/hook_class_methods_spec.rb +0 -429
- data/spec/extensions/inflector_spec.rb +0 -183
- data/spec/extensions/input_transformer_spec.rb +0 -54
- data/spec/extensions/insert_returning_select_spec.rb +0 -46
- data/spec/extensions/instance_filters_spec.rb +0 -79
- data/spec/extensions/instance_hooks_spec.rb +0 -276
- data/spec/extensions/inverted_subsets_spec.rb +0 -33
- data/spec/extensions/json_serializer_spec.rb +0 -291
- data/spec/extensions/lazy_attributes_spec.rb +0 -170
- data/spec/extensions/list_spec.rb +0 -267
- data/spec/extensions/looser_typecasting_spec.rb +0 -43
- data/spec/extensions/many_through_many_spec.rb +0 -2172
- data/spec/extensions/meta_def_spec.rb +0 -21
- data/spec/extensions/migration_spec.rb +0 -712
- data/spec/extensions/modification_detection_spec.rb +0 -80
- data/spec/extensions/mssql_optimistic_locking_spec.rb +0 -91
- data/spec/extensions/named_timezones_spec.rb +0 -108
- data/spec/extensions/nested_attributes_spec.rb +0 -697
- data/spec/extensions/null_dataset_spec.rb +0 -85
- data/spec/extensions/optimistic_locking_spec.rb +0 -128
- data/spec/extensions/pagination_spec.rb +0 -118
- data/spec/extensions/pg_array_associations_spec.rb +0 -736
- data/spec/extensions/pg_array_ops_spec.rb +0 -143
- data/spec/extensions/pg_array_spec.rb +0 -395
- data/spec/extensions/pg_enum_spec.rb +0 -92
- data/spec/extensions/pg_hstore_ops_spec.rb +0 -236
- data/spec/extensions/pg_hstore_spec.rb +0 -206
- data/spec/extensions/pg_inet_ops_spec.rb +0 -101
- data/spec/extensions/pg_inet_spec.rb +0 -52
- data/spec/extensions/pg_interval_spec.rb +0 -76
- data/spec/extensions/pg_json_ops_spec.rb +0 -229
- data/spec/extensions/pg_json_spec.rb +0 -218
- data/spec/extensions/pg_loose_count_spec.rb +0 -17
- data/spec/extensions/pg_range_ops_spec.rb +0 -58
- data/spec/extensions/pg_range_spec.rb +0 -404
- data/spec/extensions/pg_row_ops_spec.rb +0 -60
- data/spec/extensions/pg_row_plugin_spec.rb +0 -62
- data/spec/extensions/pg_row_spec.rb +0 -360
- data/spec/extensions/pg_static_cache_updater_spec.rb +0 -92
- data/spec/extensions/pg_typecast_on_load_spec.rb +0 -63
- data/spec/extensions/prepared_statements_associations_spec.rb +0 -159
- data/spec/extensions/prepared_statements_safe_spec.rb +0 -61
- data/spec/extensions/prepared_statements_spec.rb +0 -103
- data/spec/extensions/prepared_statements_with_pk_spec.rb +0 -31
- data/spec/extensions/pretty_table_spec.rb +0 -92
- data/spec/extensions/query_literals_spec.rb +0 -183
- data/spec/extensions/query_spec.rb +0 -102
- data/spec/extensions/rcte_tree_spec.rb +0 -392
- data/spec/extensions/round_timestamps_spec.rb +0 -43
- data/spec/extensions/schema_caching_spec.rb +0 -41
- data/spec/extensions/schema_dumper_spec.rb +0 -789
- data/spec/extensions/schema_spec.rb +0 -117
- data/spec/extensions/scissors_spec.rb +0 -26
- data/spec/extensions/select_remove_spec.rb +0 -38
- data/spec/extensions/sequel_3_dataset_methods_spec.rb +0 -101
- data/spec/extensions/serialization_modification_detection_spec.rb +0 -98
- data/spec/extensions/serialization_spec.rb +0 -362
- data/spec/extensions/server_block_spec.rb +0 -90
- data/spec/extensions/set_overrides_spec.rb +0 -61
- data/spec/extensions/sharding_spec.rb +0 -198
- data/spec/extensions/shared_caching_spec.rb +0 -175
- data/spec/extensions/single_table_inheritance_spec.rb +0 -297
- data/spec/extensions/singular_table_names_spec.rb +0 -22
- data/spec/extensions/skip_create_refresh_spec.rb +0 -17
- data/spec/extensions/spec_helper.rb +0 -71
- data/spec/extensions/split_array_nil_spec.rb +0 -24
- data/spec/extensions/split_values_spec.rb +0 -22
- data/spec/extensions/sql_expr_spec.rb +0 -60
- data/spec/extensions/static_cache_spec.rb +0 -361
- data/spec/extensions/string_date_time_spec.rb +0 -95
- data/spec/extensions/string_stripper_spec.rb +0 -68
- data/spec/extensions/subclasses_spec.rb +0 -66
- data/spec/extensions/table_select_spec.rb +0 -71
- data/spec/extensions/tactical_eager_loading_spec.rb +0 -82
- data/spec/extensions/thread_local_timezones_spec.rb +0 -67
- data/spec/extensions/timestamps_spec.rb +0 -175
- data/spec/extensions/to_dot_spec.rb +0 -154
- data/spec/extensions/touch_spec.rb +0 -203
- data/spec/extensions/tree_spec.rb +0 -274
- data/spec/extensions/typecast_on_load_spec.rb +0 -80
- data/spec/extensions/unlimited_update_spec.rb +0 -20
- data/spec/extensions/update_or_create_spec.rb +0 -87
- data/spec/extensions/update_primary_key_spec.rb +0 -100
- data/spec/extensions/update_refresh_spec.rb +0 -53
- data/spec/extensions/validate_associated_spec.rb +0 -52
- data/spec/extensions/validation_class_methods_spec.rb +0 -1027
- data/spec/extensions/validation_helpers_spec.rb +0 -541
- data/spec/extensions/xml_serializer_spec.rb +0 -207
- data/spec/files/bad_down_migration/001_create_alt_basic.rb +0 -4
- data/spec/files/bad_down_migration/002_create_alt_advanced.rb +0 -4
- data/spec/files/bad_timestamped_migrations/1273253849_create_sessions.rb +0 -9
- data/spec/files/bad_timestamped_migrations/1273253851_create_nodes.rb +0 -9
- data/spec/files/bad_timestamped_migrations/1273253853_3_create_users.rb +0 -3
- data/spec/files/bad_up_migration/001_create_alt_basic.rb +0 -4
- data/spec/files/bad_up_migration/002_create_alt_advanced.rb +0 -3
- data/spec/files/convert_to_timestamp_migrations/001_create_sessions.rb +0 -9
- data/spec/files/convert_to_timestamp_migrations/002_create_nodes.rb +0 -9
- data/spec/files/convert_to_timestamp_migrations/003_3_create_users.rb +0 -4
- data/spec/files/convert_to_timestamp_migrations/1273253850_create_artists.rb +0 -9
- data/spec/files/convert_to_timestamp_migrations/1273253852_create_albums.rb +0 -9
- data/spec/files/duplicate_integer_migrations/001_create_alt_advanced.rb +0 -4
- data/spec/files/duplicate_integer_migrations/001_create_alt_basic.rb +0 -4
- data/spec/files/duplicate_timestamped_migrations/1273253849_create_sessions.rb +0 -9
- data/spec/files/duplicate_timestamped_migrations/1273253853_create_nodes.rb +0 -9
- data/spec/files/duplicate_timestamped_migrations/1273253853_create_users.rb +0 -4
- data/spec/files/integer_migrations/001_create_sessions.rb +0 -9
- data/spec/files/integer_migrations/002_create_nodes.rb +0 -9
- data/spec/files/integer_migrations/003_3_create_users.rb +0 -4
- data/spec/files/interleaved_timestamped_migrations/1273253849_create_sessions.rb +0 -9
- data/spec/files/interleaved_timestamped_migrations/1273253850_create_artists.rb +0 -9
- data/spec/files/interleaved_timestamped_migrations/1273253851_create_nodes.rb +0 -9
- data/spec/files/interleaved_timestamped_migrations/1273253852_create_albums.rb +0 -9
- data/spec/files/interleaved_timestamped_migrations/1273253853_3_create_users.rb +0 -4
- data/spec/files/missing_integer_migrations/001_create_alt_basic.rb +0 -4
- data/spec/files/missing_integer_migrations/003_create_alt_advanced.rb +0 -4
- data/spec/files/missing_timestamped_migrations/1273253849_create_sessions.rb +0 -9
- data/spec/files/missing_timestamped_migrations/1273253853_3_create_users.rb +0 -4
- data/spec/files/reversible_migrations/001_reversible.rb +0 -5
- data/spec/files/reversible_migrations/002_reversible.rb +0 -5
- data/spec/files/reversible_migrations/003_reversible.rb +0 -5
- data/spec/files/reversible_migrations/004_reversible.rb +0 -5
- data/spec/files/reversible_migrations/005_reversible.rb +0 -10
- data/spec/files/timestamped_migrations/1273253849_create_sessions.rb +0 -9
- data/spec/files/timestamped_migrations/1273253851_create_nodes.rb +0 -9
- data/spec/files/timestamped_migrations/1273253853_3_create_users.rb +0 -4
- data/spec/files/transaction_specified_migrations/001_create_alt_basic.rb +0 -4
- data/spec/files/transaction_specified_migrations/002_create_basic.rb +0 -4
- data/spec/files/transaction_unspecified_migrations/001_create_alt_basic.rb +0 -3
- data/spec/files/transaction_unspecified_migrations/002_create_basic.rb +0 -3
- data/spec/files/uppercase_timestamped_migrations/1273253849_CREATE_SESSIONS.RB +0 -9
- data/spec/files/uppercase_timestamped_migrations/1273253851_CREATE_NODES.RB +0 -9
- data/spec/files/uppercase_timestamped_migrations/1273253853_3_CREATE_USERS.RB +0 -4
- data/spec/guards_helper.rb +0 -55
- data/spec/integration/associations_test.rb +0 -2454
- data/spec/integration/database_test.rb +0 -113
- data/spec/integration/dataset_test.rb +0 -1808
- data/spec/integration/eager_loader_test.rb +0 -687
- data/spec/integration/migrator_test.rb +0 -240
- data/spec/integration/model_test.rb +0 -226
- data/spec/integration/plugin_test.rb +0 -2240
- data/spec/integration/prepared_statement_test.rb +0 -467
- data/spec/integration/schema_test.rb +0 -817
- data/spec/integration/spec_helper.rb +0 -48
- data/spec/integration/timezone_test.rb +0 -86
- data/spec/integration/transaction_test.rb +0 -374
- data/spec/integration/type_test.rb +0 -133
- data/spec/model/association_reflection_spec.rb +0 -525
- data/spec/model/associations_spec.rb +0 -4426
- data/spec/model/base_spec.rb +0 -759
- data/spec/model/class_dataset_methods_spec.rb +0 -146
- data/spec/model/dataset_methods_spec.rb +0 -149
- data/spec/model/eager_loading_spec.rb +0 -2137
- data/spec/model/hooks_spec.rb +0 -604
- data/spec/model/inflector_spec.rb +0 -26
- data/spec/model/model_spec.rb +0 -982
- data/spec/model/plugins_spec.rb +0 -299
- data/spec/model/record_spec.rb +0 -2147
- data/spec/model/spec_helper.rb +0 -46
- data/spec/model/validations_spec.rb +0 -193
- data/spec/sequel_coverage.rb +0 -15
- data/spec/spec_config.rb +0 -10
data/MIT-LICENSE
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
Copyright (c) 2007-2008 Sharon Rosner
|
2
|
-
Copyright (c) 2008-
|
2
|
+
Copyright (c) 2008-2020 Jeremy Evans
|
3
3
|
|
4
4
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
5
5
|
of this software and associated documentation files (the "Software"), to
|
data/README.rdoc
CHANGED
@@ -8,12 +8,12 @@ toolkit for Ruby.
|
|
8
8
|
* Sequel includes a comprehensive ORM layer for mapping
|
9
9
|
records to Ruby objects and handling associated records.
|
10
10
|
* Sequel supports advanced database features such as prepared
|
11
|
-
statements, bound variables,
|
12
|
-
|
13
|
-
|
14
|
-
* Sequel currently has adapters for ADO, Amalgalite,
|
15
|
-
|
16
|
-
PostgreSQL, SQLAnywhere, SQLite3,
|
11
|
+
statements, bound variables, savepoints, two-phase commit,
|
12
|
+
transaction isolation, primary/replica configurations, and
|
13
|
+
database sharding.
|
14
|
+
* Sequel currently has adapters for ADO, Amalgalite,
|
15
|
+
IBM_DB, JDBC, MySQL, Mysql2, ODBC, Oracle,
|
16
|
+
PostgreSQL, SQLAnywhere, SQLite3, and TinyTDS.
|
17
17
|
|
18
18
|
== Resources
|
19
19
|
|
@@ -44,7 +44,7 @@ If you have any comments or suggestions please post to the Google group.
|
|
44
44
|
|
45
45
|
require 'sequel'
|
46
46
|
|
47
|
-
DB = Sequel.sqlite # memory database
|
47
|
+
DB = Sequel.sqlite # memory database, requires sqlite3
|
48
48
|
|
49
49
|
DB.create_table :items do
|
50
50
|
primary_key :id
|
@@ -71,7 +71,7 @@ Sequel includes an IRB console for quick access to databases (usually referred t
|
|
71
71
|
|
72
72
|
sequel sqlite://test.db # test.db in current directory
|
73
73
|
|
74
|
-
You get an IRB session with the
|
74
|
+
You get an IRB session with the Sequel::Database object stored in DB.
|
75
75
|
|
76
76
|
In addition to providing an IRB shell (the default behavior), bin/sequel also has support for migrating databases, dumping schema migrations, and copying databases. See the {bin/sequel guide}[rdoc-ref:doc/bin_sequel.rdoc] for more details.
|
77
77
|
|
@@ -83,24 +83,25 @@ Sequel uses the concept of datasets to retrieve data. A Dataset object encapsula
|
|
83
83
|
|
84
84
|
For example, the following one-liner returns the average GDP for countries in the middle east region:
|
85
85
|
|
86
|
-
DB[:countries].
|
86
|
+
DB[:countries].where(:region => 'Middle East').avg(:GDP)
|
87
87
|
|
88
88
|
Which is equivalent to:
|
89
89
|
|
90
90
|
SELECT avg(GDP) FROM countries WHERE region = 'Middle East'
|
91
91
|
|
92
|
-
Since datasets retrieve records only when needed, they can be stored and later reused. Records are fetched as hashes
|
92
|
+
Since datasets retrieve records only when needed, they can be stored and later reused. Records are fetched as hashes, and are accessed using an +Enumerable+ interface:
|
93
93
|
|
94
|
-
middle_east = DB[:countries].
|
94
|
+
middle_east = DB[:countries].where(:region => 'Middle East')
|
95
95
|
middle_east.order(:name).each{|r| puts r[:name]}
|
96
96
|
|
97
97
|
Sequel also offers convenience methods for extracting data from Datasets, such as an extended +map+ method:
|
98
98
|
|
99
|
-
middle_east.map(:name)
|
99
|
+
middle_east.map(:name) # => ['Egypt', 'Turkey', 'Israel', ...]
|
100
|
+
middle_east.map([:id, :name]) # => [[1, 'Egypt'], [3, 'Turkey'], [2, 'Israel'], ...]
|
100
101
|
|
101
|
-
Or getting results as a hash via +
|
102
|
+
Or getting results as a hash via +as_hash+, with one column as key and another as value:
|
102
103
|
|
103
|
-
middle_east.
|
104
|
+
middle_east.as_hash(:name, :area) # => {'Israel' => 20000, 'Turkey' => 120000, ...}
|
104
105
|
|
105
106
|
== Getting Started
|
106
107
|
|
@@ -109,16 +110,21 @@ Or getting results as a hash via +to_hash+, with one column as key and another a
|
|
109
110
|
To connect to a database you simply provide <tt>Sequel.connect</tt> with a URL:
|
110
111
|
|
111
112
|
require 'sequel'
|
112
|
-
DB = Sequel.connect('sqlite://blog.db')
|
113
|
+
DB = Sequel.connect('sqlite://blog.db') # requires sqlite3
|
113
114
|
|
114
115
|
The connection URL can also include such stuff as the user name, password, and port:
|
115
116
|
|
116
|
-
DB = Sequel.connect('postgres://user:password@host:port/database_name')
|
117
|
+
DB = Sequel.connect('postgres://user:password@host:port/database_name') # requires pg
|
117
118
|
|
118
119
|
You can also specify optional parameters, such as the connection pool size, or loggers for logging SQL queries:
|
119
120
|
|
120
121
|
DB = Sequel.connect("postgres://user:password@host:port/database_name",
|
121
|
-
:
|
122
|
+
max_connections: 10, logger: Logger.new('log/db.log'))
|
123
|
+
|
124
|
+
It is also possible to use a hash instead of a connection URL, but make sure to include the :adapter option in this case:
|
125
|
+
|
126
|
+
DB = Sequel.connect(adapter: :postgres, user: 'user', password: 'password', host: 'host', port: port,
|
127
|
+
database: 'database_name', max_connections: 10, logger: Logger.new('log/db.log'))
|
122
128
|
|
123
129
|
You can specify a block to connect, which will disconnect from the database after it completes:
|
124
130
|
|
@@ -166,7 +172,7 @@ Datasets are the primary way records are retrieved and manipulated. They are ge
|
|
166
172
|
posts = DB.from(:posts)
|
167
173
|
posts = DB[:posts] # same
|
168
174
|
|
169
|
-
Datasets will only fetch records when you tell them to. They can be manipulated to filter records, change ordering, join tables, etc
|
175
|
+
Datasets will only fetch records when you tell them to. They can be manipulated to filter records, change ordering, join tables, etc. Datasets are always frozen, and they are safe to use by multiple threads concurrently.
|
170
176
|
|
171
177
|
=== Retrieving Records
|
172
178
|
|
@@ -175,7 +181,7 @@ You can retrieve all records by using the +all+ method:
|
|
175
181
|
posts.all
|
176
182
|
# SELECT * FROM posts
|
177
183
|
|
178
|
-
The all method returns an array of hashes, where each hash corresponds to a record.
|
184
|
+
The +all+ method returns an array of hashes, where each hash corresponds to a record.
|
179
185
|
|
180
186
|
You can also iterate through records one at a time using +each+:
|
181
187
|
|
@@ -188,68 +194,92 @@ Or perform more advanced stuff:
|
|
188
194
|
|
189
195
|
You can also retrieve the first record in a dataset:
|
190
196
|
|
191
|
-
posts.first
|
192
|
-
# SELECT * FROM posts LIMIT 1
|
197
|
+
posts.order(:id).first
|
198
|
+
# SELECT * FROM posts ORDER BY id LIMIT 1
|
193
199
|
|
194
|
-
|
200
|
+
Note that you can get the first record in a dataset even if it isn't ordered:
|
195
201
|
|
196
|
-
posts
|
197
|
-
# SELECT * FROM posts
|
202
|
+
posts.first
|
203
|
+
# SELECT * FROM posts LIMIT 1
|
198
204
|
|
199
205
|
If the dataset is ordered, you can also ask for the last record:
|
200
206
|
|
201
207
|
posts.order(:stamp).last
|
202
208
|
# SELECT * FROM posts ORDER BY stamp DESC LIMIT 1
|
203
209
|
|
210
|
+
You can also provide a filter when asking for a single record:
|
211
|
+
|
212
|
+
posts.first(:id => 1)
|
213
|
+
# SELECT * FROM posts WHERE id = 1 LIMIT 1
|
214
|
+
|
215
|
+
Or retrieve a single value for a specific record:
|
216
|
+
|
217
|
+
posts.where(:id => 1).get(:name)
|
218
|
+
# SELECT name FROM posts WHERE id = 1 LIMIT 1
|
219
|
+
|
204
220
|
=== Filtering Records
|
205
221
|
|
206
|
-
|
222
|
+
The most common way to filter records is to provide a hash of values to match to +where+:
|
207
223
|
|
208
|
-
my_posts = posts.where(:
|
209
|
-
# WHERE category = 'ruby' AND author = 'david'
|
224
|
+
my_posts = posts.where(category: 'ruby', author: 'david')
|
225
|
+
# WHERE ((category = 'ruby') AND (author = 'david'))
|
210
226
|
|
211
227
|
You can also specify ranges:
|
212
228
|
|
213
|
-
my_posts = posts.where(:
|
214
|
-
# WHERE stamp >= '2010-06-30' AND stamp <= '2010-07-07'
|
229
|
+
my_posts = posts.where(stamp: (Date.today - 14)..(Date.today - 7))
|
230
|
+
# WHERE ((stamp >= '2010-06-30') AND (stamp <= '2010-07-07'))
|
215
231
|
|
216
232
|
Or arrays of values:
|
217
233
|
|
218
|
-
my_posts = posts.where(:
|
219
|
-
# WHERE category IN ('ruby', 'postgres', 'linux')
|
234
|
+
my_posts = posts.where(category: ['ruby', 'postgres', 'linux'])
|
235
|
+
# WHERE (category IN ('ruby', 'postgres', 'linux'))
|
220
236
|
|
221
|
-
|
237
|
+
By passing a block to where, you can use expressions (this is fairly "magical"):
|
222
238
|
|
223
239
|
my_posts = posts.where{stamp > Date.today << 1}
|
224
|
-
# WHERE stamp > '2010-06-14'
|
240
|
+
# WHERE (stamp > '2010-06-14')
|
225
241
|
my_posts = posts.where{stamp =~ Date.today}
|
226
|
-
# WHERE stamp = '2010-07-14'
|
242
|
+
# WHERE (stamp = '2010-07-14')
|
243
|
+
|
244
|
+
If you want to wrap the objects yourself, you can use expressions without the "magic":
|
227
245
|
|
228
|
-
|
246
|
+
my_posts = posts.where(Sequel[:stamp] > Date.today << 1)
|
247
|
+
# WHERE (stamp > '2010-06-14')
|
248
|
+
my_posts = posts.where(Sequel[:stamp] =~ Date.today)
|
249
|
+
# WHERE (stamp = '2010-07-14')
|
250
|
+
|
251
|
+
Some databases such as PostgreSQL and MySQL also support filtering via Regexps:
|
229
252
|
|
230
|
-
my_posts = posts.where(:
|
231
|
-
# WHERE category ~* 'ruby'
|
253
|
+
my_posts = posts.where(category: /ruby/i)
|
254
|
+
# WHERE (category ~* 'ruby')
|
232
255
|
|
233
256
|
You can also use an inverse filter via +exclude+:
|
234
257
|
|
235
|
-
my_posts = posts.exclude(:
|
236
|
-
# WHERE category NOT IN ('ruby', 'postgres', 'linux')
|
258
|
+
my_posts = posts.exclude(category: ['ruby', 'postgres', 'linux'])
|
259
|
+
# WHERE (category NOT IN ('ruby', 'postgres', 'linux'))
|
260
|
+
|
261
|
+
But note that this does a full inversion of the filter:
|
262
|
+
|
263
|
+
my_posts = posts.exclude(category: ['ruby', 'postgres', 'linux'], id: 1)
|
264
|
+
# WHERE ((category NOT IN ('ruby', 'postgres', 'linux')) OR (id != 1))
|
237
265
|
|
238
|
-
|
266
|
+
If at any point you want to use a custom SQL fragment for part of a query,
|
267
|
+
you can do so via +Sequel.lit+:
|
239
268
|
|
240
|
-
posts.where('stamp IS NOT NULL')
|
241
|
-
# WHERE stamp IS NOT NULL
|
269
|
+
posts.where(Sequel.lit('stamp IS NOT NULL'))
|
270
|
+
# WHERE (stamp IS NOT NULL)
|
242
271
|
|
243
|
-
You can
|
272
|
+
You can safely interpolate parameters into the custom SQL fragment by
|
273
|
+
providing them as additional arguments:
|
244
274
|
|
245
275
|
author_name = 'JKR'
|
246
|
-
posts.where('(stamp < ?) AND (author != ?)', Date.today - 3, author_name)
|
247
|
-
# WHERE (stamp < '2010-07-11') AND (author != 'JKR')
|
276
|
+
posts.where(Sequel.lit('(stamp < ?) AND (author != ?)', Date.today - 3, author_name))
|
277
|
+
# WHERE ((stamp < '2010-07-11') AND (author != 'JKR'))
|
248
278
|
|
249
279
|
Datasets can also be used as subqueries:
|
250
280
|
|
251
|
-
DB[:items].where(
|
252
|
-
# WHERE price > (SELECT avg(price) + 100 FROM items)
|
281
|
+
DB[:items].where(Sequel[:price] > DB[:items].select{avg(price) + 100})
|
282
|
+
# WHERE (price > (SELECT avg(price) + 100 FROM items))
|
253
283
|
|
254
284
|
After filtering, you can retrieve the matching records by using any of the retrieval methods:
|
255
285
|
|
@@ -267,8 +297,8 @@ issues that you should be aware of when using Sequel.
|
|
267
297
|
|
268
298
|
Counting records is easy using +count+:
|
269
299
|
|
270
|
-
posts.where(
|
271
|
-
# SELECT COUNT(*) FROM posts WHERE category LIKE '%ruby%'
|
300
|
+
posts.where(Sequel.like(:category, '%ruby%')).count
|
301
|
+
# SELECT COUNT(*) FROM posts WHERE (category LIKE '%ruby%' ESCAPE '\')
|
272
302
|
|
273
303
|
And you can also query maximum/minimum values via +max+ and +min+:
|
274
304
|
|
@@ -294,18 +324,15 @@ Ordering datasets is simple using +order+:
|
|
294
324
|
posts.order(:stamp, :name)
|
295
325
|
# ORDER BY stamp, name
|
296
326
|
|
297
|
-
|
327
|
+
+order+ always overrides the existing order:
|
298
328
|
|
299
329
|
posts.order(:stamp).order(:name)
|
300
330
|
# ORDER BY name
|
301
331
|
|
302
|
-
|
332
|
+
If you would like to add to the existing order, use +order_append+ or +order_prepend+:
|
303
333
|
|
304
334
|
posts.order(:stamp).order_append(:name)
|
305
335
|
# ORDER BY stamp, name
|
306
|
-
|
307
|
-
The +order_prepend+ method can be used as well:
|
308
|
-
|
309
336
|
posts.order(:stamp).order_prepend(:name)
|
310
337
|
# ORDER BY name, stamp
|
311
338
|
|
@@ -318,7 +345,7 @@ You can also specify descending order:
|
|
318
345
|
|
319
346
|
=== Core Extensions
|
320
347
|
|
321
|
-
Note the use of <tt>Sequel.desc(:stamp)</tt> in the above example. Much of Sequel's DSL uses this style, calling methods on the Sequel module that return SQL expression objects. Sequel also ships with a {core_extensions extension}[rdoc-ref:doc/core_extensions.rdoc]
|
348
|
+
Note the use of <tt>Sequel.desc(:stamp)</tt> in the above example. Much of Sequel's DSL uses this style, calling methods on the Sequel module that return SQL expression objects. Sequel also ships with a {core_extensions extension}[rdoc-ref:doc/core_extensions.rdoc] that integrates Sequel's DSL better into the Ruby language, allowing you to write:
|
322
349
|
|
323
350
|
:stamp.desc
|
324
351
|
|
@@ -335,7 +362,7 @@ Selecting specific columns to be returned is also simple using +select+:
|
|
335
362
|
posts.select(:stamp, :name)
|
336
363
|
# SELECT stamp, name FROM posts
|
337
364
|
|
338
|
-
|
365
|
+
Like +order+, +select+ overrides an existing selection:
|
339
366
|
|
340
367
|
posts.select(:stamp).select(:name)
|
341
368
|
# SELECT name FROM posts
|
@@ -349,52 +376,56 @@ As you might expect, there is an +order_append+ equivalent for +select+ called +
|
|
349
376
|
|
350
377
|
Deleting records from the table is done with +delete+:
|
351
378
|
|
352
|
-
posts.where(
|
353
|
-
# DELETE FROM posts WHERE stamp < '2010-07-11'
|
379
|
+
posts.where(Sequel[:stamp] < Date.today - 3).delete
|
380
|
+
# DELETE FROM posts WHERE (stamp < '2010-07-11')
|
354
381
|
|
355
382
|
Be very careful when deleting, as +delete+ affects all rows in the dataset.
|
356
383
|
Call +where+ first and +delete+ second:
|
357
384
|
|
358
385
|
# DO THIS:
|
359
|
-
posts.where(
|
386
|
+
posts.where(Sequel[:stamp] < Date.today - 7).delete
|
360
387
|
# NOT THIS:
|
361
|
-
posts.delete.where(
|
388
|
+
posts.delete.where(Sequel[:stamp] < Date.today - 7)
|
362
389
|
|
363
390
|
=== Inserting Records
|
364
391
|
|
365
392
|
Inserting records into the table is done with +insert+:
|
366
393
|
|
367
|
-
posts.insert(:
|
394
|
+
posts.insert(category: 'ruby', author: 'david')
|
368
395
|
# INSERT INTO posts (category, author) VALUES ('ruby', 'david')
|
369
396
|
|
370
397
|
=== Updating Records
|
371
398
|
|
372
399
|
Updating records in the table is done with +update+:
|
373
400
|
|
374
|
-
posts.where(
|
375
|
-
# UPDATE posts SET state = 'archived' WHERE stamp < '2010-07-07'
|
401
|
+
posts.where(Sequel[:stamp] < Date.today - 7).update(state: 'archived')
|
402
|
+
# UPDATE posts SET state = 'archived' WHERE (stamp < '2010-07-07')
|
376
403
|
|
377
|
-
You can
|
404
|
+
You can provide arbitrary expressions when choosing what values to set:
|
378
405
|
|
379
|
-
posts.where
|
380
|
-
# UPDATE posts SET backup_number = backup_number + 1 WHERE stamp < '2010-07-07'
|
406
|
+
posts.where(Sequel[:stamp] < Date.today - 7).update(backup_number: Sequel[:backup_number] + 1)
|
407
|
+
# UPDATE posts SET backup_number = (backup_number + 1) WHERE (stamp < '2010-07-07'))))
|
381
408
|
|
382
409
|
As with +delete+, +update+ affects all rows in the dataset, so +where+ first,
|
383
410
|
+update+ second:
|
384
411
|
|
385
412
|
# DO THIS:
|
386
|
-
posts.where(
|
413
|
+
posts.where(Sequel[:stamp] < Date.today - 7).update(:state => 'archived')
|
387
414
|
# NOT THIS:
|
388
|
-
posts.update(:state => 'archived').where(
|
415
|
+
posts.update(:state => 'archived').where(Sequel[:stamp] < Date.today - 7)
|
389
416
|
|
390
417
|
=== Transactions
|
391
418
|
|
392
|
-
You can wrap
|
419
|
+
You can wrap a block of code in a database transaction using the <tt>Database#transaction</tt> method:
|
393
420
|
|
394
421
|
DB.transaction do
|
395
|
-
|
396
|
-
posts.
|
422
|
+
# BEGIN
|
423
|
+
posts.insert(category: 'ruby', author: 'david')
|
424
|
+
# INSERT
|
425
|
+
posts.where(Sequel[:stamp] < Date.today - 7).update(:state => 'archived')
|
426
|
+
# UPDATE
|
397
427
|
end
|
428
|
+
# COMMIT
|
398
429
|
|
399
430
|
If the block does not raise an exception, the transaction will be committed.
|
400
431
|
If the block does raise an exception, the transaction will be rolled back,
|
@@ -403,21 +434,24 @@ and not raise an exception outside the block, you can raise the
|
|
403
434
|
<tt>Sequel::Rollback</tt> exception inside the block:
|
404
435
|
|
405
436
|
DB.transaction do
|
437
|
+
# BEGIN
|
406
438
|
posts.insert(:category => 'ruby', :author => 'david')
|
407
|
-
|
439
|
+
# INSERT
|
440
|
+
if posts.where('stamp < ?', Date.today - 7).update(:state => 'archived') == 0
|
441
|
+
# UPDATE
|
408
442
|
raise Sequel::Rollback
|
409
443
|
end
|
410
444
|
end
|
445
|
+
# ROLLBACK
|
411
446
|
|
412
447
|
=== Joining Tables
|
413
448
|
|
414
449
|
Sequel makes it easy to join tables:
|
415
450
|
|
416
|
-
order_items = DB[:items].join(:order_items, :
|
417
|
-
|
418
|
-
#
|
419
|
-
#
|
420
|
-
# WHERE order_id = 1234
|
451
|
+
order_items = DB[:items].join(:order_items, item_id: :id).where(order_id: 1234)
|
452
|
+
# SELECT * FROM items
|
453
|
+
# INNER JOIN order_items ON (order_items.item_id = items.id)
|
454
|
+
# WHERE (order_id = 1234)
|
421
455
|
|
422
456
|
The important thing to note here is that item_id is automatically qualified with
|
423
457
|
the table being joined, and id is automatically qualified with the last table
|
@@ -426,9 +460,9 @@ joined.
|
|
426
460
|
You can then do anything you like with the dataset:
|
427
461
|
|
428
462
|
order_total = order_items.sum(:price)
|
429
|
-
# SELECT sum(price) FROM items
|
430
|
-
# ON order_items.item_id = items.id
|
431
|
-
# WHERE
|
463
|
+
# SELECT sum(price) FROM items
|
464
|
+
# INNER JOIN order_items ON (order_items.item_id = items.id)
|
465
|
+
# WHERE (order_id = 1234)
|
432
466
|
|
433
467
|
Note that the default selection in Sequel is <tt>*</tt>, which includes all columns
|
434
468
|
in all joined tables. Because Sequel returns results as a hash keyed by column name
|
@@ -440,54 +474,53 @@ selection using +select+, +select_all+, and/or +select_append+.
|
|
440
474
|
|
441
475
|
Sequel expects column names to be specified using symbols. In addition, returned hashes always use symbols as their keys. This allows you to freely mix literal values and column references in many cases. For example, the two following lines produce equivalent SQL:
|
442
476
|
|
443
|
-
items.where(:
|
477
|
+
items.where(x: 1)
|
444
478
|
# SELECT * FROM items WHERE (x = 1)
|
445
479
|
items.where(1 => :x)
|
446
480
|
# SELECT * FROM items WHERE (1 = x)"
|
447
481
|
|
448
482
|
Ruby strings are generally treated as SQL strings:
|
449
483
|
|
450
|
-
items.where(:
|
484
|
+
items.where(x: 'x')
|
451
485
|
# SELECT * FROM items WHERE (x = 'x')
|
452
486
|
|
453
487
|
=== Qualifying identifiers (column/table names)
|
454
488
|
|
455
489
|
An identifier in SQL is a name that represents a column, table, or schema.
|
456
|
-
|
457
|
-
|
458
|
-
items.literal(:items__price)
|
459
|
-
# items.price
|
490
|
+
The recommended way to qualify columns is to use <tt>Sequel[][]</tt> or +Sequel.qualify+
|
460
491
|
|
461
|
-
|
492
|
+
Sequel[:table][:column]
|
493
|
+
Sequel.qualify(:table, :column)
|
494
|
+
# table.column
|
462
495
|
|
463
|
-
|
464
|
-
# items.price
|
496
|
+
You can also qualify tables with schemas:
|
465
497
|
|
466
|
-
|
467
|
-
|
498
|
+
Sequel[:schema][:table]
|
499
|
+
# schema.table
|
468
500
|
|
469
|
-
|
470
|
-
# SELECT * FROM some_schema.posts
|
501
|
+
or use multi-level qualification:
|
471
502
|
|
472
|
-
|
503
|
+
Sequel[:schema][:table][:column]
|
504
|
+
# schema.table.column
|
473
505
|
|
474
|
-
|
506
|
+
=== Expression aliases
|
475
507
|
|
476
|
-
|
477
|
-
# price AS p
|
478
|
-
items.literal(:items__price___p)
|
479
|
-
# items.price AS p
|
508
|
+
You can alias identifiers using <tt>Sequel[].as</tt> or +Sequel.as+:
|
480
509
|
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
# price AS p
|
510
|
+
Sequel[:column].as(:alias)
|
511
|
+
Sequel.as(:column, :alias)
|
512
|
+
# column AS alias
|
485
513
|
|
486
514
|
You can use the <tt>Sequel.as</tt> method to alias arbitrary expressions, not just identifiers:
|
487
515
|
|
488
|
-
|
516
|
+
Sequel.as(DB[:posts].select{max(id)}, :p)
|
489
517
|
# (SELECT max(id) FROM posts) AS p
|
490
518
|
|
519
|
+
And most Sequel expression objects support an +as+ method for aliasing:
|
520
|
+
|
521
|
+
(Sequel[:column] + 2).as(:c_plus_2)
|
522
|
+
# (column + 2) AS c_plus_2
|
523
|
+
|
491
524
|
== Sequel Models
|
492
525
|
|
493
526
|
A model class wraps a dataset, and an instance of that class wraps a single record in the dataset.
|
@@ -504,38 +537,37 @@ implements the active record pattern).
|
|
504
537
|
|
505
538
|
Sequel model classes assume that the table name is an underscored plural of the class name:
|
506
539
|
|
507
|
-
Post.table_name
|
540
|
+
Post.table_name # => :posts
|
508
541
|
|
509
542
|
You can explicitly set the table name or even the dataset used:
|
510
543
|
|
511
|
-
class Post < Sequel::Model(:my_posts)
|
512
|
-
end
|
544
|
+
class Post < Sequel::Model(:my_posts); end
|
513
545
|
# or:
|
514
|
-
Post
|
546
|
+
class Post < Sequel::Model(DB[:my_posts]); end
|
515
547
|
|
516
|
-
If you
|
548
|
+
If you pass a symbol to the <tt>Sequel::Model</tt> method, it assumes you are referring to the table with the same name. You can also call it with a dataset, which will set the defaults for all retrievals for that model:
|
517
549
|
|
518
|
-
Post
|
519
|
-
Post
|
550
|
+
class Post < Sequel::Model(DB[:my_posts].where(category: 'ruby')); end
|
551
|
+
class Post < Sequel::Model(DB[:my_posts].select(:id, :name).order(:date)); end
|
520
552
|
|
521
553
|
=== Model instances
|
522
554
|
|
523
|
-
Model instances are identified by a primary key.
|
555
|
+
Model instances are identified by a primary key. Sequel queries the database to determine the primary key for each model. The <tt>Model.[]</tt> method can be used to fetch records by their primary key:
|
524
556
|
|
525
557
|
post = Post[123]
|
526
558
|
|
527
559
|
The +pk+ method is used to retrieve the record's primary key value:
|
528
560
|
|
529
|
-
post.pk
|
561
|
+
post.pk # => 123
|
530
562
|
|
531
|
-
|
563
|
+
If you want to override which column(s) to use as the primary key, you can use +set_primary_key+:
|
532
564
|
|
533
565
|
class Post < Sequel::Model
|
534
566
|
set_primary_key [:category, :title]
|
535
567
|
end
|
536
568
|
|
537
569
|
post = Post['ruby', 'hello world']
|
538
|
-
post.pk
|
570
|
+
post.pk # => ['ruby', 'hello world']
|
539
571
|
|
540
572
|
You can also define a model class that does not have a primary key via +no_primary_key+, but then you lose the ability to easily update and delete records:
|
541
573
|
|
@@ -543,39 +575,43 @@ You can also define a model class that does not have a primary key via +no_prima
|
|
543
575
|
|
544
576
|
A single model instance can also be fetched by specifying a condition:
|
545
577
|
|
546
|
-
post = Post
|
578
|
+
post = Post.first(title: 'hello world')
|
547
579
|
post = Post.first{num_comments < 10}
|
548
580
|
|
581
|
+
The dataset for a model class returns rows of model instances instead of plain hashes:
|
582
|
+
|
583
|
+
DB[:posts].first.class # => Hash
|
584
|
+
Post.first.class # => Post
|
585
|
+
|
549
586
|
=== Acts like a dataset
|
550
587
|
|
551
588
|
A model class forwards many methods to the underlying dataset. This means that you can use most of the +Dataset+ API to create customized queries that return model instances, e.g.:
|
552
589
|
|
553
|
-
Post.where(:
|
590
|
+
Post.where(category: 'ruby').each{|post| p post}
|
554
591
|
|
555
592
|
You can also manipulate the records in the dataset:
|
556
593
|
|
557
594
|
Post.where{num_comments < 7}.delete
|
558
|
-
Post.where(Sequel.like(:title, /ruby/)).update(:
|
595
|
+
Post.where(Sequel.like(:title, /ruby/)).update(category: 'ruby')
|
559
596
|
|
560
597
|
=== Accessing record values
|
561
598
|
|
562
599
|
A model instance stores its values as a hash with column symbol keys, which you can access directly via the +values+ method:
|
563
600
|
|
564
|
-
post.values
|
601
|
+
post.values # => {:id => 123, :category => 'ruby', :title => 'hello world'}
|
565
602
|
|
566
603
|
You can read the record values as object attributes, assuming the attribute names are valid columns in the model's dataset:
|
567
604
|
|
568
|
-
post.id
|
569
|
-
post.title
|
605
|
+
post.id # => 123
|
606
|
+
post.title # => 'hello world'
|
570
607
|
|
571
608
|
If the record's attributes names are not valid columns in the model's dataset (maybe because you used +select_append+ to add a computed value column), you can use <tt>Model#[]</tt> to access the values:
|
572
609
|
|
573
|
-
post[:id]
|
574
|
-
post[:title]
|
610
|
+
post[:id] # => 123
|
611
|
+
post[:title] # => 'hello world'
|
575
612
|
|
576
613
|
You can also modify record values using attribute setters or the <tt>[]=</tt> method.
|
577
614
|
|
578
|
-
|
579
615
|
post.title = 'hey there'
|
580
616
|
post[:title] = 'hey there'
|
581
617
|
|
@@ -587,24 +623,26 @@ That will just change the value for the object, it will not update the row in th
|
|
587
623
|
|
588
624
|
You can also set the values for multiple columns in a single method call, using one of the mass-assignment methods. See the {mass assignment guide}[rdoc-ref:doc/mass_assignment.rdoc] for details. For example +set+ updates the model's column values without saving:
|
589
625
|
|
590
|
-
post.set(:
|
626
|
+
post.set(title: 'hey there', updated_by: 'foo')
|
591
627
|
|
592
628
|
and +update+ updates the model's column values and then saves the changes to the database:
|
593
629
|
|
594
|
-
post.update(:
|
630
|
+
post.update(title: 'hey there', updated_by: 'foo')
|
595
631
|
|
596
632
|
=== Creating new records
|
597
633
|
|
598
|
-
New
|
634
|
+
New model instances can be created by calling <tt>Model.new</tt>, which returns a new model instance without updating the database:
|
599
635
|
|
600
|
-
post = Post.
|
636
|
+
post = Post.new(title: 'hello world')
|
601
637
|
|
602
|
-
|
638
|
+
You can save the record to the database later by calling +save+ on the model instance:
|
603
639
|
|
604
|
-
post = Post.new
|
605
|
-
post.title = 'hello world'
|
606
640
|
post.save
|
607
641
|
|
642
|
+
If you want to create a new record and save it to the database at the same time, you can use <tt>Model.create</tt>:
|
643
|
+
|
644
|
+
post = Post.create(title: 'hello world')
|
645
|
+
|
608
646
|
You can also supply a block to <tt>Model.new</tt> and <tt>Model.create</tt>:
|
609
647
|
|
610
648
|
post = Post.new do |p|
|
@@ -631,7 +669,7 @@ You can execute custom code when creating, updating, or deleting records by defi
|
|
631
669
|
|
632
670
|
Note the use of +super+ if you define your own hook methods. Almost all <tt>Sequel::Model</tt> class and instance methods (not just hook methods) can be overridden safely, but you have to make sure to call +super+ when doing so, otherwise you risk breaking things.
|
633
671
|
|
634
|
-
For the example above, you should probably use a database trigger if you can. Hooks can be used for data integrity, but they will only enforce that integrity when you are modifying the database through model instances, and even then they are often subject to race conditions. It's best to use database triggers and constraints to enforce data integrity.
|
672
|
+
For the example above, you should probably use a database trigger if you can. Hooks can be used for data integrity, but they will only enforce that integrity when you are modifying the database through model instances, and even then they are often subject to race conditions. It's best to use database triggers and database constraints to enforce data integrity.
|
635
673
|
|
636
674
|
=== Deleting records
|
637
675
|
|
@@ -663,21 +701,21 @@ Associations are used in order to specify relationships between model classes th
|
|
663
701
|
|
664
702
|
+many_to_one+ and +one_to_one+ create a getter and setter for each model object:
|
665
703
|
|
666
|
-
post = Post.create(:
|
667
|
-
post.author = Author
|
704
|
+
post = Post.create(name: 'hi!')
|
705
|
+
post.author = Author.first(name: 'Sharon')
|
668
706
|
post.author
|
669
707
|
|
670
708
|
+one_to_many+ and +many_to_many+ create a getter method, a method for adding an object to the association, a method for removing an object from the association, and a method for removing all associated objects from the association:
|
671
709
|
|
672
|
-
post = Post.create(:
|
710
|
+
post = Post.create(name: 'hi!')
|
673
711
|
post.comments
|
674
712
|
|
675
|
-
comment = Comment.create(:
|
713
|
+
comment = Comment.create(text: 'hi')
|
676
714
|
post.add_comment(comment)
|
677
715
|
post.remove_comment(comment)
|
678
716
|
post.remove_all_comments
|
679
717
|
|
680
|
-
tag = Tag.create(:
|
718
|
+
tag = Tag.create(tag: 'interesting')
|
681
719
|
post.add_tag(tag)
|
682
720
|
post.remove_tag(tag)
|
683
721
|
post.remove_all_tags
|
@@ -690,7 +728,7 @@ All associations add a dataset method that can be used to further filter or reor
|
|
690
728
|
post.comments_dataset.destroy
|
691
729
|
|
692
730
|
# Return all tags related to this post with no subscribers, ordered by the tag's name
|
693
|
-
post.tags_dataset.where(:
|
731
|
+
post.tags_dataset.where(subscribers: 0).order(:name).all
|
694
732
|
|
695
733
|
=== Eager Loading
|
696
734
|
|
@@ -732,36 +770,36 @@ Associations can be eagerly loaded via +eager+ and the <tt>:eager</tt> associati
|
|
732
770
|
Post.eager(:person).eager(:tags).all
|
733
771
|
|
734
772
|
# Cascading via .eager
|
735
|
-
Tag.eager(:
|
773
|
+
Tag.eager(posts: :replies).all
|
736
774
|
|
737
775
|
# Will also grab all associated posts' tags (because of :eager)
|
738
|
-
Reply.eager(:
|
776
|
+
Reply.eager(person: :posts).all
|
739
777
|
|
740
778
|
# No depth limit (other than memory/stack), and will also grab posts' tags
|
741
779
|
# Loads all people, their posts, their posts' tags, replies to those posts,
|
742
780
|
# the person for each reply, the tag for each reply, and all posts and
|
743
781
|
# replies that have that tag. Uses a total of 8 queries.
|
744
|
-
Person.eager(:
|
782
|
+
Person.eager(posts: {replies: [:person, {tags: [:posts, :replies]}]}).all
|
745
783
|
|
746
|
-
In addition to using +eager+, you can also use +eager_graph+, which will use a single query to get the object and all associated objects. This may be necessary if you want to filter or order the result set based on columns in associated tables. It works with cascading as well, the API is
|
784
|
+
In addition to using +eager+, you can also use +eager_graph+, which will use a single query to get the object and all associated objects. This may be necessary if you want to filter or order the result set based on columns in associated tables. It works with cascading as well, the API is similar. Note that using +eager_graph+ to eagerly load multiple <tt>*_to_many</tt> associations will cause the result set to be a cartesian product, so you should be very careful with your filters when using it in that case.
|
747
785
|
|
748
|
-
You can dynamically customize the eagerly loaded dataset by using
|
786
|
+
You can dynamically customize the eagerly loaded dataset by using a proc. This proc is passed the dataset used for eager loading, and should return a modified copy of that dataset:
|
749
787
|
|
750
788
|
# Eagerly load only replies containing 'foo'
|
751
|
-
Post.eager(:
|
789
|
+
Post.eager(replies: proc{|ds| ds.where(Sequel.like(text, '%foo%'))}).all
|
752
790
|
|
753
791
|
This also works when using +eager_graph+, in which case the proc is called with dataset to graph into the current dataset:
|
754
792
|
|
755
|
-
Post.eager_graph(:
|
793
|
+
Post.eager_graph(replies: proc{|ds| ds.where(Sequel.like(text, '%foo%'))}).all
|
756
794
|
|
757
795
|
You can dynamically customize eager loads for both +eager+ and +eager_graph+ while also cascading, by making the value a single entry hash with the proc as a key, and the cascaded associations as the value:
|
758
796
|
|
759
797
|
# Eagerly load only replies containing 'foo', and the person and tags for those replies
|
760
|
-
Post.eager(:
|
798
|
+
Post.eager(replies: {proc{|ds| ds.where(Sequel.like(text, '%foo%'))} => [:person, :tags]}).all
|
761
799
|
|
762
800
|
=== Joining with Associations
|
763
801
|
|
764
|
-
You can use the association_join method to add a join to the model's dataset based on the assocation:
|
802
|
+
You can use the +association_join+ method to add a join to the model's dataset based on the assocation:
|
765
803
|
|
766
804
|
Post.association_join(:author)
|
767
805
|
# SELECT * FROM posts
|
@@ -775,7 +813,7 @@ This comes with variants for different join types:
|
|
775
813
|
|
776
814
|
Similar to the eager loading methods, you can use multiple associations and nested associations:
|
777
815
|
|
778
|
-
Post.association_join(:author, :
|
816
|
+
Post.association_join(:author, replies: :person).all
|
779
817
|
# SELECT * FROM posts
|
780
818
|
# INNER JOIN authors AS author ON (author.id = posts.author_id)
|
781
819
|
# INNER JOIN replies ON (replies.post_id = posts.id)
|
@@ -787,27 +825,44 @@ The recommended way to implement table-wide logic by defining methods on the dat
|
|
787
825
|
|
788
826
|
class Post < Sequel::Model
|
789
827
|
dataset_module do
|
790
|
-
def
|
828
|
+
def with_few_comments
|
791
829
|
where{num_comments < 30}
|
792
830
|
end
|
793
831
|
|
794
|
-
def
|
795
|
-
|
832
|
+
def clean_boring
|
833
|
+
with_few_comments.delete
|
796
834
|
end
|
797
835
|
end
|
798
836
|
end
|
799
837
|
|
800
838
|
This allows you to have access to your model API from filtered datasets as well:
|
801
839
|
|
802
|
-
Post.where(:
|
840
|
+
Post.where(category: 'ruby').clean_boring
|
841
|
+
# DELETE FROM posts WHERE ((category = 'ruby') AND (num_comments < 30))
|
803
842
|
|
804
|
-
|
843
|
+
Inside +dataset_module+ blocks, there are numerous methods that support easy creation of dataset methods.
|
844
|
+
Most of these methods are named after the dataset methods themselves, such as +select+, +order+, and
|
845
|
+
+group+:
|
805
846
|
|
806
847
|
class Post < Sequel::Model
|
807
|
-
|
808
|
-
|
848
|
+
dataset_module do
|
849
|
+
where(:with_few_comments, Sequel[:num_comments] < 30)
|
850
|
+
select :with_title_and_date, :id, :title, :post_date
|
851
|
+
order :by_post_date, :post_date
|
852
|
+
limit :top10, 10
|
853
|
+
end
|
809
854
|
end
|
810
855
|
|
856
|
+
Post.with_few_comments.with_title_and_date.by_post_date.top10
|
857
|
+
# SELECT id, title, post_date
|
858
|
+
# FROM posts
|
859
|
+
# ORDER BY post_date
|
860
|
+
# LIMIT 10
|
861
|
+
|
862
|
+
One advantage of using these methods inside dataset_module blocks, instead of
|
863
|
+
defining methods manually, is that the created methods will generally cache
|
864
|
+
the resulting values and result in better performance.
|
865
|
+
|
811
866
|
=== Model Validations
|
812
867
|
|
813
868
|
You can define a +validate+ method for your model, which +save+
|
@@ -815,8 +870,7 @@ will check before attempting to save the model in the database.
|
|
815
870
|
If an attribute of the model isn't valid, you should add an error
|
816
871
|
message for that attribute to the model object's +errors+. If an
|
817
872
|
object has any errors added by the validate method, +save+ will
|
818
|
-
raise an error
|
819
|
-
(the +raise_on_save_failure+ flag).
|
873
|
+
raise an error by default:
|
820
874
|
|
821
875
|
class Post < Sequel::Model
|
822
876
|
def validate
|
@@ -825,3 +879,24 @@ raise an error or return false depending on how it is configured
|
|
825
879
|
errors.add(:written_on, "should be in the past") if written_on >= Time.now
|
826
880
|
end
|
827
881
|
end
|
882
|
+
|
883
|
+
== Sequel Release Policy
|
884
|
+
|
885
|
+
New major versions of Sequel do not have a defined release policy, but historically have
|
886
|
+
occurred once ever few years.
|
887
|
+
|
888
|
+
New minor versions of Sequel are released around once a month near the start of the month.
|
889
|
+
|
890
|
+
New tiny versions of Sequel are only released to address security issues or regressions
|
891
|
+
in the most current release.
|
892
|
+
|
893
|
+
== Ruby Support Policy
|
894
|
+
|
895
|
+
Sequel fully supports the currently supported versions of Ruby (MRI) and JRuby. It may
|
896
|
+
support unsupported versions of Ruby or JRuby, but such support may be dropped in any
|
897
|
+
minor version if keeping it becomes a support issue. The minimum Ruby version
|
898
|
+
required to run the current version of Sequel is 1.9.2.
|
899
|
+
|
900
|
+
== Maintainer
|
901
|
+
|
902
|
+
Jeremy Evans <code@jeremyevans.net>
|