Skip to content

Commit

Permalink
5592 dashboard statistics page error (#6088)
Browse files Browse the repository at this point in the history
* set up relation and custom query
* add in ability to count by model or property
* get date search working
* fix id check in active fedora converter for specs
* use standard fedora relation if Wings is being used in all locations

---------

Co-authored-by: braydonjustice <[email protected]>
Co-authored-by: Alisha Evans <[email protected]>
Co-authored-by: Rob Kaufman <[email protected]>
  • Loading branch information
4 people authored Jul 28, 2023
1 parent 90d49e6 commit 92ead3a
Show file tree
Hide file tree
Showing 15 changed files with 296 additions and 15 deletions.
5 changes: 4 additions & 1 deletion .koppie/config/initializers/hyrax.rb
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,10 @@
Hyrax::CustomQueries::FindCollectionsByType,
Hyrax::CustomQueries::FindFileMetadata,
Hyrax::CustomQueries::FindIdsByModel,
Hyrax::CustomQueries::FindManyByAlternateIds]
Hyrax::CustomQueries::FindManyByAlternateIds,
Hyrax::CustomQueries::FindModelsByAccess,
Hyrax::CustomQueries::FindCountBy,
Hyrax::CustomQueries::FindByDateRange]
custom_queries.each do |handler|
Hyrax.query_service.custom_queries.register_query_handler(handler)
end
Expand Down
4 changes: 4 additions & 0 deletions app/models/hyrax/resource.rb
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,10 @@ def work?
false
end

def ==(other)
attributes.except(:created_at, :updated_at) == other.attributes.except(:created_at, :updated_at)
end

def permission_manager
@permission_manager ||= Hyrax::PermissionManager.new(resource: self)
end
Expand Down
37 changes: 37 additions & 0 deletions app/search_builders/hyrax/valkyrie_abstract_type_relation.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# frozen_string_literal: true

module Hyrax
class ValkyrieAbstractTypeRelation
def initialize(allowable_types: nil, _opts: {})
@allowable_types = allowable_types
end

def allowable_types
@allowable_types.present? ||
raise(NotImplementedException, "Implement allowable_types in a subclass")
end

def equivalent_class?(klass)
allowable_types.include?(klass)
end

def count
Hyrax.query_service.custom_queries.find_count_by(models: allowable_types)
end

def where(hash)
Hyrax.query_service.find_references_by(resource: hash.values.first, property: hash.keys.first)
end

def ==(other)
case other
when Relation
other.where_values == where_values
when Array
to_a == other
end
end

delegate :inspect, to: :to_a
end
end
9 changes: 9 additions & 0 deletions app/search_builders/hyrax/valkyrie_work_relation.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# frozen_string_literal: true

module Hyrax
class ValkyrieWorkRelation < ValkyrieAbstractTypeRelation
def allowable_types
Hyrax.config.curation_concerns
end
end
end
55 changes: 55 additions & 0 deletions app/services/hyrax/custom_queries/find_by_date_range.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# frozen_string_literal: true
module Hyrax
module CustomQueries
##
# @see https://github.com/samvera/valkyrie/wiki/Queries#custom-queries
class FindByDateRange
def self.queries
[:find_by_date_range]
end

def initialize(query_service:)
@query_service = query_service
end

attr_reader :query_service
delegate :resource_factory, to: :query_service
delegate :orm_class, to: :resource_factory

##
# @note this is an unoptimized default implementation of this custom
# query. it's Hyrax's policy to provide such implementations of custom
# queries in use for cross-compatibility of Valkyrie query services.
# it's advisable to provide an optimized query for the specific adapter.
#
# @param models [Array]
# @param start_datetime [DateTime]
# @param end_datetime [DateTime]
def find_by_date_range(start_datetime:, end_datetime: nil, models: nil)
end_datetime = 1.second.since(Time.zone.now) if end_datetime.blank?
if models.present?
query_service.run_query(find_models_by_date_range_query, start_datetime.to_s, end_datetime.to_s, models)
else
query_service.run_query(find_by_date_range_query, start_datetime.to_s, end_datetime.to_s)
end
end

