valkyrie 2.1.0 → 3.0.0.pre.beta.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +71 -36
  3. data/.lando.yml +58 -0
  4. data/.rubocop.yml +11 -1
  5. data/.tool-versions +1 -1
  6. data/CHANGELOG.md +94 -13
  7. data/CONTRIBUTING.md +30 -8
  8. data/README.md +24 -48
  9. data/Rakefile +26 -20
  10. data/db/config.yml +3 -10
  11. data/lib/generators/valkyrie/resource_generator.rb +3 -3
  12. data/lib/valkyrie/change_set.rb +3 -3
  13. data/lib/valkyrie/id.rb +12 -19
  14. data/lib/valkyrie/indexers/access_controls_indexer.rb +17 -17
  15. data/lib/valkyrie/persistence/buffered_persister.rb +2 -2
  16. data/lib/valkyrie/persistence/composite_persister.rb +3 -3
  17. data/lib/valkyrie/persistence/custom_query_container.rb +8 -16
  18. data/lib/valkyrie/persistence/fedora/list_node.rb +43 -43
  19. data/lib/valkyrie/persistence/fedora/metadata_adapter.rb +5 -1
  20. data/lib/valkyrie/persistence/fedora/ordered_list.rb +90 -90
  21. data/lib/valkyrie/persistence/fedora/ordered_reader.rb +5 -5
  22. data/lib/valkyrie/persistence/fedora/permissive_schema.rb +1 -1
  23. data/lib/valkyrie/persistence/fedora/persister/model_converter.rb +15 -16
  24. data/lib/valkyrie/persistence/fedora/persister/orm_converter.rb +14 -19
  25. data/lib/valkyrie/persistence/fedora/persister.rb +83 -83
  26. data/lib/valkyrie/persistence/fedora/query_service.rb +39 -41
  27. data/lib/valkyrie/persistence/memory/persister.rb +51 -35
  28. data/lib/valkyrie/persistence/memory/query_service.rb +26 -30
  29. data/lib/valkyrie/persistence/postgres/orm_converter.rb +52 -52
  30. data/lib/valkyrie/persistence/postgres/persister.rb +4 -1
  31. data/lib/valkyrie/persistence/postgres/query_service.rb +34 -34
  32. data/lib/valkyrie/persistence/shared/json_value_mapper.rb +1 -1
  33. data/lib/valkyrie/persistence/solr/metadata_adapter.rb +15 -3
  34. data/lib/valkyrie/persistence/solr/model_converter.rb +323 -340
  35. data/lib/valkyrie/persistence/solr/orm_converter.rb +4 -4
  36. data/lib/valkyrie/persistence/solr/persister.rb +16 -4
  37. data/lib/valkyrie/persistence/solr/queries/find_by_alternate_identifier_query.rb +1 -1
  38. data/lib/valkyrie/persistence/solr/queries/find_by_id_query.rb +1 -1
  39. data/lib/valkyrie/persistence/solr/queries/find_members_query.rb +1 -1
  40. data/lib/valkyrie/persistence/solr/query_service.rb +12 -12
  41. data/lib/valkyrie/persistence/solr/repository.rb +17 -7
  42. data/lib/valkyrie/resource/access_controls.rb +1 -1
  43. data/lib/valkyrie/resource.rb +0 -1
  44. data/lib/valkyrie/specs/shared_specs/change_set.rb +1 -1
  45. data/lib/valkyrie/specs/shared_specs/file.rb +1 -0
  46. data/lib/valkyrie/specs/shared_specs/persister.rb +22 -4
  47. data/lib/valkyrie/specs/shared_specs/queries.rb +7 -0
  48. data/lib/valkyrie/specs/shared_specs/resource.rb +1 -1
  49. data/lib/valkyrie/specs/shared_specs/storage_adapter.rb +19 -0
  50. data/lib/valkyrie/specs/shared_specs/write_only/metadata_adapter.rb +62 -0
  51. data/lib/valkyrie/specs/shared_specs.rb +2 -0
  52. data/lib/valkyrie/storage/disk.rb +24 -1
  53. data/lib/valkyrie/storage/fedora.rb +17 -17
  54. data/lib/valkyrie/storage_adapter.rb +12 -12
  55. data/lib/valkyrie/types.rb +1 -1
  56. data/lib/valkyrie/version.rb +1 -1
  57. data/lib/valkyrie/vocab/pcdm_use.rb +12 -0
  58. data/lib/valkyrie.rb +13 -27
  59. data/tasks/dev.rake +14 -51
  60. data/valkyrie.gemspec +3 -6
  61. metadata +25 -63
  62. data/.docker-stack/valkyrie-development/docker-compose.yml +0 -53
  63. data/.docker-stack/valkyrie-test/docker-compose.yml +0 -53
  64. data/tasks/docker.rake +0 -31
@@ -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
@@ -17,9 +17,12 @@ module Valkyrie::Persistence::Postgres
17
17
  # @return [Valkyrie::Resource] the persisted/updated resource
18
18
  # @raise [Valkyrie::Persistence::StaleObjectError] raised if the resource
19
19
  # was modified in the database between been read into memory and persisted
20
- def save(resource:)
20
+ def save(resource:, external_resource: false)
21
21
  orm_object = resource_factory.from_resource(resource: resource)
22
22
  orm_object.transaction do
23
+ if !external_resource && resource.persisted? && !orm_object.persisted?
24
+ raise Valkyrie::Persistence::ObjectNotFoundError, "The object #{resource.id} is previously persisted but not found at save time."
25
+ end
23
26
  orm_object.save!
