RSS
 

Photosynth iPhone app

23 Apr

Photosynth has been around for some time but something changed. Microsoft just releases an iPhone app allowing any user to capture panoramas in a very simple way.

I can see how I will use it to capture landscapes and beautiful skies from my iPhone.

I just went outside to try it out. This first pano is not very interesting but I wanted to try out the sharing features.

There you go:

 
No Comments

Posted in iPhone

 

EasyMock and OraclePreparedStatement

12 Feb

Last week, I started using EasyMock to test methods that call an Oracle database’s stored procedures. Typically, those methods receive an object implementing the java.sql.Connection interface.

We later get a CallableStatement out of the Connection, and start calling methods on the statement in order to pass parameters to the stored procedure before calling the statement’s execute method.

In one particular case, we were trying to pass an Oracle ARRAY to the stored procedure. For this, we need to call the setARRAY method on the statement. The problem is that setARRAY is not part of the CallableStatement interface but is specific to the OraclePreparedStatement interface.

The documented way of working this out is to cast the callable statement into an OraclePreparedStatement and then call setARRAY.

public void saveArrayToDatabase(
    Connection connection, ARRAY myArray) throws SQLException
{
  CallableStatement statement =
      connection.prepareCall("{call my_pkg.my_function(?,?)}");
  statement.setLong(1, myId);
  ((OraclePreparedStatemement)statement).setARRAY(2, myArray);
  statement.execute();
}

I can’t really say I’m happy with this cast, but that’s how it work, so just add a
// They made me do it
comment and move on.

Now, to test this method we need a Connection object whose prepareCall implementation returns a valid CallableStatement object (otherwise, the method would not execute successfully).
I initially created two mock objects this way in the JUnit test:

Connection mockConnection =
  createMock("mockConnection", Connection.class);
final CallableStatement mockCallableStatement =
  createMock("mockCallableStatement", CallableStatement.class);

Then, to make the prepareCall method on the mockConnection object return the callable statement mock object, I used an “expectation” and EasyMock’s IAnswer interface:

expect(mockConnection.prepareCall("{call my_pkg.my_function(?,?)}"))
  .andAnswer(new IAnswer<CallableStatement>() {
  public CallableStatement answer() throws Throwable {
    return mockCallableStatement;
  }
});

More EasyMock expectations can be defined, but the rubber really meets the road when, in the JUnit test, the method under test is called:

dbproxy.saveArrayToDatabase(mockConnection, myTestArray);

And unfortunately, this call turns out to be problematic. It fails miserably on a ClassCastException.
The mockCallableStatement object that is returned by the mockConnection object when the test runs cannot be cast into an OraclePreparedStatement, which makes sense.
In production, the Connection object is actually an Oracle specific object, and its prepareCall returns an object that also implements the OraclePreparedStatement interface, but it’s not the case here (we’re testing in isolation – no Oracle implementation is involved).

How to implement the test then?
Trying to have the IAnswer implementation return an OraclePreparedStatement doesn’t work.
I thought about creating a “nice” Connection mock object and completely foregoing the creation of a CallableStatement, but the method under test needs it and would throw a NullPointerException when calling a CallableStatement method (such as execute).

The best solution is to have a mock object implement both the CallableStatement and the OraclePreparedStatement interface. This would make the cast work.
EasyMock doesn’t allow mock objects to implement more than one interface but fortunately, there is a way around this: create a new interface that extends the two interfaces:

private interface HybridStatement
    extends CallableStatement, OraclePreparedStatement {};

Then, it is simply a matter of creating a mock object that implements the HybridStatement interface instead of implementing the CallableStatement interface:

Connection mockConnection =
  createMock("mockConnection", Connection.class);
final HybridStatement mockHybridStatement =
  createMock("mockHybridStatement", HybridStatement.class); 

expect(mockConnection.prepareCall("{call my_pkg.my_function(?,?)}"))
  .andAnswer(new IAnswer<CallableStatement>() {
  public CallableStatement answer() throws Throwable {
    return mockHybridStatement;
  }
});

In retrospect, this is quite logical. Even though CallableStatement and OraclePreparedStatement are not directly related (they only extend the same interface), the statement object given by Oracle implement both interfaces.
I can’t believe that it took me several hours to find what in the end is a simple and fairly logical solution.
I hope this article will help someone.

 
 

BartTracker is back!

30 Sep

I finally have a good linux server to host my old and basic BartTracker web application. It is this very server that hosts this very blog, an Amazon EC2 micro instance.

BartTracker main screen

BartTracker's home page

It took 3 evenings to resuscitate this application, and I think I faced all the difficulties it was possible to face, which made a for an awesome learning experience. I documented most of the steps I took, in case I have to redeploy the app on another server in the future.

The application is now live at http://barttracker.dyndns.org

Next steps: set up a process to backup the database on a regular basis, and possibly set up bugzilla to keep track of the bugs and tasks.

 

Hello World

26 Sep

This is the very first post. Could be the last one too.