Restructure database code.
[cfb.git] / prod / net / jaekl / cfb / db / driver / DbDriver.java
index 525ca7049d3444545a717a9788e51595b29697f3..ac9f8ccdad2030150d25d0fe06cd15078c8d7fb4 100644 (file)
@@ -19,6 +19,8 @@ import net.jaekl.cfb.db.Sequence;
 import net.jaekl.cfb.db.Table;
 
 public abstract class DbDriver {
+       static int PENDING_LIMIT = 1024;        // Rough limit at which point we'll start a new batch for batch updates
+       
        DbDriver() {
                
        }
@@ -83,6 +85,74 @@ public abstract class DbDriver {
                return result;
        }
        
+       // Returns the number of rows inserted
+       public int insert(Connection con, Table table, Object[][] values) throws SQLException 
+       {
+               int count = 0;
+               int pendingValues = 0;
+               
+               String sql = insertSql(table);
+               
+               try (PreparedStatement ps = con.prepareStatement(sql))
+               {
+                       for (int row = 0; row < values.length; ++row) {
+                               Object[] data = values[row];
+                               
+                               assert(null != data);
+                               assert(data.length == table.getNumColumns());
+                               
+                               for (int col = 0; col < data.length; ++col) {
+                                       ps.setObject(col + 1, data[col]);
+                                       pendingValues++;
+                               }
+                               ps.addBatch();
+                               
+                               int rowsFlushed = checkFlushBatch(ps, pendingValues, false);
+                               if (rowsFlushed > 0) {
+                                       count += rowsFlushed;
+                                       pendingValues = 0;
+                               }
+                       }
+                       
+                       count += checkFlushBatch(ps, pendingValues, true);
+               }
+               
+               return count;
+       }
+       
+       int checkFlushBatch(PreparedStatement ps, int pendingValues, boolean forceFlush) throws SQLException
+       {
+               int count = 0;
+               
+               if (forceFlush || (pendingValues >= PENDING_LIMIT)) 
+               {
+                       int[] updateCounts = ps.executeBatch();
+                       for (int i = 0; i < updateCounts.length; ++i) {
+                               if (updateCounts[i] > 0) {
+                                       count += updateCounts[i];
+                               }
+                       }
+               }
+               
+               return count;
+       }
+       
+       String insertSql(Table table) {
+               StringBuilder sb = new StringBuilder("INSERT INTO ");
+               sb.append(table.getName())
+                 .append(" VALUES (");
+               
+               for (int i = 0; i < table.getNumColumns(); ++i) {
+                       if (i > 0) {
+                               sb.append(",");
+                       }
+                       sb.append("?");
+               }
+               sb.append(")");
+               
+               return sb.toString();
+       }
+       
        protected String selectSql(Column[] columns, Table[] tables, Condition[] conditions) 
        {
                StringBuilder sb = new StringBuilder("SELECT ");