Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/Implement logical scopes. #62

Merged
merged 5 commits into from
Jan 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion lib/cuprum/collections/basic/scope.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,20 @@

module Cuprum::Collections::Basic
# Abstract class representing a set of filters for a basic query.
class Scope < Cuprum::Collections::Scope; end
class Scope < Cuprum::Collections::Scope
# Filters the provided data.
def call(data:)
raise ArgumentError, 'data must be an Array' unless data.is_a?(Array)

data.select { |item| match?(item: item) }
end

# Returns true if the provided item matches the scope.
def match?(item:)
raise ArgumentError, 'item must be a Hash' unless item.is_a?(Hash)

true
end
alias matches? match?
end
end
9 changes: 8 additions & 1 deletion lib/cuprum/collections/basic/scopes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@
module Cuprum::Collections::Basic
# Namespace for basic scope functionality, which filters query data.
module Scopes
autoload :CriteriaScope, 'cuprum/collections/basic/scopes/criteria_scope'
autoload :ConjunctionScope,
'cuprum/collections/basic/scopes/conjunction_scope'
autoload :CriteriaScope,
'cuprum/collections/basic/scopes/criteria_scope'
autoload :DisjunctionScope,
'cuprum/collections/basic/scopes/disjunction_scope'
autoload :NegationScope,
'cuprum/collections/basic/scopes/negation_scope'
end
end
20 changes: 20 additions & 0 deletions lib/cuprum/collections/basic/scopes/conjunction_scope.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# frozen_string_literal: true

require 'cuprum/collections/basic/scope'
require 'cuprum/collections/basic/scopes'
require 'cuprum/collections/scopes/container'

module Cuprum::Collections::Basic::Scopes
# Scope for filtering data matching all of the given scopes.
class ConjunctionScope < Cuprum::Collections::Basic::Scope
include Cuprum::Collections::Scopes::Container

# Returns true if the provided item matches all of the configured scopes.
def match?(item:)
super

scopes.all? { |scope| scope.match?(item: item) }
end
alias matches? match?
end
end
11 changes: 6 additions & 5 deletions lib/cuprum/collections/basic/scopes/criteria_scope.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,15 @@ class CriteriaScope < Cuprum::Collections::Basic::Scope
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)
# Returns true if the provided item matches the configured criteria.
def match?(item:)
super

criteria.reduce(data) do |filtered, (attribute, operator, value)|
filtered.select(&filter_for(attribute, operator, value))
criteria.all? do |(attribute, operator, value)|
filter_for(attribute, operator, value).call(item)
end
end
alias matches? match?

private

Expand Down
20 changes: 20 additions & 0 deletions lib/cuprum/collections/basic/scopes/disjunction_scope.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# frozen_string_literal: true

require 'cuprum/collections/basic/scope'
require 'cuprum/collections/basic/scopes'
require 'cuprum/collections/scopes/container'

module Cuprum::Collections::Basic::Scopes
# Scope for filtering data matching any of the given scopes.
class DisjunctionScope < Cuprum::Collections::Basic::Scope
include Cuprum::Collections::Scopes::Container

# Returns true if the provided item matches any of the configured scopes.
def match?(item:)
super

scopes.any? { |scope| scope.match?(item: item) }
end
alias matches? match?
end
end
20 changes: 20 additions & 0 deletions lib/cuprum/collections/basic/scopes/negation_scope.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# frozen_string_literal: true

require 'cuprum/collections/basic/scope'
require 'cuprum/collections/basic/scopes'
require 'cuprum/collections/scopes/container'

module Cuprum::Collections::Basic::Scopes
# Scope for filtering data not matching at least one of the given scopes.
class NegationScope < Cuprum::Collections::Basic::Scope
include Cuprum::Collections::Scopes::Container

# Returns true if the provided item does not match at least one scope.
def match?(item:)
super

scopes.any? { |scope| !scope.match?(item: item) }
end
alias matches? match?
end
end
Loading
Loading