code: package it.unibz.inf.data_pumper.mappings;
  
  /*
   * #%L
   * dataPumper
   * %%
   * Copyright (C) 2014 Free University of Bozen-Bolzano
   * %%
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   * 
   *      http://www.apache.org/licenses/LICENSE-2.0
   * 
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   * #L%
   */
  
  //import it.unibz.inf.data_pumper.connection.DBMSConnection;
  //import it.unibz.inf.data_pumper.utils.Pair;
  //import it.unibz.inf.data_pumper.utils.Template;
  //
  //import java.sql.PreparedStatement;
  //import java.sql.ResultSet;
  //import java.sql.SQLException;
  //import java.util.ArrayList;
  //import java.util.Collections;
  //import java.util.HashMap;
  //import java.util.List;
  //import java.util.Map;
  //import java.util.Set;
  //
  //import org.apache.log4j.Logger;
  
  //import utils.MyHashMapList;
  //import core.CSVPlayer;
  
  /**
   * 
   * @author tir
   * @note This is a <b>singleton</b> class.
   */
  @Deprecated
  public class TupleStore {
  //	
  //	private static TupleStore store = null;
  //	private static int tupleCnt = 0;
  //	
  //	private ArrayList<Tuple> tuples;
  //	private Map<Integer, Tuple> mId_Tuple; // id -> tuple
  //	private MyHashMapList<String, Tuple> mTableName_Tuples; // tableName -> tuple_1, tuple_2, ..., tuple_n
  //	private Map<Pair<Integer, Integer>, Float> mBufferized_DupRatios;
  //	private Map<Pair<Integer, Integer>, Integer> mBufferized_nToInsert;
  //	
  //	private static Logger logger = Logger.getLogger(TupleStore.class.getCanonicalName());
  //	
  //	private TupleStore(MyHashMapList<String, String> tuplesHash) {
  //		tuples = new ArrayList<Tuple>();
  //		mId_Tuple = new HashMap<Integer, Tuple>();
  //		mTableName_Tuples = new MyHashMapList<String, Tuple>();
  //		mBufferized_DupRatios = new HashMap<Pair<Integer,Integer>, Float>();
  //		mBufferized_nToInsert = new HashMap<Pair<Integer,Integer>, Integer>();
  //		
  //		for( String functName : tuplesHash.keyset() ){
  //			MyHashMapList<String, String> mTable_Columns = new MyHashMapList<String, String>();
  //			MyHashMapList<String, String> mTupleTemplate_Tables = new MyHashMapList<String, String>();
  //			
  //			// Extract the info regarding the tables and the columns
  //			for( String csvProj : tuplesHash.get(functName) ){
  //				List<String> temp = CSVPlayer.parseRow(csvProj, " ");
  //				String tableName = temp.get(0);
  //								
  //				String tupleTemplate = temp.get(1) + temp.get(2);
  //				
  //				List<String> columns = temp.subList(3, temp.size());
  //				
  //				List<Integer> toRemove = new ArrayList<Integer>();
  //								
  //				// Duplicates check
  //				for( int i = 0; i < columns.size(); ++i ){
  //					for( int j = i+1; j < columns.size(); ++j ){
  //						if( columns.get(i).equals(columns.get(j)) ){
  //							toRemove.add(j);
  //						}
  //					}
  //				}
  //				
  //				for( Integer index : toRemove ){
  //					columns.remove(index);
  //				}
  //				
  //				if(!mTable_Columns.containsKey(tableName)){
  //					mTable_Columns.putAll(tableName, columns); // TODO At the moment I do not recognize different columns giving 
  //					                                           //      birth to the same template
  //				}
  //				if(mTupleTemplate_Tables.containsKey(tupleTemplate)){
  //					if( !mTupleTemplate_Tables.get(tupleTemplate).equals(tableName) )
  //						mTupleTemplate_Tables.put(tupleTemplate, tableName);
  //				}
  //				else{
  //					mTupleTemplate_Tables.put(tupleTemplate, tableName);
  //				}
  //			}
  //			Tuple newT = new Tuple(++tupleCnt, functName, mTable_Columns, mTupleTemplate_Tables);
  //			tuples.add(newT);
  //			mId_Tuple.put(tupleCnt, newT);
  //			for( String tableName : mTable_Columns.keyset() ){
  //				mTableName_Tuples.put(tableName, newT);
  //			}
  //		}
  //	}
  //	
  //	public List<Tuple> getAllTuplesOfTable(String tableName){ 
  //		if(mTableName_Tuples.containsKey(tableName))
  //			return Collections.unmodifiableList(mTableName_Tuples.get(tableName));
  //		else return null;
  //	}
  //	
  //	static TupleStore getInstance(){
  //		return store;
  //	}
  //	
  //	static TupleStore getInstance(MyHashMapList<String, String> tuplesHash){
  //		if( store == null ){
  //			store = new TupleStore(tuplesHash);
  //		}
  //		return store;
  //	}
  //	
  //	public List<Tuple> allTuples(){
  //		return Collections.unmodifiableList(tuples);
  //	}
  //
  //	public Tuple getTupleOfID(int id){
  //		return mId_Tuple.get(id);
  //	}
  //	
  //	/**
  //	 * The duplicate ratios for each template are evaluated w.r.t. the UNION
  //	 * of the tuples of the tables covered by that template
  //	 * @param tt
  //	 * @return
  //	 * 
  //	 * TODO
  //	 */
  //	public TupleTemplateDecorator decorateTupleTemplate(TupleTemplate tt){
  //		
  //		TupleTemplateDecorator ttD = new TupleTemplateDecorator(tt);
  //		
  //		if( isDupRatioBufferized(ttD) ){
  //			ttD.setDupR(getBufferizedDupRatio(ttD));
  //			ttD.addToInsert(getBufferizedNToInsert(ttD));
  //		}
  //		else{
  //			DuplicateRatiosFinder dF = new DuplicateRatiosFinder();
  //			dF.fillDupRatio(ttD);
  //			bufferizeDupRatio(ttD);
  //		}
  //		
  //		return ttD;
  //	}
  //	
  //	private void bufferizeDupRatio(TupleTemplateDecorator ttD) {
  //		int tupleID = ttD.belongsToTuple();
  //		int ttID = ttD.getID();
  //		
  //		Pair<Integer, Integer> key = new Pair<Integer, Integer>(tupleID, ttID);
  //		
  //		mBufferized_DupRatios.put(key, ttD.getDupR());
  //	}
  //	
  //	public void bufferizeNToInsert(TupleTemplateDecorator ttD, int nToInsert){
  //		int tupleID = ttD.belongsToTuple();
  //		int ttID = ttD.getID();
  //		
  //		Pair<Integer,Integer> key = new Pair<Integer, Integer>(tupleID, ttID);
  //		
  //		mBufferized_nToInsert.put(key, nToInsert);
  //	}
  //	
  //	private int getBufferizedNToInsert(TupleTemplateDecorator ttD){
  //		int tupleID = ttD.belongsToTuple();
  //		int ttID = ttD.getID();
  //		
  //		Pair<Integer,Integer> key = new Pair<Integer, Integer>(tupleID, ttID);
  //		
  //		return mBufferized_nToInsert.get(key);
  //	}
  //
  //	private float getBufferizedDupRatio(TupleTemplateDecorator ttD){
  //		int tupleID = ttD.belongsToTuple();
  //		int ttID = ttD.getID();
  //		
  //		Pair<Integer,Integer> key = new Pair<Integer, Integer>(tupleID, ttID);
  //		
  //		return mBufferized_DupRatios.get(key);
  //	}
  //	
  //	private boolean isDupRatioBufferized(TupleTemplateDecorator ttD){
  //		
  //		int tupleID = ttD.belongsToTuple();
  //		int ttID = ttD.getID();
  //		
  //		Pair<Integer,Integer> key = new Pair<Integer, Integer>(tupleID, ttID);
  //		
  //		if( mBufferized_DupRatios.containsKey(key) ){
  //			return true;
  //		}
  //		return false;
  //	}
  //	
  //	
  //	public String toString(){
  //		return allTuples().toString();
  //	}
  }
  
  class DuplicateRatiosFinder{
  	
  //	private static Logger logger = Logger.getLogger(DuplicateRatiosFinder.class.getCanonicalName());
  //	
  //	private float findDuplicateRatio(TupleTemplateDecorator ttD){
  //		// (select wlbName, wlbCoreNumber from wellbore_core) union all (select wlbName, wlbCoreNumber from wellbore_core);
  //		// (select wlbName, wlbCoreNumber from wellbore_core) union (select wlbName, wlbCoreNumber from wellbore_core);
  //		
  //		if( ttD.getReferredTables().size() < 2 ) return 0; // TODO Anyways, I have a bug giving duplicate columns in the projection
  //		                                                    //      evaluated in fillTemplate(), for table licence_task (funct npdv:name).
  //		                                                    //      DEBUG
  //		
  //		DBMSConnection dbOriginal = TupleStoreFactory.getInstance().getDBMSConnection();
  //		
  //		// Find duplicates ratios
  //		int nTables = ttD.getReferredTables().size();
  //		
  //		Pair<String, String> templDiff_templUnion = getTemplateStrings(nTables); 
  //		
  //		Template tDiff = new Template(templDiff_templUnion.first);
  //		Template tUnion = new Template(templDiff_templUnion.second);
  //		
  //		fillTemplate(tDiff, ttD);
  //		fillTemplate(tUnion, ttD);
  //		
  //		logger.debug("tDiff: "+tDiff.getFilled());
  //		logger.debug("tUnion: "+tUnion.getFilled());
  //		
  //		PreparedStatement stmtDiff = dbOriginal.getPreparedStatement(tDiff);
  //		int numDiff = countNumResults(stmtDiff);
  //		
  //		PreparedStatement stmtUnion = dbOriginal.getPreparedStatement(tUnion);
  //		int numUnion = countNumResults(stmtUnion);
  //		
  //		float dupRatio = (float)(numDiff - numUnion) / (float)numDiff;
  //		
  //		closeStatements(stmtDiff, stmtUnion);
  //		
  //		logger.debug("THE DUP RATIO IS" + dupRatio);
  //		
  //		return dupRatio; 
  //	}
  //	
  //	private void closeStatements(PreparedStatement stmtDiff,
  //			PreparedStatement stmtUnion) {
  //		try {
  //			stmtDiff.close();
  //			stmtUnion.close();
  //		} catch (SQLException e) {
  //			e.printStackTrace();
  //		}
  //	}
  //
  //	private int countNumResults(PreparedStatement stmt) {
  //		
  //		int result = 0;
  //		
  //		try {
  //			ResultSet rs = stmt.executeQuery();
  //			if( rs.next() ){
  //				result = rs.getInt(1);
  //			}
  //			else throw new SQLException("The COUNT did not went smoothly");
  //		} catch (SQLException e) {
  //			e.printStackTrace();
  //		}
  //		return result;
  //	}
  //
  //	private void fillTemplate(Template template, TupleTemplate tt) {
  //		
  //		Set<String> referredTables = tt.getReferredTables();
  //		
  //		int i = 1;
  //		for( String tableName : referredTables ){
  //			StringBuilder builder = new StringBuilder();	
  //			builder.append("SELECT ");
  //			builder.append(projList(tableName, tt));
  //			builder.append(" FROM " + tableName);
  //						
  //			template.setNthPlaceholder(i, builder.toString());
  //			++i;
  //		}
  //	}
  //
  //	private String projList(String tableName, TupleTemplate tt) {
  //		
  //		StringBuilder builder = new StringBuilder();
  //		List<String> colNames = tt.getColumnsInTable(tableName);
  //		
  //		for( int i = 0; i < colNames.size(); ++i ){
  //			
  //			String colName = colNames.get(i);
  //			
  //			builder.append(colName);
  //			if( i < colNames.size() - 1 ) builder.append(", ");
  //		}
  //				
  //		return builder.toString();
  //	}
  //
  //	private Pair<String, String> getTemplateStrings(int nTables) {
  //		StringBuilder builderDiff = new StringBuilder();
  //		StringBuilder builderSet = new StringBuilder();
  //		builderDiff.append("SELECT COUNT(*) FROM (");
  //		builderSet.append("SELECT COUNT(*) FROM (");
  //		for( int i = 0; i < nTables; ++i ){
  //			builderDiff.append("(?)");
  //			builderSet.append("(?)");
  //			if( i < nTables - 1 ){
  //				builderDiff.append(" union all ");
  //				builderSet.append(" union ");
  //			}
  //		}
  //		builderDiff.append(") alias");
  //		builderSet.append(") alias");
  //				
  //		return new Pair<String, String>(builderDiff.toString(), builderSet.toString());
  //	}
  //	
  //	void fillDupRatio(TupleTemplateDecorator ttD) {
  //		
  //		float dupRatio = findDuplicateRatio(ttD);
  //		ttD.setDupR(dupRatio);
  //	}
  };