valkyrie 2.1.1 → 2.1.2

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.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +33 -29
  3. data/.lando.yml +40 -0
  4. data/.rubocop.yml +4 -1
  5. data/.tool-versions +1 -1
  6. data/CHANGELOG.md +26 -0
  7. data/README.md +19 -47
  8. data/Rakefile +21 -20
  9. data/db/config.yml +3 -10
  10. data/lib/generators/valkyrie/resource_generator.rb +3 -3
  11. data/lib/valkyrie.rb +13 -13
  12. data/lib/valkyrie/change_set.rb +3 -3
  13. data/lib/valkyrie/id.rb +14 -14
  14. data/lib/valkyrie/indexers/access_controls_indexer.rb +17 -17
  15. data/lib/valkyrie/persistence/fedora/list_node.rb +43 -43
  16. data/lib/valkyrie/persistence/fedora/ordered_list.rb +90 -90
  17. data/lib/valkyrie/persistence/fedora/ordered_reader.rb +5 -5
  18. data/lib/valkyrie/persistence/fedora/permissive_schema.rb +1 -1
  19. data/lib/valkyrie/persistence/fedora/persister.rb +80 -82
  20. data/lib/valkyrie/persistence/fedora/persister/model_converter.rb +15 -15
  21. data/lib/valkyrie/persistence/fedora/persister/orm_converter.rb +38 -18
  22. data/lib/valkyrie/persistence/fedora/query_service.rb +38 -40
  23. data/lib/valkyrie/persistence/memory/persister.rb +33 -33
  24. data/lib/valkyrie/persistence/memory/query_service.rb +26 -30
  25. data/lib/valkyrie/persistence/postgres/orm_converter.rb +52 -52
  26. data/lib/valkyrie/persistence/postgres/query_service.rb +34 -34
  27. data/lib/valkyrie/persistence/shared/json_value_mapper.rb +1 -1
  28. data/lib/valkyrie/persistence/solr/model_converter.rb +337 -337
  29. data/lib/valkyrie/persistence/solr/orm_converter.rb +3 -3
  30. data/lib/valkyrie/persistence/solr/queries/find_members_query.rb +1 -1
  31. data/lib/valkyrie/persistence/solr/query_service.rb +12 -12
  32. data/lib/valkyrie/specs/shared_specs/persister.rb +2 -2
  33. data/lib/valkyrie/storage/fedora.rb +16 -16
  34. data/lib/valkyrie/storage_adapter.rb +11 -11
  35. data/lib/valkyrie/version.rb +1 -1
  36. data/tasks/dev.rake +14 -51
  37. data/valkyrie.gemspec +3 -4
  38. metadata +22 -33
  39. data/.docker-stack/valkyrie-development/docker-compose.yml +0 -53
  40. data/.docker-stack/valkyrie-test/docker-compose.yml +0 -53
  41. data/tasks/docker.rake +0 -31
@@ -325,21 +325,21 @@ module Valkyrie::Persistence::Fedora
325
325
  class MappedFedoraValue < ::Valkyrie::ValueMapper
326
326
  private
327
327
 
328
- # Map a default Ruby data type
329
- # (This maps the existing Property to a FedoraValue first)
330
- # @param [Object] converted_value
331
- # @return [Valkyrie::Persistence::Fedora::Persister::ModelConverter::Property]
332
- def map_value(converted_value:)
333
- calling_mapper.for(
334
- Property.new(
335
- value.subject,
336
- value.key,
337
- converted_value,
338
- value.adapter,
339
- value.resource
340
- )
341
- ).result
342
- end
328
+ # Map a default Ruby data type
329
+ # (This maps the existing Property to a FedoraValue first)
330
+ # @param [Object] converted_value
331
+ # @return [Valkyrie::Persistence::Fedora::Persister::ModelConverter::Property]
332
+ def map_value(converted_value:)
333
+ calling_mapper.for(
334
+ Property.new(
335
+ value.subject,
336
+ value.key,
337
+ converted_value,
338
+ value.adapter,
339
+ value.resource
340
+ )
341
+ ).result
342
+ end
343
343
  end
