Skip to content

Commit

Permalink
Implement Basic::Scopes::CriteriaScope.
Browse files Browse the repository at this point in the history
  • Loading branch information
sleepingkingstudios committed Dec 23, 2023
1 parent 1248102 commit d8d7cb1
Show file tree
Hide file tree
Showing 8 changed files with 462 additions and 4 deletions.
2 changes: 2 additions & 0 deletions lib/cuprum/collections/basic.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,7 @@ def self.new(**options)
autoload :Commands, 'cuprum/collections/basic/commands'
autoload :Query, 'cuprum/collections/basic/query'
autoload :Repository, 'cuprum/collections/basic/repository'
autoload :Scope, 'cuprum/collections/basic/scope'
autoload :Scopes, 'cuprum/collections/basic/scopes'
end
end
9 changes: 9 additions & 0 deletions lib/cuprum/collections/basic/scope.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# frozen_string_literal: true

require 'cuprum/collections/basic'
require 'cuprum/collections/scope'

module Cuprum::Collections::Basic
# Abstract class representing a set of filters for a basic query.
class Scope < Cuprum::Collections::Scope; end
end
10 changes: 10 additions & 0 deletions lib/cuprum/collections/basic/scopes.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# frozen_string_literal: true

require 'cuprum/collections/basic'

module Cuprum::Collections::Basic
# Namespace for basic scope functionality, which filters query data.
module Scopes
autoload :CriteriaScope, 'cuprum/collections/basic/scopes/criteria_scope'
end
end
54 changes: 54 additions & 0 deletions lib/cuprum/collections/basic/scopes/criteria_scope.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# frozen_string_literal: true

require 'cuprum/collections/basic/scope'
require 'cuprum/collections/basic/scopes'
require 'cuprum/collections/queries'
require 'cuprum/collections/scopes/criteria'

module Cuprum::Collections::Basic::Scopes
# Scope for filtering on basic collection data based on criteria.
class CriteriaScope < Cuprum::Collections::Basic::Scope
include Cuprum::Collections::Scopes::Criteria

Operators = Cuprum::Collections::Queries::Operators
private_constant :Operators

# Filters the provided data based on the configured criteria.
def call(data:)
raise ArgumentError, 'data must be an Array' unless data.is_a?(Array)

criteria.reduce(data) do |filtered, (attribute, operator, value)|
filtered.select(&filter_for(attribute, operator, value))
end
end

private

def filter_for(attribute, operator, value) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
case operator
when Operators::EQUAL
@eq_filter ||= ->(item) { item[attribute] == value }
when Operators::GREATER_THAN
@gt_filter ||= ->(item) { item[attribute] > value }
when Operators::GREATER_THAN_OR_EQUAL_TO
@gte_filter ||= ->(item) { item[attribute] >= value }
when Operators::LESS_THAN
@lt_filter ||= ->(item) { item[attribute] < value }
when Operators::LESS_THAN_OR_EQUAL_TO
@lte_filter ||= ->(item) { item[attribute] <= value }
when Operators::NOT_EQUAL
@ne_filter ||= ->(item) { item[attribute] != value }
when Operators::NOT_ONE_OF
@nin_filter ||= ->(item) { !value.include?(item[attribute]) }
when Operators::ONE_OF
@in_filter ||= ->(item) { value.include?(item[attribute]) }
else
error_class =
Cuprum::Collections::Scopes::Criteria::UnknownOperatorException
message = %(unknown operator "#{operator}")

raise error_class.new(message, operator)
end
end
end
end
Loading

0 comments on commit d8d7cb1

Please sign in to comment.