From 3092fe408a79d887ab69dc5ae7e6a0037a553f8f Mon Sep 17 00:00:00 2001 From: Chris Salzberg Date: Fri, 7 Sep 2018 15:14:12 +0900 Subject: [PATCH] Refactor --- lib/mobility/backends/sequel/key_value.rb | 48 ++++++++++++------- lib/mobility/backends/sequel/table.rb | 58 ++++++++++++++--------- 2 files changed, 66 insertions(+), 40 deletions(-) diff --git a/lib/mobility/backends/sequel/key_value.rb b/lib/mobility/backends/sequel/key_value.rb index 3d0634ac6..4017b93e6 100644 --- a/lib/mobility/backends/sequel/key_value.rb +++ b/lib/mobility/backends/sequel/key_value.rb @@ -75,31 +75,45 @@ def join_translations(dataset, attr, locale, join_type) def visit(predicate, locale) case predicate when Array - predicate.map { |p| visit(p, locale) }.compact.inject do |hash, visited| - visited.merge(hash) { |_, old, new| old == :inner ? old : new } - end + visit_collection(predicate, locale) when ::Mobility::Sequel::SQL::QualifiedIdentifier - if predicate.backend_class == self && predicate.locale == locale - { predicate.attribute_name => :inner } - end + visit_sql_identifier(predicate, locale) when ::Sequel::SQL::BooleanExpression - if predicate.op == :IS - nils, ops = predicate.args.partition(&:nil?) - if hash = visit(ops, locale) - join_type = nils.empty? ? :inner : :left_outer - Hash[hash.keys.map { |key| [key, join_type] }] - else - {} - end - else - visit(predicate.args, locale) - end + visit_boolean(predicate, locale) when ::Sequel::SQL::Expression visit(predicate.args, locale) else {} end end + + def visit_boolean(boolean, locale) + if boolean.op == :IS + nils, ops = boolean.args.partition(&:nil?) + if hash = visit(ops, locale) + join_type = nils.empty? ? :inner : :left_outer + Hash[hash.keys.map { |key| [key, join_type] }] + else + {} + end + else + visit(boolean.args, locale) + end + end + + def visit_collection(collection, locale) + collection.map { |p| visit(p, locale) }.compact.inject do |hash, visited| + visited.merge(hash) { |_, old, new| old == :inner ? old : new } + end + end + + def visit_sql_identifier(identifier, locale) + if identifier.backend_class == self && identifier.locale == locale + { identifier.attribute_name => :inner } + else + {} + end + end end setup do |attributes, options| diff --git a/lib/mobility/backends/sequel/table.rb b/lib/mobility/backends/sequel/table.rb index 5247dbb38..483182d0c 100644 --- a/lib/mobility/backends/sequel/table.rb +++ b/lib/mobility/backends/sequel/table.rb @@ -66,24 +66,27 @@ def prepare_dataset(dataset, predicate, locale) private + def join_translations(dataset, locale, join_type) + if joins = dataset.opts[:join] + return dataset if joins.any? { |clause| clause.table_expr.alias == table_alias(locale) } + end + dataset.join_table(join_type, + translation_class.table_name, + { + locale: locale.to_s, + foreign_key => ::Sequel[model_class.table_name][:id] + }, + table_alias: table_alias(locale)) + end + def visit(predicate, locale) case predicate when Array - predicate.map { |obj| - visit(obj, locale).tap do |visited| - return visited if visited == :inner - end - }.compact.first + visit_collection(predicate, locale) when ::Mobility::Sequel::SQL::QualifiedIdentifier - (table_alias(locale) == predicate.table) && :inner + visit_sql_identifier(predicate, locale) when ::Sequel::SQL::BooleanExpression - if predicate.op == :'=' - predicate.args.any? { |op| visit(op, locale) } && :inner - elsif predicate.op == :IS - predicate.args.any?(&:nil?) && :left_outer - else - visit(predicate.args, locale) - end + visit_boolean(predicate, locale) when ::Sequel::SQL::Expression visit(predicate.args, locale) else @@ -91,17 +94,26 @@ def visit(predicate, locale) end end - def join_translations(dataset, locale, join_type) - if joins = dataset.opts[:join] - return dataset if joins.any? { |clause| clause.table_expr.alias == table_alias(locale) } + def visit_collection(collection, locale) + collection.map { |obj| + visit(obj, locale).tap do |visited| + return visited if visited == :inner + end + }.compact.first + end + + def visit_sql_identifier(identifier, locale) + (table_alias(locale) == identifier.table) && :inner + end + + def visit_boolean(boolean, locale) + if boolean.op == :'=' + boolean.args.any? { |op| visit(op, locale) } && :inner + elsif boolean.op == :IS + boolean.args.any?(&:nil?) && :left_outer + else + visit(boolean.args, locale) end - dataset.join_table(join_type, - translation_class.table_name, - { - locale: locale.to_s, - foreign_key => ::Sequel[model_class.table_name][:id] - }, - table_alias: table_alias(locale)) end end