sequel 3.21.0 → 3.41.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +1131 -3
- data/MIT-LICENSE +1 -1
- data/README.rdoc +106 -65
- data/Rakefile +59 -27
- data/bin/sequel +50 -26
- data/doc/active_record.rdoc +68 -52
- data/doc/advanced_associations.rdoc +201 -75
- data/doc/association_basics.rdoc +327 -79
- data/doc/bin_sequel.rdoc +144 -0
- data/doc/cheat_sheet.rdoc +21 -21
- data/doc/core_extensions.rdoc +374 -0
- data/doc/dataset_basics.rdoc +10 -10
- data/doc/dataset_filtering.rdoc +54 -42
- data/doc/mass_assignment.rdoc +56 -0
- data/doc/migration.rdoc +89 -557
- data/doc/model_hooks.rdoc +80 -29
- data/doc/object_model.rdoc +576 -0
- data/doc/opening_databases.rdoc +121 -53
- data/doc/prepared_statements.rdoc +41 -15
- data/doc/querying.rdoc +137 -56
- data/doc/reflection.rdoc +36 -10
- data/doc/release_notes/3.22.0.txt +39 -0
- data/doc/release_notes/3.23.0.txt +172 -0
- data/doc/release_notes/3.24.0.txt +420 -0
- data/doc/release_notes/3.25.0.txt +88 -0
- data/doc/release_notes/3.26.0.txt +88 -0
- data/doc/release_notes/3.27.0.txt +82 -0
- data/doc/release_notes/3.28.0.txt +304 -0
- data/doc/release_notes/3.29.0.txt +459 -0
- data/doc/release_notes/3.30.0.txt +135 -0
- data/doc/release_notes/3.31.0.txt +146 -0
- data/doc/release_notes/3.32.0.txt +202 -0
- data/doc/release_notes/3.33.0.txt +157 -0
- data/doc/release_notes/3.34.0.txt +671 -0
- data/doc/release_notes/3.35.0.txt +144 -0
- data/doc/release_notes/3.36.0.txt +245 -0
- data/doc/release_notes/3.37.0.txt +338 -0
- data/doc/release_notes/3.38.0.txt +234 -0
- data/doc/release_notes/3.39.0.txt +237 -0
- data/doc/release_notes/3.40.0.txt +73 -0
- data/doc/release_notes/3.41.0.txt +155 -0
- data/doc/schema_modification.rdoc +585 -0
- data/doc/sharding.rdoc +99 -8
- data/doc/sql.rdoc +154 -112
- data/doc/testing.rdoc +169 -0
- data/doc/thread_safety.rdoc +17 -0
- data/doc/transactions.rdoc +137 -0
- data/doc/validations.rdoc +1 -1
- data/doc/virtual_rows.rdoc +78 -43
- data/lib/sequel/adapters/ado/access.rb +334 -0
- data/lib/sequel/adapters/ado/mssql.rb +18 -12
- data/lib/sequel/adapters/ado.rb +69 -21
- data/lib/sequel/adapters/amalgalite.rb +17 -14
- data/lib/sequel/adapters/cubrid.rb +143 -0
- data/lib/sequel/adapters/db2.rb +178 -85
- data/lib/sequel/adapters/dbi.rb +19 -21
- data/lib/sequel/adapters/do/mysql.rb +17 -11
- data/lib/sequel/adapters/do/postgres.rb +2 -61
- data/lib/sequel/adapters/do/sqlite.rb +0 -10
- data/lib/sequel/adapters/do.rb +20 -39
- data/lib/sequel/adapters/firebird.rb +33 -210
- data/lib/sequel/adapters/ibmdb.rb +452 -0
- data/lib/sequel/adapters/informix.rb +6 -29
- data/lib/sequel/adapters/jdbc/as400.rb +16 -34
- data/lib/sequel/adapters/jdbc/cubrid.rb +52 -0
- data/lib/sequel/adapters/jdbc/db2.rb +78 -0
- data/lib/sequel/adapters/jdbc/derby.rb +325 -0
- data/lib/sequel/adapters/jdbc/firebird.rb +24 -0
- data/lib/sequel/adapters/jdbc/h2.rb +68 -31
- data/lib/sequel/adapters/jdbc/hsqldb.rb +189 -0
- data/lib/sequel/adapters/jdbc/informix.rb +21 -0
- data/lib/sequel/adapters/jdbc/jtds.rb +40 -0
- data/lib/sequel/adapters/jdbc/mssql.rb +3 -33
- data/lib/sequel/adapters/jdbc/mysql.rb +16 -28
- data/lib/sequel/adapters/jdbc/oracle.rb +88 -25
- data/lib/sequel/adapters/jdbc/postgresql.rb +77 -52
- data/lib/sequel/adapters/jdbc/progress.rb +21 -0
- data/lib/sequel/adapters/jdbc/sqlite.rb +20 -10
- data/lib/sequel/adapters/jdbc/sqlserver.rb +72 -0
- data/lib/sequel/adapters/jdbc/transactions.rb +83 -0
- data/lib/sequel/adapters/jdbc.rb +308 -114
- data/lib/sequel/adapters/mock.rb +372 -0
- data/lib/sequel/adapters/mysql.rb +130 -230
- data/lib/sequel/adapters/mysql2.rb +64 -63
- data/lib/sequel/adapters/odbc/mssql.rb +17 -9
- data/lib/sequel/adapters/odbc.rb +29 -10
- data/lib/sequel/adapters/openbase.rb +7 -11
- data/lib/sequel/adapters/oracle.rb +364 -57
- data/lib/sequel/adapters/postgres.rb +379 -145
- data/lib/sequel/adapters/shared/access.rb +236 -11
- data/lib/sequel/adapters/shared/cubrid.rb +216 -0
- data/lib/sequel/adapters/shared/db2.rb +353 -0
- data/lib/sequel/adapters/shared/firebird.rb +231 -0
- data/lib/sequel/adapters/shared/informix.rb +53 -0
- data/lib/sequel/adapters/shared/mssql.rb +412 -116
- data/lib/sequel/adapters/shared/mysql.rb +396 -89
- data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +166 -0
- data/lib/sequel/adapters/shared/oracle.rb +262 -45
- data/lib/sequel/adapters/shared/postgres.rb +688 -279
- data/lib/sequel/adapters/shared/progress.rb +5 -8
- data/lib/sequel/adapters/shared/sqlite.rb +317 -96
- data/lib/sequel/adapters/sqlite.rb +109 -46
- data/lib/sequel/adapters/swift/mysql.rb +10 -12
- data/lib/sequel/adapters/swift/postgres.rb +13 -79
- data/lib/sequel/adapters/swift/sqlite.rb +9 -6
- data/lib/sequel/adapters/swift.rb +31 -27
- data/lib/sequel/adapters/tinytds.rb +177 -25
- data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +77 -0
- data/lib/sequel/adapters/utils/pg_types.rb +81 -0
- data/lib/sequel/adapters/utils/split_alter_table.rb +36 -0
- data/lib/sequel/adapters/utils/stored_procedures.rb +1 -11
- data/lib/sequel/ast_transformer.rb +194 -0
- data/lib/sequel/connection_pool/sharded_single.rb +23 -13
- data/lib/sequel/connection_pool/sharded_threaded.rb +64 -13
- data/lib/sequel/connection_pool/single.rb +11 -3
- data/lib/sequel/connection_pool/threaded.rb +69 -20
- data/lib/sequel/connection_pool.rb +20 -18
- data/lib/sequel/core.rb +143 -11
- data/lib/sequel/database/connecting.rb +66 -29
- data/lib/sequel/database/dataset.rb +4 -4
- data/lib/sequel/database/dataset_defaults.rb +63 -2
- data/lib/sequel/database/logging.rb +7 -2
- data/lib/sequel/database/misc.rb +192 -51
- data/lib/sequel/database/query.rb +299 -114
- data/lib/sequel/database/schema_generator.rb +103 -36
- data/lib/sequel/database/schema_methods.rb +310 -69
- data/lib/sequel/dataset/actions.rb +344 -90
- data/lib/sequel/dataset/features.rb +101 -8
- data/lib/sequel/dataset/graph.rb +42 -15
- data/lib/sequel/dataset/misc.rb +52 -25
- data/lib/sequel/dataset/mutation.rb +12 -7
- data/lib/sequel/dataset/prepared_statements.rb +68 -30
- data/lib/sequel/dataset/query.rb +322 -68
- data/lib/sequel/dataset/sql.rb +716 -293
- data/lib/sequel/dataset.rb +8 -0
- data/lib/sequel/exceptions.rb +4 -0
- data/lib/sequel/extensions/_pretty_table.rb +83 -0
- data/lib/sequel/extensions/arbitrary_servers.rb +109 -0
- data/lib/sequel/extensions/blank.rb +4 -0
- data/lib/sequel/extensions/columns_introspection.rb +72 -0
- data/lib/sequel/extensions/connection_validator.rb +109 -0
- data/lib/sequel/extensions/constraint_validations.rb +451 -0
- data/lib/sequel/{core_sql.rb → extensions/core_extensions.rb} +30 -46
- data/lib/sequel/extensions/eval_inspect.rb +173 -0
- data/lib/sequel/extensions/inflector.rb +4 -0
- data/lib/sequel/extensions/looser_typecasting.rb +5 -4
- data/lib/sequel/extensions/migration.rb +100 -11
- data/lib/sequel/extensions/named_timezones.rb +9 -0
- data/lib/sequel/extensions/null_dataset.rb +94 -0
- data/lib/sequel/extensions/pagination.rb +4 -0
- data/lib/sequel/extensions/pg_array.rb +539 -0
- data/lib/sequel/extensions/pg_array_ops.rb +263 -0
- data/lib/sequel/extensions/pg_auto_parameterize.rb +175 -0
- data/lib/sequel/extensions/pg_hstore.rb +334 -0
- data/lib/sequel/extensions/pg_hstore_ops.rb +293 -0
- data/lib/sequel/extensions/pg_inet.rb +113 -0
- data/lib/sequel/extensions/pg_interval.rb +191 -0
- data/lib/sequel/extensions/pg_json.rb +212 -0
- data/lib/sequel/extensions/pg_range.rb +513 -0
- data/lib/sequel/extensions/pg_range_ops.rb +150 -0
- data/lib/sequel/extensions/pg_row.rb +576 -0
- data/lib/sequel/extensions/pg_row_ops.rb +182 -0
- data/lib/sequel/extensions/pg_statement_cache.rb +317 -0
- data/lib/sequel/extensions/pretty_table.rb +17 -72
- data/lib/sequel/extensions/query.rb +8 -4
- data/lib/sequel/extensions/query_literals.rb +79 -0
- data/lib/sequel/extensions/schema_caching.rb +76 -0
- data/lib/sequel/extensions/schema_dumper.rb +282 -76
- data/lib/sequel/extensions/select_remove.rb +39 -0
- data/lib/sequel/extensions/server_block.rb +140 -0
- data/lib/sequel/extensions/split_array_nil.rb +65 -0
- data/lib/sequel/extensions/sql_expr.rb +8 -110
- data/lib/sequel/extensions/string_date_time.rb +4 -0
- data/lib/sequel/extensions/thread_local_timezones.rb +10 -4
- data/lib/sequel/extensions/to_dot.rb +99 -83
- data/lib/sequel/model/associations.rb +1263 -409
- data/lib/sequel/model/base.rb +624 -171
- data/lib/sequel/model/errors.rb +1 -1
- data/lib/sequel/model/exceptions.rb +24 -2
- data/lib/sequel/model/inflections.rb +1 -1
- data/lib/sequel/model.rb +30 -11
- data/lib/sequel/no_core_ext.rb +2 -0
- data/lib/sequel/plugins/active_model.rb +13 -1
- data/lib/sequel/plugins/association_pks.rb +137 -16
- data/lib/sequel/plugins/caching.rb +25 -18
- data/lib/sequel/plugins/class_table_inheritance.rb +4 -4
- data/lib/sequel/plugins/composition.rb +44 -12
- data/lib/sequel/plugins/constraint_validations.rb +198 -0
- data/lib/sequel/plugins/dataset_associations.rb +100 -0
- data/lib/sequel/plugins/defaults_setter.rb +72 -0
- data/lib/sequel/plugins/dirty.rb +214 -0
- data/lib/sequel/plugins/eager_each.rb +59 -0
- data/lib/sequel/plugins/force_encoding.rb +6 -6
- data/lib/sequel/plugins/hook_class_methods.rb +1 -1
- data/lib/sequel/plugins/identity_map.rb +134 -15
- data/lib/sequel/plugins/instance_filters.rb +10 -0
- data/lib/sequel/plugins/instance_hooks.rb +1 -1
- data/lib/sequel/plugins/json_serializer.rb +77 -6
- data/lib/sequel/plugins/list.rb +13 -2
- data/lib/sequel/plugins/many_through_many.rb +103 -51
- data/lib/sequel/plugins/many_to_one_pk_lookup.rb +71 -0
- data/lib/sequel/plugins/nested_attributes.rb +150 -66
- data/lib/sequel/plugins/optimistic_locking.rb +8 -0
- data/lib/sequel/plugins/pg_row.rb +121 -0
- data/lib/sequel/plugins/pg_typecast_on_load.rb +65 -0
- data/lib/sequel/plugins/prepared_statements.rb +168 -0
- data/lib/sequel/plugins/prepared_statements_associations.rb +87 -0
- data/lib/sequel/plugins/prepared_statements_safe.rb +82 -0
- data/lib/sequel/plugins/prepared_statements_with_pk.rb +59 -0
- data/lib/sequel/plugins/rcte_tree.rb +31 -17
- data/lib/sequel/plugins/schema.rb +8 -3
- data/lib/sequel/plugins/serialization.rb +98 -49
- data/lib/sequel/plugins/serialization_modification_detection.rb +63 -0
- data/lib/sequel/plugins/sharding.rb +21 -54
- data/lib/sequel/plugins/single_table_inheritance.rb +57 -12
- data/lib/sequel/plugins/static_cache.rb +99 -0
- data/lib/sequel/plugins/subclasses.rb +29 -3
- data/lib/sequel/plugins/tactical_eager_loading.rb +7 -7
- data/lib/sequel/plugins/timestamps.rb +1 -1
- data/lib/sequel/plugins/touch.rb +18 -6
- data/lib/sequel/plugins/tree.rb +3 -3
- data/lib/sequel/plugins/typecast_on_load.rb +9 -12
- data/lib/sequel/plugins/update_primary_key.rb +2 -2
- data/lib/sequel/plugins/validation_class_methods.rb +2 -1
- data/lib/sequel/plugins/validation_helpers.rb +57 -4
- data/lib/sequel/plugins/xml_serializer.rb +15 -4
- data/lib/sequel/sql.rb +721 -141
- data/lib/sequel/timezones.rb +67 -40
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/db2_spec.rb +146 -0
- data/spec/adapters/firebird_spec.rb +53 -39
- data/spec/adapters/mssql_spec.rb +261 -66
- data/spec/adapters/mysql_spec.rb +597 -352
- data/spec/adapters/oracle_spec.rb +92 -117
- data/spec/adapters/postgres_spec.rb +2103 -341
- data/spec/adapters/spec_helper.rb +16 -6
- data/spec/adapters/sqlite_spec.rb +237 -76
- data/spec/core/connection_pool_spec.rb +270 -141
- data/spec/core/database_spec.rb +980 -524
- data/spec/core/dataset_spec.rb +1658 -1243
- data/spec/core/expression_filters_spec.rb +741 -334
- data/spec/core/mock_adapter_spec.rb +453 -0
- data/spec/core/object_graph_spec.rb +88 -129
- data/spec/core/schema_generator_spec.rb +4 -4
- data/spec/core/schema_spec.rb +556 -53
- data/spec/core/spec_helper.rb +7 -48
- data/spec/core_extensions_spec.rb +626 -0
- data/spec/extensions/active_model_spec.rb +13 -0
- data/spec/extensions/arbitrary_servers_spec.rb +110 -0
- data/spec/extensions/association_autoreloading_spec.rb +18 -10
- data/spec/extensions/association_dependencies_spec.rb +15 -25
- data/spec/extensions/association_pks_spec.rb +227 -33
- data/spec/extensions/association_proxies_spec.rb +4 -4
- data/spec/extensions/boolean_readers_spec.rb +25 -25
- data/spec/extensions/caching_spec.rb +47 -51
- data/spec/extensions/class_table_inheritance_spec.rb +31 -83
- data/spec/extensions/columns_introspection_spec.rb +91 -0
- data/spec/extensions/composition_spec.rb +18 -13
- data/spec/extensions/connection_validator_spec.rb +118 -0
- data/spec/extensions/constraint_validations_plugin_spec.rb +196 -0
- data/spec/extensions/constraint_validations_spec.rb +316 -0
- data/spec/extensions/dataset_associations_spec.rb +199 -0
- data/spec/extensions/defaults_setter_spec.rb +88 -0
- data/spec/extensions/dirty_spec.rb +155 -0
- data/spec/extensions/eager_each_spec.rb +34 -0
- data/spec/extensions/eval_inspect_spec.rb +67 -0
- data/spec/extensions/force_encoding_spec.rb +4 -2
- data/spec/extensions/hook_class_methods_spec.rb +97 -128
- data/spec/extensions/identity_map_spec.rb +142 -24
- data/spec/extensions/inflector_spec.rb +0 -4
- data/spec/extensions/instance_filters_spec.rb +11 -21
- data/spec/extensions/instance_hooks_spec.rb +72 -0
- data/spec/extensions/json_serializer_spec.rb +49 -12
- data/spec/extensions/lazy_attributes_spec.rb +16 -20
- data/spec/extensions/list_spec.rb +49 -40
- data/spec/extensions/looser_typecasting_spec.rb +7 -7
- data/spec/extensions/many_through_many_spec.rb +368 -254
- data/spec/extensions/many_to_one_pk_lookup_spec.rb +140 -0
- data/spec/extensions/migration_spec.rb +140 -35
- data/spec/extensions/named_timezones_spec.rb +29 -11
- data/spec/extensions/nested_attributes_spec.rb +268 -89
- data/spec/extensions/null_dataset_spec.rb +85 -0
- data/spec/extensions/optimistic_locking_spec.rb +24 -21
- data/spec/extensions/pg_array_ops_spec.rb +112 -0
- data/spec/extensions/pg_array_spec.rb +324 -0
- data/spec/extensions/pg_auto_parameterize_spec.rb +65 -0
- data/spec/extensions/pg_hstore_ops_spec.rb +140 -0
- data/spec/extensions/pg_hstore_spec.rb +200 -0
- data/spec/extensions/pg_inet_spec.rb +47 -0
- data/spec/extensions/pg_interval_spec.rb +72 -0
- data/spec/extensions/pg_json_spec.rb +99 -0
- data/spec/extensions/pg_range_ops_spec.rb +56 -0
- data/spec/extensions/pg_range_spec.rb +395 -0
- data/spec/extensions/pg_row_ops_spec.rb +58 -0
- data/spec/extensions/pg_row_plugin_spec.rb +49 -0
- data/spec/extensions/pg_row_spec.rb +340 -0
- data/spec/extensions/pg_statement_cache_spec.rb +208 -0
- data/spec/extensions/pg_typecast_on_load_spec.rb +58 -0
- data/spec/extensions/prepared_statements_associations_spec.rb +111 -0
- data/spec/extensions/prepared_statements_safe_spec.rb +61 -0
- data/spec/extensions/prepared_statements_spec.rb +87 -0
- data/spec/extensions/prepared_statements_with_pk_spec.rb +31 -0
- data/spec/extensions/pretty_table_spec.rb +7 -6
- data/spec/extensions/query_literals_spec.rb +167 -0
- data/spec/extensions/query_spec.rb +9 -3
- data/spec/extensions/rcte_tree_spec.rb +50 -43
- data/spec/extensions/schema_caching_spec.rb +41 -0
- data/spec/extensions/schema_dumper_spec.rb +434 -49
- data/spec/extensions/schema_spec.rb +30 -49
- data/spec/extensions/select_remove_spec.rb +38 -0
- data/spec/extensions/serialization_modification_detection_spec.rb +72 -0
- data/spec/extensions/serialization_spec.rb +86 -48
- data/spec/extensions/server_block_spec.rb +90 -0
- data/spec/extensions/sharding_spec.rb +69 -143
- data/spec/extensions/single_table_inheritance_spec.rb +65 -29
- data/spec/extensions/skip_create_refresh_spec.rb +1 -1
- data/spec/extensions/spec_helper.rb +34 -67
- data/spec/extensions/split_array_nil_spec.rb +24 -0
- data/spec/extensions/sql_expr_spec.rb +29 -60
- data/spec/extensions/static_cache_spec.rb +145 -0
- data/spec/extensions/subclasses_spec.rb +14 -0
- data/spec/extensions/tactical_eager_loading_spec.rb +17 -19
- data/spec/extensions/thread_local_timezones_spec.rb +22 -2
- data/spec/extensions/timestamps_spec.rb +6 -6
- data/spec/extensions/to_dot_spec.rb +8 -11
- data/spec/extensions/touch_spec.rb +53 -14
- data/spec/extensions/tree_spec.rb +11 -26
- data/spec/extensions/typecast_on_load_spec.rb +9 -6
- data/spec/extensions/update_primary_key_spec.rb +30 -24
- data/spec/extensions/validation_class_methods_spec.rb +77 -68
- data/spec/extensions/validation_helpers_spec.rb +48 -37
- data/spec/extensions/xml_serializer_spec.rb +29 -4
- data/spec/files/transaction_specified_migrations/001_create_alt_basic.rb +4 -0
- data/spec/files/transaction_specified_migrations/002_create_basic.rb +4 -0
- data/spec/files/transaction_unspecified_migrations/001_create_alt_basic.rb +3 -0
- data/spec/files/transaction_unspecified_migrations/002_create_basic.rb +3 -0
- data/spec/integration/associations_test.rb +659 -21
- data/spec/integration/database_test.rb +25 -5
- data/spec/integration/dataset_test.rb +729 -141
- data/spec/integration/eager_loader_test.rb +38 -54
- data/spec/integration/migrator_test.rb +2 -3
- data/spec/integration/model_test.rb +81 -2
- data/spec/integration/plugin_test.rb +871 -160
- data/spec/integration/prepared_statement_test.rb +272 -128
- data/spec/integration/schema_test.rb +377 -57
- data/spec/integration/spec_helper.rb +49 -32
- data/spec/integration/timezone_test.rb +38 -12
- data/spec/integration/transaction_test.rb +183 -8
- data/spec/integration/type_test.rb +40 -8
- data/spec/model/association_reflection_spec.rb +207 -8
- data/spec/model/associations_spec.rb +1206 -693
- data/spec/model/base_spec.rb +334 -100
- data/spec/model/dataset_methods_spec.rb +45 -27
- data/spec/model/eager_loading_spec.rb +828 -692
- data/spec/model/hooks_spec.rb +355 -67
- data/spec/model/model_spec.rb +251 -179
- data/spec/model/plugins_spec.rb +24 -13
- data/spec/model/record_spec.rb +506 -232
- data/spec/model/spec_helper.rb +16 -77
- data/spec/model/validations_spec.rb +38 -2
- data/spec/rcov.opts +2 -0
- metadata +223 -81
- data/spec/core/core_sql_spec.rb +0 -451
|
@@ -15,20 +15,34 @@ module Sequel
|
|
|
15
15
|
# sc2.subclasses # []
|
|
16
16
|
# ssc1.subclasses # []
|
|
17
17
|
# c.descendents # [sc1, ssc1, sc2]
|
|
18
|
+
#
|
|
19
|
+
# You can provide a block when loading the plugin, and it will be called
|
|
20
|
+
# with each subclass created:
|
|
21
|
+
#
|
|
22
|
+
# a = []
|
|
23
|
+
# Sequel::Model.plugin(:subclasses){|sc| a << sc}
|
|
24
|
+
# class A < Sequel::Model; end
|
|
25
|
+
# class B < Sequel::Model; end
|
|
26
|
+
# a # => [A, B]
|
|
18
27
|
module Subclasses
|
|
19
28
|
# Initialize the subclasses instance variable for the model.
|
|
20
|
-
def self.apply(model)
|
|
29
|
+
def self.apply(model, &block)
|
|
21
30
|
model.instance_variable_set(:@subclasses, [])
|
|
31
|
+
model.instance_variable_set(:@on_subclass, block)
|
|
22
32
|
end
|
|
23
33
|
|
|
24
34
|
module ClassMethods
|
|
35
|
+
# Callable object that should be called with every descendent
|
|
36
|
+
# class created.
|
|
37
|
+
attr_reader :on_subclass
|
|
38
|
+
|
|
25
39
|
# All subclasses for the current model. Does not
|
|
26
40
|
# include the model itself.
|
|
27
41
|
attr_reader :subclasses
|
|
28
42
|
|
|
29
43
|
# All descendent classes of this model.
|
|
30
44
|
def descendents
|
|
31
|
-
|
|
45
|
+
Sequel.synchronize{_descendents}
|
|
32
46
|
end
|
|
33
47
|
|
|
34
48
|
# Add the subclass to this model's current subclasses,
|
|
@@ -36,8 +50,20 @@ module Sequel
|
|
|
36
50
|
# in the subclass.
|
|
37
51
|
def inherited(subclass)
|
|
38
52
|
super
|
|
39
|
-
subclasses << subclass
|
|
53
|
+
Sequel.synchronize{subclasses << subclass}
|
|
40
54
|
subclass.instance_variable_set(:@subclasses, [])
|
|
55
|
+
if on_subclass
|
|
56
|
+
subclass.instance_variable_set(:@on_subclass, on_subclass)
|
|
57
|
+
on_subclass.call(subclass)
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
private
|
|
62
|
+
|
|
63
|
+
# Recursive, non-thread safe version of descendents, since
|
|
64
|
+
# the mutex Sequel uses isn't reentrant.
|
|
65
|
+
def _descendents
|
|
66
|
+
subclasses.map{|x| [x] + x.send(:_descendents)}.flatten
|
|
41
67
|
end
|
|
42
68
|
end
|
|
43
69
|
end
|
|
@@ -28,19 +28,18 @@ module Sequel
|
|
|
28
28
|
module TacticalEagerLoading
|
|
29
29
|
module InstanceMethods
|
|
30
30
|
# The dataset that retrieved this object, set if the object was
|
|
31
|
-
# reteived via Dataset#all
|
|
31
|
+
# reteived via Dataset#all.
|
|
32
32
|
attr_accessor :retrieved_by
|
|
33
33
|
|
|
34
34
|
# All model objects retrieved with this object, set if the object was
|
|
35
|
-
# reteived via Dataset#all
|
|
35
|
+
# reteived via Dataset#all.
|
|
36
36
|
attr_accessor :retrieved_with
|
|
37
37
|
|
|
38
38
|
private
|
|
39
39
|
|
|
40
|
-
# If there
|
|
41
|
-
#
|
|
42
|
-
#
|
|
43
|
-
# current object.
|
|
40
|
+
# If there the association is not in the associations cache and the object
|
|
41
|
+
# was reteived via Dataset#all, eagerly load the association for all model
|
|
42
|
+
# objects retrieved with the current object.
|
|
44
43
|
def load_associated_objects(opts, reload=false)
|
|
45
44
|
name = opts[:name]
|
|
46
45
|
if !associations.include?(name) && retrieved_by
|
|
@@ -51,6 +50,7 @@ module Sequel
|
|
|
51
50
|
# is only defined in a subclass. This particular instance can use the
|
|
52
51
|
# association, but it can't be eagerly loaded as the parent class doesn't
|
|
53
52
|
# have access to the association, and that's the class doing the eager loading.
|
|
53
|
+
nil
|
|
54
54
|
end
|
|
55
55
|
end
|
|
56
56
|
super
|
|
@@ -60,7 +60,7 @@ module Sequel
|
|
|
60
60
|
module DatasetMethods
|
|
61
61
|
private
|
|
62
62
|
|
|
63
|
-
#
|
|
63
|
+
# Set the reteived_with and retrieved_by attributes for the object
|
|
64
64
|
# with the current dataset and array of all objects.
|
|
65
65
|
def post_load(objects)
|
|
66
66
|
super
|
|
@@ -19,7 +19,7 @@ module Sequel
|
|
|
19
19
|
# # timestamp, and setting the update timestamp when creating
|
|
20
20
|
# Album.plugin :timestamps, :force=>true, :update_on_create=>true
|
|
21
21
|
module Timestamps
|
|
22
|
-
# Configure the plugin by setting the
|
|
22
|
+
# Configure the plugin by setting the available options. Note that
|
|
23
23
|
# if this method is run more than once, previous settings are ignored,
|
|
24
24
|
# and it will just use the settings given or the default settings. Options:
|
|
25
25
|
# * :create - The field to hold the create timestamp (default: :created_at)
|
data/lib/sequel/plugins/touch.rb
CHANGED
|
@@ -52,7 +52,7 @@ module Sequel
|
|
|
52
52
|
attr_accessor :touch_column
|
|
53
53
|
|
|
54
54
|
# A hash specifying the associations to touch when instances are
|
|
55
|
-
# updated or destroyed. Keys are association
|
|
55
|
+
# updated or destroyed. Keys are association name symbols and values
|
|
56
56
|
# are column name symbols.
|
|
57
57
|
attr_reader :touched_associations
|
|
58
58
|
|
|
@@ -71,8 +71,8 @@ module Sequel
|
|
|
71
71
|
associations.flatten.each do |a|
|
|
72
72
|
a = {a=>touch_column} if a.is_a?(Symbol)
|
|
73
73
|
a.each do |k,v|
|
|
74
|
-
raise(Error, "invalid association: #{k}") unless
|
|
75
|
-
touched_associations[
|
|
74
|
+
raise(Error, "invalid association: #{k}") unless association_reflection(k)
|
|
75
|
+
touched_associations[k] = v
|
|
76
76
|
end
|
|
77
77
|
end
|
|
78
78
|
end
|
|
@@ -113,10 +113,22 @@ module Sequel
|
|
|
113
113
|
Sequel::CURRENT_TIMESTAMP
|
|
114
114
|
end
|
|
115
115
|
|
|
116
|
-
#
|
|
116
|
+
# Update the updated at field for all associated objects that should be touched.
|
|
117
117
|
def touch_associations
|
|
118
|
-
model.touched_associations.each do |
|
|
119
|
-
|
|
118
|
+
model.touched_associations.each do |assoc, column|
|
|
119
|
+
r = model.association_reflection(assoc)
|
|
120
|
+
next unless r.can_have_associated_objects?(self)
|
|
121
|
+
ds = send(r.dataset_method)
|
|
122
|
+
|
|
123
|
+
if ds.send(:joined_dataset?)
|
|
124
|
+
# Can't update all values at once, so update each instance individually.
|
|
125
|
+
# Instead if doing a simple save, update via the instance's dataset,
|
|
126
|
+
# to avoid going into an infinite loop in some cases.
|
|
127
|
+
send(r[:name]).each{|x| x.this.update(column=>touch_association_value)}
|
|
128
|
+
else
|
|
129
|
+
# Update all values at once for performance reasons.
|
|
130
|
+
ds.update(column=>touch_association_value)
|
|
131
|
+
end
|
|
120
132
|
end
|
|
121
133
|
end
|
|
122
134
|
|
data/lib/sequel/plugins/tree.rb
CHANGED
|
@@ -4,7 +4,7 @@ module Sequel
|
|
|
4
4
|
# treat a Model as a tree.
|
|
5
5
|
#
|
|
6
6
|
# A column for holding the parent key is required and is :parent_id by default.
|
|
7
|
-
# This may be overridden by passing column name via :key
|
|
7
|
+
# This may be overridden by passing column name via :key.
|
|
8
8
|
#
|
|
9
9
|
# Optionally, a column to control order of nodes returned can be specified
|
|
10
10
|
# by passing column name via :order.
|
|
@@ -98,7 +98,7 @@ module Sequel
|
|
|
98
98
|
nodes
|
|
99
99
|
end
|
|
100
100
|
|
|
101
|
-
# Returns the root node of the tree that this node descends from
|
|
101
|
+
# Returns the root node of the tree that this node descends from.
|
|
102
102
|
# This node is returned if it is a root node itself.
|
|
103
103
|
def root
|
|
104
104
|
ancestors.last || self
|
|
@@ -124,7 +124,7 @@ module Sequel
|
|
|
124
124
|
end
|
|
125
125
|
end
|
|
126
126
|
|
|
127
|
-
# Plugin included when :single_root option is passed
|
|
127
|
+
# Plugin included when :single_root option is passed.
|
|
128
128
|
module SingleRoot
|
|
129
129
|
module ClassMethods
|
|
130
130
|
# Returns the single root node.
|
|
@@ -5,7 +5,7 @@ module Sequel
|
|
|
5
5
|
# typecast correctly (with correct being defined as how the model object
|
|
6
6
|
# would typecast the same column values).
|
|
7
7
|
#
|
|
8
|
-
# This plugin modifies Model
|
|
8
|
+
# This plugin modifies Model#set_values to call the setter methods (which typecast
|
|
9
9
|
# by default) for all columns given. You can either specify the columns to
|
|
10
10
|
# typecast on load in the plugin call itself, or afterwards using
|
|
11
11
|
# add_typecast_on_load_columns:
|
|
@@ -41,16 +41,11 @@ module Sequel
|
|
|
41
41
|
super
|
|
42
42
|
subclass.instance_variable_set(:@typecast_on_load_columns, typecast_on_load_columns.dup)
|
|
43
43
|
end
|
|
44
|
-
|
|
45
|
-
# Call the setter method for each of the typecast on load columns,
|
|
46
|
-
# ensuring the model object will have the correct typecasting even
|
|
47
|
-
# if the database doesn't typecast the columns correctly.
|
|
48
|
-
def load(values)
|
|
49
|
-
super.load_typecast
|
|
50
|
-
end
|
|
51
44
|
end
|
|
52
45
|
|
|
53
46
|
module InstanceMethods
|
|
47
|
+
# Call the setter method for each of the model's typecast_on_load_columns
|
|
48
|
+
# with the current value, so it can be typecasted correctly.
|
|
54
49
|
def load_typecast
|
|
55
50
|
model.typecast_on_load_columns.each do |c|
|
|
56
51
|
if v = values[c]
|
|
@@ -61,10 +56,12 @@ module Sequel
|
|
|
61
56
|
self
|
|
62
57
|
end
|
|
63
58
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
def
|
|
67
|
-
super
|
|
59
|
+
# Typecast values using #load_typecast when the values are retrieved from
|
|
60
|
+
# the database.
|
|
61
|
+
def set_values(values)
|
|
62
|
+
ret = super
|
|
63
|
+
load_typecast
|
|
64
|
+
ret
|
|
68
65
|
end
|
|
69
66
|
end
|
|
70
67
|
end
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
module Sequel
|
|
2
2
|
module Plugins
|
|
3
|
-
# The update_primary_key plugin allows you to modify an
|
|
3
|
+
# The update_primary_key plugin allows you to modify an object's
|
|
4
4
|
# primary key and then save the record. Sequel does not work
|
|
5
5
|
# correctly with primary key modifications by default. Sequel
|
|
6
6
|
# is designed to work with surrogate primary keys that never need to be
|
|
@@ -22,7 +22,7 @@ module Sequel
|
|
|
22
22
|
module UpdatePrimaryKey
|
|
23
23
|
module ClassMethods
|
|
24
24
|
# Cache the pk_hash when loading records
|
|
25
|
-
def
|
|
25
|
+
def call(h)
|
|
26
26
|
r = super(h)
|
|
27
27
|
r.pk_hash
|
|
28
28
|
r
|
|
@@ -60,7 +60,6 @@ module Sequel
|
|
|
60
60
|
|
|
61
61
|
# Setup the validations and validation_reflections hash in the subclass.
|
|
62
62
|
def inherited(subclass)
|
|
63
|
-
super
|
|
64
63
|
vr = @validation_reflections
|
|
65
64
|
subclass.class_eval do
|
|
66
65
|
@validation_mutex = Mutex.new
|
|
@@ -69,6 +68,7 @@ module Sequel
|
|
|
69
68
|
vr.each{|k,v| h[k] = v.dup}
|
|
70
69
|
@validation_reflections = h
|
|
71
70
|
end
|
|
71
|
+
super
|
|
72
72
|
end
|
|
73
73
|
|
|
74
74
|
# Instructs the model to skip validations defined in superclasses
|
|
@@ -385,6 +385,7 @@ module Sequel
|
|
|
385
385
|
error_field = a
|
|
386
386
|
a = Array(a)
|
|
387
387
|
v = Array(v)
|
|
388
|
+
next if v.empty? || !v.all?
|
|
388
389
|
ds = o.class.filter(a.zip(v))
|
|
389
390
|
num_dups = ds.count
|
|
390
391
|
allow = if num_dups == 0
|
|
@@ -40,6 +40,37 @@ module Sequel
|
|
|
40
40
|
# changing the values of the Sequel::Plugins::ValidationHelpers::DEFAULT_OPTIONS hash. You
|
|
41
41
|
# change change the default options on a per model basis
|
|
42
42
|
# by overriding a private instance method default_validation_helpers_options.
|
|
43
|
+
#
|
|
44
|
+
# By changing the default options, you can setup internationalization of the
|
|
45
|
+
# error messages. For example, you would modify the default options:
|
|
46
|
+
#
|
|
47
|
+
# Sequel::Plugins::ValidationHelpers::DEFAULT_OPTIONS.merge!(
|
|
48
|
+
# :exact_length=>{:message=>lambda{|exact| I18n.t("errors.exact_length", :exact => exact)}},
|
|
49
|
+
# :integer=>{:message=>lambda{I18n.t("errors.integer")}},
|
|
50
|
+
# ...
|
|
51
|
+
# )
|
|
52
|
+
#
|
|
53
|
+
# and then use something like this in your yaml translation file:
|
|
54
|
+
#
|
|
55
|
+
# en:
|
|
56
|
+
# errors:
|
|
57
|
+
# exact_length: "is not %{exact} characters"
|
|
58
|
+
# integer: "is not a number"
|
|
59
|
+
#
|
|
60
|
+
# Note that if you want to support internationalization of Errors#full_messages,
|
|
61
|
+
# you need to override the method. Here's an example:
|
|
62
|
+
#
|
|
63
|
+
# class Sequel::Model::Errors
|
|
64
|
+
# ATTRIBUTE_JOINER = I18n.t('errors.joiner').freeze
|
|
65
|
+
# def full_messages
|
|
66
|
+
# inject([]) do |m, kv|
|
|
67
|
+
# att, errors = *kv
|
|
68
|
+
# att.is_a?(Array) ? Array(att).map!{|v| I18n.t("attributes.#{v}")} : att = I18n.t("attributes.#{att}")
|
|
69
|
+
# errors.each {|e| m << (e.is_a?(LiteralString) ? e : "#{Array(att).join(ATTRIBUTE_JOINER)} #{e}")}
|
|
70
|
+
# m
|
|
71
|
+
# end
|
|
72
|
+
# end
|
|
73
|
+
# end
|
|
43
74
|
module ValidationHelpers
|
|
44
75
|
# Default validation options used by Sequel. Can be modified to change the error
|
|
45
76
|
# messages for all models (e.g. for internationalization), or to set certain
|
|
@@ -162,19 +193,41 @@ module Sequel
|
|
|
162
193
|
# since it can deal with a grouping of multiple attributes.
|
|
163
194
|
#
|
|
164
195
|
# Possible Options:
|
|
165
|
-
#
|
|
166
|
-
#
|
|
167
|
-
#
|
|
196
|
+
# :message :: The message to use (default: 'is already taken')
|
|
197
|
+
# :only_if_modified :: Only check the uniqueness if the object is new or
|
|
198
|
+
# one of the columns has been modified.
|
|
199
|
+
# :where :: A callable object where call takes three arguments, a dataset,
|
|
200
|
+
# the current object, and an array of columns, and should return
|
|
201
|
+
# a modified dataset that is filtered to include only rows with
|
|
202
|
+
# the same values as the current object for each column in the array.
|
|
203
|
+
#
|
|
204
|
+
# If you want to to a case insensitive uniqueness validation on a database that
|
|
205
|
+
# is case sensitive by default, you can use:
|
|
206
|
+
#
|
|
207
|
+
# :where=>(proc do |ds, obj, cols|
|
|
208
|
+
# ds.where(cols.map do |c|
|
|
209
|
+
# v = obj.send(c)
|
|
210
|
+
# v = v.downcase if v
|
|
211
|
+
# [Sequel.function(:lower, c), v]
|
|
212
|
+
# end)
|
|
213
|
+
# end)
|
|
168
214
|
def validates_unique(*atts)
|
|
169
215
|
opts = default_validation_helpers_options(:unique)
|
|
170
216
|
if atts.last.is_a?(Hash)
|
|
171
217
|
opts = opts.merge(atts.pop)
|
|
172
218
|
end
|
|
173
219
|
message = validation_error_message(opts[:message])
|
|
220
|
+
where = opts[:where]
|
|
174
221
|
atts.each do |a|
|
|
175
222
|
arr = Array(a)
|
|
176
223
|
next if opts[:only_if_modified] && !new? && !arr.any?{|x| changed_columns.include?(x)}
|
|
177
|
-
ds =
|
|
224
|
+
ds = if where
|
|
225
|
+
where.call(model.dataset, self, arr)
|
|
226
|
+
else
|
|
227
|
+
vals = arr.map{|x| send(x)}
|
|
228
|
+
next unless vals.all?
|
|
229
|
+
model.where(arr.zip(vals))
|
|
230
|
+
end
|
|
178
231
|
ds = yield(ds) if block_given?
|
|
179
232
|
ds = ds.exclude(pk_hash) unless new?
|
|
180
233
|
errors.add(a, message) unless ds.count == 0
|
|
@@ -79,6 +79,11 @@ module Sequel
|
|
|
79
79
|
#
|
|
80
80
|
# Album.array_from_xml(Album.to_xml) # same as Album.all
|
|
81
81
|
#
|
|
82
|
+
# If you have an existing array of model instances you want to convert to
|
|
83
|
+
# XML, you can call the class to_xml method with the :array option:
|
|
84
|
+
#
|
|
85
|
+
# Album.to_xml(:array=>[Album[1], Album[2]])
|
|
86
|
+
#
|
|
82
87
|
# Usage:
|
|
83
88
|
#
|
|
84
89
|
# # Add XML output capability to all model subclass instances (called before loading subclasses)
|
|
@@ -205,9 +210,9 @@ module Sequel
|
|
|
205
210
|
klass.from_xml_node(node)
|
|
206
211
|
end
|
|
207
212
|
elsif cols.include?(k)
|
|
208
|
-
self[k.to_sym] = node
|
|
213
|
+
self[k.to_sym] = node.key?('nil') ? nil : node.children.first.to_s
|
|
209
214
|
elsif meths.include?("#{k}=")
|
|
210
|
-
send("#{k}=", node
|
|
215
|
+
send("#{k}=", node.key?('nil') ? nil : node.children.first.to_s)
|
|
211
216
|
else
|
|
212
217
|
raise Error, "Entry in XML not an association or column and no setter method exists: #{k}"
|
|
213
218
|
end
|
|
@@ -266,7 +271,7 @@ module Sequel
|
|
|
266
271
|
|
|
267
272
|
name_proc = model.xml_serialize_name_proc(opts)
|
|
268
273
|
x = model.xml_builder(opts)
|
|
269
|
-
x.send(name_proc[opts.fetch(:root_name, model.send(:underscore, model.name)).to_s]) do |x1|
|
|
274
|
+
x.send(name_proc[opts.fetch(:root_name, model.send(:underscore, model.name).gsub('/', '__')).to_s]) do |x1|
|
|
270
275
|
cols.each do |c|
|
|
271
276
|
attrs = {}
|
|
272
277
|
if types
|
|
@@ -316,8 +321,14 @@ module Sequel
|
|
|
316
321
|
raise(Sequel::Error, "Dataset#to_xml") unless row_proc
|
|
317
322
|
x = model.xml_builder(opts)
|
|
318
323
|
name_proc = model.xml_serialize_name_proc(opts)
|
|
324
|
+
array = if opts[:array]
|
|
325
|
+
opts = opts.dup
|
|
326
|
+
opts.delete(:array)
|
|
327
|
+
else
|
|
328
|
+
all
|
|
329
|
+
end
|
|
319
330
|
x.send(name_proc[opts.fetch(:array_root_name, model.send(:pluralize, model.send(:underscore, model.name))).to_s]) do |x1|
|
|
320
|
-
|
|
331
|
+
array.each do |obj|
|
|
321
332
|
obj.to_xml(opts.merge(:builder=>x1))
|
|
322
333
|
end
|
|
323
334
|
end
|