package org.openlca.core.database; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.openlca.core.model.Process; import org.openlca.core.model.ProcessType; import org.openlca.core.model.descriptors.FlowDescriptor; import org.openlca.core.model.descriptors.ProcessDescriptor; public class ProcessDao extends CategorizedEntityDao<Process, ProcessDescriptor> { public ProcessDao(IDatabase database) { super(Process.class, ProcessDescriptor.class, database); } @Override protected String[] getDescriptorFields() { return new String[] { "id", "ref_id", "name", "description", "version", "last_change", "f_category", "process_type", "infrastructure_process", "f_location", "f_quantitative_reference" }; } @Override protected ProcessDescriptor createDescriptor(Object[] queryResult) { if (queryResult == null) return null; ProcessDescriptor d = super.createDescriptor(queryResult); d.setProcessType(ProcessType.valueOf((String) queryResult[7])); d.setInfrastructureProcess((Integer) queryResult[8] == 1); d.setLocation((Long) queryResult[9]); d.setQuantitativeReference((Long) queryResult[10]); return d; } public List<FlowDescriptor> getTechnologyInputs(ProcessDescriptor descriptor) { Set<Long> flowIds = getTechnologies(descriptor, true); return loadFlowDescriptors(flowIds); } public List<FlowDescriptor> getTechnologyOutputs( ProcessDescriptor descriptor) { Set<Long> flowIds = getTechnologies(descriptor, false); return loadFlowDescriptors(flowIds); } public Set<Long> getUsed() { Set<Long> ids = new HashSet<>(); String query = "SELECT DISTINCT f_default_provider FROM tbl_exchanges"; try { NativeSql.on(database).query(query, (rs) -> { ids.add(rs.getLong("f_default_provider")); return true; }); return ids; } catch (Exception e) { DatabaseException.logAndThrow(log, "failed to load used providers", e); return Collections.emptySet(); } } public void replace(long oldId, long productId, Long newId) { String statement = "UPDATE tbl_exchanges SET f_default_provider = " + newId + " " + "WHERE f_default_provider = " + oldId + " AND f_flow = " + productId; try { NativeSql.on(database).runUpdate(statement); } catch (Exception e) { DatabaseException.logAndThrow(log, "failed to replace provider " + oldId + " for product " + productId + " with " + newId, e); } } private Set<Long> getTechnologies(ProcessDescriptor descriptor, boolean input) { if (descriptor == null) return Collections.emptySet(); String sql = "select f_flow from tbl_exchanges where f_owner = " + descriptor.getId() + " and is_input = " + (input ? 1 : 0); Set<Long> ids = new HashSet<>(); try (Connection con = getDatabase().createConnection(); Statement s = con.createStatement(); ResultSet rs = s.executeQuery(sql)) { while (rs.next()) ids.add(rs.getLong("f_flow")); return ids; } catch (SQLException e) { log.error("Error loading technologies", e); return Collections.emptySet(); } } private List<FlowDescriptor> loadFlowDescriptors(Set<Long> flowIds) { if (flowIds == null || flowIds.isEmpty()) return Collections.emptyList(); FlowDao dao = new FlowDao(getDatabase()); return dao.getDescriptors(flowIds); } public boolean hasQuantitativeReference(long id) { return hasQuantitativeReference(Collections.singleton(id)).get(id); } public Map<Long, Boolean> hasQuantitativeReference(Set<Long> ids) { StringBuilder query = new StringBuilder(); query.append("SELECT id, f_quantitative_reference FROM tbl_processes "); query.append("WHERE id IN " + asSqlList(ids)); query.append(" AND f_quantitative_reference IN "); query.append("(SELECT id FROM tbl_exchanges WHERE id = f_quantitative_reference)"); Map<Long, Boolean> result = new HashMap<>(); for (long id : ids) result.put(id, false); try { NativeSql.on(database).query(query.toString(), (res) -> { result.put(res.getLong(1), res.getLong(2) != 0l); return true; }); } catch (SQLException e) { log.error("Error checking for quantitative reference existence", e); } return result; } }