344
344
 
345
345
  # Class mapping Property objects for Valkyrie IDs using typed RDF literals
@@ -97,11 +97,9 @@ module Valkyrie::Persistence::Fedora
97
97
  end
98
98
  end
99
99
 
100
- # Class for handling cases where blacklisted values should not be mapped
101
- class BlacklistedValue < ::Valkyrie::ValueMapper
102
- FedoraValue.register(self)
103
-
104
- # Determines whether or not the value has a blacklisted namespace for the RDF statement object
100
+ # Class for handling cases where deny listed values should not be mapped
101
+ class DenylistedValue < ::Valkyrie::ValueMapper
102
+ # Determines whether or not the value has a denied namespace for the RDF statement object
105
103
  # (i. e. avoid attempting to map any RDF statements making assertions about LDP containers or resource internal to Fedora)
106
104
  # @param [Property] value
107
105
  # @return [Boolean]
@@ -109,12 +107,20 @@ module Valkyrie::Persistence::Fedora
109
107
  value.statement.object.to_s.start_with?("http://www.w3.org/ns/ldp", "http://fedora.info")
110
108
  end
111
109
 
112
- # Provide the NullApplicator Class for any Property in a blacklisted namespace
110
+ # Provide the NullApplicator Class for any Property in a deny listed namespace
113
111
  def result
114
112
  NullApplicator
115
113
  end
116
114
  end
117
115
 
116
+ # @deprecated
117
+ # Class for handling cases where deny listed values should not be mapped
118
+ # @see DenylistedValue
119
+ class BlacklistedValue < DenylistedValue
120
+ FedoraValue.register(self)
121
+ warn "[DEPRECATION] Samvera is deprecating '#{self}' in 3.0.0. Use #{DenylistedValue} instead."
122
+ end
123
+
118
124
  # Class for handling cases where the RDF subject of a Property references a separate resource using a hash URI
119
125
  class DifferentSubject < ::Valkyrie::ValueMapper
120
126
  FedoraValue.register(self)
@@ -318,7 +324,7 @@ module Valkyrie::Persistence::Fedora
318
324
  # Casts the value of the RDF literal into an Applicator for DateTime values
319
325
  # @return [Applicator]
320
326
  def result
321
- value.statement.object = ::DateTime.iso8601(value.statement.object.to_s).utc
327
+ value.statement.object = ::DateTime.iso8601(value.statement.object.to_s).new_offset(0)
322
328
  calling_mapper.for(Property.new(statement: value.statement, scope: value.scope, adapter: value.adapter)).result
323
329
  end
324
330
  end
@@ -394,7 +400,7 @@ module Valkyrie::Persistence::Fedora
394
400
  # Casts the value of the RDF literal into an Applicator for DateTime values
395
401
  # @return [Applicator]
396
402
  def result
397
- value.statement.object = Time.parse(value.statement.object.to_s).utc
403
+ value.statement.object = DateTime.parse(value.statement.object.to_s).new_offset(0)
398
404
  calling_mapper.for(Property.new(statement: value.statement, scope: value.scope, adapter: value.adapter)).result
399
405
  end
400
406
  end
@@ -522,7 +528,7 @@ module Valkyrie::Persistence::Fedora
522
528
  # @param [Hash] hsh a new or existing Hash of attribute for Valkyrie resource attributes
523
529
  # @return [Hash]
524
530
  def apply_to(hsh)
525
- return if blacklist?(key)
531
+ return if deny?(key)
526
532
  hsh[key.to_sym] = if hsh.key?(key.to_sym)
527
533
  Array.wrap(hsh[key.to_sym]) + cast_array(values)
528
534
  else
@@ -541,13 +547,23 @@ module Valkyrie::Persistence::Fedora
541
547
  key
542
548
  end
543
549
 
544
- # Determines whether or not a key is blacklisted for mapping
550
+ # @deprecated
551
+ # Determines whether or not a key is on the deny list for mapping
545
552
  # (For example <http://fedora.info/definitions> assertions are not mapped to Valkyrie attributes)
546
553
  # @param [Symbol] key
