sequel 5.83.0 → 5.106.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.
- checksums.yaml +4 -4
- data/MIT-LICENSE +1 -1
- data/lib/sequel/adapters/ado/access.rb +2 -2
- data/lib/sequel/adapters/ado.rb +2 -2
- data/lib/sequel/adapters/amalgalite.rb +16 -1
- data/lib/sequel/adapters/ibmdb.rb +2 -1
- data/lib/sequel/adapters/jdbc/db2.rb +2 -2
- data/lib/sequel/adapters/jdbc/derby.rb +4 -2
- data/lib/sequel/adapters/jdbc/h2.rb +4 -4
- data/lib/sequel/adapters/jdbc/hsqldb.rb +2 -2
- data/lib/sequel/adapters/jdbc/jtds.rb +2 -2
- data/lib/sequel/adapters/jdbc/mysql.rb +3 -3
- data/lib/sequel/adapters/jdbc/oracle.rb +6 -6
- data/lib/sequel/adapters/jdbc/postgresql.rb +5 -5
- data/lib/sequel/adapters/jdbc/sqlanywhere.rb +6 -6
- data/lib/sequel/adapters/jdbc/sqlite.rb +3 -3
- data/lib/sequel/adapters/jdbc/sqlserver.rb +3 -3
- data/lib/sequel/adapters/jdbc.rb +29 -15
- data/lib/sequel/adapters/mysql.rb +1 -1
- data/lib/sequel/adapters/mysql2.rb +10 -3
- data/lib/sequel/adapters/odbc.rb +1 -1
- data/lib/sequel/adapters/oracle.rb +16 -0
- data/lib/sequel/adapters/postgres.rb +2 -1
- data/lib/sequel/adapters/shared/access.rb +1 -0
- data/lib/sequel/adapters/shared/db2.rb +8 -3
- data/lib/sequel/adapters/shared/mssql.rb +9 -8
- data/lib/sequel/adapters/shared/mysql.rb +16 -11
- data/lib/sequel/adapters/shared/oracle.rb +1 -0
- data/lib/sequel/adapters/shared/postgres.rb +438 -47
- data/lib/sequel/adapters/shared/sqlite.rb +9 -7
- data/lib/sequel/adapters/sqlite.rb +20 -2
- data/lib/sequel/adapters/tinytds.rb +2 -2
- data/lib/sequel/adapters/trilogy.rb +2 -3
- data/lib/sequel/ast_transformer.rb +2 -0
- data/lib/sequel/connection_pool/sharded_timed_queue.rb +42 -11
- data/lib/sequel/connection_pool/timed_queue.rb +33 -10
- data/lib/sequel/connection_pool.rb +8 -2
- data/lib/sequel/core.rb +31 -2
- data/lib/sequel/database/connecting.rb +1 -1
- data/lib/sequel/database/dataset_defaults.rb +3 -3
- data/lib/sequel/database/misc.rb +29 -11
- data/lib/sequel/database/query.rb +12 -12
- data/lib/sequel/database/schema_generator.rb +117 -16
- data/lib/sequel/database/schema_methods.rb +85 -30
- data/lib/sequel/dataset/actions.rb +83 -11
- data/lib/sequel/dataset/deprecated_singleton_class_methods.rb +1 -1
- data/lib/sequel/dataset/placeholder_literalizer.rb +3 -0
- data/lib/sequel/dataset/prepared_statements.rb +76 -28
- data/lib/sequel/dataset/query.rb +26 -11
- data/lib/sequel/dataset/sql.rb +40 -17
- data/lib/sequel/extensions/async_thread_pool.rb +1 -1
- data/lib/sequel/extensions/caller_logging.rb +1 -3
- data/lib/sequel/extensions/connection_checkout_event_callback.rb +151 -0
- data/lib/sequel/extensions/connection_expiration.rb +44 -5
- data/lib/sequel/extensions/connection_validator.rb +15 -10
- data/lib/sequel/extensions/constraint_validations.rb +3 -3
- data/lib/sequel/extensions/dataset_run.rb +41 -0
- data/lib/sequel/extensions/date_arithmetic.rb +6 -6
- data/lib/sequel/extensions/empty_array_consider_nulls.rb +7 -0
- data/lib/sequel/extensions/eval_inspect.rb +3 -1
- data/lib/sequel/extensions/inflector.rb +2 -2
- data/lib/sequel/extensions/lit_require_frozen.rb +131 -0
- data/lib/sequel/extensions/looser_typecasting.rb +5 -12
- data/lib/sequel/extensions/migration.rb +38 -21
- data/lib/sequel/extensions/null_dataset.rb +2 -2
- data/lib/sequel/extensions/pg_array_ops.rb +41 -0
- data/lib/sequel/extensions/pg_auto_parameterize.rb +10 -3
- data/lib/sequel/extensions/pg_auto_parameterize_duplicate_query_detection.rb +191 -0
- data/lib/sequel/extensions/pg_auto_parameterize_in_array.rb +94 -10
- data/lib/sequel/extensions/pg_enum.rb +4 -4
- data/lib/sequel/extensions/pg_hstore.rb +1 -1
- data/lib/sequel/extensions/pg_hstore_ops.rb +10 -5
- data/lib/sequel/extensions/pg_json_ops.rb +674 -18
- data/lib/sequel/extensions/pg_multirange.rb +1 -1
- data/lib/sequel/extensions/pg_range.rb +14 -2
- data/lib/sequel/extensions/pg_row.rb +5 -3
- data/lib/sequel/extensions/pg_schema_caching.rb +90 -0
- data/lib/sequel/extensions/provenance.rb +1 -3
- data/lib/sequel/extensions/query_blocker.rb +172 -0
- data/lib/sequel/extensions/schema_caching.rb +24 -9
- data/lib/sequel/extensions/schema_dumper.rb +17 -5
- data/lib/sequel/extensions/set_literalizer.rb +20 -39
- data/lib/sequel/extensions/split_array_nil.rb +12 -2
- data/lib/sequel/extensions/sqlite_json_ops.rb +1 -1
- data/lib/sequel/extensions/string_agg.rb +2 -2
- data/lib/sequel/extensions/to_dot.rb +5 -0
- data/lib/sequel/extensions/virtual_row_method_block.rb +1 -0
- data/lib/sequel/model/associations.rb +215 -15
- data/lib/sequel/model/base.rb +198 -35
- data/lib/sequel/model/plugins.rb +12 -1
- data/lib/sequel/model.rb +1 -0
- data/lib/sequel/plugins/accessed_columns.rb +4 -0
- data/lib/sequel/plugins/active_model.rb +5 -6
- data/lib/sequel/plugins/association_pks.rb +2 -0
- data/lib/sequel/plugins/auto_validations.rb +2 -0
- data/lib/sequel/plugins/class_table_inheritance_constraint_validations.rb +82 -0
- data/lib/sequel/plugins/columns_updated.rb +4 -0
- data/lib/sequel/plugins/composition.rb +3 -1
- data/lib/sequel/plugins/constraint_validations.rb +15 -10
- data/lib/sequel/plugins/dataset_associations.rb +20 -1
- data/lib/sequel/plugins/deprecated_associations.rb +151 -0
- data/lib/sequel/plugins/detect_unnecessary_association_options.rb +164 -0
- data/lib/sequel/plugins/dirty.rb +9 -2
- data/lib/sequel/plugins/enum.rb +1 -1
- data/lib/sequel/plugins/forbid_lazy_load.rb +15 -1
- data/lib/sequel/plugins/insert_conflict.rb +4 -0
- data/lib/sequel/plugins/insert_returning_select.rb +10 -1
- data/lib/sequel/plugins/inspect_pk.rb +44 -0
- data/lib/sequel/plugins/instance_filters.rb +8 -1
- data/lib/sequel/plugins/instance_hooks.rb +4 -0
- data/lib/sequel/plugins/inverted_subsets.rb +1 -0
- data/lib/sequel/plugins/json_serializer.rb +6 -10
- data/lib/sequel/plugins/lazy_attributes.rb +1 -1
- data/lib/sequel/plugins/many_through_many.rb +21 -0
- data/lib/sequel/plugins/modification_detection.rb +2 -0
- data/lib/sequel/plugins/mssql_optimistic_locking.rb +1 -1
- data/lib/sequel/plugins/nested_attributes.rb +10 -5
- data/lib/sequel/plugins/paged_operations.rb +5 -2
- data/lib/sequel/plugins/pg_array_associations.rb +2 -2
- data/lib/sequel/plugins/pg_auto_constraint_validations.rb +6 -1
- data/lib/sequel/plugins/pg_auto_validate_enums.rb +88 -0
- data/lib/sequel/plugins/pg_eager_any_typed_array.rb +95 -0
- data/lib/sequel/plugins/pg_xmin_optimistic_locking.rb +1 -1
- data/lib/sequel/plugins/rcte_tree.rb +6 -6
- data/lib/sequel/plugins/serialization.rb +23 -6
- data/lib/sequel/plugins/serialization_modification_detection.rb +4 -0
- data/lib/sequel/plugins/single_statement_dataset_destroy.rb +49 -0
- data/lib/sequel/plugins/split_values.rb +12 -0
- data/lib/sequel/plugins/sql_comments.rb +7 -2
- data/lib/sequel/plugins/static_cache.rb +13 -0
- data/lib/sequel/plugins/static_cache_cache.rb +50 -13
- data/lib/sequel/plugins/subset_conditions.rb +85 -5
- data/lib/sequel/plugins/subset_static_cache.rb +278 -0
- data/lib/sequel/plugins/table_select.rb +7 -0
- data/lib/sequel/plugins/tactical_eager_loading.rb +4 -0
- data/lib/sequel/plugins/unused_associations.rb +11 -3
- data/lib/sequel/plugins/update_primary_key.rb +4 -0
- data/lib/sequel/plugins/validation_class_methods.rb +1 -1
- data/lib/sequel/plugins/validation_contexts.rb +4 -0
- data/lib/sequel/sql.rb +27 -12
- data/lib/sequel/version.rb +1 -1
- metadata +17 -240
- data/CHANGELOG +0 -1393
- data/README.rdoc +0 -936
- data/doc/advanced_associations.rdoc +0 -884
- data/doc/association_basics.rdoc +0 -1859
- data/doc/bin_sequel.rdoc +0 -146
- data/doc/cheat_sheet.rdoc +0 -255
- data/doc/code_order.rdoc +0 -104
- data/doc/core_extensions.rdoc +0 -405
- data/doc/dataset_basics.rdoc +0 -96
- data/doc/dataset_filtering.rdoc +0 -222
- data/doc/extensions.rdoc +0 -77
- data/doc/fork_safety.rdoc +0 -84
- data/doc/mass_assignment.rdoc +0 -98
- data/doc/migration.rdoc +0 -660
- data/doc/model_dataset_method_design.rdoc +0 -129
- data/doc/model_hooks.rdoc +0 -254
- data/doc/model_plugins.rdoc +0 -270
- data/doc/mssql_stored_procedures.rdoc +0 -43
- data/doc/object_model.rdoc +0 -563
- data/doc/opening_databases.rdoc +0 -439
- data/doc/postgresql.rdoc +0 -611
- data/doc/prepared_statements.rdoc +0 -144
- data/doc/querying.rdoc +0 -1070
- data/doc/reflection.rdoc +0 -120
- data/doc/release_notes/5.0.0.txt +0 -159
- data/doc/release_notes/5.1.0.txt +0 -31
- data/doc/release_notes/5.10.0.txt +0 -84
- data/doc/release_notes/5.11.0.txt +0 -83
- data/doc/release_notes/5.12.0.txt +0 -141
- data/doc/release_notes/5.13.0.txt +0 -27
- data/doc/release_notes/5.14.0.txt +0 -63
- data/doc/release_notes/5.15.0.txt +0 -39
- data/doc/release_notes/5.16.0.txt +0 -110
- data/doc/release_notes/5.17.0.txt +0 -31
- data/doc/release_notes/5.18.0.txt +0 -69
- data/doc/release_notes/5.19.0.txt +0 -28
- data/doc/release_notes/5.2.0.txt +0 -33
- data/doc/release_notes/5.20.0.txt +0 -89
- data/doc/release_notes/5.21.0.txt +0 -87
- data/doc/release_notes/5.22.0.txt +0 -48
- data/doc/release_notes/5.23.0.txt +0 -56
- data/doc/release_notes/5.24.0.txt +0 -56
- data/doc/release_notes/5.25.0.txt +0 -32
- data/doc/release_notes/5.26.0.txt +0 -35
- data/doc/release_notes/5.27.0.txt +0 -21
- data/doc/release_notes/5.28.0.txt +0 -16
- data/doc/release_notes/5.29.0.txt +0 -22
- data/doc/release_notes/5.3.0.txt +0 -121
- data/doc/release_notes/5.30.0.txt +0 -20
- data/doc/release_notes/5.31.0.txt +0 -148
- data/doc/release_notes/5.32.0.txt +0 -46
- data/doc/release_notes/5.33.0.txt +0 -24
- data/doc/release_notes/5.34.0.txt +0 -40
- data/doc/release_notes/5.35.0.txt +0 -56
- data/doc/release_notes/5.36.0.txt +0 -60
- data/doc/release_notes/5.37.0.txt +0 -30
- data/doc/release_notes/5.38.0.txt +0 -28
- data/doc/release_notes/5.39.0.txt +0 -19
- data/doc/release_notes/5.4.0.txt +0 -80
- data/doc/release_notes/5.40.0.txt +0 -40
- data/doc/release_notes/5.41.0.txt +0 -25
- data/doc/release_notes/5.42.0.txt +0 -136
- data/doc/release_notes/5.43.0.txt +0 -98
- data/doc/release_notes/5.44.0.txt +0 -32
- data/doc/release_notes/5.45.0.txt +0 -34
- data/doc/release_notes/5.46.0.txt +0 -87
- data/doc/release_notes/5.47.0.txt +0 -59
- data/doc/release_notes/5.48.0.txt +0 -14
- data/doc/release_notes/5.49.0.txt +0 -59
- data/doc/release_notes/5.5.0.txt +0 -61
- data/doc/release_notes/5.50.0.txt +0 -78
- data/doc/release_notes/5.51.0.txt +0 -47
- data/doc/release_notes/5.52.0.txt +0 -87
- data/doc/release_notes/5.53.0.txt +0 -23
- data/doc/release_notes/5.54.0.txt +0 -27
- data/doc/release_notes/5.55.0.txt +0 -21
- data/doc/release_notes/5.56.0.txt +0 -51
- data/doc/release_notes/5.57.0.txt +0 -23
- data/doc/release_notes/5.58.0.txt +0 -31
- data/doc/release_notes/5.59.0.txt +0 -73
- data/doc/release_notes/5.6.0.txt +0 -31
- data/doc/release_notes/5.60.0.txt +0 -22
- data/doc/release_notes/5.61.0.txt +0 -43
- data/doc/release_notes/5.62.0.txt +0 -132
- data/doc/release_notes/5.63.0.txt +0 -33
- data/doc/release_notes/5.64.0.txt +0 -50
- data/doc/release_notes/5.65.0.txt +0 -21
- data/doc/release_notes/5.66.0.txt +0 -24
- data/doc/release_notes/5.67.0.txt +0 -32
- data/doc/release_notes/5.68.0.txt +0 -61
- data/doc/release_notes/5.69.0.txt +0 -26
- data/doc/release_notes/5.7.0.txt +0 -108
- data/doc/release_notes/5.70.0.txt +0 -35
- data/doc/release_notes/5.71.0.txt +0 -21
- data/doc/release_notes/5.72.0.txt +0 -33
- data/doc/release_notes/5.73.0.txt +0 -66
- data/doc/release_notes/5.74.0.txt +0 -45
- data/doc/release_notes/5.75.0.txt +0 -35
- data/doc/release_notes/5.76.0.txt +0 -86
- data/doc/release_notes/5.77.0.txt +0 -63
- data/doc/release_notes/5.78.0.txt +0 -67
- data/doc/release_notes/5.79.0.txt +0 -28
- data/doc/release_notes/5.8.0.txt +0 -170
- data/doc/release_notes/5.80.0.txt +0 -40
- data/doc/release_notes/5.81.0.txt +0 -31
- data/doc/release_notes/5.82.0.txt +0 -61
- data/doc/release_notes/5.83.0.txt +0 -56
- data/doc/release_notes/5.9.0.txt +0 -99
- data/doc/schema_modification.rdoc +0 -679
- data/doc/security.rdoc +0 -443
- data/doc/sharding.rdoc +0 -286
- data/doc/sql.rdoc +0 -648
- data/doc/testing.rdoc +0 -204
- data/doc/thread_safety.rdoc +0 -15
- data/doc/transactions.rdoc +0 -250
- data/doc/validations.rdoc +0 -558
- data/doc/virtual_rows.rdoc +0 -265
|
@@ -113,7 +113,7 @@ module Sequel
|
|
|
113
113
|
def parse_constraint_validations
|
|
114
114
|
db.extension(:_model_constraint_validations)
|
|
115
115
|
|
|
116
|
-
unless
|
|
116
|
+
unless Sequel.synchronize{db.constraint_validations}
|
|
117
117
|
hash = {}
|
|
118
118
|
db.from(constraint_validations_table).each do |r|
|
|
119
119
|
(hash[r[:table]] ||= []) << r
|
|
@@ -121,14 +121,7 @@ module Sequel
|
|
|
121
121
|
Sequel.synchronize{db.constraint_validations = hash}
|
|
122
122
|
end
|
|
123
123
|
|
|
124
|
-
if @dataset
|
|
125
|
-
ds = @dataset.with_quote_identifiers(false)
|
|
126
|
-
table_name = ds.literal(ds.first_source_table)
|
|
127
|
-
reflections = {}
|
|
128
|
-
allow_missing_columns = db_schema.select{|col, sch| sch[:allow_null] == false && nil != sch[:default]}.map(&:first)
|
|
129
|
-
@constraint_validations = (Sequel.synchronize{hash[table_name]} || []).map{|r| constraint_validation_array(r, reflections, allow_missing_columns)}
|
|
130
|
-
@constraint_validation_reflections = reflections
|
|
131
|
-
end
|
|
124
|
+
parse_constraint_validations_dataset if @dataset
|
|
132
125
|
end
|
|
133
126
|
|
|
134
127
|
# Given a specific database constraint validation metadata row hash, transform
|
|
@@ -164,7 +157,7 @@ module Sequel
|
|
|
164
157
|
arg = constraint_validation_int_range(arg)
|
|
165
158
|
type = :includes
|
|
166
159
|
when *OPERATOR_MAP.keys
|
|
167
|
-
arg = arg.to_i if type.to_s
|
|
160
|
+
arg = arg.to_i if type.to_s.start_with?('int_')
|
|
168
161
|
operator = OPERATOR_MAP[type]
|
|
169
162
|
type = :operator
|
|
170
163
|
end
|
|
@@ -236,6 +229,18 @@ module Sequel
|
|
|
236
229
|
Regexp.new(arg)
|
|
237
230
|
end
|
|
238
231
|
end
|
|
232
|
+
|
|
233
|
+
# If this model has associated dataset, use the model's table name
|
|
234
|
+
# to get the validations for just this model.
|
|
235
|
+
def parse_constraint_validations_dataset
|
|
236
|
+
ds = @dataset.with_quote_identifiers(false)
|
|
237
|
+
table_name = ds.literal(ds.first_source_table)
|
|
238
|
+
reflections = {}
|
|
239
|
+
allow_missing_columns = db_schema.select{|col, sch| sch[:allow_null] == false && nil != sch[:default]}.map(&:first)
|
|
240
|
+
hash = Sequel.synchronize{db.constraint_validations}
|
|
241
|
+
@constraint_validations = (Sequel.synchronize{hash[table_name]} || []).map{|r| constraint_validation_array(r, reflections, allow_missing_columns)}
|
|
242
|
+
@constraint_validation_reflections = reflections
|
|
243
|
+
end
|
|
239
244
|
end
|
|
240
245
|
|
|
241
246
|
module InstanceMethods
|
|
@@ -82,8 +82,27 @@ module Sequel
|
|
|
82
82
|
# database supports window functions.
|
|
83
83
|
def associated(name)
|
|
84
84
|
raise Error, "unrecognized association name: #{name.inspect}" unless r = model.association_reflection(name)
|
|
85
|
-
|
|
85
|
+
klass = r.associated_class
|
|
86
86
|
sds = opts[:limit] ? self : unordered
|
|
87
|
+
|
|
88
|
+
if r.send(:filter_by_associations_limit_strategy) == :lateral_subquery
|
|
89
|
+
ds = r.send(:associated_eager_dataset)
|
|
90
|
+
|
|
91
|
+
case r[:type]
|
|
92
|
+
when :one_to_one, :one_to_many
|
|
93
|
+
sds = sds.select(*Array(r.qualified_primary_key))
|
|
94
|
+
else
|
|
95
|
+
sds = sds.select(*r[:left_primary_keys])
|
|
96
|
+
ds = ds.select_all(klass.table_name)
|
|
97
|
+
update_select = true
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
ds = r.send(:apply_lateral_subquery_eager_limit_strategy, ds, sds, r.limit_and_offset)
|
|
101
|
+
ds = ds.clone(:select=>ds.opts[:select][0,1]) if update_select
|
|
102
|
+
return ds.clone(:eager=>nil, :eager_graph=>nil)
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
ds = klass.dataset
|
|
87
106
|
ds = case r[:type]
|
|
88
107
|
when :many_to_one
|
|
89
108
|
ds.where(r.qualified_primary_key=>sds.select(*Array(r[:qualified_key])))
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
# frozen-string-literal: true
|
|
2
|
+
|
|
3
|
+
module Sequel
|
|
4
|
+
module Plugins
|
|
5
|
+
# The deprecated_associations plugin adds support for
|
|
6
|
+
# deprecating associations. Attempts to use association
|
|
7
|
+
# methods and access association metadata for deprecated
|
|
8
|
+
# associations results in a warning.
|
|
9
|
+
#
|
|
10
|
+
# Album.plugin :deprecated_associations
|
|
11
|
+
# Album.many_to_one :artist, deprecated: true
|
|
12
|
+
# album = Album[1]
|
|
13
|
+
#
|
|
14
|
+
# # Warnings for all of the following calls
|
|
15
|
+
# album.artist
|
|
16
|
+
# album.artist_dataset
|
|
17
|
+
# album.artist = Artist[2]
|
|
18
|
+
# Album.association_reflection(:artist)
|
|
19
|
+
# Album.eager(:artist)
|
|
20
|
+
# Album.eager_graph(:artist)
|
|
21
|
+
# Album.where(artist: Artist[1]).all
|
|
22
|
+
#
|
|
23
|
+
# By default, the plugin issues a single warning per
|
|
24
|
+
# association method or association reflection. See
|
|
25
|
+
# DeprecatedAssociations.configure for options to make
|
|
26
|
+
# deprecated association issue warnings for every access,
|
|
27
|
+
# to include backtraces in warnings, or to raise an
|
|
28
|
+
# exception instead of warning.
|
|
29
|
+
#
|
|
30
|
+
# Note that Model.association_reflections and
|
|
31
|
+
# Model.all_association_reflections will include deprecated
|
|
32
|
+
# associations, and accessing the metadata for deprecated
|
|
33
|
+
# associations through these interfaces not issue warnings.
|
|
34
|
+
#
|
|
35
|
+
# Usage:
|
|
36
|
+
#
|
|
37
|
+
# # Make all models support deprecated associations
|
|
38
|
+
# # (called before loading subclasses)
|
|
39
|
+
# Sequel::Model.plugin :deprecated_associations
|
|
40
|
+
#
|
|
41
|
+
# # Make Album class support deprecated associations
|
|
42
|
+
# Album.plugin :deprecated_associations
|
|
43
|
+
module DeprecatedAssociations
|
|
44
|
+
# Exception class used for deprecated association use when
|
|
45
|
+
# raising exceptions instead of emitting warnings.
|
|
46
|
+
class Access < Sequel::Error; end
|
|
47
|
+
|
|
48
|
+
# Configure the deprecated associations plugin. Options:
|
|
49
|
+
#
|
|
50
|
+
# backtrace: Print backtrace with warning
|
|
51
|
+
# deduplicate: Set to false to emit warnings for every
|
|
52
|
+
# deprecated association method call/access
|
|
53
|
+
# (when not caching associations, this is always false)
|
|
54
|
+
# raise: Raise Sequel::Plugin::DeprecatedAssociations::Access
|
|
55
|
+
# instead of warning
|
|
56
|
+
def self.configure(model, opts = OPTS)
|
|
57
|
+
model.instance_exec do
|
|
58
|
+
(@deprecated_associations_config ||= {}).merge!(opts)
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
module ClassMethods
|
|
63
|
+
# Issue a deprecation warning if the association is deprecated.
|
|
64
|
+
def association_reflection(assoc)
|
|
65
|
+
ref = super
|
|
66
|
+
if ref && ref[:deprecated]
|
|
67
|
+
emit_deprecated_association_warning(ref, nil) do
|
|
68
|
+
"Access of association reflection for deprecated association: class:#{name} association:#{assoc}"
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
ref
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
private
|
|
75
|
+
|
|
76
|
+
# Issue a deprecation warning when the defined method is called if the
|
|
77
|
+
# association is deprecated and the method name does not start with the
|
|
78
|
+
# underscore (to avoid not warning twice, once for the public association
|
|
79
|
+
# method and once for the private association method).
|
|
80
|
+
def association_module_def(name, opts=OPTS, &block)
|
|
81
|
+
super
|
|
82
|
+
if opts[:deprecated] && name[0] != "_"
|
|
83
|
+
deprecated_associations_module.module_exec do
|
|
84
|
+
define_method(name) do |*a, &b|
|
|
85
|
+
self.class.send(:emit_deprecated_association_warning, opts, name) do
|
|
86
|
+
"Calling deprecated association method: class:#{self.class.name} association:#{opts[:name]} method:#{name}"
|
|
87
|
+
end
|
|
88
|
+
super(*a, &b)
|
|
89
|
+
end
|
|
90
|
+
alias_method name, name
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
nil
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# Issue a deprecation warning when the defined method is called if the
|
|
97
|
+
# association is deprecated.
|
|
98
|
+
def association_module_delegate_def(name, opts, &block)
|
|
99
|
+
super
|
|
100
|
+
if opts[:deprecated]
|
|
101
|
+
deprecated_associations_module.module_exec do
|
|
102
|
+
define_method(name) do |*a, &b|
|
|
103
|
+
self.class.send(:emit_deprecated_association_warning, opts, name) do
|
|
104
|
+
"Calling deprecated association method: class:#{self.class.name} association:#{opts[:name]} method:#{name}"
|
|
105
|
+
end
|
|
106
|
+
super(*a, &b)
|
|
107
|
+
end
|
|
108
|
+
# :nocov:
|
|
109
|
+
ruby2_keywords(name) if respond_to?(:ruby2_keywords, true)
|
|
110
|
+
# :nocov:
|
|
111
|
+
alias_method(name, name)
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
nil
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
# A module to add deprecated association methods to. These methods
|
|
118
|
+
# handle issuing the deprecation warnings, and call super to get the
|
|
119
|
+
# default behavior.
|
|
120
|
+
def deprecated_associations_module
|
|
121
|
+
return @deprecated_associations_module if defined?(@deprecated_associations_module)
|
|
122
|
+
@deprecated_associations_module = Module.new
|
|
123
|
+
include(@deprecated_associations_module)
|
|
124
|
+
@deprecated_associations_module
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
# Emit a deprecation warning, or raise an exception if the :raise
|
|
128
|
+
# plugin option was used.
|
|
129
|
+
def emit_deprecated_association_warning(ref, method)
|
|
130
|
+
config = @deprecated_associations_config
|
|
131
|
+
|
|
132
|
+
raise Access, yield if config[:raise]
|
|
133
|
+
|
|
134
|
+
unless config[:deduplicate] == false
|
|
135
|
+
emit = false
|
|
136
|
+
ref.send(:cached_fetch, [:deprecated_associations, method]) do
|
|
137
|
+
emit = true
|
|
138
|
+
end
|
|
139
|
+
return unless emit
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
if config[:backtrace]
|
|
143
|
+
warn yield, caller(2)
|
|
144
|
+
else
|
|
145
|
+
warn yield, :uplevel => 2
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
end
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
# frozen-string-literal: true
|
|
2
|
+
|
|
3
|
+
module Sequel
|
|
4
|
+
module Plugins
|
|
5
|
+
# The detect_unnecessary_association_options plugin can detect unnecessary
|
|
6
|
+
# association options, and either warn or raise if they are detected.
|
|
7
|
+
# This allows you to find and remove the unnecessary options.
|
|
8
|
+
# Association options are considered unnecessary if they specify the same
|
|
9
|
+
# value as Sequel's defaults.
|
|
10
|
+
#
|
|
11
|
+
# To detect unnecessary association options, you should load the plugin
|
|
12
|
+
# into your model base class (e.g. Sequel::Model) before loading your model
|
|
13
|
+
# classes. Then, after all models have been loaded, you can call the
|
|
14
|
+
# detect_unnecessary_association_options on each to check for unnecessary
|
|
15
|
+
# association options. Additionally, if you are calling finalize_associations,
|
|
16
|
+
# it will automatically check for unnecessary association options.
|
|
17
|
+
#
|
|
18
|
+
# A typical usage would be to combine this with the subclasses plugin:
|
|
19
|
+
#
|
|
20
|
+
# Sequel::Model.plugin :detect_unnecessary_association_options
|
|
21
|
+
# Sequel::Model.plugin :subclasses
|
|
22
|
+
# # load model classes
|
|
23
|
+
#
|
|
24
|
+
# # implicitly check all subclasses when freezing descendants
|
|
25
|
+
# Sequel::Model.freeze_descendants
|
|
26
|
+
#
|
|
27
|
+
# # or, if not freezing all descendants
|
|
28
|
+
# Sequel::Model.descendants.each(&:detect_unnecessary_association_options)
|
|
29
|
+
#
|
|
30
|
+
# By default, the plugin warns for every unnecessary association option.
|
|
31
|
+
# To raise an error instead, you can pass the <tt>action: :raise</tt> option when loading the
|
|
32
|
+
# plugin:
|
|
33
|
+
#
|
|
34
|
+
# Sequel::Model.plugin :detect_unnecessary_association_options, action: :raise
|
|
35
|
+
#
|
|
36
|
+
# This plugin only detects the most common unnecessary association options, such as:
|
|
37
|
+
#
|
|
38
|
+
# * :class (all associations)
|
|
39
|
+
# * :key and :primary_key (associations without join tables)
|
|
40
|
+
# * :join_table, :left_key, :right_key, :left_primary_key, :right_primary_key (single join table associations)
|
|
41
|
+
# * :left_primary_key, :right_primary_key (*_through_many associations)
|
|
42
|
+
#
|
|
43
|
+
# Only association types supported by default or supported by a plugin that
|
|
44
|
+
# ships with Sequel are supported by this plugin. Other association types are
|
|
45
|
+
# ignored.
|
|
46
|
+
module DetectUnnecessaryAssociationOptions
|
|
47
|
+
def self.configure(model, opts={})
|
|
48
|
+
model.instance_variable_set(:@detect_unnecessary_association_options_action, opts[:action] || :warn)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Raised if the plugin action is to raise and an unnecessary association option
|
|
52
|
+
# is detected.
|
|
53
|
+
class UnnecessaryAssociationOption < Sequel::Error
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
module ClassMethods
|
|
57
|
+
Plugins.inherited_instance_variables(self, :@detect_unnecessary_association_options_action => nil)
|
|
58
|
+
|
|
59
|
+
# Implicitly check for unnecessary association options when finalizing associations.
|
|
60
|
+
def finalize_associations
|
|
61
|
+
res = super
|
|
62
|
+
detect_unnecessary_association_options
|
|
63
|
+
res
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Check for unnecessary association options.
|
|
67
|
+
def detect_unnecessary_association_options
|
|
68
|
+
@association_reflections.each_value do |ref|
|
|
69
|
+
meth = "detect_unnecessary_association_options_#{ref[:type]}"
|
|
70
|
+
# Expected to call private methods.
|
|
71
|
+
# Ignore unrecognized association types.
|
|
72
|
+
# External association types can define the appropriate method to
|
|
73
|
+
# support their own unnecessary association option checks.
|
|
74
|
+
if respond_to?(meth, true)
|
|
75
|
+
# All recognized association types need same class check
|
|
76
|
+
_detect_unnecessary_association_options_class(ref)
|
|
77
|
+
send(meth, ref)
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
nil
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
private
|
|
85
|
+
|
|
86
|
+
# Action to take if an unnecessary association option is detected.
|
|
87
|
+
def unnecessary_association_options_detected(ref, key)
|
|
88
|
+
if @detect_unnecessary_association_options_action == :raise
|
|
89
|
+
raise UnnecessaryAssociationOption, "#{ref.inspect} :#{key} option unnecessary"
|
|
90
|
+
else
|
|
91
|
+
warn "#{ref.inspect} :#{key} option unnecessary"
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# Detect unnecessary :class option.
|
|
96
|
+
def _detect_unnecessary_association_options_class(ref)
|
|
97
|
+
return unless ref[:orig_class]
|
|
98
|
+
|
|
99
|
+
h = {}
|
|
100
|
+
name = ref[:name]
|
|
101
|
+
late_binding_class_option(h, ref.returns_array? ? singularize(name) : name)
|
|
102
|
+
|
|
103
|
+
begin
|
|
104
|
+
default_association_class = constantize(h[:class_name])
|
|
105
|
+
actual_association_class = ref.associated_class
|
|
106
|
+
rescue NameError
|
|
107
|
+
# Do not warn. For the default association class to not be a valid
|
|
108
|
+
# constant is expected. For the actual association class to not be
|
|
109
|
+
# a valid constant is not expected and a bug in the association, but
|
|
110
|
+
# the job of this plugin is not to detect invalid options, only
|
|
111
|
+
# unnecessary options.
|
|
112
|
+
else
|
|
113
|
+
if default_association_class.equal?(actual_association_class)
|
|
114
|
+
unnecessary_association_options_detected(ref, "class")
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
# Detect other unnecessary options. An option is considered unnecessary
|
|
120
|
+
# if the key was submitted as an association option and the value for
|
|
121
|
+
# the option is the same as the given value.
|
|
122
|
+
def _detect_unnecessary_association_options_key_value(ref, key, value)
|
|
123
|
+
if ref[:orig_opts].has_key?(key) && ref[:orig_opts][key] == value
|
|
124
|
+
unnecessary_association_options_detected(ref, key)
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
# Same as _detect_unnecessary_association_options_key_value, but calls
|
|
129
|
+
# the default_* method on the association reflection to get the default value.
|
|
130
|
+
def _detect_unnecessary_association_options_key(ref, key)
|
|
131
|
+
_detect_unnecessary_association_options_key_value(ref, key, ref.send(:"default_#{key}"))
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def detect_unnecessary_association_options_many_to_one(ref)
|
|
135
|
+
_detect_unnecessary_association_options_key(ref, :key)
|
|
136
|
+
_detect_unnecessary_association_options_key_value(ref, :primary_key, ref.associated_class.primary_key)
|
|
137
|
+
end
|
|
138
|
+
alias detect_unnecessary_association_options_pg_array_to_many detect_unnecessary_association_options_many_to_one
|
|
139
|
+
|
|
140
|
+
def detect_unnecessary_association_options_one_to_many(ref)
|
|
141
|
+
_detect_unnecessary_association_options_key(ref, :key)
|
|
142
|
+
_detect_unnecessary_association_options_key_value(ref, :primary_key, primary_key)
|
|
143
|
+
end
|
|
144
|
+
alias detect_unnecessary_association_options_one_to_one detect_unnecessary_association_options_one_to_many
|
|
145
|
+
alias detect_unnecessary_association_options_many_to_pg_array detect_unnecessary_association_options_one_to_many
|
|
146
|
+
|
|
147
|
+
def detect_unnecessary_association_options_many_to_many(ref)
|
|
148
|
+
[:join_table, :left_key, :right_key].each do |key|
|
|
149
|
+
_detect_unnecessary_association_options_key(ref, key)
|
|
150
|
+
end
|
|
151
|
+
_detect_unnecessary_association_options_key_value(ref, :left_primary_key, primary_key)
|
|
152
|
+
_detect_unnecessary_association_options_key_value(ref, :right_primary_key, ref.associated_class.primary_key)
|
|
153
|
+
end
|
|
154
|
+
alias detect_unnecessary_association_options_one_through_one detect_unnecessary_association_options_many_to_many
|
|
155
|
+
|
|
156
|
+
def detect_unnecessary_association_options_many_through_many(ref)
|
|
157
|
+
_detect_unnecessary_association_options_key_value(ref, :left_primary_key, primary_key)
|
|
158
|
+
_detect_unnecessary_association_options_key_value(ref, :right_primary_key, ref.associated_class.primary_key)
|
|
159
|
+
end
|
|
160
|
+
alias detect_unnecessary_association_options_one_through_many detect_unnecessary_association_options_many_through_many
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
end
|
data/lib/sequel/plugins/dirty.rb
CHANGED
|
@@ -63,6 +63,10 @@ module Sequel
|
|
|
63
63
|
# # Make the Album class record previous values
|
|
64
64
|
# Album.plugin :dirty
|
|
65
65
|
module Dirty
|
|
66
|
+
module ClassMethods
|
|
67
|
+
Plugins.model_instance_variables(self, :@previous_changes, :@initial_values, :@missing_initial_values)
|
|
68
|
+
end
|
|
69
|
+
|
|
66
70
|
module InstanceMethods
|
|
67
71
|
# A hash of previous changes before the object was
|
|
68
72
|
# saved, in the same format as #column_changes.
|
|
@@ -234,8 +238,11 @@ module Sequel
|
|
|
234
238
|
iv.delete(column)
|
|
235
239
|
end
|
|
236
240
|
else
|
|
237
|
-
|
|
238
|
-
|
|
241
|
+
if db_schema[column]
|
|
242
|
+
check_missing_initial_value(column)
|
|
243
|
+
iv[column] = get_column_value(column)
|
|
244
|
+
end
|
|
245
|
+
|
|
239
246
|
super
|
|
240
247
|
end
|
|
241
248
|
end
|
data/lib/sequel/plugins/enum.rb
CHANGED
|
@@ -39,6 +39,9 @@ module Sequel
|
|
|
39
39
|
#
|
|
40
40
|
# Album.first.artist # no error
|
|
41
41
|
#
|
|
42
|
+
# This behavior of enabling +forbid_lazy_load+ automatically from dataset
|
|
43
|
+
# methods can be disabled using the plugin's +:allow_by_default+ option.
|
|
44
|
+
#
|
|
42
45
|
# You can allow lazy loading associations for an instance that it
|
|
43
46
|
# was previously forbidden for:
|
|
44
47
|
#
|
|
@@ -98,13 +101,24 @@ module Sequel
|
|
|
98
101
|
#
|
|
99
102
|
# # Make the Album class support forbidding lazy load
|
|
100
103
|
# Album.plugin :forbid_lazy_load
|
|
104
|
+
#
|
|
105
|
+
# # Let lazy loading be forbidden by object, but not automatically for any
|
|
106
|
+
# # object loaded via dataset.
|
|
107
|
+
# Album.plugin :forbid_lazy_load, allow_by_default: true
|
|
101
108
|
module ForbidLazyLoad
|
|
109
|
+
def self.apply(model, opts=OPTS)
|
|
110
|
+
unless opts[:allow_by_default]
|
|
111
|
+
model.send(:dataset_extend, ForbidByDefault, :create_class_methods=>false)
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
102
115
|
# Error raised when attempting to lazy load an association when
|
|
103
116
|
# lazy loading has been forbidden.
|
|
104
117
|
class Error < StandardError
|
|
105
118
|
end
|
|
106
119
|
|
|
107
120
|
module ClassMethods
|
|
121
|
+
Plugins.model_instance_variables(self, :@forbid_lazy_load)
|
|
108
122
|
Plugins.def_dataset_methods(self, :forbid_lazy_load)
|
|
109
123
|
|
|
110
124
|
# If the static_cache plugin is used by the associated class for
|
|
@@ -179,7 +193,7 @@ module Sequel
|
|
|
179
193
|
end
|
|
180
194
|
end
|
|
181
195
|
|
|
182
|
-
module
|
|
196
|
+
module ForbidByDefault
|
|
183
197
|
# Mark model instances retrieved in this call as forbidding lazy loading.
|
|
184
198
|
def each
|
|
185
199
|
if row_proc
|
|
@@ -42,6 +42,10 @@ module Sequel
|
|
|
42
42
|
end
|
|
43
43
|
end
|
|
44
44
|
|
|
45
|
+
module ClassMethods
|
|
46
|
+
Plugins.model_instance_variables(self, :@insert_conflict_opts)
|
|
47
|
+
end
|
|
48
|
+
|
|
45
49
|
module InstanceMethods
|
|
46
50
|
# Set the insert_conflict options to pass to the dataset when inserting.
|
|
47
51
|
def insert_conflict(opts=OPTS)
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
module Sequel
|
|
4
4
|
module Plugins
|
|
5
|
-
# If the model's dataset selects explicit columns and the
|
|
5
|
+
# If the model's dataset selects explicit columns (or table.*) and the
|
|
6
6
|
# database supports it, the insert_returning_select plugin will
|
|
7
7
|
# automatically set the RETURNING clause on the dataset used to
|
|
8
8
|
# insert rows to the columns selected, which allows the default model
|
|
@@ -45,6 +45,9 @@ module Sequel
|
|
|
45
45
|
ret
|
|
46
46
|
end
|
|
47
47
|
|
|
48
|
+
RETURN_ALL = [Sequel::Dataset::WILDCARD].freeze
|
|
49
|
+
private_constant :RETURN_ALL
|
|
50
|
+
|
|
48
51
|
# Determine the columns to use for the returning clause, or return nil
|
|
49
52
|
# if they can't be determined and a returning clause should not be
|
|
50
53
|
# added automatically.
|
|
@@ -52,6 +55,12 @@ module Sequel
|
|
|
52
55
|
return unless ds.supports_returning?(:insert)
|
|
53
56
|
return unless values = ds.opts[:select]
|
|
54
57
|
|
|
58
|
+
# SELECT table.* -> RETURNING *
|
|
59
|
+
if values.length == 1 && values[0].is_a?(Sequel::SQL::ColumnAll)
|
|
60
|
+
return RETURN_ALL
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# SELECT column1, table.column2, ... -> RETURNING column1, column2, ...
|
|
55
64
|
values = values.map{|v| ds.unqualified_column_for(v)}
|
|
56
65
|
if values.all?
|
|
57
66
|
values
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# frozen-string-literal: true
|
|
2
|
+
|
|
3
|
+
module Sequel
|
|
4
|
+
module Plugins
|
|
5
|
+
# The inspect_pk plugin includes the pk right next to the
|
|
6
|
+
# model name in inspect, allowing for easily copying and
|
|
7
|
+
# pasting to retrieve a copy of the object:
|
|
8
|
+
#
|
|
9
|
+
# Album.with_pk(1).inspect
|
|
10
|
+
# # default: #<Album @values={...}>
|
|
11
|
+
# # with inspect_pk: #<Album[1] @values={...}>
|
|
12
|
+
#
|
|
13
|
+
# Usage:
|
|
14
|
+
#
|
|
15
|
+
# # Make all model instances include pk in inspect output
|
|
16
|
+
# Sequel::Model.plugin :inspect_pk
|
|
17
|
+
#
|
|
18
|
+
# # Make Album instances include pk in inspect output
|
|
19
|
+
# Album.plugin :inspect_pk
|
|
20
|
+
module InspectPk
|
|
21
|
+
module InstanceMethods
|
|
22
|
+
private
|
|
23
|
+
|
|
24
|
+
# The primary key value to include in the inspect output, if any.
|
|
25
|
+
# For composite primary keys, this only includes a value if all
|
|
26
|
+
# fields are present.
|
|
27
|
+
def inspect_pk
|
|
28
|
+
if primary_key && (pk = self.pk) && (!(Array === pk) || pk.all?)
|
|
29
|
+
pk
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Include the instance's primary key in the output.
|
|
34
|
+
def inspect_prefix
|
|
35
|
+
if v = inspect_pk
|
|
36
|
+
"#{super}[#{v.inspect}]"
|
|
37
|
+
else
|
|
38
|
+
super
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -50,6 +50,10 @@ module Sequel
|
|
|
50
50
|
model.require_modification = true
|
|
51
51
|
end
|
|
52
52
|
|
|
53
|
+
module ClassMethods
|
|
54
|
+
Plugins.model_instance_variables(self, :@instance_filters)
|
|
55
|
+
end
|
|
56
|
+
|
|
53
57
|
module InstanceMethods
|
|
54
58
|
# Clear the instance filters after successfully destroying the object.
|
|
55
59
|
def after_destroy
|
|
@@ -102,7 +106,10 @@ module Sequel
|
|
|
102
106
|
|
|
103
107
|
# Apply the instance filters to the given dataset
|
|
104
108
|
def apply_instance_filters(ds)
|
|
105
|
-
instance_filters.inject(ds)
|
|
109
|
+
instance_filters.inject(ds) do |ds1, i|
|
|
110
|
+
block = i[1]
|
|
111
|
+
ds1.where(*i[0], &block)
|
|
112
|
+
end
|
|
106
113
|
end
|
|
107
114
|
|
|
108
115
|
# Clear the instance filters.
|
|
@@ -28,6 +28,10 @@ module Sequel
|
|
|
28
28
|
# # Add the instance hook methods just to Album instances
|
|
29
29
|
# Album.plugin :instance_hooks
|
|
30
30
|
module InstanceHooks
|
|
31
|
+
module ClassMethods
|
|
32
|
+
Plugins.model_instance_variables(self, :@instance_hooks)
|
|
33
|
+
end
|
|
34
|
+
|
|
31
35
|
module InstanceMethods
|
|
32
36
|
Sequel::Model::HOOKS.each{|h| class_eval(<<-END , __FILE__, __LINE__+1)}
|
|
33
37
|
def #{h}_hook(&block)
|
|
@@ -32,6 +32,7 @@ module Sequel
|
|
|
32
32
|
def self.apply(model, &block)
|
|
33
33
|
model.instance_exec do
|
|
34
34
|
@dataset_module_class = Class.new(@dataset_module_class) do
|
|
35
|
+
Sequel.set_temp_name(self){"#{model.name}::@dataset_module_class(InvertedSubsets)"}
|
|
35
36
|
include DatasetModuleMethods
|
|
36
37
|
if block
|
|
37
38
|
define_method(:inverted_subset_name, &block)
|
|
@@ -106,13 +106,7 @@ module Sequel
|
|
|
106
106
|
# and breaks some aspects of the json_serializer plugin. You can undo the damage
|
|
107
107
|
# done by active_support/json by doing:
|
|
108
108
|
#
|
|
109
|
-
#
|
|
110
|
-
# def to_json(options = {})
|
|
111
|
-
# JSON.generate(self)
|
|
112
|
-
# end
|
|
113
|
-
# end
|
|
114
|
-
# Array.send(:prepend, ActiveSupportBrokenJSONFix)
|
|
115
|
-
# Hash.send(:prepend, ActiveSupportBrokenJSONFix)
|
|
109
|
+
# ActiveSupport::ToJsonWithActiveSupportEncoder.send(:remove_method, :to_json)
|
|
116
110
|
#
|
|
117
111
|
# Note that this will probably cause active_support/json to no longer work
|
|
118
112
|
# correctly in some cases.
|
|
@@ -168,6 +162,8 @@ module Sequel
|
|
|
168
162
|
end
|
|
169
163
|
|
|
170
164
|
module ClassMethods
|
|
165
|
+
Plugins.model_instance_variables(self, :@json_serializer_opts)
|
|
166
|
+
|
|
171
167
|
# The default opts to use when serializing model objects to JSON.
|
|
172
168
|
attr_reader :json_serializer_opts
|
|
173
169
|
|
|
@@ -370,9 +366,9 @@ module Sequel
|
|
|
370
366
|
end
|
|
371
367
|
|
|
372
368
|
# Convert the receiver to a JSON data structure using the given arguments.
|
|
373
|
-
def to_json_data(*args
|
|
374
|
-
if
|
|
375
|
-
to_json(*args){|x| return
|
|
369
|
+
def to_json_data(*args)
|
|
370
|
+
if defined?(yield)
|
|
371
|
+
to_json(*args){|x| return yield(x)}
|
|
376
372
|
else
|
|
377
373
|
to_json(*args){|x| return x}
|
|
378
374
|
end
|
|
@@ -64,7 +64,7 @@ module Sequel
|
|
|
64
64
|
# :dataset :: The base dataset to use for the lazy attribute lookup
|
|
65
65
|
# :table :: The table name to use to qualify the attribute and primary key columns.
|
|
66
66
|
def define_lazy_attribute_getter(a, opts=OPTS)
|
|
67
|
-
include(@lazy_attributes_module ||= Module.new) unless @lazy_attributes_module
|
|
67
|
+
include(@lazy_attributes_module ||= Sequel.set_temp_name(Module.new){"#{name}::@lazy_attributes_module"}) unless @lazy_attributes_module
|
|
68
68
|
@lazy_attributes_module.class_eval do
|
|
69
69
|
define_method(a) do
|
|
70
70
|
if !values.has_key?(a) && !new?
|