aboutsummaryrefslogblamecommitdiffstats
path: root/lib/arel/engines/sql/formatters.rb
blob: 03e7deec007f8e6b45b454717cda188ad0e09a6b (plain) (tree)
1
2
3
4
5
6
7
8
9


                   
                                                    
 

                                  
                                             
                                         
         




                                  




                                                
                                               




                                             
       
 

                                  

                                                                                                           
         
 
                                
                                                

                                                                                
            

                                                                                                                               
           
         
 
                                   
                                                                 
         
 



                      
 




                                 
 

                                   
 
                                   

                                                                                                                                                     

         
 




                                                                                                         
 





                                    



                                                                                                         
 


                                                                          
 
                      
                          
         
 


                                     
 
                                   


                         
 
                                     
                                   


                  
 
                                    
                                   
                                                              
         
 
                      






                                                                                

         
 



                                         
 
                            
                                              

         
 


                                
   
module Arel
  module Sql
    class Formatter
      attr_reader :environment, :christener, :engine

      def initialize(environment)
        @environment = environment
        @christener  = environment.christener
        @engine      = environment.engine
      end

      def name_for thing
        @christener.name_for thing
      end

      def quote_column_name name
        engine.connection.quote_column_name name
      end

      def quote_table_name name
        engine.connection.quote_table_name name
      end

      def quote value, column = nil
        engine.connection.quote value, column
      end
    end

    class SelectClause < Formatter
      def attribute(attribute)
        "#{quote_table_name(name_for(attribute.original_relation))}.#{quote_column_name(attribute.name)}" +
        (attribute.alias ? " AS #{quote(attribute.alias.to_s)}" : "")
      end

      def expression(expression)
        if expression.function_sql == "DISTINCT"
          "#{expression.function_sql} #{expression.attribute.to_sql(self)}" +
          (expression.alias ? " AS #{quote_column_name(expression.alias)}" : '')
        else
          "#{expression.function_sql}(#{expression.attribute.to_sql(self)})" +
          (expression.alias ? " AS #{quote_column_name(expression.alias)}" : " AS #{expression.function_sql.to_s.downcase}_id")
        end
      end

      def select(select_sql, table)
        "(#{select_sql}) AS #{quote_table_name(name_for(table))}"
      end

      def value(value)
        value
      end
    end

    class PassThrough < Formatter
      def value(value)
        value
      end
    end

    class WhereClause < PassThrough
    end

    class OrderClause < PassThrough
      def ordering(ordering)
        "#{quote_table_name(name_for(ordering.attribute.original_relation))}.#{quote_column_name(ordering.attribute.name)} #{ordering.direction_sql}"
      end
    end

    class GroupClause < PassThrough
      def attribute(attribute)
        "#{quote_table_name(name_for(attribute.original_relation))}.#{quote_column_name(attribute.name)}"
      end
    end

    class HavingClause < PassThrough
      def attribute(attribute)
        attribute
      end
    end

    class WhereCondition < Formatter
      def attribute(attribute)
        "#{quote_table_name(name_for(attribute.original_relation))}.#{quote_column_name(attribute.name)}"
      end

      def expression(expression)
        "#{expression.function_sql}(#{expression.attribute.to_sql(self)})"
      end

      def value(value)
        value.to_sql(self)
      end

      def scalar(value, column = nil)
        quote(value, column)
      end

      def select(select_sql, table)
        "(#{select_sql})"
      end
    end

    class SelectStatement < Formatter
      def select(select_sql, table)
        select_sql
      end
    end

    class TableReference < Formatter
      def select(select_sql, table)
        "(#{select_sql}) #{quote_table_name(name_for(table))}"
      end

      def table(table)
        table_name = table.name
        return table_name if table_name =~ /\s/

        unique_name = name_for(table)

        quote_table_name(table_name) +
          (table_name != unique_name ? " #{quote_table_name(unique_name)}" : '')
      end
    end

    class Attribute < WhereCondition
      def scalar(scalar)
        quote(scalar, environment.column)
      end

      def range(left, right)
        "#{scalar(left)} AND #{scalar(right)}"
      end
    end

    class Value < WhereCondition
    end
  end
end