-
Notifications
You must be signed in to change notification settings - Fork 23
/
query_service.rb
96 lines (84 loc) · 2.93 KB
/
query_service.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# frozen_string_literal: true
module Valkyrie::Persistence::Fedora
class QueryService
attr_reader :adapter
delegate :connection, :resource_factory, to: :adapter
def initialize(adapter:)
@adapter = adapter
end
def find_by(id:)
id = Valkyrie::ID.new(id.to_s) if id.is_a?(String)
validate_id(id)
uri = adapter.id_to_uri(id)
begin
resource = Ldp::Resource.for(connection, uri, connection.get(uri))
resource_factory.to_resource(object: resource)
rescue ::Ldp::Gone, ::Ldp::NotFound
raise ::Valkyrie::Persistence::ObjectNotFoundError
end
end
def find_parents(resource:)
content = content_with_inbound(id: resource.id)
parent_ids = content.graph.query([nil, RDF::Vocab::ORE.proxyFor, nil]).map(&:subject).map { |x| x.to_s.gsub(/#.*/, '') }.map { |x| adapter.uri_to_id(x) }
parent_ids.lazy.map do |id|
find_by(id: id)
end
end
def include_uris
[
::RDF::Vocab::Fcrepo4.InboundReferences
]
end
def find_members(resource:, model: nil)
return [] unless resource.respond_to? :member_ids
result = Array(resource.member_ids).lazy.map do |id|
find_by(id: id)
end.select(&:present?)
return result unless model
result.select { |obj| obj.is_a?(model) }
end
def find_all
resource = Ldp::Resource.for(connection, adapter.base_path, connection.get(adapter.base_path))
ids = resource.graph.query([nil, RDF::Vocab::LDP.contains, nil]).map(&:object).map { |x| adapter.uri_to_id(x) }
ids.lazy.map do |id|
find_by(id: id)
end
rescue ::Ldp::NotFound
[]
end
def find_all_of_model(model:)
find_all.select do |m|
m.is_a?(model)
end
end
def find_references_by(resource:, property:)
(resource[property] || []).select { |x| x.is_a?(Valkyrie::ID) }.lazy.map do |id|
find_by(id: id)
end
end
def content_with_inbound(id:)
uri = adapter.id_to_uri(id)
connection.get(uri) do |req|
prefer_headers = Ldp::PreferHeaders.new(req.headers["Prefer"])
prefer_headers.include = prefer_headers.include | include_uris
req.headers["Prefer"] = prefer_headers.to_s
end
end
def find_inverse_references_by(resource:, property:)
validate_id resource.id
content = content_with_inbound(id: resource.id)
property_uri = adapter.schema.predicate_for(property: property, resource: nil)
ids = content.graph.query([nil, property_uri, nil]).map(&:subject).map { |x| x.to_s.gsub(/#.*/, '') }.map { |x| adapter.uri_to_id(x) }
ids.lazy.map do |id|
find_by(id: id)
end
end
def custom_queries
@custom_queries ||= ::Valkyrie::Persistence::CustomQueryContainer.new(query_service: self)
end
private
def validate_id(id)
raise ArgumentError, 'id must be a Valkyrie::ID' unless id.is_a? Valkyrie::ID
end
end
end