import java.sql.*;

public class JavaConcBench implements Runnable {
   private static int nThread;
   private static int thrCnt = 0;
   final private static String FIRST_REC = "First record";
   final private static int N_INSERT = 10000;
   public static void main (String args[]) throws SQLException {
      try {
         nThread = Integer.parseInt (args[0]);
      } catch (Exception e) {
         System.err.println ("Usage: java JavaConcBench <n-thread>("+e+")");
         return;
      }
      Connection con = getConnection();
      Statement stmt = con.createStatement();
      try {
         stmt.executeUpdate ("drop table conc_test");
      } catch (SQLException e) {
      }
      stmt.executeUpdate (
                 "create table conc_test (cnt numeric(7), lcn numeric(7), txt char(30))");
      stmt.executeUpdate (
                 "create unique index conc_test_01 on conc_test (cnt)");
      stmt.executeUpdate (
                 "create unique index conc_test_02 on conc_test (txt)");
      stmt.executeUpdate (
                 "insert into conc_test values (1, 0, '" + FIRST_REC + "')");
      con.close();

      for (int i = 0; i < nThread; i++)
         new Thread (new JavaConcBench()).start();
      System.out.println ("Fine");
   }

   static Connection getConnection() throws SQLException {
      Connection Return = null;

      String driver = "IT.picosoft.jdbc.PicoDriver";

      String url = "jdbc:picodb:localhost:6789:picoSqlTest";

      try {
         Class.forName (driver);
         Return = DriverManager.getConnection (url, "", "");
      } catch (ClassNotFoundException e) {
         throw new SQLException ("JDBC Driver not found! " + driver);
      }
      return Return;
   }


   synchronized static int getThreadNumber() {
      return ++thrCnt;
   }

   public void run () {
      int num = getThreadNumber();
      Thread tt = Thread.currentThread();
      Connection con = null;
      try {
         con = getConnection();
         Statement stmt = con.createStatement();
         Statement updStmt = con.createStatement();
         ResultSet rs;
         double n;
         double lcn = 0;

         updStmt.executeUpdate ("insert into conc_test values ("+(-num)+", 0, '" +
                                tt + "')");
         do {
            rs = stmt.executeQuery ("select cnt from conc_test where txt = '"
                                  + FIRST_REC + "' for update");
            rs.next();
            n = rs.getDouble (1);
            updStmt.executeUpdate ("update conc_test set cnt = " + (n + 1) +
                                " where txt = '" + FIRST_REC + "'");
            rs.close();
            updStmt.executeUpdate ("update conc_test set cnt = " + n +
                                ", lcn = " + (++lcn) + 
                                " where txt = '" + tt + "'");
            n++;
         } while (n < N_INSERT);
      } catch (SQLException e) {
         e.printStackTrace();
         return;
      } finally {
         if (con != null)
            try {
               con.close();
            } catch (SQLException e) {
            }
      }
   }

   static void pause (String str) {
      System.out.println (str);
      try {
         System.in.read();
      } catch (Exception e) {}
   }
}
