class Card::Query::SqlStatement

At present, SqlStatement contains (imho) too much knowledge about card constructs. For example, all the permission and trash handling is here.

In principle, the Query class should “interpret” statements into a few objects and a clean Query hierarchy. The SqlStatement class should be able to traverse that hierarchy and do little more than run “to_sql” on its parts, and in so doing construct a valid SQL statement.

convert @query sort rep into order by statement order information is stored in @mods, @mods, and @mods

Constants

ORDER_MAP

Public Class Methods

new(query=nil) click to toggle source
# File lib/card/query/sql_statement.rb, line 18
def initialize query=nil
  @query = query
  @mods = query&.mods
end

Public Instance Methods

build() click to toggle source
# File lib/card/query/sql_statement.rb, line 23
def build
  @fields = fields
  @tables = tables
  @joins  = joins
  @where  = where
  @group  = group
  @order  = order
  @limit_and_offset = limit_and_offset
  self
end
cast_type(type) click to toggle source
# File lib/card/query/sql_statement.rb, line 114
def cast_type type
  cxn ||= ActiveRecord::Base.connection
  (val = cxn.cast_types[type.to_sym]) ? val[:name] : safe_sql(type)
end
comment() click to toggle source
# File lib/card/query/sql_statement.rb, line 52
def comment
  return nil unless Card.config.sql_comments && @query.comment

  "/* #{@query.comment} */\n"
end
fields() click to toggle source
# File lib/card/query/sql_statement.rb, line 62
def fields
  table = @query.table_alias
  field = @mods[:return] unless @mods[:return] =~ /^_\w+/
  field = field.blank? ? :card : field.to_sym
  field = full_field(table, field)
  [field, @mods[:sort_join_field]].compact * ", "
end
from() click to toggle source
# File lib/card/query/sql_statement.rb, line 44
def from
  "FROM #{@tables}"
end
full_field(table, field) click to toggle source
# File lib/card/query/sql_statement.rb, line 70
def full_field table, field
  case field
  when :card, :raw then "#{table}.*"
  when :content    then "#{table}.db_content"
  when :name, :key then "#{table}.name, #{table}.left_id, #{table}.right_id"
  when :count      then "coalesce(count( distinct #{table}.id),0) as count"
  else
    standard_full_field table, field
  end
end
full_syntax() { |: return| ... } click to toggle source
# File lib/card/query/sql_statement.rb, line 106
def full_syntax
  @query.full? ? yield : return
end
group() click to toggle source
# File lib/card/query/sql_statement.rb, line 89
def group
  group = @mods[:group]
  "GROUP BY #{safe_sql group}" if group.present?
end
leading_space() click to toggle source
# File lib/card/query/sql_statement.rb, line 48
def leading_space
  " " * (@query.depth * 2)
end
limit_and_offset() click to toggle source
# File lib/card/query/sql_statement.rb, line 94
def limit_and_offset
  full_syntax do
    limit = @mods[:limit]
    offset = @mods[:offset]
    if limit.to_i.positive?
      string =  "LIMIT  #{limit.to_i} "
      string += "OFFSET #{offset.to_i} " if offset.present?
      string
    end
  end
end
safe_sql(txt) click to toggle source
# File lib/card/query/sql_statement.rb, line 110
def safe_sql txt
  Query.safe_sql txt
end
select() click to toggle source
# File lib/card/query/sql_statement.rb, line 40
def select
  "#{leading_space}SELECT DISTINCT #{@fields}"
end
standard_full_field(table, field) click to toggle source
# File lib/card/query/sql_statement.rb, line 81
def standard_full_field table, field
  if Query.attributes[field.to_sym] == :basic
    "#{table}.#{field}"
  else
    safe_sql field
  end
end
tables() click to toggle source
# File lib/card/query/sql_statement.rb, line 58
def tables
  "#{@query.table} #{@query.table_alias}"
end
to_s() click to toggle source
# File lib/card/query/sql_statement.rb, line 34
def to_s
  [
    comment, select, from, @joins, @where, @group, @order, @limit_and_offset
  ].compact.join " "
end