import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.ResultSet;

public class TestMasterConnIdle implements Runnable {
	public static final int MAX_CHECKS = 10000;
	public static final int NUM_THREADS = 4;
	public static final int TIME_TO_SLEEP = 10000;
	public static final int WRITE_FREQUENCY = 3;
	public static final int WAIT_TIMEOUT = 10;
	
	public void run() {
		Connection conn = null;
		Statement stmt = null;
		ResultSet rs = null;

		try {
			Boolean checkMore = true;
			int numChecks = 0;
			
			conn = DriverManager.getConnection("jdbc:mariadb://127.0.0.1/db1",
			"maxscale", "password");
			
			stmt = conn.createStatement();
			stmt.execute("SET wait_timeout = " + Integer.toString(WAIT_TIMEOUT));
			stmt.close();
			stmt = null;

			while (checkMore) {
				System.out.format("Checking thread %d.%n", Thread.currentThread().getId());
				
				numChecks++;
				
				if (numChecks >= MAX_CHECKS) {
					checkMore = false;
				}
				
				if (numChecks % WRITE_FREQUENCY == 0) {		
					stmt = conn.createStatement();
					stmt.executeUpdate("INSERT INTO db1.tab (str) VALUES ('str')");
					stmt.close();
					stmt = null;
				}
				
				else {
					stmt = conn.createStatement();
					rs = stmt.executeQuery("SELECT * FROM db1.tab LIMIT 10");

					while (rs.next()) {
						String thisVal = rs.getString("str");
					}
					
					rs.close();
					rs = null;
					stmt.close();
					stmt = null;
				}
				
				
				if (checkMore) {
					Thread.sleep(TIME_TO_SLEEP);
				}
			}
			
		} catch (SQLException ex) {
		// handle any errors
			System.out.println("SQLException: " + ex.getMessage());
			System.out.println("SQLState: " + ex.getSQLState());
			System.out.println("VendorError: " + ex.getErrorCode());
		} catch (Exception ex) {
		// handle any errors
			System.out.println("Exception: " + ex.getMessage());
		} finally {
			if (rs != null) {
				try {
					rs.close();
				} catch (SQLException sqlEx) { } // ignore

				rs = null;
			}
			
			if (stmt != null) {
				try {
					stmt.close();
				} catch (SQLException sqlEx) { } // ignore

				stmt = null;
			}
				
			if (conn != null) {
				try {
					conn.close();
				} catch (SQLException sqlEx) { } // ignore

				conn = null;
			}
		}
	}
	
	public static void main(String[] args) {
		Thread[] connThreads = new Thread[NUM_THREADS];
		
		try {
			// The newInstance() call is a work around for some
			// broken Java implementations

			Class.forName("org.mariadb.jdbc.Driver").newInstance();
			
			for (int i = 0; i < NUM_THREADS; i++) {
				connThreads[i] = new Thread(new TestMasterConnIdle());
				connThreads[i].start();
			}

		} catch (Exception ex) {
			System.out.println("Exception: " + ex.getMessage());
		}
	}
}
