001 002package gudusoft.gsqlparser.pp.stmtformatter; 003 004import gudusoft.gsqlparser.EDbVendor; 005import gudusoft.gsqlparser.ETokenType; 006import gudusoft.gsqlparser.TCustomSqlStatement; 007import gudusoft.gsqlparser.TGSqlParser; 008import gudusoft.gsqlparser.TSourceToken; 009import gudusoft.gsqlparser.TSourceTokenList; 010import gudusoft.gsqlparser.pp.para.GFmtOpt; 011import gudusoft.gsqlparser.pp.para.GFmtOptFactory; 012import gudusoft.gsqlparser.pp.para.styleenums.TAlignStyle; 013import gudusoft.gsqlparser.pp.para.styleenums.TCaseOption; 014import gudusoft.gsqlparser.pp.para.styleenums.TLinefeedsCommaOption; 015import gudusoft.gsqlparser.pp.print.IPrinter; 016import gudusoft.gsqlparser.pp.print.PrinterFactory; 017 018import java.io.ByteArrayOutputStream; 019import java.io.OutputStream; 020import java.util.concurrent.Callable; 021import java.util.concurrent.FutureTask; 022 023public class SqlFormatter 024{ 025 026 public String format( TGSqlParser parser, GFmtOpt option ) 027 { 028 if (option.removeComment) { 029 parser = preHandleRemoveComment(parser); 030 } 031 032 OutputStream o = new ByteArrayOutputStream( ); 033 IPrinter printer = PrinterFactory.createTextPrinter( o ); 034 035 FormatterFactory.createAllStmtsFormatter( option ) 036 .beforeFormat( parser.sqlstatements ); 037 038 for ( int i = 0; i < parser.sqlstatements.size( ); i++ ) 039 { 040 TCustomSqlStatement sql = parser.sqlstatements.get( i ); 041 FormatterFactory.processStatement( option, sql ); 042 } 043 if ( parser.sqlstatements != null && parser.sqlstatements.size( ) > 0 ) 044 { 045 FormatterFactory.createAllStmtsFormatter( option ) 046 .doFormat( parser.sqlstatements ); 047 FormatterFactory.createAllStmtsFormatter( option ) 048 .afterFormat( parser.sqlstatements ); 049 050 printer.setOutputConfig( FormatterFactory.outputConfigFor( option, parser.getDbVendor( ) ) ); 051 printer.print( parser.sqlstatements.get( 0 ).getStartToken( ).container ); 052 } 053 054 FormatterFactory.clearAllObject( option.sessionId ); 055 return o.toString( ); 056 } 057 058 public static TGSqlParser preHandleRemoveComment(TGSqlParser parser) { 059 Callable<String> removeCommenTask = new Callable<String>() { 060 @Override 061 public String call() throws Exception { 062 GFmtOpt removeCommentOption = GFmtOptFactory.newInstance(); 063 removeCommentOption.removeComment = true; 064 OutputStream o = new ByteArrayOutputStream(); 065 IPrinter printer = PrinterFactory.createTextPrinter(o); 066 067 TSourceToken startToken = parser.sqlstatements.get( 0 ).getStartToken( ); 068 TSourceTokenList list = startToken.container; 069 for (int i = 0; i < list.size(); i++) { 070 TSourceToken t = list.get(i); 071 if (t.tokentype == ETokenType.ttsimplecomment || t.tokentype == ETokenType.ttbracketedcomment) { 072 if ( t.toString( ).startsWith( "/*+" ) ) 073 continue; 074 t.setAstext(" "); 075 t.tokentype = ETokenType.ttwhitespace; 076 } 077 } 078 079 // SQL whatever the caller prints with: this text is parsed again (printed as HTML, the 080 // HTML itself was parsed and formatted into a second layer of HTML) 081 printer.setOutputConfig( null ); 082 printer.print( parser.sqlstatements.get( 0 ).getStartToken( ).container ); 083 084 085 FormatterFactory.clearAllObject(removeCommentOption.sessionId); 086 return o.toString(); 087 } 088 }; 089 090 FutureTask<String> futureTask = new FutureTask<>(removeCommenTask); 091 Thread thread = new Thread(futureTask); 092 thread.start(); 093 094 try { 095 String removeCommentSql = futureTask.get(); 096 TGSqlParser removeCommentParser = new TGSqlParser( parser.getDbVendor() ); 097 removeCommentParser.sqltext = removeCommentSql; 098 removeCommentParser.parse(); 099 return removeCommentParser; 100 } catch (Exception e) { 101 } 102 return parser; 103 } 104 105 public static void main( String[] args ) 106 { 107 GFmtOpt option = GFmtOptFactory.newInstance( ); 108 option.linenumberEnabled = false; 109 option.parametersStyle = TAlignStyle.AsStacked; 110 option.parametersComma = TLinefeedsCommaOption.LfbeforeCommaWithSpace; 111 option.beStyleFunctionRightBEOnNewline = false; 112// option.removeComment = true; 113 option.caseKeywords = TCaseOption.CoLowercase; 114 option.caseWhenThenInSameLine = true; 115// option.linenumberEnabled = true; 116 TGSqlParser sqlparser = new TGSqlParser( EDbVendor.dbvpostgresql ); 117 sqlparser.sqltext = 118 119 120 "\n" + 121 "WITH RECURSIVE employee_recursive(distance, employee_name, manager_name) AS (\n" + 122 " SELECT 1, employee_name, manager_name\n" + 123 " FROM employee\n" + 124 " WHERE manager_name = 'Mary'\n" + 125 " UNION ALL\n" + 126 " SELECT er.distance + 1, e.employee_name, e.manager_name\n" + 127 " FROM employee_recursive er, employee e\n" + 128 " WHERE er.employee_name = e.manager_name\n" + 129 " )\n" + 130 "SELECT distance, employee_name FROM employee_recursive;\n"; 131 sqlparser.parse( ); 132 String result = new SqlFormatter( ).format( sqlparser, option ); 133 System.out.println( result ); 134 135 } 136}