import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.sql.SQLException;

/**
  * Lors de l'ex&eacute;cution du script avec Connector/J 5.1.18, le script bloque.
  * Lors de l'ex&eacute;cution du script avec Connector/J < 5.1 le script ne bloque pas mais l&egrave;ve une NullPointerException pour trois processus sur quatre.
  * 
  * Ce script &agrave; &eacute;t&eacute; test&acute; avec 
  * MySQL 5.1, 5.0, 4.1, 
  * Connector/J  3.0.17, 3.1.14, 3.2.0-alpha, 5.0.8, 5.1.18,
  * JRE 1.6.0_27, 1.6.0_29, 1.7.0_01.
  * 
  * La requ&ecirc;te de cr&eacute;ation de la table client utilis&eacute; dans l'exemple est :
  * CREATE TABLE `client` (/n  `num` bigint(20) unsigned NOT NULL,/n  `noPrn` char(100) NOT NULL,/n  `etCiv` char(15) NOT NULL,/n  `add1` char(50) DEFAULT NULL,/n  `add2` char(50) DEFAULT NULL,/n  `add3` char(50) DEFAULT NULL,/n  `cp` char(5) DEFAULT NULL,/n  `ville` char(50) DEFAULT NULL,/n  `bloque` tinyint(4) NOT NULL DEFAULT '0',/n  `tIdent` char(20) DEFAULT NULL,/n  `nIdent` char(80) DEFAULT NULL,/n  `tel` char(20) DEFAULT NULL,/n  `dma` date DEFAULT NULL,/n  `mail` char(100) DEFAULT NULL,/n  `tvaIntra` char(15) DEFAULT NULL,/n  `caHT` double NOT NULL DEFAULT '0',/n  `caHR` double NOT NULL DEFAULT '0',/n  `ret` double NOT NULL DEFAULT '0',/n  `rep` double NOT NULL DEFAULT '0',/n  `new` smallint(6) NOT NULL DEFAULT '2',/n  `dtModif` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,/n  `detaxe` tinyint(1) unsigned NOT NULL DEFAULT '0',/n  PRIMARY KEY (`num`)/n) ENGINE=MyISAM DEFAULT CHARSET=latin1
  * Cette structure n'a, &agrave; priori, aucune importance. Il suffit qu'il existe une table client dans la base de donn&eacute;es pour les tests.
  * La structure sera alors CREATE TABLE client (noPrn CHAR(100)). Elle devra contenir au moins trois ligne pour le test.
  */
public class TestConnectorJ
{
	public static void main (String[] argv)
	{
		try
		{
			Class.forName ("com.mysql.jdbc.Driver").newInstance();
		}
		catch (ClassNotFoundException c)
		{
			System.err.println ("Class driver ConnectorJ introuvable.\n" + c.getLocalizedMessage ());
			System.exit (1);
		}
		catch (InstantiationException i)
		{
			System.err.println ("Erreur lors de l'invocation de newInstance pour le driver ConnectorJ.\n" + i.getLocalizedMessage ());
			System.exit (1);
		}
		catch (IllegalAccessException ill)
		{
			System.err.println ("IllegalAccessException : " + ill.getLocalizedMessage ());
			System.exit (1);
		}
		
		try
		{
			new TestConnectorJ (argv);
		}
		catch (SQLException s)
		{
			System.err.println ("Erreur accès à la base de données.\n" + s.getLocalizedMessage ());
			System.exit (1);
		}
	}
	
	/**
	  * @param argv les param&egrave;tres de la ligne de commande doivent &ecirc;tre :
		* <ul>
		*   <li>0 : hoteSQL</li>
		*   <li>1 : portSQL</li>
		*   <li>2 : user</li>
		*   <li>3 : password</li>
		*   <li>4 : database</li>
		* </ul>
	  */
	public TestConnectorJ (String[] argv)
	throws SQLException
	{
		if (argv.length != 5)
		{
			System.err.println ("Usage : " + SYNTAXE);
			System.exit (1);
		}
		try
		{
			Long.parseLong (argv[1]);
		}
		catch (NumberFormatException n)
		{
			System.err.println ("Le numéro de port n'est pas valide.\n" + n.getLocalizedMessage () + "\nUsage : " + SYNTAXE);
			System.exit (1);
		}
		String     url       = "jdbc:mysql://" + argv[0] + ":" + argv[1] + "/" + argv[4] + "?user=" + argv[2] + "&password=" + argv[3] + "&autoGenerateTestcaseScript=true";
		Connection connexion = DriverManager.getConnection (url);
		Statement  statement = connexion.createStatement ();
		
		ThreadConcurentStatement th1 = new ThreadConcurentStatement ("firstLoad", statement),
														 th2 = new ThreadConcurentStatement ("secondLoad", statement),
														 th3 = new ThreadConcurentStatement ("thirdLoad",  statement),
														 th4 = new ThreadConcurentStatement ("fourthLoad", statement);
		th1.start ();
		th2.start ();
		th3.start ();
		th4.start ();
	}
	
	private class ThreadConcurentStatement
	extends Thread
	{
		ThreadConcurentStatement (String threadName, Statement s)
		{
			super (threadName);
			_statement = s;			
		}
		
		public void run ()
		{
			int errCount = 0;
			for (int idx = 0; idx < 5; idx ++)
			{
				try
				{
					ResultSet result = _statement.executeQuery ("SELECT * FROM client LIMIT 3");
					while (result.next ())
						System.out.println (result.getString ("noPrn"));
				}
				catch (SQLException s)
				{
					System.err.println ("Erreur database : " + s.getLocalizedMessage ());
					if (errCount == 10)
						System.exit (1);
					errCount ++;
				}				
				System.out.println (getName () + " " + idx);
			}
		}		
		Statement _statement;
	}
	
	private static final String SYNTAXE = "java TestConnectorJ hoteSQL portSQL user password database";
}