valkyrie 1.2.2 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.docker-stack/valkyrie-development/docker-compose.yml +0 -22
- data/.docker-stack/valkyrie-test/docker-compose.yml +0 -22
- data/CHANGELOG.md +7 -0
- data/README.md +2 -0
- data/lib/valkyrie/persistence/fedora/persister/model_converter.rb +1 -1
- data/lib/valkyrie/persistence/fedora/persister.rb +1 -1
- data/lib/valkyrie/persistence/memory/query_service.rb +2 -6
- data/lib/valkyrie/persistence/solr/model_converter.rb +1 -1
- data/lib/valkyrie/resource.rb +76 -2
- data/lib/valkyrie/specs/shared_specs/file.rb +5 -0
- data/lib/valkyrie/specs/shared_specs/resource.rb +77 -0
- data/lib/valkyrie/types.rb +16 -0
- data/lib/valkyrie/version.rb +1 -1
- data/tasks/dev.rake +8 -17
- data/valkyrie_logo.png +0 -0
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 548ddef374169cdcc984f7990ec0fb0d8b89502a
|
4
|
+
data.tar.gz: 2ca99fe44d1cc2733eecb1b55c7f2ef100bcbe03
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bce389d966f1728e132f9167e871e44e1a9f2ad595e309a4c995be1eecc58e9fde87235d909823b0be65a6af46d682f8758ad2553c5e39d34cd3dd8da17a5a00
|
7
|
+
data.tar.gz: 6cfdfffce9c65714d45489a7b1aa63c8062c96d24ca45b28036278ddb24b69dd96ce7497e0f03e058eee5e446e1d12b88f10cf081c27bb592c5f76cf4ef4e8e8
|
@@ -44,25 +44,3 @@ services:
|
|
44
44
|
interval: 30s
|
45
45
|
timeout: 5s
|
46
46
|
retries: 3
|
47
|
-
solr_index:
|
48
|
-
image: solr:7.2-alpine
|
49
|
-
ports:
|
50
|
-
- 8987:8983
|
51
|
-
volumes:
|
52
|
-
- solr_index:/opt/solr/server/solr/mycores
|
53
|
-
- "../../solr:/solr_config"
|
54
|
-
entrypoint:
|
55
|
-
- docker-entrypoint.sh
|
56
|
-
- solr-precreate
|
57
|
-
- hydra-dev
|
58
|
-
- "/solr_config/config"
|
59
|
-
healthcheck:
|
60
|
-
test:
|
61
|
-
- CMD
|
62
|
-
- wget
|
63
|
-
- "-O"
|
64
|
-
- "/dev/null"
|
65
|
-
- http://localhost:8983/solr/
|
66
|
-
interval: 30s
|
67
|
-
timeout: 5s
|
68
|
-
retries: 3
|
@@ -44,25 +44,3 @@ services:
|
|
44
44
|
interval: 30s
|
45
45
|
timeout: 5s
|
46
46
|
retries: 3
|
47
|
-
solr_index:
|
48
|
-
image: solr:7.2-alpine
|
49
|
-
ports:
|
50
|
-
- 8985:8983
|
51
|
-
volumes:
|
52
|
-
- solr_index:/opt/solr/server/solr/mycores
|
53
|
-
- "../../solr:/solr_config"
|
54
|
-
entrypoint:
|
55
|
-
- docker-entrypoint.sh
|
56
|
-
- solr-precreate
|
57
|
-
- hydra-test
|
58
|
-
- "/solr_config/config"
|
59
|
-
healthcheck:
|
60
|
-
test:
|
61
|
-
- CMD
|
62
|
-
- wget
|
63
|
-
- "-O"
|
64
|
-
- "/dev/null"
|
65
|
-
- http://localhost:8983/solr/
|
66
|
-
interval: 30s
|
67
|
-
timeout: 5s
|
68
|
-
retries: 3
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -2,6 +2,8 @@
|
|
2
2
|
|
3
3
|
Valkyrie is a gem for enabling multiple backends for storage of files and metadata in Samvera.
|
4
4
|
|
5
|
+
![Valkyrie Logo](valkyrie_logo.png)
|
6
|
+
|
5
7
|
[![CircleCI](https://circleci.com/gh/samvera-labs/valkyrie.svg?style=svg)](https://circleci.com/gh/samvera-labs/valkyrie)
|
6
8
|
[![Coverage Status](https://coveralls.io/repos/github/samvera-labs/valkyrie/badge.svg?branch=master)](https://coveralls.io/github/samvera-labs/valkyrie?branch=master)
|
7
9
|
[![Stories in Ready](https://badge.waffle.io/samvera-labs/valkyrie.png?label=ready&title=Ready)](https://waffle.io/samvera-labs/valkyrie)
|
@@ -296,7 +296,7 @@ module Valkyrie::Persistence::Fedora
|
|
296
296
|
# @param [Object] value
|
297
297
|
# @return [Boolean]
|
298
298
|
def self.handles?(value)
|
299
|
-
value.is_a?(Property) && value.value.is_a?(Hash) && value.value[:internal_resource]
|
299
|
+
value.is_a?(Property) && (value.value.is_a?(Hash) || value.value.is_a?(Valkyrie::Resource)) && value.value[:internal_resource]
|
300
300
|
end
|
301
301
|
|
302
302
|
# Generate a new parent graph containing the child graph generated from the ModelConverter::Property objects
|
@@ -165,7 +165,7 @@ module Valkyrie::Persistence::Fedora
|
|
165
165
|
# @return [Valkyrie::Persistence::OptimisticLockToken]
|
166
166
|
def native_lock_token(resource)
|
167
167
|
return unless resource.optimistic_locking_enabled?
|
168
|
-
resource[Valkyrie::Persistence::Attributes::OPTIMISTIC_LOCK].find { |lock_token| lock_token.adapter_id == "native-#{adapter.id}" }
|
168
|
+
resource[Valkyrie::Persistence::Attributes::OPTIMISTIC_LOCK].find { |lock_token| lock_token.adapter_id.to_s == "native-#{adapter.id}" }
|
169
169
|
end
|
170
170
|
|
171
171
|
# Set Fedora request headers:
|
@@ -36,7 +36,7 @@ module Valkyrie::Persistence::Memory
|
|
36
36
|
def find_by_alternate_identifier(alternate_identifier:)
|
37
37
|
alternate_identifier = Valkyrie::ID.new(alternate_identifier.to_s) if alternate_identifier.is_a?(String)
|
38
38
|
validate_id(alternate_identifier)
|
39
|
-
cache.select { |_key, resource| resource[
|
39
|
+
cache.select { |_key, resource| resource[:alternate_ids].include?(alternate_identifier) }.values.first || raise(::Valkyrie::Persistence::ObjectNotFoundError)
|
40
40
|
end
|
41
41
|
|
42
42
|
# Get a batch of resources by ID.
|
@@ -113,11 +113,7 @@ module Valkyrie::Persistence::Memory
|
|
113
113
|
def find_inverse_references_by(resource:, property:)
|
114
114
|
ensure_persisted(resource)
|
115
115
|
find_all.select do |obj|
|
116
|
-
|
117
|
-
Array.wrap(obj[property]).include?(resource.id)
|
118
|
-
rescue
|
119
|
-
false
|
120
|
-
end
|
116
|
+
Array.wrap(obj[property]).include?(resource.id)
|
121
117
|
end
|
122
118
|
end
|
123
119
|
|
@@ -222,7 +222,7 @@ module Valkyrie::Persistence::Solr
|
|
222
222
|
# @param [Object] value
|
223
223
|
# @return [Boolean]
|
224
224
|
def self.handles?(value)
|
225
|
-
value.value.is_a?(Hash)
|
225
|
+
value.value.is_a?(Hash) || value.value.is_a?(Valkyrie::Resource)
|
226
226
|
end
|
227
227
|
|
228
228
|
# Constructs a SolrRow object for a Property with a Hash value
|
data/lib/valkyrie/resource.rb
CHANGED
@@ -34,6 +34,17 @@ module Valkyrie
|
|
34
34
|
schema.keys.without(:new_record)
|
35
35
|
end
|
36
36
|
|
37
|
+
def self.new(attributes = default_attributes)
|
38
|
+
if attributes.is_a?(Hash) && attributes.keys.map(&:class).uniq.include?(String)
|
39
|
+
warn "[DEPRECATION] Instantiating a Valkyrie::Resource with strings as keys has " \
|
40
|
+
"been deprecated and will be removed in the next major release. " \
|
41
|
+
"Please use symbols instead." \
|
42
|
+
"Called from #{Gem.location_of_caller.join(':')}"
|
43
|
+
attributes = attributes.symbolize_keys
|
44
|
+
end
|
45
|
+
super
|
46
|
+
end
|
47
|
+
|
37
48
|
# Define an attribute. Attributes are used to describe resources.
|
38
49
|
# @param name [Symbol]
|
39
50
|
# @param type [Dry::Types::Type]
|
@@ -86,9 +97,55 @@ module Valkyrie
|
|
86
97
|
self.class.optimistic_locking_enabled?
|
87
98
|
end
|
88
99
|
|
100
|
+
class DeprecatedHashWrite < Hash
|
101
|
+
def []=(_k, _v)
|
102
|
+
if @soft_frozen
|
103
|
+
warn "[DEPRECATION] Writing directly to attributes has been deprecated." \
|
104
|
+
" Please use #set_value(k, v) instead or #dup first." \
|
105
|
+
" In the next major version, this hash will be frozen. \n" \
|
106
|
+
"Called from #{Gem.location_of_caller.join(':')}"
|
107
|
+
end
|
108
|
+
super
|
109
|
+
end
|
110
|
+
|
111
|
+
def delete(*_args)
|
112
|
+
if @soft_frozen
|
113
|
+
warn "[DEPRECATION] Writing directly to attributes has been deprecated." \
|
114
|
+
" Please use #set_value(k, v) instead or #dup first." \
|
115
|
+
" In the next major version, this hash will be frozen. \n" \
|
116
|
+
"Called from #{Gem.location_of_caller.join(':')}"
|
117
|
+
end
|
118
|
+
super
|
119
|
+
end
|
120
|
+
|
121
|
+
def delete_if(*_args)
|
122
|
+
if @soft_frozen
|
123
|
+
warn "[DEPRECATION] Writing directly to attributes has been deprecated." \
|
124
|
+
" Please use #set_value(k, v) instead or #dup first." \
|
125
|
+
" In the next major version, this hash will be frozen. \n" \
|
126
|
+
"Called from #{Gem.location_of_caller.join(':')}"
|
127
|
+
end
|
128
|
+
super
|
129
|
+
end
|
130
|
+
|
131
|
+
def soft_freeze!
|
132
|
+
@soft_frozen = true
|
133
|
+
self
|
134
|
+
end
|
135
|
+
|
136
|
+
def soft_thaw!
|
137
|
+
@soft_frozen = false
|
138
|
+
self
|
139
|
+
end
|
140
|
+
|
141
|
+
def dup
|
142
|
+
super.soft_thaw!
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
89
146
|
# @return [Hash] Hash of attributes
|
90
147
|
def attributes
|
91
|
-
to_h
|
148
|
+
DeprecatedHashWrite.new.merge(to_h).soft_freeze!
|
92
149
|
end
|
93
150
|
|
94
151
|
# @param name [Symbol] Attribute name
|
@@ -106,7 +163,7 @@ module Valkyrie
|
|
106
163
|
|
107
164
|
# @return [Boolean]
|
108
165
|
def persisted?
|
109
|
-
|
166
|
+
new_record == false
|
110
167
|
end
|
111
168
|
|
112
169
|
def to_key
|
@@ -133,5 +190,22 @@ module Valkyrie
|
|
133
190
|
def human_readable_type
|
134
191
|
self.class.human_readable_type
|
135
192
|
end
|
193
|
+
|
194
|
+
##
|
195
|
+
# Return an attribute's value.
|
196
|
+
# @param name [#to_sym] the name of the attribute to read
|
197
|
+
def [](name)
|
198
|
+
super(name.to_sym)
|
199
|
+
rescue NoMethodError
|
200
|
+
nil
|
201
|
+
end
|
202
|
+
|
203
|
+
##
|
204
|
+
# Set an attribute's value.
|
205
|
+
# @param key [#to_sym] the name of the attribute to set
|
206
|
+
# @param value [] the value to set key to.
|
207
|
+
def set_value(key, value)
|
208
|
+
instance_variable_set(:"@#{key}", self.class.schema[key.to_sym].call(value))
|
209
|
+
end
|
136
210
|
end
|
137
211
|
end
|
@@ -9,4 +9,9 @@ RSpec.shared_examples 'a Valkyrie::StorageAdapter::File' do
|
|
9
9
|
it { is_expected.to respond_to(:read) }
|
10
10
|
it { is_expected.to respond_to(:rewind) }
|
11
11
|
it { is_expected.to respond_to(:id) }
|
12
|
+
describe "#disk_path" do
|
13
|
+
it "returns an existing disk path" do
|
14
|
+
expect(File.exist?(file.disk_path)).to eq true
|
15
|
+
end
|
16
|
+
end
|
12
17
|
end
|
@@ -67,4 +67,81 @@ RSpec.shared_examples 'a Valkyrie::Resource' do
|
|
67
67
|
expect(my_custom_resource.human_readable_type).to eq "My Custom Resource"
|
68
68
|
end
|
69
69
|
end
|
70
|
+
|
71
|
+
describe "#[]" do
|
72
|
+
it "allows access to properties which are set" do
|
73
|
+
resource_klass.attribute :my_property
|
74
|
+
resource = resource_klass.new
|
75
|
+
|
76
|
+
resource.my_property = "test"
|
77
|
+
|
78
|
+
expect(resource[:my_property]).to eq ["test"]
|
79
|
+
resource_klass.schema.delete(:my_property)
|
80
|
+
end
|
81
|
+
it "returns nil for non-existent properties" do
|
82
|
+
resource = resource_klass.new
|
83
|
+
|
84
|
+
expect(resource[:bad_property]).to eq nil
|
85
|
+
end
|
86
|
+
it "can be accessed via a string" do
|
87
|
+
resource_klass.attribute :other_property
|
88
|
+
resource = resource_klass.new
|
89
|
+
|
90
|
+
resource.other_property = "test"
|
91
|
+
|
92
|
+
expect(resource["other_property"]).to eq ["test"]
|
93
|
+
resource_klass.schema.delete(:other_property)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
describe "#set_value" do
|
98
|
+
it "can set a value" do
|
99
|
+
resource_klass.attribute :set_value_property
|
100
|
+
resource = resource_klass.new
|
101
|
+
|
102
|
+
resource.set_value(:set_value_property, "test")
|
103
|
+
|
104
|
+
expect(resource.set_value_property).to eq ["test"]
|
105
|
+
resource.set_value("set_value_property", "testing")
|
106
|
+
expect(resource.set_value_property).to eq ["testing"]
|
107
|
+
resource_klass.schema.delete(:set_value_property)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
describe ".new" do
|
112
|
+
it "can set values with symbols" do
|
113
|
+
resource_klass.attribute :symbol_property
|
114
|
+
|
115
|
+
resource = resource_klass.new(symbol_property: "bla")
|
116
|
+
|
117
|
+
expect(resource.symbol_property).to eq ["bla"]
|
118
|
+
resource_klass.schema.delete(:symbol_property)
|
119
|
+
end
|
120
|
+
it "can set values with string properties, but will throw a deprecation error" do
|
121
|
+
resource_klass.attribute :string_property
|
122
|
+
|
123
|
+
resource = nil
|
124
|
+
expect { resource = resource_klass.new("string_property" => "bla") }.to output(/\[DEPRECATION\]/).to_stderr
|
125
|
+
|
126
|
+
expect(resource.string_property).to eq ["bla"]
|
127
|
+
resource_klass.schema.delete(:string_property)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
describe "#attributes" do
|
132
|
+
it "returns all defined attributs, including nil keys" do
|
133
|
+
resource_klass.attribute :bla
|
134
|
+
|
135
|
+
resource = resource_klass.new
|
136
|
+
|
137
|
+
expect(resource.attributes).to have_key(:bla)
|
138
|
+
expect(resource.attributes[:internal_resource]).to eq resource_klass.to_s
|
139
|
+
expect { resource.attributes[:internal_resource] = "bla" }.to output(/\[DEPRECATION\]/).to_stderr
|
140
|
+
expect { resource.attributes.delete_if { true } }.to output(/\[DEPRECATION\]/).to_stderr
|
141
|
+
expect { resource.attributes.delete(:internal_resource) }.to output(/\[DEPRECATION\]/).to_stderr
|
142
|
+
expect { resource.attributes.dup[:internal_resource] = "bla" }.not_to output.to_stderr
|
143
|
+
|
144
|
+
resource_klass.schema.delete(:bla)
|
145
|
+
end
|
146
|
+
end
|
70
147
|
end
|
data/lib/valkyrie/types.rb
CHANGED
@@ -98,5 +98,21 @@ module Valkyrie
|
|
98
98
|
SingleValuedString = Valkyrie::Types::String.constructor do |value|
|
99
99
|
::Array.wrap(value).first.to_s
|
100
100
|
end
|
101
|
+
Valkyrie::Types::Integer = Dry::Types["int"]
|
102
|
+
Valkyrie::Types::Coercible::Integer = Dry::Types["coercible.int"]
|
103
|
+
Int = Dry::Types["int"].constructor do |value|
|
104
|
+
warn "[DEPRECATION] Valkyrie::Types::Int has been renamed in dry-types and this " \
|
105
|
+
"reference will be removed in the next major version of Valkyrie. Please use " \
|
106
|
+
"Valkyrie::Types::Integer instead. " \
|
107
|
+
"Called from #{Gem.location_of_caller.join(':')}"
|
108
|
+
Dry::Types["int"][value]
|
109
|
+
end
|
110
|
+
Coercible::Int = Dry::Types["coercible.int"].constructor do |value|
|
111
|
+
warn "[DEPRECATION] Valkyrie::Types::Coercible::Int has been renamed in dry-types and this " \
|
112
|
+
"reference will be removed in the next major version of Valkyrie. Please use " \
|
113
|
+
"Valkyrie::Types::Coercible::Integer instead. " \
|
114
|
+
"Called from #{Gem.location_of_caller.join(':')}"
|
115
|
+
Dry::Types["coercible.int"][value]
|
116
|
+
end
|
101
117
|
end
|
102
118
|
end
|
data/lib/valkyrie/version.rb
CHANGED
data/tasks/dev.rake
CHANGED
@@ -7,14 +7,10 @@ namespace :server do
|
|
7
7
|
require 'fcrepo_wrapper'
|
8
8
|
SolrWrapper.wrap(shared_solr_opts.merge(port: 8984, instance_dir: 'tmp/blacklight-core-test')) do |solr|
|
9
9
|
solr.with_collection(name: "blacklight-core-test", dir: Pathname.new(__dir__).join("..", "solr", "config").to_s) do
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
loop do
|
15
|
-
sleep(1)
|
16
|
-
end
|
17
|
-
end
|
10
|
+
FcrepoWrapper.wrap(shared_fedora_opts.merge(port: 8988, fcrepo_home_dir: "tmp/fcrepo4-test-data")) do |_fcrepo|
|
11
|
+
puts "Setup solr & fedora."
|
12
|
+
loop do
|
13
|
+
sleep(1)
|
18
14
|
end
|
19
15
|
end
|
20
16
|
end
|
@@ -26,7 +22,6 @@ namespace :server do
|
|
26
22
|
require 'solr_wrapper'
|
27
23
|
require 'fcrepo_wrapper'
|
28
24
|
SolrWrapper.instance(shared_solr_opts.merge(port: 8984, instance_dir: 'tmp/blacklight-core-test')).remove_instance_dir!
|
29
|
-
SolrWrapper.instance(shared_solr_opts.merge(port: 8985, instance_dir: 'tmp/hydra-test')).remove_instance_dir!
|
30
25
|
FcrepoWrapper.default_instance(shared_fedora_opts.merge(port: 8988, fcrepo_home_dir: "tmp/fcrepo4-test-data")).remove_instance_dir!
|
31
26
|
puts "Cleaned up test solr & fedora servers."
|
32
27
|
end
|
@@ -38,14 +33,10 @@ namespace :server do
|
|
38
33
|
|
39
34
|
SolrWrapper.wrap(shared_solr_opts.merge(port: 8983, instance_dir: 'tmp/blacklight-core')) do |solr|
|
40
35
|
solr.with_collection(name: "blacklight-core", dir: Pathname.new(__dir__).join("..", "solr", "config").to_s) do
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
loop do
|
46
|
-
sleep(1)
|
47
|
-
end
|
48
|
-
end
|
36
|
+
FcrepoWrapper.wrap(shared_fedora_opts.merge(port: 8986, fcrepo_home_dir: "fcrepo4-dev-data")) do |_fcrepo|
|
37
|
+
puts "Setup Solr & Fedora"
|
38
|
+
loop do
|
39
|
+
sleep(1)
|
49
40
|
end
|
50
41
|
end
|
51
42
|
end
|
data/valkyrie_logo.png
ADDED
Binary file
|
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: 1.
|
4
|
+
version: 1.3.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: 2018-
|
11
|
+
date: 2018-12-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: dry-struct
|
@@ -570,6 +570,7 @@ files:
|
|
570
570
|
- tasks/dev.rake
|
571
571
|
- tasks/docker.rake
|
572
572
|
- valkyrie.gemspec
|
573
|
+
- valkyrie_logo.png
|
573
574
|
homepage:
|
574
575
|
licenses: []
|
575
576
|
metadata: {}
|
@@ -589,7 +590,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
589
590
|
version: '0'
|
590
591
|
requirements: []
|
591
592
|
rubyforge_project:
|
592
|
-
rubygems_version: 2.
|
593
|
+
rubygems_version: 2.6.14
|
593
594
|
signing_key:
|
594
595
|
specification_version: 4
|
595
596
|
summary: An ORM using the Data Mapper pattern, specifically built to solve Digital
|