lib/mobility/backends/sequel/pg_query_methods.rb in mobility-0.5.1 vs lib/mobility/backends/sequel/pg_query_methods.rb in mobility-0.6.0
- old
+ new
@@ -1,27 +1,38 @@
+# frozen_string_literal: true
+
module Mobility
module Backends
module Sequel
=begin
-Defines query methods for Postgres backends. Including class must define two
-private methods:
+Internal module builder defining query methods for Postgres backends. Including
+class must define three methods:
-- a private method +matches+ which takes a key (column name), value and
- locale and returns an SQL expression, and checks that the column has the
- specified value in the specified locale
-- a private method +has_locale+ which takes a key (column name) and locale, and
- returns an SQL expression which checks that the column has a value in the
- locale
+- a method +matches+ which takes a key (column name) and a locale to match and
+ returns an SQL expression checking that the column has the specified value
+ in the specified locale
+- a method +exists+ which takes a key (column name) and locale, and returns
+ an SQL expression which checks that the column has a value in the locale
+- a method +quote+ which quotes the value to be matched
-(The +matches+ and +has_locale+ methods are implemented slightly differently
+(The +matches+/+exists+/+quote+ methods are implemented slightly differently
for hstore/json/jsonb/container backends.)
+@see Mobility::Backends::Sequel::Json::QueryMethods
+@see Mobility::Backends::Sequel::Jsonb::QueryMethods
+@see Mobility::Backends::Sequel::Hstore::QueryMethods
+@see Mobility::Backends::Sequel::Container::JsonQueryMethods
+@see Mobility::Backends::Sequel::Container::JsonbQueryMethods
+
=end
module PgQueryMethods
- def initialize(attributes, _)
+ attr_reader :column_affix
+
+ def initialize(attributes, options)
super
+ @column_affix = "#{options[:column_prefix]}%s#{options[:column_suffix]}"
define_query_methods
end
# Create query for conditions and translated keys
# @note This is a destructive action, it will alter +cond+.
@@ -31,15 +42,27 @@
# @param [Boolean] invert Invert query, true for +exclude+, false otherwise
# @return [Sequel::SQL::Expression] Query expression
def create_query!(cond, keys, invert = false)
keys.map { |key|
values = cond.delete(key)
- values = [values] unless values.is_a?(Array)
- values.map { |value| create_query_op(key, value, invert) }.inject(&:|)
+ values = values.is_a?(Array) ? values.uniq: [values]
+ create_query_op(key, values, invert)
}.inject(invert ? :| : :&)
end
+ def matches(_key, _locale)
+ raise NotImplementedError
+ end
+
+ def exists(_key, _locale)
+ raise NotImplementedError
+ end
+
+ def quote(_value)
+ raise NotImplementedError
+ end
+
private
def define_query_methods
%w[exclude or where].each do |method_name|
define_query_method(method_name)
@@ -64,26 +87,28 @@
super(*cond, &block)
end
end
end
- def create_query_op(key, value, invert)
+ def create_query_op(key, values, invert)
locale = Mobility.locale.to_s
+ values = values.map(&method(:quote))
+ values = values.first if values.size == 1
+ match = matches(key, locale) =~ values
+
if invert
- has_locale(key, locale) & ~matches(key, value, locale)
+ exists(key, locale) & ~match
else
- value.nil? ? ~has_locale(key, locale) : matches(key, value, locale)
+ values.nil? ? ~exists(key, locale) : match
end
end
- def matches(_key, _value, _locale)
- raise NotImplementedError
- end
- def has_locale(_key, _locale)
- raise NotImplementedError
+ def column_name(attribute)
+ (column_affix % attribute).to_sym
end
end
+ private_constant :PgQueryMethods
end
end
end