valkyrie 1.2.0.rc1 → 1.2.0.rc2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +8 -0
  3. data/README.md +12 -4
  4. data/lib/valkyrie/persistence/composite_persister.rb +1 -1
  5. data/lib/valkyrie/persistence/fedora/list_node.rb +42 -3
  6. data/lib/valkyrie/persistence/fedora/metadata_adapter.rb +26 -0
  7. data/lib/valkyrie/persistence/fedora/ordered_list.rb +36 -5
  8. data/lib/valkyrie/persistence/fedora/ordered_reader.rb +6 -0
  9. data/lib/valkyrie/persistence/fedora/permissive_schema.rb +20 -1
  10. data/lib/valkyrie/persistence/fedora/persister.rb +33 -4
  11. data/lib/valkyrie/persistence/fedora/persister/alternate_identifier.rb +6 -0
  12. data/lib/valkyrie/persistence/fedora/persister/model_converter.rb +254 -4
  13. data/lib/valkyrie/persistence/fedora/persister/orm_converter.rb +250 -3
  14. data/lib/valkyrie/persistence/fedora/persister/resource_factory.rb +6 -0
  15. data/lib/valkyrie/persistence/fedora/query_service.rb +22 -4
  16. data/lib/valkyrie/persistence/memory/metadata_adapter.rb +2 -0
  17. data/lib/valkyrie/persistence/memory/persister.rb +11 -3
  18. data/lib/valkyrie/persistence/memory/query_service.rb +11 -0
  19. data/lib/valkyrie/persistence/postgres/metadata_adapter.rb +2 -0
  20. data/lib/valkyrie/persistence/postgres/orm.rb +4 -0
  21. data/lib/valkyrie/persistence/postgres/orm_converter.rb +62 -2
  22. data/lib/valkyrie/persistence/postgres/persister.rb +18 -7
  23. data/lib/valkyrie/persistence/postgres/query_service.rb +103 -11
  24. data/lib/valkyrie/persistence/postgres/resource_converter.rb +10 -0
  25. data/lib/valkyrie/persistence/postgres/resource_factory.rb +3 -0
  26. data/lib/valkyrie/persistence/solr/composite_indexer.rb +10 -0
  27. data/lib/valkyrie/persistence/solr/metadata_adapter.rb +7 -0
  28. data/lib/valkyrie/persistence/solr/model_converter.rb +137 -0
  29. data/lib/valkyrie/persistence/solr/orm_converter.rb +168 -0
  30. data/lib/valkyrie/persistence/solr/persister.rb +13 -5
  31. data/lib/valkyrie/persistence/solr/queries.rb +1 -0
  32. data/lib/valkyrie/persistence/solr/queries/default_paginator.rb +11 -1
  33. data/lib/valkyrie/persistence/solr/queries/find_all_query.rb +12 -0
  34. data/lib/valkyrie/persistence/solr/queries/find_by_alternate_identifier_query.rb +12 -0
  35. data/lib/valkyrie/persistence/solr/queries/find_by_id_query.rb +11 -0
  36. data/lib/valkyrie/persistence/solr/queries/find_inverse_references_query.rb +13 -0
  37. data/lib/valkyrie/persistence/solr/queries/find_many_by_ids_query.rb +9 -0
  38. data/lib/valkyrie/persistence/solr/queries/find_members_query.rb +23 -0
  39. data/lib/valkyrie/persistence/solr/queries/find_ordered_references_query.rb +50 -0
  40. data/lib/valkyrie/persistence/solr/queries/find_references_query.rb +15 -0
  41. data/lib/valkyrie/persistence/solr/query_service.rb +47 -14
  42. data/lib/valkyrie/persistence/solr/repository.rb +21 -4
  43. data/lib/valkyrie/persistence/solr/resource_factory.rb +2 -0
  44. data/lib/valkyrie/resource.rb +1 -0
  45. data/lib/valkyrie/specs/shared_specs.rb +1 -0
  46. data/lib/valkyrie/specs/shared_specs/persister.rb +92 -2
  47. data/lib/valkyrie/specs/shared_specs/queries.rb +12 -0
  48. data/lib/valkyrie/specs/shared_specs/solr_indexer.rb +40 -0
  49. data/lib/valkyrie/storage/fedora.rb +0 -2
  50. data/lib/valkyrie/version.rb +1 -1
  51. metadata +4 -2