def find_models_by_date_range_query
<<-SQL
SELECT * FROM orm_resources
WHERE created_at >= ?
AND created_at <= ?
AND internal_resource IN (?);
SQL
end

def find_by_date_range_query
<<-SQL
SELECT * FROM orm_resources
WHERE created_at >= ?
AND created_at <= ?;
SQL
end
end
end
end
62 changes: 62 additions & 0 deletions app/services/hyrax/custom_queries/find_count_by.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# frozen_string_literal: true
module Hyrax
module CustomQueries
##
# @see https://github.com/samvera/valkyrie/wiki/Queries#custom-queries
class FindCountBy
def self.queries
[:find_count_by]
end

def initialize(query_service:)
@query_service = query_service
end

attr_reader :query_service
delegate :resource_factory, to: :query_service
delegate :orm_class, to: :resource_factory

##
# @note this is an unoptimized default implementation of this custom
# query. it's Hyrax's policy to provide such implementations of custom
# queries in use for cross-compatibility of Valkyrie query services.
# it's advisable to provide an optimized query for the specific adapter.
#
# @param hash [Hash] the hash representation of the query
def find_count_by(hash = {}, models: nil)
return nil if models.empty? && hash.blank?

internal_array = ["{ #{hash.map { |k, v| "\"#{k}\": #{v}" }.join(', ')} }"] if hash.present?
if models.empty?
query_service.orm_class.count_by_sql(([find_count_by_properties_query] + internal_array))
elsif hash.blank?
query_service.orm_class.count_by_sql([find_count_by_models_query] + [models])
else
query_service.orm_class.count_by_sql(([find_count_by_properties_and_models_query] + internal_array + [models]))
end
end

def find_count_by_properties_and_models_query
<<-SQL
SELECT count(*) FROM orm_resources
WHERE metadata @> ?
AND internal_resource IN (?);
SQL
end

def find_count_by_models_query
<<-SQL
SELECT count(*) FROM orm_resources
WHERE internal_resource IN (?);
SQL
end

def find_count_by_properties_query
<<-SQL
SELECT count(*) FROM orm_resources
WHERE metadata @> ?;
SQL
end
end
end
end
59 changes: 59 additions & 0 deletions app/services/hyrax/custom_queries/find_models_by_access.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# frozen_string_literal: true
module Hyrax
module CustomQueries
##
# @see https://github.com/samvera/valkyrie/wiki/Queries#custom-queries
class FindModelsByAccess
def self.queries
[:find_models_by_access]
end

def initialize(query_service:)
@query_service = query_service
end

attr_reader :query_service
delegate :resource_factory, to: :query_service
delegate :orm_class, to: :resource_factory

##
# @note this is an unoptimized default implementation of this custom
# query. it's Hyrax's policy to provide such implementations of custom
# queries in use for cross-compatibility of Valkyrie query services.
# it's advisable to provide an optimized query for the specific adapter.
#
# @param model [Class]
# @param ids [Enumerable<#to_s>, Symbol]
#
def find_models_by_access(mode:, models: nil, agent:, group: nil)
agent = "group/#{agent}" if group.present?
internal_array = "{\"permissions\": [{\"mode\": \"#{mode}\", \"agent\": \"#{agent}\"}]}"
if models.present?
query_service.run_query(find_models_by_access_query, internal_array, models)
else
query_service.run_query(find_by_access_query, internal_array)
end
end

