feat(query): introduce Prism and Orm

This commit is contained in:
dualfroz committed 2026-09-08 20:46:43 +02:00
1 parent 4e8b73332d
commit 9b333d5046
1 file changed
+54
+54
View File
@@ -0,0 +1,54 @@
module Prism
module Orm
module Query
module Predicates
OPERATORS = {
eq: ->(actual, expected) { actual == expected },
ne: ->(actual, expected) { actual != expected },
gt: ->(actual, expected) { !actual.nil? && actual > expected },
gte: ->(actual, expected) { !actual.nil? && actual >= expected },
lt: ->(actual, expected) { !actual.nil? && actual < expected },
lte: ->(actual, expected) { !actual.nil? && actual <= expected },
in: ->(actual, expected) { Array(expected).include?(actual) },
not_in: ->(actual, expected) { !Array(expected).include?(actual) },
like: ->(actual, expected) { !actual.nil? && like_match?(actual, expected) },
not_like: ->(actual, expected) { !actual.nil? && !like_match?(actual, expected) }
}.freeze
class UnknownOperator < StandardError; end
def self.like_match?(actual, pattern)
source = '\A' + Regexp.escape(pattern.to_s).gsub('%', '.*').gsub('_', '.') + '\z'
actual.to_s.match?(Regexp.new(source, Regexp::IGNORECASE))
end
# Evaluates a single column's stored value against an expected
# matcher, which may be a scalar, Range, Array, Regexp, or a Hash
# of operator => value pairs (e.g. { gt: 5, lt: 10 }).
def self.evaluate(actual, expected)
case expected
when Hash
expected.all? { |operator, value| evaluate_operator(actual, operator, value) }
when Range
expected.cover?(actual)
when Regexp
!actual.nil? && actual.to_s.match?(expected)
when Array
expected.include?(actual)
else
actual == expected
end
end
def self.evaluate_operator(actual, operator, value)
operator = operator.to_sym
return value ? actual.nil? : !actual.nil? if operator == :is_null
fn = OPERATORS[operator]
raise UnknownOperator, "unknown query operator #{operator.inspect}" unless fn
fn.call(actual, value)
end
end
end
end
end