/*
* codjo.net
*
* Common Apache License 2.0
*/
package net.codjo.utils;
import net.codjo.model.Table;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import org.apache.log4j.Logger;
/**
* Compare deux tables
*
* @author $Author: acharif $
* @version $Revision: 1.5 $
*
*/
public class Comparator {
int[] columnsToSkip = null;
String orderClause = "";
double precision = -1;
TestEnvironnement testEnv = null;
Connection connection = null;
// Log
private static final Logger APP = Logger.getLogger(Comparator.class);
/**
* Constructeur complet
*
* @param t Environnement de test
* @param columnToSkip Num�ro de la colonne � zapper
* @param orderClause Le tri souhait� avant comparaison
*/
public Comparator(TestEnvironnement t, int columnToSkip, String orderClause) {
this.testEnv = t;
initColumnToSkip(columnToSkip);
this.orderClause = orderClause;
}
/**
* Constructeur all�g� 2
*
* @param t Environnement de test
* @param columnToSkip Num�ro de la colonne � zapper
*/
public Comparator(TestEnvironnement t, int columnToSkip) {
this.testEnv = t;
initColumnToSkip(columnToSkip);
}
/**
* Constructeur all�g� 3
*
* @param columnToSkip Num�ro de la colonne � zapper
*/
public Comparator(int columnToSkip) {
this.testEnv = TestEnvironnement.newEnvironment();
initColumnToSkip(columnToSkip);
}
/**
* Constructeur all�g� 4
*
* @param t Environnement de test
*/
public Comparator(TestEnvironnement t) {
this.testEnv = t;
}
/**
* Fixe la connexion � utiliser pour la comparaison
*
* @param con La connexion � utilis�e
*/
public void setConnection(Connection con) {
connection = con;
}
/**
* Lancement de la comparaison de deux tables
*
* @param table1 La premi�re table
* @param table2 La deuxi�me table (et oui !)
*
* @return Egalit� des deux tables
*
* @exception SQLException Probl�me d'acc�s base
*/
public boolean Equals(Table table1, Table table2)
throws SQLException {
if (sameNumberOfCol(table1, table2) == false) {
return false;
}
Connection con = null;
Statement stmt1 = null;
Statement stmt2 = null;
ResultSet rs1 = null;
ResultSet rs2 = null;
Object obj1;
Object obj2 = null;
try {
if (connection == null) {
con = testEnv.getHomeConnection();
}
else {
con = connection;
}
stmt1 = con.createStatement();
stmt2 = con.createStatement();
if (sameNumberOfRow(stmt1, table1, table2) == false) {
return false;
}
if ("".equals(orderClause)) {
rs1 = stmt1.executeQuery("select * from " + table1.getDBTableName());
rs2 = stmt2.executeQuery("select * from " + table2.getDBTableName());
}
else {
rs1 = stmt1.executeQuery("select * from " + table1.getDBTableName()
+ " order by " + orderClause);
rs2 = stmt2.executeQuery("select * from " + table2.getDBTableName()
+ " order by " + orderClause);
}
int numLine = 0;
while ((rs1.next()) && (rs2.next())) {
numLine++;
for (int i = 1; i <= table1.getNumberOfCol(); i++) {
if (!isColumnToSkip(i)) {
obj1 = rs1.getObject(i);
obj2 = rs2.getObject(i);
if (isEqual(obj1, obj2) == false) {
APP.debug("[Comparator] Ligne " + numLine
+ " Colonne " + rs1.getMetaData().getColumnName(i) + "\n"
+ " Table " + table1.getDBTableName() + " valeur = ("
+ obj1 + ")" + "\n" + " Table " + table2.getDBTableName()
+ " valeur = (" + obj2 + ")");
return false;
}
}
}
}
return true;
}
finally {
if (stmt1 != null) {
stmt1.close();
}
if (stmt2 != null) {
stmt2.close();
}
}
}
/**
* Positionne les colonnes a ne pas comparer
*
* @param columns liste d'indice de colonne
*/
public void setColumnsToSkip(int[] columns) {
this.columnsToSkip = columns;
}
/**
* Positionne la precision utilisee lors de la comparaison de deux numerique. On dit
* que a et b sont egaux si : <code>(abs(a - b)) =< precision</code>
*
* @param precision La nouvelle valeur de precision
*/
public void setPrecision(double precision) {
this.precision = precision;
}
/**
* Retourne l'attribut equal de Comparator
*
* @param obj1 Description of the Parameter
* @param obj2 Description of the Parameter
*
* @return La valeur de equal
*/
boolean isEqual(Object obj1, Object obj2) {
if (obj1 == obj2) {
return true;
}
if (obj1 != null && obj1.equals(obj2)) {
return true;
}
if (obj1 != null
&& obj2 != null
&& precision > 0
&& obj1 instanceof Number
&& obj2 instanceof Number) {
double a = ((Number)obj1).doubleValue();
double b = ((Number)obj2).doubleValue();
return Math.abs(a - b) <= precision;
}
return false;
}
/**
* Initialise le tableau des colonnes "a ne pas comparer" avec une seule colonne.
*
* @param columnToSkip Description of the Parameter
*/
private void initColumnToSkip(int columnToSkip) {
this.columnsToSkip = new int[] {columnToSkip};
}
/**
* Retourne l'attribut columnToSkip de Comparator
*
* @param col Description of the Parameter
*
* @return La valeur de columnToSkip
*/
private boolean isColumnToSkip(int col) {
if (columnsToSkip == null) {
return false;
}
for (int i = 0; i < columnsToSkip.length; i++) {
if (columnsToSkip[i] == col) {
return true;
}
}
return false;
}
/**
* Description of the Method
*
* @param table1 Description of Parameter
* @param table2 Description of Parameter
*
* @return Description of the Returned Value
*/
private boolean sameNumberOfCol(Table table1, Table table2) {
if (table1.getNumberOfCol() != table2.getNumberOfCol()) {
APP.debug("[Comparator] Nombre de colonnes diff�rent !" + "\n"
+ " Table " + table1.getDBTableName() + " : " + table1.getNumberOfCol()
+ " colonne(s)" + "\n" + " Table " + table2.getDBTableName() + " : "
+ table2.getNumberOfCol() + " colonne(s)");
return false;
}
return true;
}
/**
* Description of the Method
*
* @param stmt1 Description of Parameter
* @param table1 Description of Parameter
* @param table2 Description of Parameter
*
* @return Description of the Returned Value
*
* @exception SQLException Description of Exception
*/
private boolean sameNumberOfRow(Statement stmt1, Table table1, Table table2)
throws SQLException {
ResultSet rs =
stmt1.executeQuery("select count(*) from " + table1.getDBTableName());
try {
rs.next();
int nbRow1 = rs.getInt(1);
rs = stmt1.executeQuery("select count(*) from " + table2.getDBTableName());
rs.next();
int nbRow2 = rs.getInt(1);
if (nbRow1 != nbRow2) {
APP.debug("[Comparator] Nombre de lignes diff�rent !" + "\n"
+ " Table " + table1.getDBTableName() + " : " + nbRow1 + " ligne(s)"
+ "\n" + " Table " + table2.getDBTableName() + " : " + nbRow2
+ " ligne(s)");
return false;
}
return true;
}
finally {
rs.close();
}
}
}