547
554
  # @return [Boolean]
548
555
  def blacklist?(key)
549
- blacklist.each do |blacklist_item|
550
- return true if key.start_with?(blacklist_item)
556
+ warn "[DEPRECATION] Samvera is deprecating '#{self.class}#blacklist?' in 3.0.0. Use #{self.class}#deny? instead."
557
+ deny?(key)
558
+ end
559
+
560
+ # Determines whether or not a key is on the deny list for mapping
561
+ # (For example <http://fedora.info/definitions> assertions are not mapped to Valkyrie attributes)
562
+ # @param [Symbol] key
563
+ # @return [Boolean]
564
+ def deny?(key)
565
+ denylist.each do |denylist_item|
566
+ return true if key.start_with?(denylist_item)
551
567
  end
552
568
  false
553
569
  end
@@ -556,16 +572,20 @@ module Valkyrie::Persistence::Fedora
556
572
  # @param [Object] values
557
573
  # @return [Array<Object>]
558
574
  def cast_array(values)
559
- if values.is_a?(Time)
560
- [values]
561
- else
562
- Array(values)
563
- end
575
+ Array(values)
564
576
  end
565
577
 
566
- # Retrieve a list of blacklisted URIs for predicates
578
+ # @deprecated
579
+ # Retrieve a list of denied URIs for predicates
567
580
  # @return [Array<String>]
568
581
  def blacklist
