jdbcexport-to-csvresultsetapache-commons-csv

How to get the number of rows written by CSVPrinter?


My code runs a SELECTstatement, and saves the entire ResultSet into a file with a single call to CSVprinter.printRecords(resultSet).

This works very nicely except, I'd like to know, how many records were written... The method itself does not return anything -- an opportunity to make life easier missed by the developers.

I tried calling resultSet.getRow() after printing -- hoping, it will be at the last one, thus giving me the total -- but that always returns zero.

I tried calling resultSet.last() before getRow(), but that fails, because mine is a "forward only" result-set. The afterLast() fails for the same reason.

I could loop over the result-set myself -- passing individual rows to CSVPrinter and counting them -- but that certainly is not as convenient and concise. Is there any other way?

Update: created the improvement request, for whatever that's worth...


Solution

  • You can also do it with a Proxy:

        public class CountingResultSet implements InvocationHandler {
            private ResultSet original; 
            private int counter;
    
        public static ResultSet newProxy(final ResultSet original) {
            return (ResultSet) Proxy.newProxyInstance(
                    OracleVArrayTests.class.getClassLoader(), 
                      new Class[] { ResultSet.class }, 
                      new CountingResultSet(original)); 
        }
        
        public CountingResultSet(final ResultSet original) {
            this.original = original ;
            this.counter = 0;
        }
        
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) 
          throws Throwable {
            if (method.getName().equals("next")) {
                Boolean res = (Boolean)method.invoke(this.original, args);
                if (res) ++this.counter;
                return res;
            }
            
            return method.invoke(this.original,  args);
        }
        
        int getCounter() { return this.counter; }
    }
    

    And getting the count:

        try (final ResultSet rs = CountingResultSet.newProxy((ResultSet) ...)) {
        ...
        ((CountingResultSet)Proxy.getInvocationHandler(rs)).getCounter();
        ...
        }