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