24
27
  if resource.id && resource.id.to_s != orm_object.id
25
28
  raise Valkyrie::Persistence::UnsupportedDatatype,
@@ -251,46 +251,46 @@ module Valkyrie::Persistence::Postgres
251
251
 
252
252
  private
253
253
 
254
- def find_ordered_references_by(resource:, property:, model: nil)
255
- if model
256
- run_query(find_ordered_references_with_type_query, property, resource.id.to_s, model)
257
- else
258
- run_query(find_ordered_references_query, property, resource.id.to_s)
259
- end
254
+ def find_ordered_references_by(resource:, property:, model: nil)
255
+ if model
256
+ run_query(find_ordered_references_with_type_query, property, resource.id.to_s, model)
257
+ else
258
+ run_query(find_ordered_references_query, property, resource.id.to_s)
260
259
  end
260
+ end
261
261
 
262
- def find_unordered_references_by(resource:, property:, model: nil)
263
- if model
264
- run_query(find_references_with_type_query, property, resource.id.to_s, model)
265
- else
266
- run_query(find_references_query, property, resource.id.to_s)
267
- end
262
+ def find_unordered_references_by(resource:, property:, model: nil)
263
+ if model
264
+ run_query(find_references_with_type_query, property, resource.id.to_s, model)
265
+ else
266
+ run_query(find_references_query, property, resource.id.to_s)
268
267
  end
268
+ end
269
269
 
270
- # Determines whether or not an Object is a Valkyrie ID
271
- # @param [Object] id
272
- # @raise [ArgumentError]
273
- def validate_id(id)
274
- raise ArgumentError, 'id must be a Valkyrie::ID' unless id.is_a? Valkyrie::ID
275
- end
270
+ # Determines whether or not an Object is a Valkyrie ID
271
+ # @param [Object] id
272
+ # @raise [ArgumentError]
273
+ def validate_id(id)
274
+ raise ArgumentError, 'id must be a Valkyrie::ID' unless id.is_a? Valkyrie::ID
275
+ end
276
276
 
277
- # Determines whether or not a resource has been persisted
278
- # @param [Object] resource
279
- # @raise [ArgumentError]
280
- def ensure_persisted(resource)
281
- raise ArgumentError, 'resource is not saved' unless resource.persisted?
282
- end
277
+ # Determines whether or not a resource has been persisted
278
+ # @param [Object] resource
279
+ # @raise [ArgumentError]
280
+ def ensure_persisted(resource)
281
+ raise ArgumentError, 'resource is not saved' unless resource.persisted?
282
+ end
283
283
 
284
- # Accesses the data type in PostgreSQL used for the primary key
285
- # (For example, a UUID)
286
- # @see https://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/SchemaCache.html#method-i-columns_hash
287
- # @return [Symbol]
288
- def id_type
289
- @id_type ||= orm_class.columns_hash["id"].type
290
- end
284
+ # Accesses the data type in PostgreSQL used for the primary key
285
+ # (For example, a UUID)
286
+ # @see https://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/SchemaCache.html#method-i-columns_hash
287
+ # @return [Symbol]
288
+ def id_type
289
+ @id_type ||= orm_class.columns_hash["id"].type
290
+ end
291
291
 
292
- def ordered_property?(resource:, property:)
293
- resource.ordered_attribute?(property)
294
- end
292
+ def ordered_property?(resource:, property:)
293
+ resource.ordered_attribute?(property)
294
+ end
295
295
  end
296
296
  end
@@ -152,7 +152,7 @@ module Valkyrie::Persistence::Shared
152
152
  # Generates a Time object in the UTC from the datestamp string value
153
153
  # @return [Time]
154
154
  def result
155
- DateTime.iso8601(value).utc
155
+ DateTime.iso8601(value).new_offset(0)
156
156
  end
157
157
  end
158
158
  end
@@ -27,18 +27,30 @@ module Valkyrie::Persistence::Solr
27
27
  # )
28
28
  # )
29
29
  class MetadataAdapter
30
- attr_reader :connection, :resource_indexer
30
+ attr_reader :connection, :resource_indexer, :write_only
31
31
  # @param connection [RSolr::Client] The RSolr connection to index to.
32
32
  # @param resource_indexer [Class, #to_solr] An indexer which is able to
33
33
  # receive a `resource` argument and then has an instance method `#to_solr`
34
- def initialize(connection:, resource_indexer: NullIndexer)
34
+ # @param write_only [Boolean] If true act as a write only adapter.
35
+ # @param soft_commit [Boolean] If false, don't soft commit.
36
+ def initialize(connection:, resource_indexer: NullIndexer, write_only: false, soft_commit: true)
35
37
  @connection = connection
36
38
  @resource_indexer = resource_indexer
39
+ @write_only = write_only
40
+ @soft_commit = soft_commit
37
41
  end
38
42
 
39
43
  # @return [Valkyrie::Persistence::Solr::Persister] The solr persister.
40
44
  def persister
41
- Valkyrie::Persistence::Solr::Persister.new(adapter: self)
45
+ @persister ||= Valkyrie::Persistence::Solr::Persister.new(adapter: self)
46
+ end
47
+
48
+ def write_only?
49
+ write_only
50
+ end
51
+
52
+ def soft_commit?
53
+ @soft_commit
42
54
  end
43
55
 
44
56
  # @return [Valkyrie::Persistence::Solr::QueryService] The solr query