582
+ warn "[DEPRECATION] Samvera is deprecating '#{self.class}#blacklist' in 3.0.0. Use #{self.class}#denylist instead."
583
+ denylist
584
+ end
585
+
586
+ # Retrieve a list of denied URIs for predicates
587
+ # @return [Array<String>]
588
+ def denylist
569
589
  [
570
590
  "http://fedora.info/definitions",
571
591
  "http://www.iana.org/assignments/relation/last"
@@ -31,11 +31,9 @@ module Valkyrie::Persistence::Fedora
31
31
  def find_many_by_ids(ids:)
32
32
  ids = ids.uniq
33
33
  ids.map do |id|
34
- begin
35
- find_by(id: id)
36
- rescue ::Valkyrie::Persistence::ObjectNotFoundError
37
- nil
38
- end
34
+ find_by(id: id)
35
+ rescue ::Valkyrie::Persistence::ObjectNotFoundError
36
+ nil
39
37
  end.reject(&:nil?)
40
38
  end
41
39
 
@@ -137,44 +135,44 @@ module Valkyrie::Persistence::Fedora
137
135
 
138
136
  private
139
137
 
140
- def find_inverse_reference_ids_by_unordered(resource:, property:)
141
- content = content_with_inbound(id: resource.id)
142
- property_uri = adapter.schema.predicate_for(property: property, resource: nil)
143
- content.graph.query([nil, property_uri, adapter.id_to_uri(resource.id)]).map(&:subject).map { |x| x.to_s.gsub(/#.*/, '') }.map { |x| adapter.uri_to_id(x) }
144
- end
138
+ def find_inverse_reference_ids_by_unordered(resource:, property:)
139
+ content = content_with_inbound(id: resource.id)
140
+ property_uri = adapter.schema.predicate_for(property: property, resource: nil)
141
+ content.graph.query([nil, property_uri, adapter.id_to_uri(resource.id)]).map(&:subject).map { |x| x.to_s.gsub(/#.*/, '') }.map { |x| adapter.uri_to_id(x) }
142
+ end
145
143
 
146
- def find_inverse_references_by_ordered(resource:, property:, ignore_ids: [])
147
- content = content_with_inbound(id: resource.id)
148
- ids = content.graph.query([nil, ::RDF::Vocab::ORE.proxyFor, adapter.id_to_uri(resource.id)]).map(&:subject).map { |x| x.to_s.gsub(/#.*/, '') }.map { |x| adapter.uri_to_id(x) }
149
- ids.uniq!
150
- ids.delete_if { |id| ignore_ids.include? id }
151
- ids.lazy.map { |id| find_by(id: id) }.select { |o| o[property].include?(resource.id) }
152
- end
144
+ def find_inverse_references_by_ordered(resource:, property:, ignore_ids: [])
145
+ content = content_with_inbound(id: resource.id)
146
+ ids = content.graph.query([nil, ::RDF::Vocab::ORE.proxyFor, adapter.id_to_uri(resource.id)]).map(&:subject).map { |x| x.to_s.gsub(/#.*/, '') }.map { |x| adapter.uri_to_id(x) }
147
+ ids.uniq!
148
+ ids.delete_if { |id| ignore_ids.include? id }
149
+ ids.lazy.map { |id| find_by(id: id) }.select { |o| o[property].include?(resource.id) }
150
+ end
153
151
 
154
- # Ensures that an object is (or can be cast into a) Valkyrie::ID
155
- # @return [Valkyrie::ID]
156
- # @raise [ArgumentError]
157
- def validate_id(id)
158
- id = Valkyrie::ID.new(id.to_s) if id.is_a?(String)
159
- raise ArgumentError, 'id must be a Valkyrie::ID' unless id.is_a? Valkyrie::ID
160
- end
152
+ # Ensures that an object is (or can be cast into a) Valkyrie::ID
153
+ # @return [Valkyrie::ID]
154
+ # @raise [ArgumentError]
155
+ def validate_id(id)
156
+ id = Valkyrie::ID.new(id.to_s) if id.is_a?(String)
157
+ raise ArgumentError, 'id must be a Valkyrie::ID' unless id.is_a? Valkyrie::ID
158
+ end
161
159
 
162
- # Resolve a URI for an LDP resource in Fedora and construct a Valkyrie::Resource
163
- # @param uri [RDF::URI]
164
- # @return [Valkyrie::Resource]
165
- # @raise [Valkyrie::Persistence::ObjectNotFoundError]
166
- def resource_from_uri(uri)
167
- resource = Ldp::Resource.for(connection, uri, connection.get(uri))
168
- resource_factory.to_resource(object: resource)
169
- rescue ::Ldp::Gone, ::Ldp::NotFound
170
- raise ::Valkyrie::Persistence::ObjectNotFoundError
171
- end
160
+ # Resolve a URI for an LDP resource in Fedora and construct a Valkyrie::Resource
161
+ # @param uri [RDF::URI]
162
+ # @return [Valkyrie::Resource]
163
+ # @raise [Valkyrie::Persistence::ObjectNotFoundError]
164
+ def resource_from_uri(uri)
165
+ resource = Ldp::Resource.for(connection, uri, connection.get(uri))
166
+ resource_factory.to_resource(object: resource)
167
+ rescue ::Ldp::Gone, ::Ldp::NotFound
168
+ raise ::Valkyrie::Persistence::ObjectNotFoundError
169
+ end
172
170
 
173
- # Ensures that a Valkyrie::Resource has been persisted
174
- # @param resource [Valkyrie::Resource]
175
- # @raise [ArgumentError]
176
- def ensure_persisted(resource)
177
- raise ArgumentError, 'resource is not saved' unless resource.persisted?
178
- end
171
+ # Ensures that a Valkyrie::Resource has been persisted
172
+ # @param resource [Valkyrie::Resource]
173
+ # @raise [ArgumentError]
174
+ def ensure_persisted(resource)
175
+ raise ArgumentError, 'resource is not saved' unless resource.persisted?
176
+ end
179
177
  end
180
178
  end
@@ -62,46 +62,46 @@ module Valkyrie::Persistence::Memory
62
62
 
63
63
  private
64
64
 
65
- def generate_id(resource)
66
- resource.new(id: SecureRandom.uuid)
67
- end
65
+ def generate_id(resource)
66
+ resource.new(id: SecureRandom.uuid)
67
+ end
68
68
 
69
- # Convert all dates to DateTime in the UTC time zone for consistency.
70
- def normalize_dates!(resource)
71
- resource.attributes.each { |k, v| resource.send("#{k}=", normalize_date_values(v)) }
72
- end
69
+ # Convert all dates to DateTime in the UTC time zone for consistency.
70
+ def normalize_dates!(resource)
71
+ resource.attributes.each { |k, v| resource.send("#{k}=", normalize_date_values(v)) }
72
+ end
73
73
 
74
- def normalize_date_values(v)
75
- return v.map { |val| normalize_date_value(val) } if v.is_a?(Array)
76
- normalize_date_value(v)
77
- end
74
+ def normalize_date_values(v)
75
+ return v.map { |val| normalize_date_value(val) } if v.is_a?(Array)
76
+ normalize_date_value(v)
77
+ end
78
78
 
79
- def normalize_date_value(value)
80
- return value.utc if value.is_a?(DateTime)
81
- return value.to_datetime.utc if value.is_a?(Time)
82
- value
83
- end
79
+ def normalize_date_value(value)
80
+ return value.new_offset(0) if value.is_a?(DateTime)
81
+ return value.to_datetime.new_offset(0) if value.is_a?(Time)
82
+ value
83
+ end
84
84
 
85
- # Create a new lock token based on the current timestamp.
86
- def generate_lock_token(resource)
87
- return unless resource.optimistic_locking_enabled?
88
- token = Valkyrie::Persistence::OptimisticLockToken.new(adapter_id: adapter.id, token: Time.now.to_r)
89
- resource.set_value(Valkyrie::Persistence::Attributes::OPTIMISTIC_LOCK, token)
90
- end
85
+ # Create a new lock token based on the current timestamp.
86
+ def generate_lock_token(resource)
87
+ return unless resource.optimistic_locking_enabled?
88
+ token = Valkyrie::Persistence::OptimisticLockToken.new(adapter_id: adapter.id, token: Time.now.to_r)
89
+ resource.set_value(Valkyrie::Persistence::Attributes::OPTIMISTIC_LOCK, token)
90
+ end
91
91
 
92
- # Check whether a resource is current.
93
- def valid_lock?(resource)
94
- return true unless resource.optimistic_locking_enabled?
92
+ # Check whether a resource is current.
93
+ def valid_lock?(resource)
94
+ return true unless resource.optimistic_locking_enabled?
95
95
 
96
- cached_resource = cache[resource.id]
97
- return true if cached_resource.blank?
96
+ cached_resource = cache[resource.id]
97
+ return true if cached_resource.blank?
98
98
 
99
- resource_lock_tokens = resource[Valkyrie::Persistence::Attributes::OPTIMISTIC_LOCK]
100
- resource_value = resource_lock_tokens.find { |lock_token| lock_token.adapter_id == adapter.id }
101
- return true if resource_value.blank?
99
+ resource_lock_tokens = resource[Valkyrie::Persistence::Attributes::OPTIMISTIC_LOCK]
100
+ resource_value = resource_lock_tokens.find { |lock_token| lock_token.adapter_id == adapter.id }
101
+ return true if resource_value.blank?
102
102
 
103
- cached_value = cached_resource[Valkyrie::Persistence::Attributes::OPTIMISTIC_LOCK].first
104
- cached_value == resource_value
105
- end
103
+ cached_value = cached_resource[Valkyrie::Persistence::Attributes::OPTIMISTIC_LOCK].first
104
+ cached_value == resource_value
105
+ end
106
106
  end
107
107
  end
@@ -51,11 +51,9 @@ module Valkyrie::Persistence::Memory
51
51
  def find_many_by_ids(ids:)
52
52
  ids = ids.uniq
53
53
  ids.map do |id|
54
- begin
55
- find_by(id: id)
56
- rescue ::Valkyrie::Persistence::ObjectNotFoundError
57
- nil
58
- end
54
+ find_by(id: id)
55
+ rescue ::Valkyrie::Persistence::ObjectNotFoundError
56
+ nil
59
57
  end.reject(&:nil?)
60
58
  end
61
59
 
@@ -80,7 +78,7 @@ module Valkyrie::Persistence::Memory
80
78
  # @return integer. Count objects in the persistence backend
81
79
  # with the given class.
82
80
  def count_all_of_model(model:)
83
- cache.values.select { |obj| obj.is_a?(model) }.count
81
+ cache.values.count { |obj| obj.is_a?(model) }
84
82
  end
85
83
 
86
84
  # Get all members of a given resource.
@@ -105,11 +103,9 @@ module Valkyrie::Persistence::Memory
105
103
  # `property` property on `resource`. Not necessarily in order.
106
104
  def find_references_by(resource:, property:, model: nil)
107
105
  refs = Array.wrap(resource[property]).map do |id|
108
- begin
109
- find_by(id: id)
110
- rescue ::Valkyrie::Persistence::ObjectNotFoundError
111
- nil
112
- end
106
+ find_by(id: id)
107
+ rescue ::Valkyrie::Persistence::ObjectNotFoundError
108
+ nil
113
109
  end.reject(&:nil?)
114
110
  refs.uniq! unless ordered_property?(resource: resource, property: property)
115
111
  return refs unless model
@@ -159,27 +155,27 @@ module Valkyrie::Persistence::Memory
159
155
 
160
156
  private
161
157
 
162
- # @return [Array<Valkyrie::ID>] a list of the identifiers of the member objects
163
- def member_ids(resource:)
164
- return [] unless resource.respond_to? :member_ids
165
- resource.member_ids || []
166
- end
158
+ # @return [Array<Valkyrie::ID>] a list of the identifiers of the member objects
159
+ def member_ids(resource:)
160
+ return [] unless resource.respond_to? :member_ids
161
+ resource.member_ids || []
162
+ end
167
163
 
168
- # Determine whether or not a value is a Valkyrie ID
169
- # @param [Object] id
170
- # @return [Boolean]
171
- def validate_id(id)
172
- raise ArgumentError, 'id must be a Valkyrie::ID' unless id.is_a? Valkyrie::ID
173
- end
164
+ # Determine whether or not a value is a Valkyrie ID
165
+ # @param [Object] id
166
+ # @return [Boolean]
167
+ def validate_id(id)
168
+ raise ArgumentError, 'id must be a Valkyrie::ID' unless id.is_a? Valkyrie::ID
169
+ end
174
170
 
175
- # Ensure that a given Valkyrie Resource has been persisted
176
- # @param [Valkyrie::Resource] resource
177
- def ensure_persisted(resource)
178
- raise ArgumentError, 'resource is not saved' unless resource.persisted?
179
- end
171
+ # Ensure that a given Valkyrie Resource has been persisted
172
+ # @param [Valkyrie::Resource] resource
173
+ def ensure_persisted(resource)
174
+ raise ArgumentError, 'resource is not saved' unless resource.persisted?
175
+ end
180
176
 
181
- def ordered_property?(resource:, property:)
182
- resource.ordered_attribute?(property)
183
- end
177
+ def ordered_property?(resource:, property:)
178
+ resource.ordered_attribute?(property)
179
+ end
184
180
  end
185
181
  end
@@ -21,65 +21,65 @@ module Valkyrie::Persistence::Postgres
21
21
 
22
22
  private
23
23
 
24
- # Construct a new Valkyrie Resource using the attributes retrieved from the database
25
- # @return [Valkyrie::Resource]
26
- def resource
27
- resource_klass.new(
28
- attributes.merge(
29
- new_record: false,
30
- Valkyrie::Persistence::Attributes::OPTIMISTIC_LOCK => lock_token
31
- )
24
+ # Construct a new Valkyrie Resource using the attributes retrieved from the database
25
+ # @return [Valkyrie::Resource]
26
+ def resource
27
+ resource_klass.new(
28
+ attributes.merge(
29
+ new_record: false,
30
+ Valkyrie::Persistence::Attributes::OPTIMISTIC_LOCK => lock_token
32
31
  )
33
- end
32
+ )
33
+ end
34
34
 
35
- # Construct the optimistic lock token using the adapter and lock version for the Resource
36
- # @return [Valkyrie::Persistence::OptimisticLockToken]
37
- def lock_token
38
- return lock_token_warning unless orm_object.class.column_names.include?("lock_version")
39
- @lock_token ||=
40
- Valkyrie::Persistence::OptimisticLockToken.new(
41
- adapter_id: resource_factory.adapter_id,
42
- token: orm_object.lock_version
43
- )
44
- end
35
+ # Construct the optimistic lock token using the adapter and lock version for the Resource
36
+ # @return [Valkyrie::Persistence::OptimisticLockToken]
37
+ def lock_token
38
+ return lock_token_warning unless orm_object.class.column_names.include?("lock_version")
39
+ @lock_token ||=
40
+ Valkyrie::Persistence::OptimisticLockToken.new(
41
+ adapter_id: resource_factory.adapter_id,
42
+ token: orm_object.lock_version
43
+ )
44
+ end
45
45
 
46
- # Issue a migration warning for previous releases of Valkyrie which did not support optimistic locking
47
- def lock_token_warning
48
- return nil unless resource_klass.optimistic_locking_enabled?
49
- warn "[MIGRATION REQUIRED] You have loaded a resource from the Postgres adapter with " \
50
- "optimistic locking enabled, but the necessary migrations have not been run. \n" \
51
- "Please run `bin/rails valkyrie_engine:install:migrations && bin/rails db:migrate` " \
52
- "to enable this feature for Postgres."
53
- nil
54
- end
46
+ # Issue a migration warning for previous releases of Valkyrie which did not support optimistic locking
47
+ def lock_token_warning
48
+ return nil unless resource_klass.optimistic_locking_enabled?
49
+ warn "[MIGRATION REQUIRED] You have loaded a resource from the Postgres adapter with " \
50
+ "optimistic locking enabled, but the necessary migrations have not been run. \n" \
51
+ "Please run `bin/rails valkyrie_engine:install:migrations && bin/rails db:migrate` " \
52
+ "to enable this feature for Postgres."
53
+ nil
54
+ end
55
55
 
56
- # Retrieve the Class used to construct the Valkyrie Resource
57
- # @return [Class]
58
- def resource_klass
59
- Valkyrie.config.resource_class_resolver.call(internal_resource)
60
- end
56
+ # Retrieve the Class used to construct the Valkyrie Resource
57
+ # @return [Class]
58
+ def resource_klass
59
+ Valkyrie.config.resource_class_resolver.call(internal_resource)
60
+ end
61
61
 
62
- # Access the String for the Valkyrie Resource type within the attributes
63
- # @return [String]
64
- def internal_resource
65
- attributes[:internal_resource]
66
- end
62
+ # Access the String for the Valkyrie Resource type within the attributes
63
+ # @return [String]
64
+ def internal_resource
65
+ attributes[:internal_resource]
66
+ end
67
67
 
68
- # @return [Hash] Valkyrie-style hash of attributes.
69
- def attributes
70
- @attributes ||= orm_object.attributes.merge(rdf_metadata).symbolize_keys
71
- end
68
+ # @return [Hash] Valkyrie-style hash of attributes.
69
+ def attributes
70
+ @attributes ||= orm_object.attributes.merge(rdf_metadata).symbolize_keys
71
+ end
72
72
 
73
- # Generate a Hash derived from Valkyrie Resource metadata encoded in the RDF
74
- # @return [Hash]
75
- def rdf_metadata
76
- @rdf_metadata ||= RDFMetadata.new(orm_object.metadata).result
77
- end
73
+ # Generate a Hash derived from Valkyrie Resource metadata encoded in the RDF
74
+ # @return [Hash]
75
+ def rdf_metadata
76
+ @rdf_metadata ||= RDFMetadata.new(orm_object.metadata).result
77
+ end
78
78
 
79
- # Responsible for converting `metadata` JSON-B field in
80
- # {Valkyrie::Persistence::Postgres::ORM::Resource} into an acceptable hash
81
- # for {Valkyrie::Resource}
82
- class RDFMetadata < ::Valkyrie::Persistence::Shared::JSONValueMapper
83
- end
79
+ # Responsible for converting `metadata` JSON-B field in
80
+ # {Valkyrie::Persistence::Postgres::ORM::Resource} into an acceptable hash
81
+ # for {Valkyrie::Resource}
82
+ class RDFMetadata < ::Valkyrie::Persistence::Shared::JSONValueMapper
83
+ end
84
84
  end
85
85
  end