@@ -7,14 +7,20 @@ module Valkyrie::Persistence::Fedora
7
7
  require 'valkyrie/persistence/fedora/persister/model_converter'
8
8
  require 'valkyrie/persistence/fedora/persister/orm_converter'
9
9
  attr_reader :adapter
10
+
11
+ # @param [Valkyrie::Persistence::Fedora::MetadataAdapter] adapter
10
12
  def initialize(adapter:)
11
13
  @adapter = adapter
12
14
  end
13
15
 
16
+ # Construct a LDP::Container::Basic object for a Valkyrie Resource
17
+ # @return [Valkyrie::Resource] resource
14
18
  def from_resource(resource:)
15
19
  ModelConverter.new(resource: resource, adapter: adapter).convert
16
20
  end
17
21
 
22
+ # Construct a Valkyrie::Resource object for a Valkyrie Resource
23
+ # @return [LDP::Container::Basic] object
18
24
  def to_resource(object:)
19
25
  OrmConverter.new(object: object, adapter: adapter).convert
20
26
  end
@@ -47,6 +47,9 @@ module Valkyrie::Persistence::Fedora
47
47
  end
48
48
  end
49
49
 
50
+ # Specify the URIs used in triples directly related to the requested resource
51
+ # @see https://wiki.duraspace.org/display/FEDORA4x/RESTful+HTTP+API#RESTfulHTTPAPI-GETRetrievethecontentoftheresource
52
+ # @return [Array<RDF::URI>]
50
53
  def include_uris
