card/lib/card/query/sql_statement/where.rb
class Card
module Query
class SqlStatement
# handle where clause in SqlStatement
module Where
def where explicit=true
conditions = [explicit_conditions(@query), implicit_conditions(@query)]
conditions = conditions.reject(&:blank?).join " AND "
"#{'WHERE ' if explicit}#{conditions}" unless conditions.blank?
end
# conditions explicitly specified in the query object
def explicit_conditions query
cond_list = basic_conditions query.conditions
cond_list += conditions_from query.subqueries
cond_list.reject!(&:blank?)
format_conditions cond_list, query
end
# depending on how a query is "fastened", its conditions may be rendered
# along with the superquery's
def conditions_from subqueries
subqueries.map do |query|
next if query.conditions_on_join
case query.fasten
when :exist then exist_condition query
when :in then in_condition query
else explicit_conditions query
end
end
end
def exist_condition query
"#{maybe_not query}EXISTS (#{spaced_subquery_sql query})"
end
def maybe_not query
query.negate ? "NOT " : ""
end
def in_condition query
field = query.mods[:in_field]
"#{field} #{maybe_not query}IN (#{spaced_subquery_sql query})"
end
def spaced_subquery_sql subquery
"\n#{subquery.sql}\n#{leading_space}"
end
# the conditions stored in the query's @conditions variable
def basic_conditions conditions
conditions.map do |condition|
case condition
when String then condition
when Array then standard_condition(condition)
end
end
end
def standard_condition condition
field, val = condition
val.to_sql field
end
# handle trash and permissions
# only applies to card queries
def implicit_conditions query
return unless query.is_a?(CardQuery)
table = query.table_alias
[trash_condition(table), permission_conditions(table)].compact * " AND "
end
def trash_condition table
"#{table}.trash is false"
end
def permission_conditions table
return if Auth.always_ok?
read_rules = Auth.as_card.read_rules
read_rule_list = read_rules.present? ? read_rules.join(",") : 1
"#{table}.read_rule_id IN (#{read_rule_list})"
end
# convert list of conditions to string
def format_conditions cond_list, query
if cond_list.size > 1
"(#{cond_list.join condition_joint(query)})"
else
cond_list.join
end
end
def condition_joint query
" #{query.current_conjunction.upcase} "
end
end
end
end
end