package org.molgenis.lifelines.utils; import java.math.BigDecimal; import java.util.Arrays; import java.util.List; import javax.persistence.EntityManager; import org.apache.log4j.Logger; import org.hibernate.Session; import org.hibernate.Transaction; import org.molgenis.framework.db.Database; import org.molgenis.framework.db.DatabaseException; import org.molgenis.pheno.Measurement; import app.DatabaseFactory; import org.apache.commons.lang.StringUtils; import org.molgenis.organization.Investigation; import org.molgenis.protocol.Protocol; /** * Creates an View on top of EAV table to reconstruct original table, This is * useful for querying & testing data in original format! * * @author joris lops */ public class EAVToView { private static Logger log = Logger.getLogger(EAVToView.class); private final String schemaName; private final String tableName; private final List<Measurement> fields; private final String schemaToExportView; private final Protocol protocol; private final Investigation investigation; private final int studyId; public EAVToView(int studyId, String schemaName, String tableName, List<Measurement> fields, String schemaToExportView, Protocol protocol, Investigation investigation) throws DatabaseException, Exception { this.studyId = studyId; this.schemaName = schemaName; this.tableName = tableName.toUpperCase(); this.schemaToExportView = schemaToExportView; this.fields = fields; this.protocol = protocol; // this.databaseTarget = databaseTarget; this.investigation = investigation; load(); } public static String createQuery(Investigation investigation, Protocol protocol, List<Measurement> measurements, EntityManager em, LoaderUtils.eDatabase database) throws Exception { return createQuery(investigation, protocol, measurements, em, false, database); } public static String createQuery(Investigation investigation, Protocol protocol, List<Measurement> measurements, EntityManager em, boolean tableInAlias, LoaderUtils.eDatabase database) throws Exception { String column = "max(case when o.feature = %d then %s end) %s \n"; StringBuilder query = new StringBuilder("SELECT "); for (int i = 0; i < measurements.size(); ++i) { Measurement m = measurements.get(i); String castPart = LoaderUtils.getCast(m.getDataType(), database); String fieldAlias = null; if (tableInAlias) { fieldAlias = String.format("%s_%s", protocol.getName(), m.getName()); } else { fieldAlias = String.format("%s", m.getName()); } fieldAlias = StringUtils.substring(fieldAlias, 0, 30); // fieldAlias = StringUtils.substring(fieldAlias, 0, 28); query.append(String.format(column, m.getId(), String.format(castPart, "value"), fieldAlias)); if (i + 1 < measurements.size()) { query.append(","); } } query.append(String .format(" FROM \n observedvalue o join protocolapplication pa on (o.protocolapplication = pa.id) \n WHERE o.investigation = %d AND pa.protocol = %d \n GROUP BY o.protocolapplication", investigation.getId(), protocol.getId())); return query.toString(); } private void load() throws DatabaseException, Exception { Database db = DatabaseFactory.create(); EntityManager em = db.getEntityManager(); String query = createQuery(investigation, protocol, fields, em, false, LoaderUtils.eDatabase.ORACLE); String viewQuery = ""; String tempTableName = (schemaToExportView != null) ? "" + schemaToExportView + "." : ""; tempTableName += tableName; // if(databaseTarget.equals("mysql")) { // viewQuery = String.format("CREATE TABLE %s %S", tempTableName, // query.toString()); // } else { // String materializedView = // "CREATE MATERIALIZED VIEW %s NOCACHE NOPARALLEL BUILD IMMEDIATE USING INDEX REFRESH ON DEMAND COMPLETE DISABLE QUERY REWRITE AS %s"; String view = "CREATE VIEW %s AS %s"; viewQuery = String.format(view, tempTableName, query.toString()); ; // } // Object result = // db.getEntityManager().createNativeQuery(viewQuery).getResultList(); // if(result != null) // System.out.println("view created"); // else // System.out.println("view created failed!"); Session s = db.getEntityManager().unwrap(Session.class); Transaction t = s.beginTransaction(); // if(databaseTarget.equals("mysql")) { // s.createSQLQuery(String.format("DROP TABLE IF EXISTS %s", // tableName)).executeUpdate(); // } // else //oracle // { String viewExists = "select count(*) " + "from user_objects " + "where object_type = 'VIEW' " + "and object_name = :viewName"; log.debug(String.format("[%d-%s] %s", studyId, tableName, viewExists)); // figure out if it exists first int viewCount = ((BigDecimal) em.createNativeQuery(viewExists).setParameter("viewName", tableName) .getSingleResult()).intValue(); if (viewCount == 1) { s.createSQLQuery(String.format("DROP VIEW %s", tableName)).executeUpdate(); } log.debug(String.format("[%d-%s] %s", studyId, tableName, viewQuery.toString())); System.out.println(viewQuery); s.createSQLQuery(viewQuery).executeUpdate(); // } t.commit(); } }