tags:

views:

216

answers:

1

I am developing an application that needs to store information to a database. I would like to use a Scala solution if possible. If the database connectivity fails for some reason, I would like to write the raw SQL statements that would have been executed to a .sql script file. The idea is that when/if the connectivity to the database is restored I would like to execute that script in Scala/Java to bring the database back into sync. It is also nice to have the .sql script around in case there is a failure in the program, so that a manual execution of the script could occur.

How do I record the sql statements that I am going to execute to a file in Scala/Java? Then, how do I execute a that file (or really any .sql script) in Scala/Java?

+4  A: 

you can proxy your Connection object:

public class ConnectionProxy {

    public ConnectionProxy(Object anObject) {
        super(anObject);
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {              
        Object result = method.invoke(target, args);
        String methodName = method.getName();

        if (methodName.equals("createStatement")) {
            result = ProxyBuilder.createProxy(result, new StatementProxy(result));
        }

        return result;
    }
}

in order to intercept any call to Statement.execute(String sql):

public class StatementProxy {

    public StatementProxy(Object anObject) {
        super(anObject);
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {               
       try {
           return method.invoke(proxy, args);
       } catch (SQLException sqle) {
           if (method.getName().contains("execute")) {
              String sql = "";

              if (args != null && args[0] != null) {
                  sql = args[0].toString();
              }

              saveToFile(arg);
           }

           throw sqle;   
        }
    }
}

where ProxyBuilder is a simple helper class:

public final class ProxyBuilder {

    public static Connection tracingConnection(Connection connection) {
        return createProxy(connection, new ConnectionProxy(connection));
    }

    static <T> T createProxy(T anObject, InvocationHandler invocationHandler) {
        return createProxy(anObject, invocationHandler, anObject.getClass().getInterfaces());
    }

    static <T> T createProxy(T anObject, InvocationHandler invocationHandler, Class... forcedInterfaces) {
        return (T) Proxy.newProxyInstance(
            anObject.getClass().getClassLoader(),
            forcedInterfaces,
            invocationHandler);
        }
}

Of course, this is not your final production code but it is a good starting point.

dfa