def find_models_by_access_query
<<-SQL
SELECT * FROM orm_resources
WHERE id IN (
SELECT uuid(metadata::json#>'{access_to,0}'->>'id') FROM orm_resources
WHERE metadata @> ?
) AND internal_resource IN (?);
SQL
end

def find_by_access_query
<<-SQL
SELECT * FROM orm_resources
WHERE id IN (
SELECT uuid(metadata::json#>'{access_to,0}'->>'id') FROM orm_resources
WHERE metadata @> ?
);
SQL
end
end
end
end
2 changes: 1 addition & 1 deletion app/services/hyrax/statistics/depositors/summary.rb
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ def date_query
end

def query_service
Hyrax::Statistics::QueryService.new
Hyrax::Statistics::ValkyrieQueryService.new
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion app/services/hyrax/statistics/over_time.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def query(min, max)
end

def query_service
Hyrax::Statistics::QueryService.new
Hyrax::Statistics::ValkyrieQueryService.new
end

# How many points are in this data set
Expand Down
49 changes: 49 additions & 0 deletions app/services/hyrax/statistics/valkyrie_query_service.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# frozen_string_literal: true
module Hyrax
module Statistics
class ValkyrieQueryService < QueryService
# query to find works created during the time range
# @param [DateTime] start_datetime starting date time for range query
# @param [DateTime] end_datetime ending date time for range query
def find_by_date_created(start_datetime, end_datetime = nil)
return [] if start_datetime.blank? # no date just return nothing
return super unless non_wings_valkyire?

Hyrax.query_service.custom_queries.find_by_date_range(start_datetime: start_datetime,
end_datetime: end_datetime,
models: relation.allowable_types).to_a
end

def find_registered_in_date_range(start_datetime, end_datetime = nil)
return super unless non_wings_valkyire?
find_by_date_created(start_datetime, end_datetime) & where_registered.to_a
end

def find_public_in_date_range(start_datetime, end_datetime = nil)
return super unless non_wings_valkyire?
find_by_date_created(start_datetime, end_datetime) & where_public.to_a
end

def relation
return super unless non_wings_valkyire?
Hyrax::ValkyrieWorkRelation.new
end

private

def where_access_is(access_level)
# returns all works where the access level is public
return super unless non_wings_valkyire?

Hyrax.custom_queries.find_models_by_access(mode: 'read',
models: relation.allowable_types,
group: true,
agent: access_level)
end

def non_wings_valkyire?
Hyrax.config.use_valkyrie? && (!defined?(Wings) || (defined?(Wings) && Hyrax.config.disable_wings))
end
end
end
end
2 changes: 1 addition & 1 deletion app/services/hyrax/statistics/works/count.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def by_permission
private

def query_service
@query_service ||= Hyrax::Statistics::QueryService.new
@query_service ||= Hyrax::Statistics::ValkyrieQueryService.new
end

def by_date_and_permission
Expand Down
2 changes: 1 addition & 1 deletion lib/wings/active_fedora_converter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ def active_fedora_class
# then the id hasn't been minted and shouldn't yet be set.
# @return [String]
def id
return resource[:id].to_s if resource[:id]&.is_a?(::Valkyrie::ID) && resource[:id].present?
return resource[:id].to_s if resource[:id].present? && resource[:id]&.is_a?(::Valkyrie::ID)
return "" unless resource.respond_to?(:alternate_ids)

resource.alternate_ids.first.to_s
Expand Down
5 changes: 4 additions & 1 deletion lib/wings/setup.rb
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,10 @@ def build_or_set(attributes, &block)
Wings::CustomQueries::FindCollectionsByType,
Wings::CustomQueries::FindFileMetadata, # override Hyrax::CustomQueries::FindFileMetadata
Wings::CustomQueries::FindIdsByModel,
Wings::CustomQueries::FindManyByAlternateIds] # override Hyrax::CustomQueries::FindManyByAlternateIds
Wings::CustomQueries::FindManyByAlternateIds,
Hyrax::CustomQueries::FindModelsByAccess,
Hyrax::CustomQueries::FindCountBy,
Hyrax::CustomQueries::FindByDateRange] # override Hyrax::CustomQueries::FindManyByAlternateIds
custom_queries.each do |query_handler|
Valkyrie.config.metadata_adapter.query_service.custom_queries.register_query_handler(query_handler)
end
Expand Down
4 changes: 2 additions & 2 deletions spec/factories/generic_works.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@
end

after(:create) do |work, _evaluator|
work.save! if work.member_of_collections.present?
work.save! if work.try(:member_of_collections) && work.member_of_collections.present?
end

title { ["Test title"] }

after(:build) do |work, evaluator|
work.apply_depositor_metadata(evaluator.user.user_key)
work.apply_depositor_metadata(evaluator.user.user_key) if work.try(:apply_depositor_metadata, evaluator.user.user_key)
end

factory :public_generic_work, aliases: [:public_work], traits: [:public]
Expand Down
Loading

0 comments on commit 92ead3a

Please sign in to comment.