valkyrie 3.4.0 → 3.5.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/.circleci/config.yml +1 -1
- data/.lando.yml +1 -1
- data/CHANGELOG.md +8 -0
- data/lib/valkyrie/persistence/fedora/persister/orm_converter.rb +3 -2
- data/lib/valkyrie/persistence/fedora/query_service.rb +1 -0
- data/lib/valkyrie/persistence/shared/json_value_mapper.rb +1 -0
- data/lib/valkyrie/specs/shared_specs/queries.rb +10 -0
- data/lib/valkyrie/specs/shared_specs/storage_adapter.rb +20 -4
- data/lib/valkyrie/storage/disk.rb +10 -3
- data/lib/valkyrie/storage/fedora.rb +16 -7
- data/lib/valkyrie/storage/memory.rb +9 -2
- data/lib/valkyrie/storage/versioned_disk.rb +18 -7
- data/lib/valkyrie/version.rb +1 -1
- data/lib/valkyrie.rb +6 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7ba113a4df1fa120076006223d629be9d186f96736fbb363781bc78f6c038013
|
4
|
+
data.tar.gz: 89e485a082def7836f884354b136c081496b5a9f36e98c2f9f31127dc053ab28
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3d3537379fb136ec2ca843e2dd13d85a22c46a9c74d94f1ca3cfb1ab32f4a193394ab1ff9deae649939e3260b0ba9e9d8f423f3fb87d40043d107ff646fb74bc
|
7
|
+
data.tar.gz: 4a908d4d2574d5017bc81af1683d714b028b5d1ab17e086ff0f8ea6d0a764348f3efd3f308aeedac4623956ccfce915a5c5d611ab84d7e9e2d08c22d5afe623a
|
data/.circleci/config.yml
CHANGED
@@ -28,7 +28,7 @@ jobs:
|
|
28
28
|
environment:
|
29
29
|
CATALINA_OPTS: "-Djava.awt.headless=true -Dfile.encoding=UTF-8 -server -Xms512m -Xmx1024m -XX:NewSize=256m -XX:MaxNewSize=256m -XX:PermSize=256m -XX:MaxPermSize=256m -XX:+DisableExplicitGC"
|
30
30
|
JAVA_OPTIONS: "-Djetty.http.port=8998 -Dfcrepo.dynamic.jms.port=61618 -Dfcrepo.dynamic.stomp.port=61614"
|
31
|
-
- image: fcrepo/fcrepo:6.
|
31
|
+
- image: fcrepo/fcrepo:6.5.1-RC3-tomcat9
|
32
32
|
environment:
|
33
33
|
CATALINA_OPTS: "-Djava.awt.headless=true -Dfile.encoding=UTF-8 -server -Xms512m -Xmx1024m -XX:NewSize=256m -XX:MaxNewSize=256m -XX:PermSize=256m -XX:MaxPermSize=256m -XX:+DisableExplicitGC -Dorg.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true"
|
34
34
|
JAVA_OPTS: "-Djetty.http.port=8978 -Dfcrepo.dynamic.jms.port=61619 -Dfcrepo.dynamic.stomp.port=61615 -Dorg.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true"
|
data/.lando.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
# v3.5.0 2024-12-10
|
2
|
+
|
3
|
+
* Provides new boolean configuration setting `auto_cast_iso8601_as_datetime` ([dchandekstark](https://github.com/dchandekstark))
|
4
|
+
* Align behavior of server managed properties with Fedora. ([dlpierce](https://github.com/dlpierce))
|
5
|
+
* Check for nil id to avoid InvalidURIError ([dlpierce](https://github.com/dlpierce))
|
6
|
+
* Support Fedora 6.5 ([dlpierce](https://github.com/dlpierce))
|
7
|
+
* Make storage adapters report their protocol string ([dlpierce](https://github.com/dlpierce))
|
8
|
+
|
1
9
|
# v3.4.0 2024-10-11
|
2
10
|
|
3
11
|
## Changes since last release
|
@@ -105,7 +105,8 @@ module Valkyrie::Persistence::Fedora
|
|
105
105
|
# @param [Property] value
|
106
106
|
# @return [Boolean]
|
107
107
|
def self.handles?(value)
|
108
|
-
value.statement.
|
108
|
+
value.statement.predicate == RDF.type &&
|
109
|
+
value.statement.object.to_s.start_with?('http://www.w3.org/ns/ldp#', 'http://fedora.info/definitions/v4/repository#')
|
109
110
|
end
|
110
111
|
|
111
112
|
# Provide the NullApplicator Class for any Property in a deny listed namespace
|
@@ -562,7 +563,7 @@ module Valkyrie::Persistence::Fedora
|
|
562
563
|
# @return [Array<String>]
|
563
564
|
def denylist
|
564
565
|
[
|
565
|
-
"http://fedora.info/definitions",
|
566
|
+
"http://fedora.info/definitions/v4/repository#",
|
566
567
|
"http://www.iana.org/assignments/relation/last"
|
567
568
|
]
|
568
569
|
end
|
@@ -162,6 +162,7 @@ module Valkyrie::Persistence::Fedora
|
|
162
162
|
# @return [Valkyrie::Resource]
|
163
163
|
# @raise [Valkyrie::Persistence::ObjectNotFoundError]
|
164
164
|
def resource_from_uri(uri)
|
165
|
+
raise ::Valkyrie::Persistence::ObjectNotFoundError if uri.nil?
|
165
166
|
resource = Ldp::Resource.for(connection, uri, connection.get(uri))
|
166
167
|
resource_factory.to_resource(object: resource)
|
167
168
|
rescue ::Ldp::Gone, ::Ldp::NotFound
|
@@ -139,6 +139,7 @@ module Valkyrie::Persistence::Shared
|
|
139
139
|
# @return [Boolean]
|
140
140
|
# rubocop:disable Metrics/CyclomaticComplexity
|
141
141
|
def self.handles?(value)
|
142
|
+
return false unless ::Valkyrie.config.auto_cast_iso8601_as_datetime
|
142
143
|
return false unless value.is_a?(String)
|
143
144
|
return false unless value[4] == "-" && value[10] == "T"
|
144
145
|
year = value.to_s[0..3]
|
@@ -86,8 +86,13 @@ RSpec.shared_examples 'a Valkyrie query provider' do
|
|
86
86
|
expect { query_service.find_by(id: Valkyrie::ID.new("123123123")) }.to raise_error ::Valkyrie::Persistence::ObjectNotFoundError
|
87
87
|
end
|
88
88
|
|
89
|
+
it 'returns a Valkyrie::Persistence::ObjectNotFoundError for an empty string' do
|
90
|
+
expect { query_service.find_by(id: '') }.to raise_error ::Valkyrie::Persistence::ObjectNotFoundError
|
91
|
+
end
|
92
|
+
|
89
93
|
it 'raises an error if the id is not a Valkyrie::ID or a string' do
|
90
94
|
expect { query_service.find_by(id: 123) }.to raise_error ArgumentError
|
95
|
+
expect { query_service.find_by(id: nil) }.to raise_error ArgumentError
|
91
96
|
end
|
92
97
|
end
|
93
98
|
|
@@ -117,8 +122,13 @@ RSpec.shared_examples 'a Valkyrie query provider' do
|
|
117
122
|
expect { query_service.find_by_alternate_identifier(alternate_identifier: Valkyrie::ID.new("123123123")) }.to raise_error ::Valkyrie::Persistence::ObjectNotFoundError
|
118
123
|
end
|
119
124
|
|
125
|
+
it "raises a Valkyrie::Persistence::ObjectNotFoundError for a non-found alternate identifier" do
|
126
|
+
expect { query_service.find_by_alternate_identifier(alternate_identifier: '') }.to raise_error ::Valkyrie::Persistence::ObjectNotFoundError
|
127
|
+
end
|
128
|
+
|
120
129
|
it 'raises an error if the alternate identifier is not a Valkyrie::ID or a string' do
|
121
130
|
expect { query_service.find_by_alternate_identifier(alternate_identifier: 123) }.to raise_error ArgumentError
|
131
|
+
expect { query_service.find_by_alternate_identifier(alternate_identifier: nil) }.to raise_error ArgumentError
|
122
132
|
end
|
123
133
|
|
124
134
|
it 'can have multiple alternate identifiers' do
|
@@ -12,6 +12,7 @@ RSpec.shared_examples 'a Valkyrie::StorageAdapter' do
|
|
12
12
|
Valkyrie::Specs.send(:remove_const, :CustomResource)
|
13
13
|
end
|
14
14
|
subject { storage_adapter }
|
15
|
+
it { is_expected.to respond_to(:protocol) }
|
15
16
|
it { is_expected.to respond_to(:handles?).with_keywords(:id) }
|
16
17
|
it { is_expected.to respond_to(:find_by).with_keywords(:id) }
|
17
18
|
it { is_expected.to respond_to(:delete).with_keywords(:id) }
|
@@ -74,8 +75,9 @@ RSpec.shared_examples 'a Valkyrie::StorageAdapter' do
|
|
74
75
|
resource = Valkyrie::Specs::CustomResource.new(id: "test#{SecureRandom.uuid}")
|
75
76
|
sha1 = Digest::SHA1.file(file).to_s
|
76
77
|
size = file.size
|
77
|
-
|
78
|
+
uploaded_file = storage_adapter.upload(file: file, original_filename: 'foo.jpg', resource: resource, fake_upload_argument: true)
|
78
79
|
|
80
|
+
expect(uploaded_file).to be_kind_of Valkyrie::StorageAdapter::File
|
79
81
|
expect(uploaded_file).to respond_to(:checksum).with_keywords(:digests)
|
80
82
|
expect(uploaded_file).to respond_to(:valid?).with_keywords(:size, :digests)
|
81
83
|
expect(uploaded_file.checksum(digests: [Digest::SHA1.new])).to eq([sha1])
|
@@ -133,28 +135,42 @@ RSpec.shared_examples 'a Valkyrie::StorageAdapter' do
|
|
133
135
|
# Deleting a version should leave the current versions
|
134
136
|
if storage_adapter.supports?(:version_deletion)
|
135
137
|
storage_adapter.delete(id: uploaded_file.version_id)
|
136
|
-
|
138
|
+
remnants = storage_adapter.find_versions(id: uploaded_file.id)
|
139
|
+
expect(remnants.length).to eq 1
|
140
|
+
expect(remnants.first.version_id).to eq new_version.version_id
|
137
141
|
expect { storage_adapter.find_by(id: uploaded_file.version_id) }.to raise_error Valkyrie::StorageAdapter::FileNotFound
|
138
142
|
end
|
139
143
|
current_length = storage_adapter.find_versions(id: new_version.id).length
|
140
144
|
|
141
145
|
# Restoring a previous version is just pumping its file into upload_version
|
142
146
|
newest_version = storage_adapter.upload_version(file: new_version, id: new_version.id)
|
147
|
+
current_length += 1
|
143
148
|
expect(newest_version.version_id).not_to eq new_version.id
|
144
149
|
expect(storage_adapter.find_by(id: newest_version.id).version_id).to eq newest_version.version_id
|
145
150
|
|
146
151
|
# I can restore a version twice
|
147
152
|
newest_version = storage_adapter.upload_version(file: new_version, id: new_version.id)
|
153
|
+
current_length += 1
|
148
154
|
expect(newest_version.version_id).not_to eq new_version.id
|
149
155
|
expect(storage_adapter.find_by(id: newest_version.id).version_id).to eq newest_version.version_id
|
150
|
-
expect(storage_adapter.find_versions(id: newest_version.id).length).to eq current_length
|
156
|
+
expect(storage_adapter.find_versions(id: newest_version.id).length).to eq current_length
|
157
|
+
|
158
|
+
# Fedora 6.5 may not create versions when the timestamp is the same?
|
159
|
+
# See: https://fedora-repository.atlassian.net/browse/FCREPO-3958
|
160
|
+
sleep 1 if storage_adapter.supports?(:list_deleted_versions)
|
151
161
|
|
152
162
|
# NOTE: We originally wanted deleting the current record to push it into the
|
153
163
|
# versions history, but FCRepo 4/5/6 doesn't work that way, so we changed to
|
154
164
|
# instead make deleting delete everything.
|
155
165
|
storage_adapter.delete(id: new_version.id)
|
156
166
|
expect { storage_adapter.find_by(id: new_version.id) }.to raise_error Valkyrie::StorageAdapter::FileNotFound
|
157
|
-
|
167
|
+
|
168
|
+
if storage_adapter.supports?(:list_deleted_versions)
|
169
|
+
expect(storage_adapter.find_versions(id: new_version.id).length).to eq current_length
|
170
|
+
else
|
171
|
+
expect(storage_adapter.find_versions(id: new_version.id).length).to eq 0
|
172
|
+
end
|
173
|
+
|
158
174
|
ensure
|
159
175
|
f&.close
|
160
176
|
end
|
@@ -3,6 +3,8 @@ module Valkyrie::Storage
|
|
3
3
|
# Implements the DataMapper Pattern to store binary data on disk
|
4
4
|
class Disk
|
5
5
|
attr_reader :base_path, :path_generator, :file_mover
|
6
|
+
PROTOCOL = 'disk://'
|
7
|
+
|
6
8
|
def initialize(base_path:, path_generator: BucketedStorage, file_mover: FileUtils.method(:mv))
|
7
9
|
@base_path = Pathname.new(base_path.to_s)
|
8
10
|
@path_generator = path_generator.new(base_path: base_path)
|
@@ -18,13 +20,13 @@ module Valkyrie::Storage
|
|
18
20
|
new_path = path_generator.generate(resource: resource, file: file, original_filename: original_filename)
|
19
21
|
FileUtils.mkdir_p(new_path.parent)
|
20
22
|
file_mover.call(file.path, new_path)
|
21
|
-
find_by(id: Valkyrie::ID.new("
|
23
|
+
find_by(id: Valkyrie::ID.new("#{protocol}#{new_path}"))
|
22
24
|
end
|
23
25
|
|
24
26
|
# @param id [Valkyrie::ID]
|
25
27
|
# @return [Boolean] true if this adapter can handle this type of identifer
|
26
28
|
def handles?(id:)
|
27
|
-
id.to_s.start_with?("
|
29
|
+
id.to_s.start_with?("#{protocol}#{base_path}")
|
28
30
|
end
|
29
31
|
|
30
32
|
# @param feature [Symbol] Feature to test for.
|
@@ -33,8 +35,13 @@ module Valkyrie::Storage
|
|
33
35
|
false
|
34
36
|
end
|
35
37
|
|
38
|
+
# @return [String] identifier prefix
|
39
|
+
def protocol
|
40
|
+
PROTOCOL
|
41
|
+
end
|
42
|
+
|
36
43
|
def file_path(id)
|
37
|
-
id.to_s.gsub(
|
44
|
+
id.to_s.gsub(/^#{Regexp.escape(protocol)}/, '')
|
38
45
|
end
|
39
46
|
|
40
47
|
# Return the file associated with the given identifier
|
@@ -27,7 +27,7 @@ module Valkyrie::Storage
|
|
27
27
|
# @param id [Valkyrie::ID]
|
28
28
|
# @return [Boolean] true if this adapter can handle this type of identifer
|
29
29
|
def handles?(id:)
|
30
|
-
id.to_s.start_with?(
|
30
|
+
id.to_s.start_with?(protocol)
|
31
31
|
end
|
32
32
|
|
33
33
|
# @param feature [Symbol] Feature to test for.
|
@@ -36,9 +36,16 @@ module Valkyrie::Storage
|
|
36
36
|
return true if feature == :versions
|
37
37
|
# Fedora 6 auto versions and you can't delete versions.
|
38
38
|
return true if feature == :version_deletion && fedora_version < 6
|
39
|
+
# Fedora 6.5+ lists versions for deleted objects
|
40
|
+
return true if feature == :list_deleted_versions && fedora_version >= 6.5
|
39
41
|
false
|
40
42
|
end
|
41
43
|
|
44
|
+
# @return [String] identifier prefix
|
45
|
+
def protocol
|
46
|
+
PROTOCOL
|
47
|
+
end
|
48
|
+
|
42
49
|
# Return the file associated with the given identifier
|
43
50
|
# @param id [Valkyrie::ID]
|
44
51
|
# @return [Valkyrie::StorageAdapter::StreamFile]
|
@@ -61,7 +68,7 @@ module Valkyrie::Storage
|
|
61
68
|
# Fedora 6 auto versions, so check to see if there's a version for this
|
62
69
|
# initial upload. If not, then mint one (fedora 4/5)
|
63
70
|
version_id = current_version_id(id: valkyrie_identifier(uri: identifier)) || mint_version(identifier, latest_version(identifier))
|
64
|
-
perform_find(id: Valkyrie::ID.new(identifier.to_s.sub(/^.+\/\//,
|
71
|
+
perform_find(id: Valkyrie::ID.new(identifier.to_s.sub(/^.+\/\//, protocol)), version_id: version_id)
|
65
72
|
end
|
66
73
|
|
67
74
|
# @param id [Valkyrie::ID] ID of the Valkyrie::StorageAdapter::StreamFile to
|
@@ -77,7 +84,7 @@ module Valkyrie::Storage
|
|
77
84
|
end
|
78
85
|
upload_file(fedora_uri: uri, io: file)
|
79
86
|
version_id = mint_version(uri, latest_version(uri))
|
80
|
-
perform_find(id: Valkyrie::ID.new(uri.to_s.sub(/^.+\/\//,
|
87
|
+
perform_find(id: Valkyrie::ID.new(uri.to_s.sub(/^.+\/\//, protocol)), version_id: version_id)
|
81
88
|
end
|
82
89
|
|
83
90
|
# @param id [Valkyrie::ID]
|
@@ -88,7 +95,9 @@ module Valkyrie::Storage
|
|
88
95
|
version_list.map do |version|
|
89
96
|
id = valkyrie_identifier(uri: version["@id"])
|
90
97
|
perform_find(id: id, version_id: id)
|
91
|
-
|
98
|
+
rescue Valkyrie::StorageAdapter::FileNotFound
|
99
|
+
nil
|
100
|
+
end.compact
|
92
101
|
end
|
93
102
|
|
94
103
|
# Delete the file in Fedora associated with the given identifier.
|
@@ -197,12 +206,12 @@ module Valkyrie::Storage
|
|
197
206
|
# Translate the Valkrie ID into a URL for the fedora file
|
198
207
|
# @return [RDF::URI]
|
199
208
|
def fedora_identifier(id:)
|
200
|
-
identifier = id.to_s.sub(
|
209
|
+
identifier = id.to_s.sub(protocol, "#{connection.http.scheme}://")
|
201
210
|
RDF::URI(identifier)
|
202
211
|
end
|
203
212
|
|
204
213
|
def valkyrie_identifier(uri:)
|
205
|
-
id = uri.to_s.sub("http://",
|
214
|
+
id = uri.to_s.sub("http://", protocol)
|
206
215
|
Valkyrie::ID.new(id)
|
207
216
|
end
|
208
217
|
|
@@ -211,7 +220,7 @@ module Valkyrie::Storage
|
|
211
220
|
# @return [IOProxy]
|
212
221
|
def response(id:)
|
213
222
|
response = connection.http.get(fedora_identifier(id: id))
|
214
|
-
raise Valkyrie::StorageAdapter::FileNotFound unless response.success?
|
223
|
+
raise Valkyrie::StorageAdapter::FileNotFound, "HTTP #{response.status} #{response.body}" unless response.success?
|
215
224
|
IOProxy.new(response.body)
|
216
225
|
end
|
217
226
|
|
@@ -6,6 +6,8 @@ module Valkyrie::Storage
|
|
6
6
|
# in cases where you want to preserve real data
|
7
7
|
class Memory
|
8
8
|
attr_reader :cache
|
9
|
+
PROTOCOL = 'memory://'
|
10
|
+
|
9
11
|
def initialize
|
10
12
|
@cache = {}
|
11
13
|
end
|
@@ -16,7 +18,7 @@ module Valkyrie::Storage
|
|
16
18
|
# @param _extra_arguments [Hash] additional arguments which may be passed to other adapters
|
17
19
|
# @return [Valkyrie::StorageAdapter::StreamFile]
|
18
20
|
def upload(file:, original_filename:, resource: nil, **_extra_arguments)
|
19
|
-
identifier = Valkyrie::ID.new("
|
21
|
+
identifier = Valkyrie::ID.new("#{protocol}#{resource.id}")
|
20
22
|
version_id = Valkyrie::ID.new("#{identifier}##{SecureRandom.uuid}")
|
21
23
|
cache[identifier] ||= {}
|
22
24
|
cache[identifier][:current] = Valkyrie::StorageAdapter::StreamFile.new(id: identifier, io: file, version_id: version_id)
|
@@ -67,7 +69,7 @@ module Valkyrie::Storage
|
|
67
69
|
# @param id [Valkyrie::ID]
|
68
70
|
# @return [Boolean] true if this adapter can handle this type of identifer
|
69
71
|
def handles?(id:)
|
70
|
-
id.to_s.start_with?(
|
72
|
+
id.to_s.start_with?(protocol)
|
71
73
|
end
|
72
74
|
|
73
75
|
# @param feature [Symbol] Feature to test for.
|
@@ -83,6 +85,11 @@ module Valkyrie::Storage
|
|
83
85
|
end
|
84
86
|
end
|
85
87
|
|
88
|
+
# @return [String] identifier prefix
|
89
|
+
def protocol
|
90
|
+
PROTOCOL
|
91
|
+
end
|
92
|
+
|
86
93
|
def id_and_version(id)
|
87
94
|
id, version = id.to_s.split("#")
|
88
95
|
[Valkyrie::ID.new(id), version]
|
@@ -7,6 +7,8 @@ module Valkyrie::Storage
|
|
7
7
|
# with "deletionmarker" in the name of the file.
|
8
8
|
class VersionedDisk
|
9
9
|
attr_reader :base_path, :path_generator, :file_mover
|
10
|
+
PROTOCOL = 'versiondisk://'
|
11
|
+
|
10
12
|
def initialize(base_path:, path_generator: ::Valkyrie::Storage::Disk::BucketedStorage, file_mover: FileUtils.method(:cp))
|
11
13
|
@base_path = Pathname.new(base_path.to_s)
|
12
14
|
@path_generator = path_generator.new(base_path: base_path)
|
@@ -26,7 +28,7 @@ module Valkyrie::Storage
|
|
26
28
|
return sleep(0.001) && upload(file: file, original_filename: original_filename, resource: resource, paused: true, **extra_arguments) if !paused && File.exist?(new_path)
|
27
29
|
FileUtils.mkdir_p(new_path.parent)
|
28
30
|
file_mover.call(file.try(:path) || file.try(:disk_path), new_path)
|
29
|
-
find_by(id: Valkyrie::ID.new("
|
31
|
+
find_by(id: Valkyrie::ID.new("#{protocol}#{new_path}"))
|
30
32
|
end
|
31
33
|
|
32
34
|
def current_timestamp
|
@@ -50,13 +52,13 @@ module Valkyrie::Storage
|
|
50
52
|
return sleep(0.001) && upload_version(id: id, file: file, paused: true) if !paused && File.exist?(new_path)
|
51
53
|
FileUtils.mkdir_p(new_path.parent)
|
52
54
|
file_mover.call(file.try(:path) || file.try(:disk_path), new_path)
|
53
|
-
find_by(id: Valkyrie::ID.new("
|
55
|
+
find_by(id: Valkyrie::ID.new("#{protocol}#{new_path}"))
|
54
56
|
end
|
55
57
|
|
56
58
|
# @param id [Valkyrie::ID]
|
57
59
|
# @return [Boolean] true if this adapter can handle this type of identifer
|
58
60
|
def handles?(id:)
|
59
|
-
id.to_s.start_with?("
|
61
|
+
id.to_s.start_with?("#{protocol}#{base_path}")
|
60
62
|
end
|
61
63
|
|
62
64
|
# @param feature [Symbol] Feature to test for.
|
@@ -66,6 +68,11 @@ module Valkyrie::Storage
|
|
66
68
|
false
|
67
69
|
end
|
68
70
|
|
71
|
+
# @return [String] identifier prefix
|
72
|
+
def protocol
|
73
|
+
PROTOCOL
|
74
|
+
end
|
75
|
+
|
69
76
|
# Return the file associated with the given identifier
|
70
77
|
# @param id [Valkyrie::ID]
|
71
78
|
# @return [Valkyrie::StorageAdapter::File]
|
@@ -95,7 +102,7 @@ module Valkyrie::Storage
|
|
95
102
|
# @return [Array<Valkyrie::StorageAdapter::File>]
|
96
103
|
def find_versions(id:)
|
97
104
|
version_files(id: id).select { |x| !x.to_s.include?("deletionmarker") }.map do |file|
|
98
|
-
find_by(id: Valkyrie::ID.new("
|
105
|
+
find_by(id: Valkyrie::ID.new("#{protocol}#{file}"))
|
99
106
|
end
|
100
107
|
end
|
101
108
|
|
@@ -106,7 +113,7 @@ module Valkyrie::Storage
|
|
106
113
|
end
|
107
114
|
|
108
115
|
def file_path(version_id)
|
109
|
-
version_id.to_s.gsub(
|
116
|
+
version_id.to_s.gsub(/^#{Regexp.escape(protocol)}/, '')
|
110
117
|
end
|
111
118
|
|
112
119
|
# @return VersionId A VersionId value that's resolved a current reference,
|
@@ -128,6 +135,10 @@ module Valkyrie::Storage
|
|
128
135
|
@id = id
|
129
136
|
end
|
130
137
|
|
138
|
+
def protocol
|
139
|
+
PROTOCOL
|
140
|
+
end
|
141
|
+
|
131
142
|
def current_reference_id
|
132
143
|
self.class.new(Valkyrie::ID.new(string_id.gsub(version, "current")))
|
133
144
|
end
|
@@ -139,13 +150,13 @@ module Valkyrie::Storage
|
|
139
150
|
end
|
140
151
|
|
141
152
|
def file_path
|
142
|
-
@file_path ||= string_id.gsub(
|
153
|
+
@file_path ||= string_id.gsub(/^#{Regexp.escape(protocol)}/, '')
|
143
154
|
end
|
144
155
|
|
145
156
|
def version_files
|
146
157
|
root = Pathname.new(file_path)
|
147
158
|
root.parent.children.select { |file| file.basename.to_s.end_with?(filename) }.sort.reverse.map do |file|
|
148
|
-
VersionId.new(Valkyrie::ID.new("
|
159
|
+
VersionId.new(Valkyrie::ID.new("#{protocol}#{file}"))
|
149
160
|
end
|
150
161
|
end
|
151
162
|
|
data/lib/valkyrie/version.rb
CHANGED
data/lib/valkyrie.rb
CHANGED
@@ -101,6 +101,10 @@ module Valkyrie
|
|
101
101
|
self[:index_tsim_only_threshold].to_i
|
102
102
|
end
|
103
103
|
|
104
|
+
def auto_cast_iso8601_as_datetime
|
105
|
+
self[:auto_cast_iso8601_as_datetime]
|
106
|
+
end
|
107
|
+
|
104
108
|
# @api public
|
105
109
|
#
|
106
110
|
# The returned anonymous method (e.g. responds to #call) has a signature of
|
@@ -123,7 +127,8 @@ module Valkyrie
|
|
123
127
|
def defaults
|
124
128
|
{
|
125
129
|
resource_class_resolver: method(:default_resource_class_resolver),
|
126
|
-
index_tsim_only_threshold: 1000
|
130
|
+
index_tsim_only_threshold: 1000,
|
131
|
+
auto_cast_iso8601_as_datetime: true
|
127
132
|
}
|
128
133
|
end
|
129
134
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: valkyrie
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Trey Pendragon
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-10
|
11
|
+
date: 2024-12-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: dry-struct
|