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
-
#count_all_of_model(model:) ⇒ Object
Count all records for a specific resource type.
-
#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:, model: nil) ⇒ Array<Valkyrie::Resource>
Get all resources which link to a resource with a given 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_inverse_references_with_type_query ⇒ String
Generate the SQL query for retrieving member resources in PostgreSQL using a JSON object literal (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_ordered_references_with_type_query ⇒ Object
-
#find_parents(resource:) ⇒ Array<Valkyrie::Resource>
Find all parent resources for a given Valkyrie Resource.
-
#find_references_by(resource:, property:, model: nil) ⇒ Array<Valkyrie::Resource>
Get all resources referenced from a resource with a given 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.
- #find_references_with_type_query ⇒ Object
-
#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
#count_all_of_model(model:) ⇒ Object
Count all records for a specific resource type
41 42 43 |
# File 'lib/valkyrie/persistence/postgres/query_service.rb', line 41 def count_all_of_model(model:) orm_class.where(internal_resource: model.to_s).count end |
#custom_queries ⇒ Valkyrie::Persistence::CustomQueryContainer
Constructs a Valkyrie::Persistence::CustomQueryContainer using this query service
248 249 250 |
# File 'lib/valkyrie/persistence/postgres/query_service.rb', line 248 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.find_each.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).find_each.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
49 50 51 52 53 54 55 |
# File 'lib/valkyrie/persistence/postgres/query_service.rb', line 49 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
61 62 63 64 65 66 |
# File 'lib/valkyrie/persistence/postgres/query_service.rb', line 61 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:, model: nil) ⇒ Array<Valkyrie::Resource>
Get all resources which link to a resource with a given property.
116 117 118 119 120 121 122 123 124 125 126 |
# File 'lib/valkyrie/persistence/postgres/query_service.rb', line 116 def find_inverse_references_by(resource: nil, id: nil, property:, model: nil) raise ArgumentError, "Provide resource or id" unless resource || id ensure_persisted(resource) if resource id ||= resource.id internal_array = "{\"#{property}\": [{\"id\": \"#{id}\"}]}" if model run_query(find_inverse_references_with_type_query, internal_array, model) else run_query(find_inverse_references_query, internal_array) end 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
181 182 183 184 185 186 |
# File 'lib/valkyrie/persistence/postgres/query_service.rb', line 181 def find_inverse_references_query <<-SQL SELECT * FROM orm_resources WHERE metadata @> ? SQL end |
#find_inverse_references_with_type_query ⇒ String
Generate the SQL query for retrieving member resources in PostgreSQL using a
JSON object literal (e. g. { "alternate_ids": [{"id": "d6e88f80-41b3-4dbf-a2a0-cd79e20f6d10"}] }).
and resource type as arguments
This uses JSON functions in order to retrieve JSON property values
195 196 197 198 199 200 201 |
# File 'lib/valkyrie/persistence/postgres/query_service.rb', line 195 def find_inverse_references_with_type_query <<-SQL SELECT * FROM orm_resources WHERE metadata @> ? AND internal_resource = ? SQL end |
#find_many_by_ids(ids:) ⇒ Array<Valkyrie::Resource>
Find records using a set of Valkyrie IDs, and map each to Valkyrie
Resources
72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/valkyrie/persistence/postgres/query_service.rb', line 72 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
88 89 90 91 92 93 94 95 |
# File 'lib/valkyrie/persistence/postgres/query_service.rb', line 88 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
147 148 149 150 151 152 153 154 |
# File 'lib/valkyrie/persistence/postgres/query_service.rb', line 147 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
165 166 167 168 169 170 171 172 173 |
# File 'lib/valkyrie/persistence/postgres/query_service.rb', line 165 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
228 229 230 231 232 233 234 235 |
# File 'lib/valkyrie/persistence/postgres/query_service.rb', line 228 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_ordered_references_with_type_query ⇒ Object
237 238 239 240 241 242 243 244 |
# File 'lib/valkyrie/persistence/postgres/query_service.rb', line 237 def find_ordered_references_with_type_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 = ? AND member.internal_resource = ? ORDER BY b.member_pos SQL end |
#find_parents(resource:) ⇒ Array<Valkyrie::Resource>
Find all parent resources for a given Valkyrie Resource
100 101 102 |
# File 'lib/valkyrie/persistence/postgres/query_service.rb', line 100 def find_parents(resource:) find_inverse_references_by(resource: resource, property: :member_ids) end |
#find_references_by(resource:, property:, model: nil) ⇒ Array<Valkyrie::Resource>
Get all resources referenced from a resource with a given property.
105 106 107 108 109 110 111 112 113 |
# File 'lib/valkyrie/persistence/postgres/query_service.rb', line 105 def find_references_by(resource:, property:, model: nil) return [] if resource.id.blank? || resource[property].blank? # only return ordered if needed to avoid performance penalties if ordered_property?(resource: resource, property: property) find_ordered_references_by(resource: resource, property: property, model: model) else find_unordered_references_by(resource: resource, property: property, model: model) 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
212 213 214 215 216 217 218 |
# File 'lib/valkyrie/persistence/postgres/query_service.rb', line 212 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 |
#find_references_with_type_query ⇒ Object
220 221 222 223 224 225 226 |
# File 'lib/valkyrie/persistence/postgres/query_service.rb', line 220 def find_references_with_type_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 = ? AND member.internal_resource = ? SQL end |
#run_query(query, *args) ⇒ Array<Valkyrie::Resource>
Execute a query in SQL for resource records and map them to Valkyrie
Resources
132 133 134 135 136 |
# File 'lib/valkyrie/persistence/postgres/query_service.rb', line 132 def run_query(query, *args) orm_class.find_by_sql(([query] + args)).lazy.map do |object| resource_factory.to_resource(object: object) end end |