
import java.sql.*;
import java.util.*;

import org.apache.derby.iapi.services.context.ContextManager;
import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
import org.apache.derby.impl.jdbc.EmbedConnection;
import org.apache.derby.impl.sql.compile.QueryTreeNode;

/**
 * Little program to run the Derby parser on a text string and to print
 * the resulting abstract syntax tree produced by the parser.
 */
public class MyTreeWalker {
    ///////////////////////////////////////////////////////////////////////////////////
    //
    // CONSTANTS
    //
    ///////////////////////////////////////////////////////////////////////////////////

    Vector<MyField> vf = new Vector<MyField>();
    private static final String DRIVER_NAME = "org.apache.derby.jdbc.EmbeddedDriver";
    private static final String CONNECTION_URL = "jdbc:derby:memory:dummy;create=true";
    private static final String DERBY_DEBUG_SETTING = "derby.debug.true";
    private static final String STOP_AFTER_PARSING = "StopAfterParsing";
    private static final String STOPPED_AFTER_PARSING = "42Z55";
    private static final String SHUTDOWN_URL = "jdbc:derby:;shutdown=true";
    public static final String LANG_CONNECTION = "LanguageConnectionContext";

    // elements and attributes
    public static final String QUERY_TREE = "queryTree";
    public static final String QUERY_TEXT = "queryText";
    public static final String NODE = "node";
    public static final String NODE_TYPE_ATTR = "type";
    public static final String CONTENTS = "contents";
    public static final String MEMBER = "member";
    public static final String NAME_ATTR = "name";
    public static final String VALUE_ATTR = "value";
    ///////////////////////////////////////////////////////////////////////////////////
    //
    // STATE
    //
    ///////////////////////////////////////////////////////////////////////////////////

    ///////////////////////////////////////////////////////////////////////////////////
    //
    // CONSTRUCTOR
    //
    ///////////////////////////////////////////////////////////////////////////////////
    private MyTreeWalker() {
    }

    ///////////////////////////////////////////////////////////////////////////////////
    //
    // ENTRY POINT
    //
    ///////////////////////////////////////////////////////////////////////////////////
    /**
     * Entry point. Takes one argument: the string to be parsed. Along
     * the way, this program will create a dummy Derby database if it
     * doesn't already exist.
     *
     * <ul>
     * <li>arg[ 0 ] = Query text to parse and turn into an AST.</li>
     * </ul>
     */
    public static void main(String[] args)
            throws Exception {
        MyTreeWalker astParser = new MyTreeWalker();
//        String[] a = {"insert into eurofile.tdepro (dpcdst, dpcdme, dpcdpr) values(?, ?)"};
//        String[] a = {"insert into eurofile.tdepro (dpcdst, dpcdme, dpcdpr) (select aa a1, bb a2, cc a3 from eurofile.tdeppr where bb = ? and qq = ?)"};

//        String[] a = {"insert into eurofile.tdepro (dpcdst, dpcdme, dpcdpr) values(?, ?, ?)"};
//        String[] a = {"insert into eurofile.tdepro (dpcdst, dpcdme, dpcdpr) values(?, ?, 'PPP')"};
//        String[] a = {"INSERT INTO \"public\".\"a b c\" (a,b) VALUES ( ?, ?)"};


//        NB NB i caratteri per delimitare il nome della tabella vanno sostituiti; THIS DOESN'T WORK
//        String[] a = {"INSERT INTO `new table2` (c2,c3) VALUES ( ?, ?)"}
//        NB NB i caratteri per delimitare il nome della tabella vanno sostituiti;


//  String[] a = {"insert into eurofile.tdepro (dpcdst, dpcdme, dpcdpr) (select t.aa a1, t.bb a2, f.cc a3 from eurofile.tdeppr t, pippo.pluto f where t.bb = ? and f.qq = 'uuu')"};
//  String[] a = {"insert into eurofile.tdepro (dpcdst, dpcdme, dpcdpr) (select aa, bb, cc from eurofile.tdeppr, pippo.pluto where bb = ? and qq = 'uuu')"};
//  String[] a = {"insert into eurofile.tdepro (dpcdst, dpcdme, dpcdpr) (select t.*, u.bb, u.cc from eurofile.tdestr t, eurofile.tdeana u where u.bb = ? and t.qq = 'uuu')"};
//  String[] a = {"insert into eurofile.tdepro (select t.*, u.bb, u.cc from eurofile.tdestr t, eurofile.tdeana u where u.bb = ? and t.qq = 'uuu')"};
  String[] a = {"insert into eurofile.tdepro values(?, ?, 'dddd', ?, 1, ?)"};


  astParser.execute(a);
    }

    private void execute(String[] args)
            throws Exception {
        System.setProperty(DERBY_DEBUG_SETTING, STOP_AFTER_PARSING);
        Class.forName(DRIVER_NAME);

        String text = args[ 0];
        Connection conn = DriverManager.getConnection(CONNECTION_URL);
        PreparedStatement ps = null;

        {
            try {
                ps = conn.prepareStatement(text);
            } catch (SQLException se) {
                String sqlState = se.getSQLState();

                if (!STOPPED_AFTER_PARSING.equals(sqlState)) {
                    throw se;
                }
            }

            ContextManager contextManager = ((EmbedConnection) conn).getContextManager();
//            LanguageConnectionContext   lcc = (LanguageConnectionContext) contextManager.getContext( ContextId.LANG_CONNECTION);
            LanguageConnectionContext lcc = (LanguageConnectionContext) contextManager.getContext(LANG_CONNECTION);
            QueryTreeNode queryTree = (QueryTreeNode) lcc.getLastQueryTree();

            MyInsertParser mip = new MyInsertParser();
            queryTree.accept(mip);
            mip.endVisit();
            vf = mip.getData();
        }

        for (int i = 0; i < vf.size(); i++) {
            System.out.println("nodo " + i + "= " + vf.elementAt(i).toString());
        }
        try {
            DriverManager.getConnection(SHUTDOWN_URL);
        } catch (Exception e) {
        }
    }

}
