Class: Valkyrie::Persistence::Postgres::QueryService
- Inherits:
-
Object
- Object
- Valkyrie::Persistence::Postgres::QueryService
- Defined in:
- lib/valkyrie/persistence/postgres/query_service.rb
Overview
Query Service for the Postgres Metadata Adapter
Most queries are delegated through to the ActiveRecord model ORM::Resource
Instance Attribute Summary collapse
-
#adapter ⇒ Object
readonly
Returns the value of attribute adapter.
-
#resource_factory ⇒ Object
readonly
Returns the value of attribute resource_factory.
Instance Method Summary collapse
-
#custom_queries ⇒ Valkyrie::Persistence::CustomQueryContainer
Constructs a Valkyrie::Persistence::CustomQueryContainer using this query service.
-
#find_all ⇒ Array<Valkyrie::Resource>
Retrieve all records for the resource and construct Valkyrie Resources for each record.
-
#find_all_of_model(model:) ⇒ Array<Valkyrie::Resource>
Retrieve all records for a specific resource type and construct Valkyrie Resources for each record.
-
#find_by(id:) ⇒ Valkyrie::Resource
Find a record using a Valkyrie ID, and map it to a Valkyrie Resource.
-
#find_by_alternate_identifier(alternate_identifier:) ⇒ Valkyrie::Resource
Find and a record using a Valkyrie ID for an alternate ID, and construct a Valkyrie Resource.
-
#find_inverse_references_by(resource: nil, id: nil, property:) ⇒ Array<Valkyrie::Resource>
Find all resources referencing a given Valkyrie Resource by a property.
-
#find_inverse_references_query ⇒ String
Generate the SQL query for retrieving member resources in PostgreSQL using a JSON object literal as an argument (e. g. { “alternate_ids”: [“d6e88f80-41b3-4dbf-a2a0-cd79e20f6d10”] }).
-
#find_many_by_ids(ids:) ⇒ Array<Valkyrie::Resource>
Find records using a set of Valkyrie IDs, and map each to Valkyrie Resources.
-
#find_members(resource:, model: nil) ⇒ Array<Valkyrie::Resource>
Find all member resources for a given Valkyrie Resource.
-
#find_members_query ⇒ String
Generate the SQL query for retrieving member resources in PostgreSQL using a resource ID as an argument.
-
#find_members_with_type_query ⇒ String
Generate the SQL query for retrieving member resources in PostgreSQL using a resource ID and resource type as arguments.
- #find_ordered_references_query ⇒ Object
-
#find_parents(resource:) ⇒ Array<Valkyrie::Resource>
Find all parent resources for a given Valkyrie Resource.
-
#find_references_by(resource:, property:) ⇒ Array<Valkyrie::Resource>
Find all resources related to a given Valkyrie Resource by a property.
-
#find_references_query ⇒ String
Generate the SQL query for retrieving member resources in PostgreSQL using a JSON object literal and resource ID as arguments.
-
#initialize(adapter:, resource_factory:) ⇒ QueryService
constructor
A new instance of QueryService.
-
#run_query(query, *args) ⇒ Array<Valkyrie::Resource>
Execute a query in SQL for resource records and map them to Valkyrie Resources.
Constructor Details
#initialize(adapter:, resource_factory:) ⇒ QueryService
Returns a new instance of QueryService.
14 15 16 17 |
# File 'lib/valkyrie/persistence/postgres/query_service.rb', line 14 def initialize(adapter:, resource_factory:) @resource_factory = resource_factory @adapter = adapter end |
Instance Attribute Details
#adapter ⇒ Object (readonly)
Returns the value of attribute adapter.
10 11 12 |
# File 'lib/valkyrie/persistence/postgres/query_service.rb', line 10 def adapter @adapter end |
#resource_factory ⇒ Object (readonly)
Returns the value of attribute resource_factory.
10 11 12 |
# File 'lib/valkyrie/persistence/postgres/query_service.rb', line 10 def resource_factory @resource_factory end |
Instance Method Details
#custom_queries ⇒ Valkyrie::Persistence::CustomQueryContainer
Constructs a Valkyrie::Persistence::CustomQueryContainer using this query service
211 212 213 |
# File 'lib/valkyrie/persistence/postgres/query_service.rb', line 211 def custom_queries @custom_queries ||= ::Valkyrie::Persistence::CustomQueryContainer.new(query_service: self) end |
#find_all ⇒ Array<Valkyrie::Resource>
Retrieve all records for the resource and construct Valkyrie Resources
for each record
22 23 24 25 26 |
# File 'lib/valkyrie/persistence/postgres/query_service.rb', line 22 def find_all orm_class.all.lazy.map do |orm_object| resource_factory.to_resource(object: orm_object) end end |
#find_all_of_model(model:) ⇒ Array<Valkyrie::Resource>
Retrieve all records for a specific resource type and construct Valkyrie
Resources for each record
32 33 34 35 36 |
# File 'lib/valkyrie/persistence/postgres/query_service.rb', line 32 def find_all_of_model(model:) orm_class.where(internal_resource: model.to_s).lazy.map do |orm_object| resource_factory.to_resource(object: orm_object) end end |
#find_by(id:) ⇒ Valkyrie::Resource
Find a record using a Valkyrie ID, and map it to a Valkyrie Resource
42 43 44 45 46 47 48 |
# File 'lib/valkyrie/persistence/postgres/query_service.rb', line 42 def find_by(id:) id = Valkyrie::ID.new(id.to_s) if id.is_a?(String) validate_id(id) resource_factory.to_resource(object: orm_class.find(id.to_s)) rescue ActiveRecord::RecordNotFound raise Valkyrie::Persistence::ObjectNotFoundError end |
#find_by_alternate_identifier(alternate_identifier:) ⇒ Valkyrie::Resource
54 55 56 57 58 59 |
# File 'lib/valkyrie/persistence/postgres/query_service.rb', line 54 def find_by_alternate_identifier(alternate_identifier:) alternate_identifier = Valkyrie::ID.new(alternate_identifier.to_s) if alternate_identifier.is_a?(String) validate_id(alternate_identifier) internal_array = "{\"alternate_ids\": [{\"id\": \"#{alternate_identifier}\"}]}" run_query(find_inverse_references_query, internal_array).first || raise(Valkyrie::Persistence::ObjectNotFoundError) end |
#find_inverse_references_by(resource: nil, id: nil, property:) ⇒ Array<Valkyrie::Resource>
Find all resources referencing a given Valkyrie Resource by a property
115 116 117 118 119 120 121 |
# File 'lib/valkyrie/persistence/postgres/query_service.rb', line 115 def find_inverse_references_by(resource: nil, id: nil, property:) raise ArgumentError, "Provide resource or id" unless resource || id ensure_persisted(resource) if resource id ||= resource.id internal_array = "{\"#{property}\": [{\"id\": \"#{id}\"}]}" run_query(find_inverse_references_query, internal_array) end |
#find_inverse_references_query ⇒ String
Generate the SQL query for retrieving member resources in PostgreSQL using a
JSON object literal as an argument (e. g. { "alternate_ids": [{"id": "d6e88f80-41b3-4dbf-a2a0-cd79e20f6d10"}] }).
This uses JSON functions in order to retrieve JSON property values
176 177 178 179 180 181 |
# File 'lib/valkyrie/persistence/postgres/query_service.rb', line 176 def find_inverse_references_query <<-SQL SELECT * FROM orm_resources WHERE metadata @> ? SQL end |
#find_many_by_ids(ids:) ⇒ Array<Valkyrie::Resource>
Find records using a set of Valkyrie IDs, and map each to Valkyrie
Resources
65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/valkyrie/persistence/postgres/query_service.rb', line 65 def find_many_by_ids(ids:) ids.map! do |id| id = Valkyrie::ID.new(id.to_s) if id.is_a?(String) validate_id(id) id.to_s end orm_class.where(id: ids).map do |orm_resource| resource_factory.to_resource(object: orm_resource) end end |
#find_members(resource:, model: nil) ⇒ Array<Valkyrie::Resource>
Find all member resources for a given Valkyrie Resource
81 82 83 84 85 86 87 88 |
# File 'lib/valkyrie/persistence/postgres/query_service.rb', line 81 def find_members(resource:, model: nil) return [] if resource.id.blank? if model run_query(find_members_with_type_query, resource.id.to_s, model.to_s) else run_query(find_members_query, resource.id.to_s) end end |
#find_members_query ⇒ String
this uses a CROSS JOIN for all combinations of member IDs with the IDs of their parents
Generate the SQL query for retrieving member resources in PostgreSQL using a
resource ID as an argument.
This also uses JSON functions in order to retrieve JSON property values
142 143 144 145 146 147 148 149 |
# File 'lib/valkyrie/persistence/postgres/query_service.rb', line 142 def find_members_query <<-SQL SELECT member.* FROM orm_resources a, jsonb_array_elements(a.metadata->'member_ids') WITH ORDINALITY AS b(member, member_pos) JOIN orm_resources member ON (b.member->>'id')::#{id_type} = member.id WHERE a.id = ? ORDER BY b.member_pos SQL end |
#find_members_with_type_query ⇒ String
this uses a CROSS JOIN for all combinations of member IDs with the IDs of their parents
Generate the SQL query for retrieving member resources in PostgreSQL using a
resource ID and resource type as arguments.
This also uses JSON functions in order to retrieve JSON property values
160 161 162 163 164 165 166 167 168 |
# File 'lib/valkyrie/persistence/postgres/query_service.rb', line 160 def find_members_with_type_query <<-SQL SELECT member.* FROM orm_resources a, jsonb_array_elements(a.metadata->'member_ids') WITH ORDINALITY AS b(member, member_pos) JOIN orm_resources member ON (b.member->>'id')::#{id_type} = member.id WHERE a.id = ? AND member.internal_resource = ? ORDER BY b.member_pos SQL end |
#find_ordered_references_query ⇒ Object
200 201 202 203 204 205 206 207 |
# File 'lib/valkyrie/persistence/postgres/query_service.rb', line 200 def find_ordered_references_query <<-SQL SELECT member.* FROM orm_resources a, jsonb_array_elements(a.metadata->?) WITH ORDINALITY AS b(member, member_pos) JOIN orm_resources member ON (b.member->>'id')::#{id_type} = member.id WHERE a.id = ? ORDER BY b.member_pos SQL end |
#find_parents(resource:) ⇒ Array<Valkyrie::Resource>
Find all parent resources for a given Valkyrie Resource
93 94 95 |
# File 'lib/valkyrie/persistence/postgres/query_service.rb', line 93 def find_parents(resource:) find_inverse_references_by(resource: resource, property: :member_ids) end |
#find_references_by(resource:, property:) ⇒ Array<Valkyrie::Resource>
Find all resources related to a given Valkyrie Resource by a property
101 102 103 104 105 106 107 108 109 |
# File 'lib/valkyrie/persistence/postgres/query_service.rb', line 101 def find_references_by(resource:, property:) return [] if resource.id.blank? || resource[property].blank? # only return ordered if needed to avoid performance penalties if ordered_property?(resource: resource, property: property) run_query(find_ordered_references_query, property, resource.id.to_s) else run_query(find_references_query, property, resource.id.to_s) end end |
#find_references_query ⇒ String
this uses a CROSS JOIN for all combinations of member IDs with the IDs of their parents
Generate the SQL query for retrieving member resources in PostgreSQL using a
JSON object literal and resource ID as arguments.
This also uses JSON functions in order to retrieve JSON property values
192 193 194 195 196 197 198 |
# File 'lib/valkyrie/persistence/postgres/query_service.rb', line 192 def find_references_query <<-SQL SELECT DISTINCT member.* FROM orm_resources a, jsonb_array_elements(a.metadata->?) AS b(member) JOIN orm_resources member ON (b.member->>'id')::#{id_type} = member.id WHERE a.id = ? SQL end |
#run_query(query, *args) ⇒ Array<Valkyrie::Resource>
Execute a query in SQL for resource records and map them to Valkyrie
Resources
127 128 129 130 131 |
# File 'lib/valkyrie/persistence/postgres/query_service.rb', line 127 def run_query(query, *args) orm_class.find_by_sql(([query] + args)).lazy.map do |object| resource_factory.to_resource(object: object) end end |