package org.gcube.documentstore.persistence; import java.sql.Connection; import java.sql.Statement; import java.util.Collection; import java.util.HashMap; import java.util.Map; import org.gcube.accounting.utility.postgresql.RecordToDBConnection; import org.gcube.accounting.utility.postgresql.RecordToDBMapping; import org.gcube.documentstore.records.AggregatedRecord; import org.gcube.documentstore.records.Record; import org.gcube.documentstore.records.RecordUtility; public class StatementMap { private static final InheritableThreadLocal> statementsThreadLocal = new InheritableThreadLocal>() { @Override protected Map initialValue() { return new HashMap(); } }; private PersistenceBackendConfiguration configuration; private RecordToDBMapping recordToDBMapping; public StatementMap(PersistenceBackendConfiguration configuration) { this.configuration = configuration; this.recordToDBMapping = new RecordToDBMapping(); Map>> aggregatedRecords = RecordUtility.getAggregatedRecordClassesFound(); for(String typeName : aggregatedRecords.keySet()) { try { Class> clz = aggregatedRecords.get(typeName); recordToDBMapping.addRecordToDB(clz, configuration); } catch (Exception e) { new RuntimeException(e); } } } protected Connection getConnection(Class> clz) throws Exception { RecordToDBConnection recordDBInfo = recordToDBMapping.getRecordDBInfo(clz); if(recordDBInfo == null) { recordToDBMapping.addRecordToDB(clz, configuration); recordDBInfo = recordToDBMapping.getRecordDBInfo(clz); } return recordDBInfo.getConnection(); } public synchronized Statement getStatement(Record record) throws Exception { Map map = statementsThreadLocal.get(); String type = record.getRecordType(); Statement statement = map.get(type); if(statement == null) { Class> clz = RecordUtility.getAggregatedRecordClass(type); Connection connection = getConnection(clz); statement = connection.createStatement(); map.put(type, statement); } return statement; } public synchronized void close() throws Exception { Map map = statementsThreadLocal.get(); Collection statements = map.values(); statementsThreadLocal.remove(); for(Statement statement : statements) { statement.close(); Connection connection = statement.getConnection(); connection.commit(); connection.close(); } } }