sequel 4.49.0 → 5.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +70 -0
- data/README.rdoc +195 -136
- data/Rakefile +26 -42
- data/bin/sequel +3 -5
- data/doc/advanced_associations.rdoc +86 -163
- data/doc/association_basics.rdoc +197 -274
- data/doc/bin_sequel.rdoc +5 -3
- data/doc/cheat_sheet.rdoc +66 -43
- data/doc/code_order.rdoc +1 -8
- data/doc/core_extensions.rdoc +81 -56
- data/doc/dataset_basics.rdoc +8 -17
- data/doc/dataset_filtering.rdoc +81 -86
- data/doc/extensions.rdoc +3 -10
- data/doc/mass_assignment.rdoc +73 -30
- data/doc/migration.rdoc +19 -36
- data/doc/model_dataset_method_design.rdoc +14 -17
- data/doc/model_hooks.rdoc +15 -25
- data/doc/model_plugins.rdoc +10 -10
- data/doc/mssql_stored_procedures.rdoc +3 -3
- data/doc/object_model.rdoc +52 -70
- data/doc/opening_databases.rdoc +39 -32
- data/doc/postgresql.rdoc +48 -38
- data/doc/prepared_statements.rdoc +27 -22
- data/doc/querying.rdoc +173 -150
- data/doc/reflection.rdoc +5 -6
- data/doc/release_notes/5.0.0.txt +159 -0
- data/doc/schema_modification.rdoc +63 -60
- data/doc/security.rdoc +97 -88
- data/doc/sharding.rdoc +43 -30
- data/doc/sql.rdoc +53 -65
- data/doc/testing.rdoc +3 -5
- data/doc/thread_safety.rdoc +2 -4
- data/doc/transactions.rdoc +18 -17
- data/doc/validations.rdoc +48 -45
- data/doc/virtual_rows.rdoc +87 -115
- data/lib/sequel.rb +1 -1
- data/lib/sequel/adapters/ado.rb +9 -25
- data/lib/sequel/adapters/ado/access.rb +7 -13
- data/lib/sequel/adapters/ado/mssql.rb +2 -9
- data/lib/sequel/adapters/amalgalite.rb +3 -18
- data/lib/sequel/adapters/ibmdb.rb +9 -45
- data/lib/sequel/adapters/jdbc.rb +13 -73
- data/lib/sequel/adapters/jdbc/db2.rb +8 -37
- data/lib/sequel/adapters/jdbc/derby.rb +4 -50
- data/lib/sequel/adapters/jdbc/h2.rb +4 -25
- data/lib/sequel/adapters/jdbc/hsqldb.rb +1 -26
- data/lib/sequel/adapters/jdbc/jtds.rb +2 -9
- data/lib/sequel/adapters/jdbc/mssql.rb +1 -11
- data/lib/sequel/adapters/jdbc/mysql.rb +1 -15
- data/lib/sequel/adapters/jdbc/oracle.rb +4 -26
- data/lib/sequel/adapters/jdbc/postgresql.rb +2 -31
- data/lib/sequel/adapters/jdbc/sqlanywhere.rb +4 -17
- data/lib/sequel/adapters/jdbc/sqlite.rb +1 -7
- data/lib/sequel/adapters/jdbc/sqlserver.rb +1 -13
- data/lib/sequel/adapters/jdbc/transactions.rb +1 -14
- data/lib/sequel/adapters/mock.rb +4 -30
- data/lib/sequel/adapters/mysql.rb +7 -44
- data/lib/sequel/adapters/mysql2.rb +5 -23
- data/lib/sequel/adapters/odbc.rb +0 -19
- data/lib/sequel/adapters/odbc/db2.rb +1 -1
- data/lib/sequel/adapters/odbc/mssql.rb +4 -12
- data/lib/sequel/adapters/odbc/oracle.rb +1 -1
- data/lib/sequel/adapters/oracle.rb +7 -13
- data/lib/sequel/adapters/postgres.rb +13 -57
- data/lib/sequel/adapters/postgresql.rb +1 -1
- data/lib/sequel/adapters/shared/access.rb +11 -51
- data/lib/sequel/adapters/shared/db2.rb +3 -61
- data/lib/sequel/adapters/shared/mssql.rb +21 -157
- data/lib/sequel/adapters/shared/mysql.rb +23 -224
- data/lib/sequel/adapters/shared/oracle.rb +13 -41
- data/lib/sequel/adapters/shared/postgres.rb +44 -259
- data/lib/sequel/adapters/shared/sqlanywhere.rb +4 -96
- data/lib/sequel/adapters/shared/sqlite.rb +12 -101
- data/lib/sequel/adapters/sqlanywhere.rb +4 -23
- data/lib/sequel/adapters/sqlite.rb +2 -19
- data/lib/sequel/adapters/tinytds.rb +5 -15
- data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +1 -1
- data/lib/sequel/adapters/utils/mysql_mysql2.rb +2 -4
- data/lib/sequel/adapters/utils/mysql_prepared_statements.rb +3 -6
- data/lib/sequel/adapters/utils/replace.rb +0 -5
- data/lib/sequel/adapters/utils/stored_procedures.rb +0 -2
- data/lib/sequel/adapters/utils/unmodified_identifiers.rb +2 -0
- data/lib/sequel/ast_transformer.rb +3 -94
- data/lib/sequel/connection_pool.rb +26 -28
- data/lib/sequel/connection_pool/sharded_single.rb +1 -4
- data/lib/sequel/connection_pool/sharded_threaded.rb +97 -95
- data/lib/sequel/connection_pool/single.rb +0 -2
- data/lib/sequel/connection_pool/threaded.rb +94 -110
- data/lib/sequel/core.rb +42 -101
- data/lib/sequel/database.rb +12 -2
- data/lib/sequel/database/connecting.rb +23 -60
- data/lib/sequel/database/dataset.rb +6 -9
- data/lib/sequel/database/dataset_defaults.rb +4 -48
- data/lib/sequel/database/features.rb +5 -4
- data/lib/sequel/database/logging.rb +2 -9
- data/lib/sequel/database/misc.rb +23 -55
- data/lib/sequel/database/query.rb +8 -13
- data/lib/sequel/database/schema_generator.rb +89 -64
- data/lib/sequel/database/schema_methods.rb +61 -79
- data/lib/sequel/database/transactions.rb +4 -24
- data/lib/sequel/dataset.rb +18 -10
- data/lib/sequel/dataset/actions.rb +53 -107
- data/lib/sequel/dataset/dataset_module.rb +3 -15
- data/lib/sequel/dataset/features.rb +30 -30
- data/lib/sequel/dataset/graph.rb +40 -49
- data/lib/sequel/dataset/misc.rb +12 -37
- data/lib/sequel/dataset/placeholder_literalizer.rb +4 -4
- data/lib/sequel/dataset/prepared_statements.rb +23 -51
- data/lib/sequel/dataset/query.rb +71 -155
- data/lib/sequel/dataset/sql.rb +30 -225
- data/lib/sequel/deprecated.rb +18 -27
- data/lib/sequel/exceptions.rb +1 -17
- data/lib/sequel/extensions/_model_pg_row.rb +0 -7
- data/lib/sequel/extensions/_pretty_table.rb +1 -3
- data/lib/sequel/extensions/arbitrary_servers.rb +10 -10
- data/lib/sequel/extensions/connection_expiration.rb +1 -1
- data/lib/sequel/extensions/connection_validator.rb +1 -1
- data/lib/sequel/extensions/constraint_validations.rb +11 -11
- data/lib/sequel/extensions/core_extensions.rb +39 -49
- data/lib/sequel/extensions/core_refinements.rb +39 -45
- data/lib/sequel/extensions/current_datetime_timestamp.rb +0 -4
- data/lib/sequel/extensions/date_arithmetic.rb +7 -7
- data/lib/sequel/extensions/duplicate_columns_handler.rb +12 -9
- data/lib/sequel/extensions/empty_array_consider_nulls.rb +2 -2
- data/lib/sequel/extensions/eval_inspect.rb +4 -11
- data/lib/sequel/extensions/freeze_datasets.rb +1 -69
- data/lib/sequel/extensions/from_block.rb +1 -35
- data/lib/sequel/extensions/graph_each.rb +2 -2
- data/lib/sequel/extensions/identifier_mangling.rb +9 -19
- data/lib/sequel/extensions/implicit_subquery.rb +2 -2
- data/lib/sequel/extensions/inflector.rb +4 -4
- data/lib/sequel/extensions/migration.rb +23 -40
- data/lib/sequel/extensions/no_auto_literal_strings.rb +2 -84
- data/lib/sequel/extensions/null_dataset.rb +2 -8
- data/lib/sequel/extensions/pagination.rb +1 -17
- data/lib/sequel/extensions/pg_array.rb +20 -189
- data/lib/sequel/extensions/pg_hstore.rb +11 -50
- data/lib/sequel/extensions/pg_hstore_ops.rb +2 -2
- data/lib/sequel/extensions/pg_inet.rb +2 -15
- data/lib/sequel/extensions/pg_interval.rb +1 -20
- data/lib/sequel/extensions/pg_json.rb +7 -27
- data/lib/sequel/extensions/pg_loose_count.rb +1 -1
- data/lib/sequel/extensions/pg_range.rb +6 -121
- data/lib/sequel/extensions/pg_range_ops.rb +1 -3
- data/lib/sequel/extensions/pg_row.rb +5 -77
- data/lib/sequel/extensions/pg_row_ops.rb +2 -13
- data/lib/sequel/extensions/query.rb +3 -4
- data/lib/sequel/extensions/round_timestamps.rb +0 -6
- data/lib/sequel/extensions/schema_dumper.rb +13 -13
- data/lib/sequel/extensions/select_remove.rb +3 -3
- data/lib/sequel/extensions/split_array_nil.rb +2 -2
- data/lib/sequel/extensions/sql_comments.rb +2 -2
- data/lib/sequel/extensions/string_agg.rb +11 -8
- data/lib/sequel/extensions/symbol_aref.rb +6 -20
- data/lib/sequel/model.rb +27 -62
- data/lib/sequel/model/associations.rb +128 -131
- data/lib/sequel/model/base.rb +171 -711
- data/lib/sequel/model/default_inflections.rb +1 -1
- data/lib/sequel/model/errors.rb +0 -3
- data/lib/sequel/model/exceptions.rb +2 -6
- data/lib/sequel/model/inflections.rb +1 -26
- data/lib/sequel/model/plugins.rb +1 -0
- data/lib/sequel/plugins/active_model.rb +2 -5
- data/lib/sequel/plugins/association_dependencies.rb +15 -15
- data/lib/sequel/plugins/association_pks.rb +14 -28
- data/lib/sequel/plugins/association_proxies.rb +6 -7
- data/lib/sequel/plugins/auto_validations.rb +4 -4
- data/lib/sequel/plugins/before_after_save.rb +0 -43
- data/lib/sequel/plugins/blacklist_security.rb +9 -8
- data/lib/sequel/plugins/boolean_readers.rb +3 -3
- data/lib/sequel/plugins/boolean_subsets.rb +2 -2
- data/lib/sequel/plugins/caching.rb +5 -5
- data/lib/sequel/plugins/class_table_inheritance.rb +71 -102
- data/lib/sequel/plugins/column_conflicts.rb +2 -2
- data/lib/sequel/plugins/column_select.rb +2 -2
- data/lib/sequel/plugins/composition.rb +15 -24
- data/lib/sequel/plugins/constraint_validations.rb +4 -3
- data/lib/sequel/plugins/csv_serializer.rb +13 -20
- data/lib/sequel/plugins/dataset_associations.rb +2 -2
- data/lib/sequel/plugins/def_dataset_method.rb +5 -5
- data/lib/sequel/plugins/defaults_setter.rb +1 -1
- data/lib/sequel/plugins/delay_add_association.rb +1 -1
- data/lib/sequel/plugins/finder.rb +16 -10
- data/lib/sequel/plugins/force_encoding.rb +1 -7
- data/lib/sequel/plugins/hook_class_methods.rb +4 -106
- data/lib/sequel/plugins/input_transformer.rb +10 -11
- data/lib/sequel/plugins/insert_returning_select.rb +1 -9
- data/lib/sequel/plugins/instance_filters.rb +5 -5
- data/lib/sequel/plugins/instance_hooks.rb +7 -52
- data/lib/sequel/plugins/inverted_subsets.rb +3 -1
- data/lib/sequel/plugins/json_serializer.rb +19 -19
- data/lib/sequel/plugins/lazy_attributes.rb +1 -10
- data/lib/sequel/plugins/list.rb +6 -6
- data/lib/sequel/plugins/many_through_many.rb +11 -8
- data/lib/sequel/plugins/mssql_optimistic_locking.rb +3 -3
- data/lib/sequel/plugins/nested_attributes.rb +18 -31
- data/lib/sequel/plugins/optimistic_locking.rb +3 -3
- data/lib/sequel/plugins/pg_array_associations.rb +8 -2
- data/lib/sequel/plugins/pg_row.rb +2 -11
- data/lib/sequel/plugins/prepared_statements.rb +13 -66
- data/lib/sequel/plugins/prepared_statements_safe.rb +1 -1
- data/lib/sequel/plugins/rcte_tree.rb +7 -7
- data/lib/sequel/plugins/serialization.rb +15 -33
- data/lib/sequel/plugins/serialization_modification_detection.rb +1 -1
- data/lib/sequel/plugins/sharding.rb +2 -8
- data/lib/sequel/plugins/single_table_inheritance.rb +10 -13
- data/lib/sequel/plugins/skip_create_refresh.rb +3 -3
- data/lib/sequel/plugins/static_cache.rb +8 -9
- data/lib/sequel/plugins/string_stripper.rb +3 -3
- data/lib/sequel/plugins/subclasses.rb +1 -1
- data/lib/sequel/plugins/subset_conditions.rb +2 -2
- data/lib/sequel/plugins/table_select.rb +2 -2
- data/lib/sequel/plugins/tactical_eager_loading.rb +4 -4
- data/lib/sequel/plugins/timestamps.rb +6 -7
- data/lib/sequel/plugins/touch.rb +4 -8
- data/lib/sequel/plugins/tree.rb +3 -3
- data/lib/sequel/plugins/typecast_on_load.rb +2 -2
- data/lib/sequel/plugins/unlimited_update.rb +1 -7
- data/lib/sequel/plugins/update_or_create.rb +3 -3
- data/lib/sequel/plugins/update_refresh.rb +3 -3
- data/lib/sequel/plugins/uuid.rb +7 -11
- data/lib/sequel/plugins/validation_class_methods.rb +10 -9
- data/lib/sequel/plugins/validation_contexts.rb +4 -4
- data/lib/sequel/plugins/validation_helpers.rb +26 -25
- data/lib/sequel/plugins/whitelist_security.rb +13 -9
- data/lib/sequel/plugins/xml_serializer.rb +24 -25
- data/lib/sequel/sql.rb +145 -276
- data/lib/sequel/timezones.rb +8 -22
- data/lib/sequel/version.rb +2 -2
- data/spec/adapter_spec.rb +1 -1
- data/spec/adapters/db2_spec.rb +2 -103
- data/spec/adapters/mssql_spec.rb +89 -68
- data/spec/adapters/mysql_spec.rb +101 -480
- data/spec/adapters/oracle_spec.rb +1 -9
- data/spec/adapters/postgres_spec.rb +312 -565
- data/spec/adapters/spec_helper.rb +12 -31
- data/spec/adapters/sqlanywhere_spec.rb +2 -77
- data/spec/adapters/sqlite_spec.rb +8 -146
- data/spec/bin_spec.rb +11 -16
- data/spec/core/connection_pool_spec.rb +173 -74
- data/spec/core/database_spec.rb +64 -244
- data/spec/core/dataset_spec.rb +81 -415
- data/spec/core/deprecated_spec.rb +3 -3
- data/spec/core/expression_filters_spec.rb +37 -144
- data/spec/core/mock_adapter_spec.rb +176 -4
- data/spec/core/object_graph_spec.rb +11 -60
- data/spec/core/placeholder_literalizer_spec.rb +1 -14
- data/spec/core/schema_generator_spec.rb +51 -40
- data/spec/core/schema_spec.rb +74 -77
- data/spec/core/spec_helper.rb +6 -24
- data/spec/core/version_spec.rb +1 -1
- data/spec/core_extensions_spec.rb +7 -83
- data/spec/core_model_spec.rb +2 -2
- data/spec/deprecation_helper.rb +2 -14
- data/spec/extensions/accessed_columns_spec.rb +1 -1
- data/spec/extensions/active_model_spec.rb +3 -3
- data/spec/extensions/after_initialize_spec.rb +1 -1
- data/spec/extensions/arbitrary_servers_spec.rb +2 -2
- data/spec/extensions/association_dependencies_spec.rb +1 -1
- data/spec/extensions/association_pks_spec.rb +4 -59
- data/spec/extensions/association_proxies_spec.rb +1 -1
- data/spec/extensions/auto_literal_strings_spec.rb +1 -12
- data/spec/extensions/auto_validations_spec.rb +1 -1
- data/spec/extensions/blacklist_security_spec.rb +1 -1
- data/spec/extensions/blank_spec.rb +1 -1
- data/spec/extensions/boolean_readers_spec.rb +1 -1
- data/spec/extensions/boolean_subsets_spec.rb +1 -1
- data/spec/extensions/caching_spec.rb +1 -1
- data/spec/extensions/class_table_inheritance_spec.rb +35 -1086
- data/spec/extensions/column_conflicts_spec.rb +1 -1
- data/spec/extensions/column_select_spec.rb +4 -4
- data/spec/extensions/columns_introspection_spec.rb +1 -1
- data/spec/extensions/columns_updated_spec.rb +1 -1
- data/spec/extensions/composition_spec.rb +1 -7
- data/spec/extensions/connection_expiration_spec.rb +3 -3
- data/spec/extensions/connection_validator_spec.rb +3 -3
- data/spec/extensions/constraint_validations_plugin_spec.rb +1 -1
- data/spec/extensions/constraint_validations_spec.rb +1 -1
- data/spec/extensions/core_refinements_spec.rb +1 -3
- data/spec/extensions/csv_serializer_spec.rb +4 -9
- data/spec/extensions/current_datetime_timestamp_spec.rb +1 -1
- data/spec/extensions/dataset_associations_spec.rb +2 -1
- data/spec/extensions/dataset_source_alias_spec.rb +1 -1
- data/spec/extensions/date_arithmetic_spec.rb +3 -3
- data/spec/extensions/def_dataset_method_spec.rb +1 -1
- data/spec/extensions/defaults_setter_spec.rb +2 -2
- data/spec/extensions/delay_add_association_spec.rb +8 -9
- data/spec/extensions/dirty_spec.rb +1 -1
- data/spec/extensions/duplicate_columns_handler_spec.rb +1 -1
- data/spec/extensions/eager_each_spec.rb +2 -2
- data/spec/extensions/empty_array_consider_nulls_spec.rb +1 -1
- data/spec/extensions/error_splitter_spec.rb +1 -1
- data/spec/extensions/error_sql_spec.rb +1 -1
- data/spec/extensions/eval_inspect_spec.rb +1 -1
- data/spec/extensions/finder_spec.rb +1 -1
- data/spec/extensions/force_encoding_spec.rb +2 -5
- data/spec/extensions/freeze_datasets_spec.rb +1 -1
- data/spec/extensions/graph_each_spec.rb +5 -5
- data/spec/extensions/hook_class_methods_spec.rb +1 -194
- data/spec/extensions/identifier_mangling_spec.rb +17 -170
- data/spec/extensions/implicit_subquery_spec.rb +1 -5
- data/spec/extensions/inflector_spec.rb +1 -1
- data/spec/extensions/input_transformer_spec.rb +7 -2
- data/spec/extensions/insert_returning_select_spec.rb +1 -1
- data/spec/extensions/instance_filters_spec.rb +1 -1
- data/spec/extensions/instance_hooks_spec.rb +1 -95
- data/spec/extensions/inverted_subsets_spec.rb +1 -1
- data/spec/extensions/json_serializer_spec.rb +1 -1
- data/spec/extensions/lazy_attributes_spec.rb +1 -7
- data/spec/extensions/list_spec.rb +1 -1
- data/spec/extensions/looser_typecasting_spec.rb +1 -1
- data/spec/extensions/many_through_many_spec.rb +1 -1
- data/spec/extensions/migration_spec.rb +2 -2
- data/spec/extensions/modification_detection_spec.rb +1 -1
- data/spec/extensions/mssql_optimistic_locking_spec.rb +1 -1
- data/spec/extensions/named_timezones_spec.rb +3 -3
- data/spec/extensions/nested_attributes_spec.rb +1 -29
- data/spec/extensions/null_dataset_spec.rb +1 -11
- data/spec/extensions/optimistic_locking_spec.rb +1 -1
- data/spec/extensions/pagination_spec.rb +1 -1
- data/spec/extensions/pg_array_associations_spec.rb +4 -1
- data/spec/extensions/pg_array_ops_spec.rb +1 -1
- data/spec/extensions/pg_array_spec.rb +3 -48
- data/spec/extensions/pg_enum_spec.rb +1 -1
- data/spec/extensions/pg_hstore_ops_spec.rb +1 -1
- data/spec/extensions/pg_hstore_spec.rb +23 -32
- data/spec/extensions/pg_inet_ops_spec.rb +1 -1
- data/spec/extensions/pg_inet_spec.rb +1 -14
- data/spec/extensions/pg_interval_spec.rb +3 -13
- data/spec/extensions/pg_json_ops_spec.rb +1 -1
- data/spec/extensions/pg_json_spec.rb +1 -13
- data/spec/extensions/pg_loose_count_spec.rb +1 -1
- data/spec/extensions/pg_range_ops_spec.rb +1 -1
- data/spec/extensions/pg_range_spec.rb +3 -88
- data/spec/extensions/pg_row_ops_spec.rb +1 -1
- data/spec/extensions/pg_row_plugin_spec.rb +1 -1
- data/spec/extensions/pg_row_spec.rb +1 -44
- data/spec/extensions/pg_static_cache_updater_spec.rb +1 -1
- data/spec/extensions/prepared_statements_safe_spec.rb +1 -1
- data/spec/extensions/prepared_statements_spec.rb +13 -48
- data/spec/extensions/pretty_table_spec.rb +1 -1
- data/spec/extensions/query_spec.rb +1 -12
- data/spec/extensions/rcte_tree_spec.rb +1 -1
- data/spec/extensions/round_timestamps_spec.rb +1 -5
- data/spec/extensions/s_spec.rb +1 -1
- data/spec/extensions/schema_caching_spec.rb +1 -1
- data/spec/extensions/schema_dumper_spec.rb +1 -1
- data/spec/extensions/select_remove_spec.rb +1 -1
- data/spec/extensions/sequel_4_dataset_methods_spec.rb +1 -1
- data/spec/extensions/serialization_modification_detection_spec.rb +1 -1
- data/spec/extensions/serialization_spec.rb +2 -14
- data/spec/extensions/server_block_spec.rb +1 -1
- data/spec/extensions/server_logging_spec.rb +2 -2
- data/spec/extensions/sharding_spec.rb +1 -1
- data/spec/extensions/shared_caching_spec.rb +1 -28
- data/spec/extensions/single_table_inheritance_spec.rb +2 -5
- data/spec/extensions/singular_table_names_spec.rb +1 -1
- data/spec/extensions/skip_create_refresh_spec.rb +1 -1
- data/spec/extensions/spec_helper.rb +5 -27
- data/spec/extensions/split_array_nil_spec.rb +1 -1
- data/spec/extensions/split_values_spec.rb +1 -1
- data/spec/extensions/sql_comments_spec.rb +1 -1
- data/spec/extensions/sql_expr_spec.rb +1 -1
- data/spec/extensions/static_cache_spec.rb +1 -1
- data/spec/extensions/string_agg_spec.rb +2 -2
- data/spec/extensions/string_date_time_spec.rb +1 -1
- data/spec/extensions/string_stripper_spec.rb +1 -1
- data/spec/extensions/subclasses_spec.rb +1 -1
- data/spec/extensions/subset_conditions_spec.rb +1 -1
- data/spec/extensions/symbol_aref_refinement_spec.rb +1 -1
- data/spec/extensions/symbol_as_refinement_spec.rb +1 -1
- data/spec/extensions/table_select_spec.rb +4 -4
- data/spec/extensions/tactical_eager_loading_spec.rb +1 -6
- data/spec/extensions/thread_local_timezones_spec.rb +1 -1
- data/spec/extensions/timestamps_spec.rb +3 -3
- data/spec/extensions/to_dot_spec.rb +1 -1
- data/spec/extensions/touch_spec.rb +1 -1
- data/spec/extensions/tree_spec.rb +1 -1
- data/spec/extensions/typecast_on_load_spec.rb +1 -1
- data/spec/extensions/unlimited_update_spec.rb +1 -1
- data/spec/extensions/update_or_create_spec.rb +1 -1
- data/spec/extensions/update_primary_key_spec.rb +4 -3
- data/spec/extensions/update_refresh_spec.rb +1 -1
- data/spec/extensions/uuid_spec.rb +10 -12
- data/spec/extensions/validate_associated_spec.rb +1 -1
- data/spec/extensions/validation_class_methods_spec.rb +3 -3
- data/spec/extensions/validation_contexts_spec.rb +1 -1
- data/spec/extensions/validation_helpers_spec.rb +10 -44
- data/spec/extensions/whitelist_security_spec.rb +5 -5
- data/spec/extensions/xml_serializer_spec.rb +3 -3
- data/spec/guards_helper.rb +2 -1
- data/spec/integration/associations_test.rb +1 -23
- data/spec/integration/database_test.rb +7 -7
- data/spec/integration/dataset_test.rb +5 -47
- data/spec/integration/eager_loader_test.rb +1 -1
- data/spec/integration/migrator_test.rb +1 -1
- data/spec/integration/model_test.rb +4 -82
- data/spec/integration/plugin_test.rb +6 -22
- data/spec/integration/prepared_statement_test.rb +8 -88
- data/spec/integration/schema_test.rb +6 -6
- data/spec/integration/spec_helper.rb +13 -21
- data/spec/integration/timezone_test.rb +5 -5
- data/spec/integration/transaction_test.rb +3 -55
- data/spec/integration/type_test.rb +9 -9
- data/spec/model/association_reflection_spec.rb +24 -9
- data/spec/model/associations_spec.rb +124 -303
- data/spec/model/base_spec.rb +18 -137
- data/spec/model/class_dataset_methods_spec.rb +2 -20
- data/spec/model/dataset_methods_spec.rb +1 -20
- data/spec/model/eager_loading_spec.rb +17 -11
- data/spec/model/hooks_spec.rb +5 -300
- data/spec/model/inflector_spec.rb +1 -1
- data/spec/model/model_spec.rb +15 -320
- data/spec/model/plugins_spec.rb +2 -16
- data/spec/model/record_spec.rb +29 -121
- data/spec/model/spec_helper.rb +5 -15
- data/spec/model/validations_spec.rb +1 -1
- data/spec/sequel_warning.rb +1 -12
- metadata +8 -64
- data/doc/active_record.rdoc +0 -927
- data/lib/sequel/adapters/cubrid.rb +0 -160
- data/lib/sequel/adapters/do.rb +0 -166
- data/lib/sequel/adapters/do/mysql.rb +0 -69
- data/lib/sequel/adapters/do/postgres.rb +0 -46
- data/lib/sequel/adapters/do/sqlite3.rb +0 -41
- data/lib/sequel/adapters/jdbc/as400.rb +0 -92
- data/lib/sequel/adapters/jdbc/cubrid.rb +0 -65
- data/lib/sequel/adapters/jdbc/firebirdsql.rb +0 -37
- data/lib/sequel/adapters/jdbc/informix-sqli.rb +0 -34
- data/lib/sequel/adapters/jdbc/jdbcprogress.rb +0 -34
- data/lib/sequel/adapters/odbc/progress.rb +0 -12
- data/lib/sequel/adapters/shared/cubrid.rb +0 -245
- data/lib/sequel/adapters/shared/firebird.rb +0 -261
- data/lib/sequel/adapters/shared/informix.rb +0 -63
- data/lib/sequel/adapters/shared/progress.rb +0 -40
- data/lib/sequel/adapters/swift.rb +0 -169
- data/lib/sequel/adapters/swift/mysql.rb +0 -50
- data/lib/sequel/adapters/swift/postgres.rb +0 -49
- data/lib/sequel/adapters/swift/sqlite.rb +0 -48
- data/lib/sequel/adapters/utils/pg_types.rb +0 -4
- data/lib/sequel/dataset/mutation.rb +0 -98
- data/lib/sequel/extensions/_deprecated_identifier_mangling.rb +0 -117
- data/lib/sequel/extensions/empty_array_ignore_nulls.rb +0 -8
- data/lib/sequel/extensions/filter_having.rb +0 -65
- data/lib/sequel/extensions/hash_aliases.rb +0 -51
- data/lib/sequel/extensions/meta_def.rb +0 -37
- data/lib/sequel/extensions/query_literals.rb +0 -86
- data/lib/sequel/extensions/ruby18_symbol_extensions.rb +0 -26
- data/lib/sequel/extensions/sequel_3_dataset_methods.rb +0 -133
- data/lib/sequel/extensions/set_overrides.rb +0 -82
- data/lib/sequel/no_core_ext.rb +0 -4
- data/lib/sequel/plugins/association_autoreloading.rb +0 -11
- data/lib/sequel/plugins/identifier_columns.rb +0 -49
- data/lib/sequel/plugins/many_to_one_pk_lookup.rb +0 -11
- data/lib/sequel/plugins/pg_typecast_on_load.rb +0 -90
- data/lib/sequel/plugins/prepared_statements_associations.rb +0 -137
- data/lib/sequel/plugins/prepared_statements_with_pk.rb +0 -71
- data/lib/sequel/plugins/schema.rb +0 -84
- data/lib/sequel/plugins/scissors.rb +0 -37
- data/spec/core/dataset_mutation_spec.rb +0 -253
- data/spec/extensions/_deprecated_identifier_mangling_spec.rb +0 -314
- data/spec/extensions/before_after_save_spec.rb +0 -40
- data/spec/extensions/filter_having_spec.rb +0 -42
- data/spec/extensions/from_block_spec.rb +0 -21
- data/spec/extensions/hash_aliases_spec.rb +0 -26
- data/spec/extensions/identifier_columns_spec.rb +0 -19
- data/spec/extensions/meta_def_spec.rb +0 -35
- data/spec/extensions/no_auto_literal_strings_spec.rb +0 -69
- data/spec/extensions/pg_typecast_on_load_spec.rb +0 -70
- data/spec/extensions/prepared_statements_associations_spec.rb +0 -212
- data/spec/extensions/prepared_statements_with_pk_spec.rb +0 -40
- data/spec/extensions/query_literals_spec.rb +0 -185
- data/spec/extensions/schema_spec.rb +0 -123
- data/spec/extensions/scissors_spec.rb +0 -27
- data/spec/extensions/sequel_3_dataset_methods_spec.rb +0 -118
- data/spec/extensions/set_overrides_spec.rb +0 -75
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d494778be10a685dadd0181b0f35d8976ad80de5
|
4
|
+
data.tar.gz: 3de435547bc07c151e6511915b034c4c70909b28
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 71e23a94e737525c4bcf0ad0e16376a8ec933bf6962dce7c5032971ec3f8b7cb140c194ad51a41e818c4597025c3403b5f3777941ecf247595f8b7294ac9804f
|
7
|
+
data.tar.gz: d57c4092428f1ca13fb1fce70e9f26dae1f53e5c04f75aef5c5ad2ea5d0ac664c06443b86f7881a7abe7c499b977476fddb3155c9856290eb573b3a6d810b7a4
|
data/CHANGELOG
CHANGED
@@ -1,3 +1,73 @@
|
|
1
|
+
=== 5.0.0 (2017-09-01)
|
2
|
+
|
3
|
+
* Make bin/sequel -M option always use base 10 (jeremyevans)
|
4
|
+
|
5
|
+
* Don't use savepoints when creating indexes inside a transaction on databases that don't support transactional schema modifications (jeremyevans) (#1407)
|
6
|
+
|
7
|
+
* Support :if_not_exists option when creating indexes on PostgreSQL 9.5+ (DyegoCosta) (#1405)
|
8
|
+
|
9
|
+
* Make threaded connection pools not block while connections are being made (jeremyevans)
|
10
|
+
|
11
|
+
* SQL::Expression#clone and #dup now return self, since all expressions should be frozen value objects (jeremyevans)
|
12
|
+
|
13
|
+
* Don't create empty arrays for unused association callbacks (jeremyevans)
|
14
|
+
|
15
|
+
* Cache association method name symbols instead of recomputing them everytime (jeremyevans)
|
16
|
+
|
17
|
+
* Raise an exception if attempting to create a prepared statement using a dataset with a delayed evaluation (jeremyevans)
|
18
|
+
|
19
|
+
* Make ConnectionPool#size thread safe by using the pool mutex (jeremyevans)
|
20
|
+
|
21
|
+
* Use instance_exec instead of instance_eval when passing a block, to work with lambdas that accept no arguments (jeremyevans)
|
22
|
+
|
23
|
+
* Freeze SQL::StringAgg instances in string_agg extension (jeremyevans)
|
24
|
+
|
25
|
+
* Freeze SQL::DateAdd instances in date_arithmetic extension (jeremyevans)
|
26
|
+
|
27
|
+
* Freeze SQL::Expression.comparison_attrs (jeremyevans)
|
28
|
+
|
29
|
+
* Rename SQL::Subscript#f to #expression, keeping #f as an alias (jeremyevans)
|
30
|
+
|
31
|
+
* Require the :pool_class Database option be a class to use a custom connection pool (jeremyevans)
|
32
|
+
|
33
|
+
* Make the class_table_inheritance plugin raise an Error during update if any UPDATE query does not affect a single row (jeremyevans)
|
34
|
+
|
35
|
+
* Change most send calls to public_send unless calling private methods is expected (jeremyevans)
|
36
|
+
|
37
|
+
* Database schema and schema generator methods now return nil (jeremyevans)
|
38
|
+
|
39
|
+
* Model#validates_unique in the validation helpers plugin now defaults to only checking on new or modified values (jeremyevans)
|
40
|
+
|
41
|
+
* Deprecate Model#_before_validation (private_method), use Model#before_validation now (jeremyevans)
|
42
|
+
|
43
|
+
* Always run before/after/around validation hooks when saving, even when not validating the object (jeremyevans)
|
44
|
+
|
45
|
+
* Deprecate Model use_after_commit_rollback class and instance accessors (jeremyevans)
|
46
|
+
|
47
|
+
* Deprecate Model.allowed_columns reader (jeremyevans)
|
48
|
+
|
49
|
+
* Freeze internal constants that shouldn't be modified at runtime (jeremyevans)
|
50
|
+
|
51
|
+
* Attempt to connect to the database immediately when creating the Database instance (jeremyevans)
|
52
|
+
|
53
|
+
* Make association_pks plugin delay the setting of associated objects until the current object is saved by default (jeremyevans)
|
54
|
+
|
55
|
+
* Joined datasets used as model datasets are now automatically wrapped in a subquery (jeremyevans)
|
56
|
+
|
57
|
+
* Setting an invalid dataset for a model class now raises an exception by default (jeremyevans)
|
58
|
+
|
59
|
+
* Getting all values for newly created models now happens before calling after_create, instead of after (jeremyevans)
|
60
|
+
|
61
|
+
* Remove use of @was_new/@columns_updated instance variables when saving model objects (jeremyevans)
|
62
|
+
|
63
|
+
* Disable symbol splitting by default (jeremyevans)
|
64
|
+
|
65
|
+
* Make datasets frozen by default (jeremyevans)
|
66
|
+
|
67
|
+
* Drop support for ruby 1.8.7, minimum now is 1.9.2 (jeremyevans)
|
68
|
+
|
69
|
+
* Remove deprecated adapters, extensions, plugins, constants, and features (jeremyevans)
|
70
|
+
|
1
71
|
=== 4.49.0 (2017-08-01)
|
2
72
|
|
3
73
|
* Make dataset_associations plugin automatically alias tables when using many_through_many associations that join the same table multiple times (jeremyevans)
|
data/README.rdoc
CHANGED
@@ -8,9 +8,9 @@ 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
|
-
|
11
|
+
statements, bound variables, savepoints, two-phase commit,
|
12
|
+
transaction isolation, master/slave configurations, and
|
13
|
+
database sharding.
|
14
14
|
* Sequel currently has adapters for ADO, Amalgalite,
|
15
15
|
IBM_DB, JDBC, MySQL, Mysql2, ODBC, Oracle,
|
16
16
|
PostgreSQL, SQLAnywhere, SQLite3, and TinyTDS.
|
@@ -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
|
|
@@ -89,18 +89,19 @@ 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
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
|
|
@@ -118,7 +119,12 @@ The connection URL can also include such stuff as the user name, password, and p
|
|
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 safe to use by multiple threads concurrently.
|
170
176
|
|
171
177
|
=== Retrieving Records
|
172
178
|
|
@@ -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":
|
245
|
+
|
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')
|
227
250
|
|
228
|
-
Some
|
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'))
|
237
260
|
|
238
|
-
|
261
|
+
But note that this does a full inversion of the filter:
|
239
262
|
|
240
|
-
posts.
|
241
|
-
# WHERE
|
263
|
+
my_posts = posts.exclude(category: ['ruby', 'postgres', 'linux'], id: 1)
|
264
|
+
# WHERE ((category NOT IN ('ruby', 'postgres', 'linux')) OR (id != 1))
|
242
265
|
|
243
|
-
|
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+:
|
268
|
+
|
269
|
+
posts.where(Sequel.lit('stamp IS NOT NULL'))
|
270
|
+
# WHERE (stamp IS NOT NULL)
|
271
|
+
|
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
|
|
@@ -268,7 +298,7 @@ issues that you should be aware of when using Sequel.
|
|
268
298
|
Counting records is easy using +count+:
|
269
299
|
|
270
300
|
posts.where(Sequel.like(:category, '%ruby%')).count
|
271
|
-
# SELECT COUNT(*) FROM posts WHERE category LIKE '%ruby%'
|
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
|
|
@@ -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')
|
439
|
+
# INSERT
|
407
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,57 +474,52 @@ 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
|
|
491
|
-
|
519
|
+
And most Sequel expression objects support an +as+ method for aliasing:
|
492
520
|
|
493
|
-
Sequel
|
521
|
+
(Sequel[:column] + 2).as(:c_plus_2)
|
522
|
+
# (column + 2) AS c_plus_2
|
494
523
|
|
495
524
|
== Sequel Models
|
496
525
|
|
@@ -508,7 +537,7 @@ implements the active record pattern).
|
|
508
537
|
|
509
538
|
Sequel model classes assume that the table name is an underscored plural of the class name:
|
510
539
|
|
511
|
-
Post.table_name
|
540
|
+
Post.table_name # => :posts
|
512
541
|
|
513
542
|
You can explicitly set the table name or even the dataset used:
|
514
543
|
|
@@ -518,27 +547,27 @@ You can explicitly set the table name or even the dataset used:
|
|
518
547
|
|
519
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:
|
520
549
|
|
521
|
-
class Post < Sequel::Model(DB[:my_posts].where(:
|
550
|
+
class Post < Sequel::Model(DB[:my_posts].where(category: 'ruby')); end
|
522
551
|
class Post < Sequel::Model(DB[:my_posts].select(:id, :name).order(:date)); end
|
523
552
|
|
524
553
|
=== Model instances
|
525
554
|
|
526
|
-
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:
|
527
556
|
|
528
557
|
post = Post[123]
|
529
558
|
|
530
559
|
The +pk+ method is used to retrieve the record's primary key value:
|
531
560
|
|
532
|
-
post.pk
|
561
|
+
post.pk # => 123
|
533
562
|
|
534
|
-
|
563
|
+
If you want to override which column(s) to use as the primary key, you can use +set_primary_key+:
|
535
564
|
|
536
565
|
class Post < Sequel::Model
|
537
566
|
set_primary_key [:category, :title]
|
538
567
|
end
|
539
568
|
|
540
569
|
post = Post['ruby', 'hello world']
|
541
|
-
post.pk
|
570
|
+
post.pk # => ['ruby', 'hello world']
|
542
571
|
|
543
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:
|
544
573
|
|
@@ -546,39 +575,43 @@ You can also define a model class that does not have a primary key via +no_prima
|
|
546
575
|
|
547
576
|
A single model instance can also be fetched by specifying a condition:
|
548
577
|
|
549
|
-
post = Post
|
578
|
+
post = Post.first(title: 'hello world')
|
550
579
|
post = Post.first{num_comments < 10}
|
551
580
|
|
581
|
+
The dataset for a model class returns rows a model instances instead of plain hashes:
|
582
|
+
|
583
|
+
DB[:posts].first.class # => Hash
|
584
|
+
Post.first.class # => Post
|
585
|
+
|
552
586
|
=== Acts like a dataset
|
553
587
|
|
554
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.:
|
555
589
|
|
556
|
-
Post.where(:
|
590
|
+
Post.where(category: 'ruby').each{|post| p post}
|
557
591
|
|
558
592
|
You can also manipulate the records in the dataset:
|
559
593
|
|
560
594
|
Post.where{num_comments < 7}.delete
|
561
|
-
Post.where(Sequel.like(:title, /ruby/)).update(:
|
595
|
+
Post.where(Sequel.like(:title, /ruby/)).update(category: 'ruby')
|
562
596
|
|
563
597
|
=== Accessing record values
|
564
598
|
|
565
599
|
A model instance stores its values as a hash with column symbol keys, which you can access directly via the +values+ method:
|
566
600
|
|
567
|
-
post.values
|
601
|
+
post.values # => {:id => 123, :category => 'ruby', :title => 'hello world'}
|
568
602
|
|
569
603
|
You can read the record values as object attributes, assuming the attribute names are valid columns in the model's dataset:
|
570
604
|
|
571
|
-
post.id
|
572
|
-
post.title
|
605
|
+
post.id # => 123
|
606
|
+
post.title # => 'hello world'
|
573
607
|
|
574
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:
|
575
609
|
|
576
|
-
post[:id]
|
577
|
-
post[:title]
|
610
|
+
post[:id] # => 123
|
611
|
+
post[:title] # => 'hello world'
|
578
612
|
|
579
613
|
You can also modify record values using attribute setters or the <tt>[]=</tt> method.
|
580
614
|
|
581
|
-
|
582
615
|
post.title = 'hey there'
|
583
616
|
post[:title] = 'hey there'
|
584
617
|
|
@@ -590,24 +623,26 @@ That will just change the value for the object, it will not update the row in th
|
|
590
623
|
|
591
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:
|
592
625
|
|
593
|
-
post.set(:
|
626
|
+
post.set(title: 'hey there', updated_by: 'foo')
|
594
627
|
|
595
628
|
and +update+ updates the model's column values and then saves the changes to the database:
|
596
629
|
|
597
|
-
post.update(:
|
630
|
+
post.update(title: 'hey there', updated_by: 'foo')
|
598
631
|
|
599
632
|
=== Creating new records
|
600
633
|
|
601
|
-
New
|
634
|
+
New model instances can be created by calling <tt>Model.new</tt>, which returns a new model instance without updating the database:
|
602
635
|
|
603
|
-
post = Post.
|
636
|
+
post = Post.new(title: 'hello world')
|
604
637
|
|
605
|
-
|
638
|
+
You can save the record to the database later by calling +save+ on the model instance:
|
606
639
|
|
607
|
-
post = Post.new
|
608
|
-
post.title = 'hello world'
|
609
640
|
post.save
|
610
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
|
+
|
611
646
|
You can also supply a block to <tt>Model.new</tt> and <tt>Model.create</tt>:
|
612
647
|
|
613
648
|
post = Post.new do |p|
|
@@ -634,7 +669,7 @@ You can execute custom code when creating, updating, or deleting records by defi
|
|
634
669
|
|
635
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.
|
636
671
|
|
637
|
-
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.
|
638
673
|
|
639
674
|
=== Deleting records
|
640
675
|
|
@@ -666,21 +701,21 @@ Associations are used in order to specify relationships between model classes th
|
|
666
701
|
|
667
702
|
+many_to_one+ and +one_to_one+ create a getter and setter for each model object:
|
668
703
|
|
669
|
-
post = Post.create(:
|
670
|
-
post.author = Author
|
704
|
+
post = Post.create(name: 'hi!')
|
705
|
+
post.author = Author.first(name: 'Sharon')
|
671
706
|
post.author
|
672
707
|
|
673
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:
|
674
709
|
|
675
|
-
post = Post.create(:
|
710
|
+
post = Post.create(name: 'hi!')
|
676
711
|
post.comments
|
677
712
|
|
678
|
-
comment = Comment.create(:
|
713
|
+
comment = Comment.create(text: 'hi')
|
679
714
|
post.add_comment(comment)
|
680
715
|
post.remove_comment(comment)
|
681
716
|
post.remove_all_comments
|
682
717
|
|
683
|
-
tag = Tag.create(:
|
718
|
+
tag = Tag.create(tag: 'interesting')
|
684
719
|
post.add_tag(tag)
|
685
720
|
post.remove_tag(tag)
|
686
721
|
post.remove_all_tags
|
@@ -693,7 +728,7 @@ All associations add a dataset method that can be used to further filter or reor
|
|
693
728
|
post.comments_dataset.destroy
|
694
729
|
|
695
730
|
# Return all tags related to this post with no subscribers, ordered by the tag's name
|
696
|
-
post.tags_dataset.where(:
|
731
|
+
post.tags_dataset.where(subscribers: 0).order(:name).all
|
697
732
|
|
698
733
|
=== Eager Loading
|
699
734
|
|
@@ -735,32 +770,32 @@ Associations can be eagerly loaded via +eager+ and the <tt>:eager</tt> associati
|
|
735
770
|
Post.eager(:person).eager(:tags).all
|
736
771
|
|
737
772
|
# Cascading via .eager
|
738
|
-
Tag.eager(:
|
773
|
+
Tag.eager(posts: :replies).all
|
739
774
|
|
740
775
|
# Will also grab all associated posts' tags (because of :eager)
|
741
|
-
Reply.eager(:
|
776
|
+
Reply.eager(person: :posts).all
|
742
777
|
|
743
778
|
# No depth limit (other than memory/stack), and will also grab posts' tags
|
744
779
|
# Loads all people, their posts, their posts' tags, replies to those posts,
|
745
780
|
# the person for each reply, the tag for each reply, and all posts and
|
746
781
|
# replies that have that tag. Uses a total of 8 queries.
|
747
|
-
Person.eager(:
|
782
|
+
Person.eager(posts: {replies: [:person, {tags: [:posts, :replies]}]}).all
|
748
783
|
|
749
|
-
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.
|
750
785
|
|
751
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:
|
752
787
|
|
753
788
|
# Eagerly load only replies containing 'foo'
|
754
|
-
Post.eager(:
|
789
|
+
Post.eager(replies: proc{|ds| ds.where(Sequel.like(text, '%foo%'))}).all
|
755
790
|
|
756
791
|
This also works when using +eager_graph+, in which case the proc is called with dataset to graph into the current dataset:
|
757
792
|
|
758
|
-
Post.eager_graph(:
|
793
|
+
Post.eager_graph(replies: proc{|ds| ds.where(Sequel.like(text, '%foo%'))}).all
|
759
794
|
|
760
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:
|
761
796
|
|
762
797
|
# Eagerly load only replies containing 'foo', and the person and tags for those replies
|
763
|
-
Post.eager(:
|
798
|
+
Post.eager(replies: {proc{|ds| ds.where(Sequel.like(text, '%foo%'))} => [:person, :tags]}).all
|
764
799
|
|
765
800
|
=== Joining with Associations
|
766
801
|
|
@@ -778,7 +813,7 @@ This comes with variants for different join types:
|
|
778
813
|
|
779
814
|
Similar to the eager loading methods, you can use multiple associations and nested associations:
|
780
815
|
|
781
|
-
Post.association_join(:author, :
|
816
|
+
Post.association_join(:author, replies: :person).all
|
782
817
|
# SELECT * FROM posts
|
783
818
|
# INNER JOIN authors AS author ON (author.id = posts.author_id)
|
784
819
|
# INNER JOIN replies ON (replies.post_id = posts.id)
|
@@ -802,16 +837,16 @@ The recommended way to implement table-wide logic by defining methods on the dat
|
|
802
837
|
|
803
838
|
This allows you to have access to your model API from filtered datasets as well:
|
804
839
|
|
805
|
-
Post.where(:
|
840
|
+
Post.where(category: 'ruby').clean_boring
|
806
841
|
# DELETE FROM posts WHERE ((category = 'ruby') AND (num_comments < 30))
|
807
842
|
|
808
843
|
Inside +dataset_module+ blocks, there are numerous methods that support easy creation of dataset methods.
|
809
844
|
Most of these methods are named after the dataset methods themselves, such as +select+, +order+, and
|
810
|
-
+group
|
845
|
+
+group+:
|
811
846
|
|
812
847
|
class Post < Sequel::Model
|
813
848
|
dataset_module do
|
814
|
-
|
849
|
+
where(:with_few_comments, Sequel[:num_comments] < 30)
|
815
850
|
select :with_title_and_date, :id, :title, :post_date
|
816
851
|
order :by_post_date, :post_date
|
817
852
|
limit :top10, 10
|
@@ -824,6 +859,10 @@ Most of these methods are named after the dataset methods themselves, such as +s
|
|
824
859
|
# ORDER BY post_date
|
825
860
|
# LIMIT 10
|
826
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
|
+
|
827
866
|
=== Model Validations
|
828
867
|
|
829
868
|
You can define a +validate+ method for your model, which +save+
|
@@ -831,8 +870,7 @@ will check before attempting to save the model in the database.
|
|
831
870
|
If an attribute of the model isn't valid, you should add an error
|
832
871
|
message for that attribute to the model object's +errors+. If an
|
833
872
|
object has any errors added by the validate method, +save+ will
|
834
|
-
raise an error
|
835
|
-
(the +raise_on_save_failure+ flag).
|
873
|
+
raise an error by default:
|
836
874
|
|
837
875
|
class Post < Sequel::Model
|
838
876
|
def validate
|
@@ -841,3 +879,24 @@ raise an error or return false depending on how it is configured
|
|
841
879
|
errors.add(:written_on, "should be in the past") if written_on >= Time.now
|
842
880
|
end
|
843
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 of 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>
|