51
54
  [
52
55
  ::RDF::Vocab::Fcrepo4.InboundReferences
@@ -64,8 +67,6 @@ module Valkyrie::Persistence::Fedora
64
67
  end
65
68
 
66
69
  # (see Valkyrie::Persistence::Memory::QueryService#find_all)
67
- #
68
- # @note This requires iterating over every resource in Fedora.
69
70
  def find_all
70
71
  resource = Ldp::Resource.for(connection, adapter.base_path, connection.get(adapter.base_path))
71
72
  ids = resource.graph.query([nil, RDF::Vocab::LDP.contains, nil]).map(&:object).map { |x| adapter.uri_to_id(x) }
@@ -77,8 +78,6 @@ module Valkyrie::Persistence::Fedora
77
78
  end
78
79
 
79
80
  # (see Valkyrie::Persistence::Memory::QueryService#find_all_of_model)
80
- #
81
- # @note This requires iterating over every resource in Fedora.
82
81
  def find_all_of_model(model:)
83
82
  find_all.select do |m|
84
83
  m.is_a?(model)
@@ -92,6 +91,11 @@ module Valkyrie::Persistence::Fedora
92
91
  end
93
92
  end
94
93
 
94
+ # Retrieves the RDF graph for the LDP container for a resource
95
+ # This includes inbound links
96
+ # @see https://wiki.duraspace.org/display/FEDORA4x/RESTful+HTTP+API#RESTfulHTTPAPI-GETRetrievethecontentoftheresource
97
+ # @param id [Valkyrie::ID]
98
+ # @return [Faraday::Response]
95
99
  def content_with_inbound(id:)
96
100
  uri = adapter.id_to_uri(id)
97
101
  connection.get(uri) do |req|
@@ -102,6 +106,9 @@ module Valkyrie::Persistence::Fedora
102
106
  end
103
107
 
104
108
  # (see Valkyrie::Persistence::Memory::QueryService#find_inverse_references_by)
109
+ # Find all resources referencing a given resource (e. g. parents)
110
+ # *This is done by iterating through the ID of each resource referencing the resource in the query, and requesting each resource over the HTTP*
111
+ # *Also, an initial request is made to find the URIs of the resources referencing the resource in the query*
105
112
  def find_inverse_references_by(resource:, property:)
106
113
  ensure_persisted(resource)
107
114
  content = content_with_inbound(id: resource.id)
@@ -112,17 +119,25 @@ module Valkyrie::Persistence::Fedora
112
119
  end
113
120
  end
114
121
 
122
+ # (see Valkyrie::Persistence::Memory::QueryService#custom_queries)
115
123
  def custom_queries
116
124
  @custom_queries ||= ::Valkyrie::Persistence::CustomQueryContainer.new(query_service: self)
117
125
  end
118
126
 
119
127
  private
120
128
 
129
+ # Ensures that an object is (or can be cast into a) Valkyrie::ID
130
+ # @return [Valkyrie::ID]
131
+ # @raise [ArgumentError]
121
132
  def validate_id(id)
122
133
  id = Valkyrie::ID.new(id.to_s) if id.is_a?(String)
123
134
  raise ArgumentError, 'id must be a Valkyrie::ID' unless id.is_a? Valkyrie::ID
124
135
  end
125
136
 
137
+ # Resolve a URI for an LDP resource in Fedora and construct a Valkyrie::Resource
138
+ # @param uri [RDF::URI]
139
+ # @return [Valkyrie::Resource]
140
+ # @raise [Valkyrie::Persistence::ObjectNotFoundError]
126
141
  def resource_from_uri(uri)
127
142
  resource = Ldp::Resource.for(connection, uri, connection.get(uri))
128
143
  resource_factory.to_resource(object: resource)
@@ -130,6 +145,9 @@ module Valkyrie::Persistence::Fedora
130
145
  raise ::Valkyrie::Persistence::ObjectNotFoundError
131
146
  end
132
147
 
148
+ # Ensures that a Valkyrie::Resource has been persisted
149
+ # @param resource [Valkyrie::Resource]
150
+ # @raise [ArgumentError]
133
151
  def ensure_persisted(resource)
134
152
  raise ArgumentError, 'resource is not saved' unless resource.persisted?
135
153
  end
@@ -20,10 +20,12 @@ module Valkyrie::Persistence::Memory
20
20
  @query_service ||= Valkyrie::Persistence::Memory::QueryService.new(adapter: self)
21
21
  end
22
22
 
23
+ # @return [Hash] The in-memory data cache.
23
24
  def cache
24
25
  @cache ||= {}
25
26
  end
26
27
 
28
+ # @return [Valkyrie::ID] Identifier for this metadata adapter.
27
29
  def id
28
30
  @id ||= Valkyrie::ID.new(Digest::MD5.hexdigest(self.class.to_s))
29
31
  end
@@ -14,11 +14,13 @@ module Valkyrie::Persistence::Memory
14
14
  @adapter = adapter
15
15
  end
16
16
 
17
+ # Save a single resource.
17
18
  # @param resource [Valkyrie::Resource] The resource to save.
18
19
  # @return [Valkyrie::Resource] The resource with an `#id` value generated by the
19
20
  # persistence backend.
21
+ # @raise [Valkyrie::Persistence::StaleObjectError]
20
22
  def save(resource:)
21
- raise Valkyrie::Persistence::StaleObjectError, resource.id unless valid_lock?(resource)
23
+ raise Valkyrie::Persistence::StaleObjectError, "The object #{resource.id} has been updated by another process." unless valid_lock?(resource)
22
24
 
23
25
  # duplicate the resource so we are not creating side effects on the caller's resource
24
26
  internal_resource = resource.dup
@@ -32,25 +34,28 @@ module Valkyrie::Persistence::Memory
32
34
  cache[internal_resource.id] = internal_resource
33
35
  end
34
36
 
37
+ # Save a batch of resources.
35
38
  # @param resources [Array<Valkyrie::Resource>] List of resources to save.
36
39
  # @return [Array<Valkyrie::Resource>] List of resources with an `#id` value
37
40
  # generated by the persistence backend.
41
+ # @raise [Valkyrie::Persistence::StaleObjectError]
38
42
  def save_all(resources:)
39
43
  resources.map do |resource|
40
44
  save(resource: resource)
41
45
  end
42
46
  rescue Valkyrie::Persistence::StaleObjectError
43
47
  # Re-raising with no error message to prevent confusion
44
- raise Valkyrie::Persistence::StaleObjectError
48
+ raise Valkyrie::Persistence::StaleObjectError, "One or more resources have been updated by another process."
45
49
  end
46
50
 
51
+ # Delete a resource.
47
52
  # @param resource [Valkyrie::Resource] The resource to delete from the persistence
48
53
  # backend.
49
54
  def delete(resource:)
50
55
  cache.delete(resource.id)
51
56
  end
52
57
 
53
- # Wipes all data in the persistence backend.
58
+ # Removes all data from the persistence backend.
54
59
  def wipe!
55
60
  cache.clear
56
61
  end
@@ -61,6 +66,7 @@ module Valkyrie::Persistence::Memory
61
66
  resource.new(id: SecureRandom.uuid)
62
67
  end
63
68
 
69
+ # Convert all dates to DateTime in the UTC time zone for consistency.
64
70
  def normalize_dates!(resource)
65
71
  resource.attributes.each { |k, v| resource.send("#{k}=", normalize_date_values(v)) }
66
72
  end
@@ -76,12 +82,14 @@ module Valkyrie::Persistence::Memory
76
82
  value
77
83
  end
78
84
 
85
+ # Create a new lock token based on the current timestamp.
79
86
  def generate_lock_token(resource)
80
87
  return unless resource.optimistic_locking_enabled?
81
88
  token = Valkyrie::Persistence::OptimisticLockToken.new(adapter_id: adapter.id, token: Time.now.to_r)
82
89
  resource.send("#{Valkyrie::Persistence::Attributes::OPTIMISTIC_LOCK}=", token)
83
90
  end
84
91
 
92
+ # Check whether a resource is current.
85
93
  def valid_lock?(resource)
86
94
  return true unless resource.optimistic_locking_enabled?
87
95
 
@@ -15,6 +15,7 @@ module Valkyrie::Persistence::Memory
15
15
  @query_handlers = []
16
16
  end
17
17
 
18
+ # Get a single resource by ID.
18
19
  # @param id [Valkyrie::ID] The ID to query for.
19
20
  # @raise [Valkyrie::Persistence::ObjectNotFoundError] Raised when the ID
20
21
  # isn't in the persistence backend.
@@ -26,6 +27,7 @@ module Valkyrie::Persistence::Memory
26
27
  cache[id] || raise(::Valkyrie::Persistence::ObjectNotFoundError)
27
28
  end
28
29
 
30
+ # Get a single resource by `alternate_identifier`.
29
31
  # @param alternate_identifier [Valkyrie::ID] The alternate identifier to query for.
30
32
  # @raise [Valkyrie::Persistence::ObjectNotFoundError] Raised when the alternate identifier
31
33
  # isn't in the persistence backend.
@@ -37,6 +39,7 @@ module Valkyrie::Persistence::Memory
37
39
  cache.select { |_key, resource| resource['alternate_ids'].include?(alternate_identifier) }.values.first || raise(::Valkyrie::Persistence::ObjectNotFoundError)
38
40
  end
39
41
 
42
+ # Get a batch of resources by ID.
40
43
  # @param ids [Array<Valkyrie::ID, String>] The IDs to query for.
41
44
  # @raise [ArgumentError] Raised when any ID is not a String or a Valkyrie::ID
42
45
  # @return [Array<Valkyrie::Resource>] All requested objects that were found
@@ -50,11 +53,13 @@ module Valkyrie::Persistence::Memory
50
53
  end.reject(&:nil?)
51
54
  end
52
55
 
56
+ # Get all objects.
53
57
  # @return [Array<Valkyrie::Resource>] All objects in the persistence backend.
54
58
  def find_all
55
59
  cache.values
56
60
  end
57
61
 
62
+ # Get all objects of a given model.
58
63
  # @param model [Class] Class to query for.
59
64
  # @return [Array<Valkyrie::Resource>] All objects in the persistence backend
60
65
  # with the given class.
@@ -64,6 +69,7 @@ module Valkyrie::Persistence::Memory
64
69
  end
65
70
  end
66
71
 
72
+ # Get all members of a given resource.
67
73
  # @param resource [Valkyrie::Resource] Model whose members are being searched for.
68
74
  # @param model [Class] Class to query for. (optional)
69
75
  # @return [Array<Valkyrie::Resource>] child objects of type `model` referenced by
@@ -76,6 +82,7 @@ module Valkyrie::Persistence::Memory
76
82
  result.select { |obj| obj.is_a?(model) }
77
83
  end
78
84
 
85
+ # Get all resources referenced from a resource with a given property.
79
86
  # @param resource [Valkyrie::Resource] Model whose property is being searched.
80
87
  # @param property [Symbol] Property which, on the `resource`, contains {Valkyrie::ID}s which are
81
88
  # to be de-referenced.
@@ -87,6 +94,7 @@ module Valkyrie::Persistence::Memory
87
94
  end
88
95
  end
89
96
 
97
+ # Get all resources which link to a resource with a given property.
90
98
  # @param resource [Valkyrie::Resource] The resource which is being referenced by
91
99
  # other resources.
92
100
  # @param property [Symbol] The property which, on other resources, is
@@ -106,6 +114,7 @@ module Valkyrie::Persistence::Memory
106
114
  end
107
115
  end
108
116
 
117
+ # Find all parents of a given resource.
109
118
  # @param resource [Valkyrie::Resource] The resource whose parents are being searched
110
119
  # for.
111
120
  # @return [Array<Valkyrie::Resource>] All resources which are parents of the given
@@ -117,6 +126,8 @@ module Valkyrie::Persistence::Memory
117
126
  end
118
127
  end
119
128
 
129
+ # Get the set of custom queries configured for this query service.
130
+ # @return [Valkyrie::Persistence::CustomQueryContainer] Container of custom queries
120
131
  def custom_queries
121
132
  @custom_queries ||= ::Valkyrie::Persistence::CustomQueryContainer.new(query_service: self)
122
133
  end
@@ -26,6 +26,8 @@ module Valkyrie::Persistence::Postgres
26
26
  @resource_factory ||= Valkyrie::Persistence::Postgres::ResourceFactory.new(adapter: self)
27
27
  end
28
28
 
29
+ # Construct a Valkyrie ID object using an MD5 hash generated from the database URL
30
+ # @return [Valkyrie::ID]
29
31
  def id
30
32
  @id ||= begin
31
33
  to_hash = "#{resource_factory.orm_class.connection_config['host']}:#{resource_factory.orm_class.connection_config['database']}"
@@ -3,6 +3,10 @@ require 'valkyrie/persistence/postgres/orm/resource'
3
3
  module Valkyrie::Persistence::Postgres
4
4
  # Namespace for ActiveRecord access in Postgres adapter.
5
5
  module ORM
6
+ # Provides the name prefix for the ActiveRecord database table name
7
+ # (Maps to the data model for persistence)
8
+ # @see https://api.rubyonrails.org/classes/ActiveRecord/ModelSchema.html#method-c-table_name_prefix
9
+ # @return [String]
6
10
  def self.table_name_prefix
7
11
  'orm_'
8
12
  end
@@ -4,6 +4,9 @@ module Valkyrie::Persistence::Postgres
4
4
  # {Valkyrie::Persistence::Postgres::ORM::Resource} to a {Valkyrie::Resource}
5
5
  class ORMConverter
6
6
  attr_reader :orm_object, :resource_factory
7
+
8
+ # @param [ORM::Resource] orm_object
9
+ # @param [ResourceFactory] resource_factory
7
10
  def initialize(orm_object, resource_factory:)
8
11
  @orm_object = orm_object
9
12
  @resource_factory = resource_factory
@@ -11,12 +14,15 @@ module Valkyrie::Persistence::Postgres
11
14
 
12
15
  # Create a new instance of the class described in attributes[:internal_resource]
13
16
  # and send it all the attributes that @orm_object has
17
+ # @return [Valkyrie::Resource]
14
18
  def convert!
15
19
  @resource ||= resource
16
20
  end
17
21
 
18
22
  private
19
23
 
24
+ # Construct a new Valkyrie Resource using the attributes retrieved from the database
25
+ # @return [Valkyrie::Resource]
20
26
  def resource
21
27
  resource_klass.new(
22
28
  attributes.merge(
@@ -26,6 +32,8 @@ module Valkyrie::Persistence::Postgres
26
32
  )
27
33
  end
28
34
 
35
+ # Construct the optimistic lock token using the adapter and lock version for the Resource
36
+ # @return [Valkyrie::Persistence::OptimisticLockToken]
29
37
  def lock_token
30
38
  return lock_token_warning unless orm_object.class.column_names.include?("lock_version")
31
39
  @lock_token ||=
@@ -35,6 +43,7 @@ module Valkyrie::Persistence::Postgres
35
43
  )
36
44
  end
37
45
 
46
+ # Issue a migration warning for previous releases of Valkyrie which did not support optimistic locking
38
47
  def lock_token_warning
39
48
  return nil unless resource_klass.optimistic_locking_enabled?
40
49
  warn "[MIGRATION REQUIRED] You have loaded a resource from the Postgres adapter with " \
@@ -44,10 +53,14 @@ module Valkyrie::Persistence::Postgres
44
53
  nil
45
54
  end
46
55
 
56
+ # Retrieve the Class used to construct the Valkyrie Resource
57
+ # @return [Class]
47
58
  def resource_klass
48
59
  internal_resource.constantize
49
60
  end
50
61
 
62
+ # Access the String for the Valkyrie Resource type within the attributes
63
+ # @return [String]
51
64
  def internal_resource
52
65
  attributes[:internal_resource]
53
66
  end
@@ -57,6 +70,8 @@ module Valkyrie::Persistence::Postgres
57
70
  @attributes ||= orm_object.attributes.merge(rdf_metadata).symbolize_keys
58
71
  end
59
72
 
73
+ # Generate a Hash derived from Valkyrie Resource metadata encoded in the RDF
74
+ # @return [Hash]
60
75
  def rdf_metadata
61
76
  @rdf_metadata ||= RDFMetadata.new(orm_object.metadata).result
62
77
  end
@@ -66,12 +81,16 @@ module Valkyrie::Persistence::Postgres
66
81
  # for {Valkyrie::Resource}
67
82
  class RDFMetadata
68
83
  attr_reader :metadata
84
+
85
+ # @param [Hash] metadata
69
86
  def initialize(metadata)
70
87
  # nil hash values are handled by the default state in dry-types
71
88
  # anyways, so don't bother processing them here.
72
89
  @metadata = metadata.compact
73
90
  end
74
91
 
92
+ # Convert the database attribute values and map these to the existing keys in the Valkyrie Resource metadata
93
+ # @return [Hash]
75
94
  def result
76
95
  Hash[
77
96
  metadata.map do |key, value|
@@ -80,16 +99,26 @@ module Valkyrie::Persistence::Postgres
80
99
  ]
81
100
  end
82
101
 
102
+ # Abstract base class for mapping PostgreSQL database field values to Valkyrie Resource attributes
83
103
  class PostgresValue < ::Valkyrie::ValueMapper
84
104
  end
105
+
85
106
  # Converts {RDF::Literal} typed-literals from JSON-LD stored into an
86
107
  # {RDF::Literal}
87
108
  class HashValue < ::Valkyrie::ValueMapper
88
109
  PostgresValue.register(self)
110
+
111
+ # Determines whether or not a value is a Hash containing the key "@value"
112
+ # @param [Object] value
113
+ # @return [Boolean]
89
114
  def self.handles?(value)
90
115
  value.is_a?(Hash) && value["@value"]
91
116
  end
92
117
 
118
+ # Constructs a RDF::Literal object using the Object keyed to "@value"
119
+ # in the value Hash, as well as the language keyed to "@language" and
120
+ # datatype keyed to "@type"
121
+ # @return [RDF::Literal]
93
122
  def result
94
123
  RDF::Literal.new(value["@value"],
95
124
  language: value["@language"],
@@ -100,10 +129,16 @@ module Valkyrie::Persistence::Postgres
100
129
  # Converts stored IDs into {Valkyrie::ID}s
101
130
  class IDValue < ::Valkyrie::ValueMapper
102
131
  PostgresValue.register(self)
132
+
133
+ # Determines whether or not a value is a Hash containing the key "id" (excluding those storing the Valkyrie Resource type)
134
+ # @param [Object] value
135
+ # @return [Boolean]
103
136
  def self.handles?(value)
104
137
  value.is_a?(Hash) && value["id"] && !value["internal_resource"]
105
138
  end
106
139
 
140
+ # Constructs a Valkyrie::ID object using the String keyed to "id" in the value
141
+ # @return [Valkyrie::ID]
107
142
  def result
108
143
  Valkyrie::ID.new(value["id"])
109
144
  end
@@ -112,10 +147,16 @@ module Valkyrie::Persistence::Postgres
112
147
  # Converts stored URIs into {RDF::URI}s
113
148
  class URIValue < ::Valkyrie::ValueMapper
114
149
  PostgresValue.register(self)
150
+
151
+ # Determines whether or not a value is a Hash containing the key "@id"
152
+ # @param [Object] value
153
+ # @return [Boolean]
115
154
  def self.handles?(value)
116
155
  value.is_a?(Hash) && value["@id"]
117
156
  end
118
157
 
158
+ # Constructs a RDF::URI object using the URI keyed to @id in the value
159
+ # @return [RDF::URI]
119
160
  def result
120
161
  ::RDF::URI.new(value["@id"])
121
162
  end
@@ -124,10 +165,16 @@ module Valkyrie::Persistence::Postgres
124
165
  # Converts nested records into {Valkyrie::Resource}s
125
166
  class NestedRecord < ::Valkyrie::ValueMapper
126
167
  PostgresValue.register(self)
168
+
169
+ # Determines whether or not a value is a Hash containing multiple keys
170
+ # @param [Object] value
171
+ # @return [Boolean]
127
172
  def self.handles?(value)
128
173
  value.is_a?(Hash) && value.keys.length > 1
129
174
  end
130
175
 
176
+ # Generates a Hash derived from the RDFMetadata for the value
177
+ # @return [Hash]
131
178
  def result
132
179
  RDFMetadata.new(value).result.symbolize_keys
133
180
  end
@@ -136,13 +183,19 @@ module Valkyrie::Persistence::Postgres
136
183
  # Handles iterating over arrays of values and converting each value.
137
184
  class EnumeratorValue < ::Valkyrie::ValueMapper
138
185
  PostgresValue.register(self)
186
+
187
+ # Determines whether or not a value has enumerable behavior
188
+ # @param [Object] value
189
+ # @return [Boolean]
139
190
  def self.handles?(value)
140
191
  value.respond_to?(:each)
141
192
  end
142
193
 
194
+ # Convert the elements in the enumerable value in Valkyrie attribute values
195
+ # Casts single-valued arrays to the first value, letting Types::Set and
196
+ # Types::Array handle converting it back.
197
+ # @return [Array<Object>]
143
198
  def result
144
- # Cast single-valued arrays to the first value, let Types::Set and
145
- # Types::Array handle converting it back.
146
199
  if value.length == 1
147
200
  calling_mapper.for(value.first).result
148
201
  else
@@ -156,6 +209,11 @@ module Valkyrie::Persistence::Postgres
156
209
  # Converts Date strings to `DateTime`
157
210
  class DateValue < ::Valkyrie::ValueMapper
158
211
  PostgresValue.register(self)
212
+
213
+ # Determines whether or not a value is an ISO 8601 datestamp String
214
+ # e. g. 1970-01-01
215
+ # @param [Object] value
216
+ # @return [Boolean]
159
217
  def self.handles?(value)
160
218
  return false unless value.is_a?(String)
161
219
  return false unless value[4] == "-"
@@ -166,6 +224,8 @@ module Valkyrie::Persistence::Postgres
166
224
  false
167
225
  end
168
226
 
227
+ # Generates a Time object in the UTC from the datestamp string value
228
+ # @return [Time]
169
229
  def result
170
230
  DateTime.iso8601(value).utc
171
231
  end