2012-04-27 31 views
13

Có cách nào dễ dàng để in đẹp SQL ngẫu nhiên trong bảng điều khiển (đường ray 3) không?SQL In Khá trong Ruby

Tương tự như awesome_print hoặc thậm chí Pretty Print.

Nó không phải hiểu tất cả các phương ngữ có thể hoặc là siêu cao cấp.
Tất cả những gì tôi thực sự muốn là kiểm tra SQL được tạo bởi ActiveRecord dễ dàng hơn.

Hiện tại tôi chỉ cần sao chép SQL trực tuyến để định dạng nó rõ ràng là một kẻ giết người năng suất.

Tôi thực sự muốn query.to_sql.pretty_format_sql và thấy kết quả đẹp hơn.

Cảm ơn.

+0

Nếu bạn đang sử dụng JRuby bạn có thể xem xét một số câu trả lời cho một [câu hỏi tương tự] (http://stackoverflow.com/q/312552/215168) đặt ra cho Java, chẳng hạn như 'org.hibernate Hibernate của. jdbc.util.BasicFormatterImpl' –

+0

Hah, sử dụng MRI. –

Trả lời

9

Hãy thử điều này:

git clone https://github.com/sonota/anbt-sql-formatter 
cd anbt-sql-formatter 
rails setup.rb 

Sau đó, trong một initializer Rails:

# config/initializers/pretty_format_sql.rb 
class String 
    def pretty_format_sql 
    require "anbt-sql-formatter/formatter" 
    rule = AnbtSql::Rule.new 
    rule.keyword = AnbtSql::Rule::KEYWORD_UPPER_CASE 
    %w(count sum substr date).each{|func_name| 
     rule.function_names << func_name.upcase 
    } 
    rule.indent_string = " " 
    formatter = AnbtSql::Formatter.new(rule) 
    formatter.format(self) 
    end 
end 

Test:

rails console 
# Some complex SQL 
puts Recipe.joins(:festivity).where(['? BETWEEN festivities.starts_at AND festivities.ends_at', Time.utc(0,Time.now.month,Time.now.day,12,0,0)]).to_sql.pretty_format_sql 
SELECT 
     "recipes" . * 
    FROM 
     "recipes" INNER JOIN "festivities" 
      ON "festivities" . "id" = "recipes" . "festivity_id" 
    WHERE 
     (
      '0000-04-27 12:00:00.000000' BETWEEN festivities.starts_at AND festivities.ends_at 
     ) 
=> nil 

tôi để lại tinh chỉnh cho bạn (refactoring: khỉ vá -> mô-đun, định dạng tùy chỉnh, v.v.-))

+2

Nó nên làm công việc, nhưng tôi thực sự muốn tránh việc sử dụng các plugin không được chấp nhận (không đá quý). –

+0

Tôi cảm thấy rằng nó không phải là một "tiêu chuẩn" lib ... nhưng nó không phải là khó để trích xuất các phần tốt và làm cho họ một viên ngọc (tôi đã thử nghiệm nó và nó hoạt động khá tốt, và thấy rằng tôi couldnt tìm giải pháp thay thế, tại sao lại viết lại những điều làm việc?) ... Tôi sẽ cố gắng! – mdesantis

7

Các anbt-sql-formatter của first answeravailable as a gem, bạn có thể cài đặt nó với:

gem install anbt-sql-formatter 

Dưới đây là một ví dụ về việc sử dụng:

require "anbt-sql-formatter/formatter" 
rule = AnbtSql::Rule.new 
    formatter = AnbtSql::Formatter.new(rule) 

[ 
"SELECT `col1`, `col2` FROM `table` WHERE ((`col1` = 1) AND (`col2` = 5))", 
"SELECT `col1`, `col2` FROM `table` WHERE (`col1` = 1) AND (`col2` = 5)", 
"SELECT `col1` FROM `table` WHERE (`col1` IN (SELECT * FROM `table21` WHERE (`col2` = 5)))", 
"SELECT `col1` FROM `table` INNER JOIN `tab2` ON (`tab1`.`id` = `tab2`.`id1`) WHERE ((`id` >= 1) AND (`id` <= 5))", 
].each{|sql_cmd| 
    puts "======" 
    puts sql_cmd 
    puts formatter.format(sql_cmd) 
} 

Kết quả:

====== 
SELECT `col1`, `col2` FROM `table` WHERE ((`col1` = 1) AND (`col2` = 5)) 
SELECT 
     `col1` 
     ,`col2` 
    FROM 
     `table` 
    WHERE 
     (
      (
       `col1` = 1 
      ) 
      AND (
       `col2` = 5 
      ) 
     ) 
====== 
SELECT `col1`, `col2` FROM `table` WHERE (`col1` = 1) AND (`col2` = 5) 
SELECT 
     `col1` 
     ,`col2` 
    FROM 
     `table` 
    WHERE 
     (
      `col1` = 1 
     ) 
     AND (
      `col2` = 5 
     ) 
====== 
SELECT `col1` FROM `table` WHERE (`col1` IN (SELECT * FROM `table21` WHERE (`col2` = 5))) 
SELECT 
     `col1` 
    FROM 
     `table` 
    WHERE 
     (
      `col1` IN (
       SELECT 
         * 
        FROM 
         `table21` 
        WHERE 
         (
          `col2` = 5 
         ) 
      ) 
     ) 
====== 
SELECT `col1` FROM `table` INNER JOIN `tab2` ON (`tab1`.`id` = `tab2`.`id1`) WHERE ((`id` >= 1) AND (`id` <= 5)) 
SELECT 
     `col1` 
    FROM 
     `table` INNER JOIN `tab2` 
      ON (
      `tab1`.`id` = `tab2`.`id1` 
     ) 
    WHERE 
     (
      (
       `id` >= 1 
      ) 
      AND (
       `id` <= 5 
      ) 
     ) 

Cũng là khả năng mở rộng các quy tắc, ví dụ

# User defined additional functions: 
%w(count sum substr date coalesce).each{|func_name| 
    rule.function_names << func_name.upcase 
}