package org.agile.grenoble.data; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.text.MessageFormat; import org.agile.grenoble.questions.AnswerType; import org.agile.grenoble.questions.ConfigurationType; import org.agile.grenoble.questions.QuestionType; import org.agile.grenoble.questions.QuestionsType; import org.agile.grenoble.user.User; import com.mysql.jdbc.exceptions.MySQLSyntaxErrorException; public class AnswersStorage { private Connection conn = null ; protected static final String SELECT_FROM_NOKIA_TEST_VERSIONS_ORDER_BY_AN_ID = "select * from NokiaTest.versions order by anId"; protected static final String CREATE_DATABASE_IF_NOT_EXISTS_NOKIA_TEST = "Create database IF NOT EXISTS NokiaTest"; protected static final String DROP_TABLE_IF_EXISTS_NOKIA_TEST_SURVEYS = "Drop table IF EXISTS NokiaTest.surveys"; protected static final String CREATE_TABLE_NOKIA_TEST_SURVEYS = "Create table NokiaTest.surveys (anId INT AUTO_INCREMENT UNIQUE, aName VARCHAR(56), anEmail VARCHAR(56), aDate TIMESTAMP)"; protected static final String DROP_TABLE_IF_EXISTS_NOKIA_TEST_VERSIONS = "Drop table IF EXISTS NokiaTest.versions"; protected static final String CREATE_TABLE_NOKIA_TEST_VERSIONS = "Create table NokiaTest.versions (anId INT AUTO_INCREMENT UNIQUE, aVersion VARCHAR(56), aDate TIMESTAMP)"; private static int schemaVersion = 2 ; protected static final String INSERT_INTO_NOKIA_TEST_VERSIONS = MessageFormat.format( "insert into NokiaTest.versions (aVersion) values ({0})", schemaVersion); protected static final String SELECT_AN_ID_A_NAME_AN_EMAIL_FROM_NOKIATEST_SURVEYS = "Select anId, aName, anEmail from nokiatest.surveys where aName=''{0}'' ;"; protected static final String INSERT_INTO_NOKIATEST_SURVEYS_A_NAME_AN_EMAIL = "INSERT INTO nokiatest.surveys (aName,anEmail) VALUES (''{0}'',''{1}'');"; protected Connection getConnection() { if (conn == null ) { conn = createConnection(); return conn ; } else { return conn ; } } protected void setConnection(Connection conn) { this.conn = conn; } private Connection createConnection() { Connection conn = null; try { Class.forName("com.mysql.jdbc.Driver").newInstance(); conn = DriverManager.getConnection("jdbc:mysql://localhost/?" + "user=root&password=agile123"); } catch (SQLException e) { // handle any errors of type SQL System.out.println("SQLException: " + e.getMessage()); System.out.println("SQLState: " + e.getSQLState()); System.out.println("VendorError: " + e.getErrorCode()); } catch (InstantiationException e) { System.out.println("SQLException: " + e.getMessage()); e.printStackTrace(); } catch (IllegalAccessException e) { System.out.println("SQLException: " + e.getMessage()); e.printStackTrace(); } catch (ClassNotFoundException e) { System.out.println("SQLException: " + e.getMessage()); e.printStackTrace(); } return conn ; } public void initializeDB(QuestionsType questions) throws SQLException { Connection conn = getConnection(); if (conn != null) { Statement stat = conn.createStatement(); ResultSet res = null; try { res = stat.executeQuery(SELECT_FROM_NOKIA_TEST_VERSIONS_ORDER_BY_AN_ID); } catch (MySQLSyntaxErrorException e) { System.out.println("No result: " +e ); //e.printStackTrace(); } if (res == null ) { stat.close(); initDB(conn,questions); } else { System.out.println("Up2date table, doing nothing"); //TODO we should check the version installed of the schema res.close(); stat.close(); } } } protected void initDB(Connection conn,QuestionsType questions) throws SQLException { Statement stat = conn.createStatement() ; //add the ifnot exist, as the installation may be incremental executeQuery(stat, CREATE_DATABASE_IF_NOT_EXISTS_NOKIA_TEST); executeQuery(stat, DROP_TABLE_IF_EXISTS_NOKIA_TEST_SURVEYS); executeQuery(stat, CREATE_TABLE_NOKIA_TEST_SURVEYS) ; executeQuery(stat, DROP_TABLE_IF_EXISTS_NOKIA_TEST_VERSIONS); executeQuery(stat, CREATE_TABLE_NOKIA_TEST_VERSIONS) ; executeQuery(stat, INSERT_INTO_NOKIA_TEST_VERSIONS); //TODO generate schema from table definition ... simple/complex.... for (int i =0 ; i < questions.getQuestionArray().length; i++) { createTableForQuestions(stat,questions.getQuestionArray(i),i); } stat.close(); } protected void executeQuery(Statement stat, String query) throws SQLException { stat.execute(query); } private int getNbFields(QuestionType question) { int nb = 0; if (question.getConfiguration().getType()== ConfigurationType.Type.SINGLE) { nb = 1; } else if (question.getConfiguration().getType()== ConfigurationType.Type.MULTIPLE) { nb = question.getConfiguration().getNumber(); } else { //complex for (int i=0; i < question.getQuestionArray().length; i ++) { QuestionType child = question.getQuestionArray(i); nb += getNbFields(child); } //end for } //end if return nb ; } protected boolean createTableForQuestions(Statement stat, QuestionType question, int indice) throws SQLException { String fields = ""; boolean res = stat.execute("Drop table IF EXISTS NokiaTest.question_"+indice); if (!res) System.out.println("failed to drop table question_"+indice); int nb = getNbFields(question); for (int i=0; i < nb;i++) { if (i>0) fields += "," ; fields += "anAnswers_"+i+" INT" ; } //end for String query = "Create table IF NOT EXISTS NokiaTest.question_"+indice+" (anId INT UNIQUE, "+fields+")"; System.out.println ("Query is : " + query ); res = stat.execute(query); return res; } public User getorCreateUser(String pName, String pEmail) throws SQLException { Connection conn = getConnection(); User user = null ; if (conn != null) { Statement stat = conn.createStatement(); ResultSet res = stat.executeQuery(MessageFormat.format(SELECT_AN_ID_A_NAME_AN_EMAIL_FROM_NOKIATEST_SURVEYS,pName)); user = new User(); if ((res != null) && res.next() ) { user.setName(res.getString(2)); user.setEmail(res.getString(3)); user.setId(res.getInt(1)); } else { System.out.println("No user found, should create a new one"); user = createUser(stat, pName,pEmail); } res.close(); stat.close(); } else { System.out.println("ERROR GETTING A CONNECTION ") ; } //end if return user ; } protected User createUser(Statement stat, String pName, String pEmail) throws SQLException { boolean ok = stat.execute(MessageFormat.format(INSERT_INTO_NOKIATEST_SURVEYS_A_NAME_AN_EMAIL, pName, pEmail)); if (!ok) System.out.println("Fail to add a new user") ; User iUser = newUser(pName, pEmail); selectLastInsertedUserId(stat, iUser); System.out.println("Created user : " + pName + ", " + iUser.getEmail() + ","+ iUser.getId() ); return iUser ; } protected void selectLastInsertedUserId(Statement stat, User iUser) throws SQLException { ResultSet res = stat.executeQuery("SELECT LAST_INSERT_ID();"); if (res.next()) { iUser.setId(res.getInt(1)); } else { System.out.println("Can not get id generated for user ") ; iUser.setId(-1); } res.close(); } private User newUser(String pName, String pEmail) { User iUser = new User(); iUser.setName(pName); iUser.setEmail(pEmail); return iUser; } public void storeAnswers(QuestionsType questions, int pUserId) throws SQLException { Connection conn = getConnection(); if (conn != null) { Statement stat = conn.createStatement(); boolean res = true ; for (int i =0 ; i < questions.getQuestionArray().length; i++) { res &= storePointForQuestions(stat,questions.getQuestionArray(i),pUserId,i); } } else { System.out.println("ERROR GETTING A CONNECTION ") ; } //end if } private String getPoints(QuestionType question) { String points = null ; if (question.getConfiguration().getType()== ConfigurationType.Type.SINGLE) { // points = getQuestionPoint(question); if (points == null ) points = "0"; } else if (question.getConfiguration().getType()== ConfigurationType.Type.MULTIPLE) { points = getQuestionPoint(question); if (points == null ) points = "0"; } else { //complex for (int i=0; i < question.getQuestionArray().length; i ++) { QuestionType child = question.getQuestionArray(i); if (points != null) { points += ","+ getPoints(child); } else { points = getPoints(child); } } //end for } //end if return points ; } /* * works for single and multiple ... we do some loop free ... but who cares ... */ private String getQuestionPoint(QuestionType question) { String points=null; for (int i=0; i < question.getAnswers().getAnswerArray().length; i++) { if ( question.getAnswers().getAnswerArray(i).getSelected() == AnswerType.Selected.TRUE ) { if (points != null) points += "," ; points= question.getAnswers().getAnswerArray(i).getPoint() ; } } //System.out.println("We have update points for question : " + question.getLabel() + ", and we have found : " + points ); return points ; } private boolean storePointForQuestions(Statement stat, QuestionType question, int pUserId, int indice) throws SQLException { String fields = getPoints(question); String query = "Insert into NokiaTest.question_"+indice+" VALUES (" +pUserId +","+fields+") ; "; System.out.println ("Query is : " + query ); int res = stat.executeUpdate(query); System.out.println("We have update "+res + " rows"); return (res==1); } }