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