/* * Copyright (c) 2017 OBiBa. All rights reserved. * * This program and the accompanying materials * are made available under the terms of the GNU Public License v3.0. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.obiba.magma.js.methods; import java.io.IOException; import java.util.Collection; import java.util.List; import java.util.SortedSet; import java.util.TreeSet; import java.util.concurrent.TimeUnit; import org.hibernate.SessionFactory; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.obiba.magma.Datasource; import org.obiba.magma.MagmaEngine; import org.obiba.magma.Value; import org.obiba.magma.ValueTable; import org.obiba.magma.ValueTableWriter; import org.obiba.magma.Variable; import org.obiba.magma.VariableEntity; import org.obiba.magma.VariableValueSource; import org.obiba.magma.VectorSource; import org.obiba.magma.datasource.generated.GeneratedValueTable; import org.obiba.magma.datasource.hibernate.HibernateDatasource; import org.obiba.magma.js.AbstractJsTest; import org.obiba.magma.js.views.VariablesClause; import org.obiba.magma.support.DatasourceCopier; import org.obiba.magma.support.Initialisables; import org.obiba.magma.type.IntegerType; import org.obiba.magma.views.DefaultViewManagerImpl; import org.obiba.magma.views.MemoryViewPersistenceStrategy; import org.obiba.magma.views.View; import org.obiba.magma.views.ViewManager; import org.obiba.magma.xstream.MagmaXStreamExtension; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.support.TransactionCallbackWithoutResult; import org.springframework.transaction.support.TransactionTemplate; import com.google.common.base.Stopwatch; import com.google.common.collect.Lists; import static org.fest.assertions.api.Assertions.assertThat; import static org.obiba.magma.Variable.Builder.newVariable; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("/test-context.xml") @SuppressWarnings({ "OverlyLongMethod", "PMD.NcssMethodCount" }) public class GlobalMethodsHibernateTest extends AbstractJsTest { private static final Logger log = LoggerFactory.getLogger(GlobalMethodsHibernateTest.class); private static final String DATASOURCE = "ds"; private static final String TABLE = "table"; private static final String VARIABLE_AGE = "age"; private static final String VARIABLE_WEIGHT = "weight"; private static final String VARIABLE_HEIGHT = "height"; private ViewManager viewManager; @Autowired private SessionFactory sessionFactory; @Autowired private TransactionTemplate transactionTemplate; public GlobalMethodsHibernateTest() { System.setProperty("net.sf.ehcache.skipUpdateCheck", "true"); } @Before @Override public void before() { super.before(); viewManager = new DefaultViewManagerImpl(new MemoryViewPersistenceStrategy()); cleanlyRemoveHibernateDatasource(true); } @After @Override public void after() { super.after(); cleanlyRemoveHibernateDatasource(true); } @Override protected MagmaEngine newEngine() { MagmaEngine magmaEngine = super.newEngine(); magmaEngine.extend(new MagmaXStreamExtension()); return magmaEngine; } @Override protected void shutdownEngine() { transactionTemplate.execute(new TransactionCallbackWithoutResult() { @Override protected void doInTransactionWithoutResult(TransactionStatus status) { MagmaEngine.get().shutdown(); } }); } private void cleanlyRemoveHibernateDatasource(final boolean drop) { transactionTemplate.execute(new TransactionCallbackWithoutResult() { @Override protected void doInTransactionWithoutResult(TransactionStatus status) { try { if(drop) { Datasource datasource = new HibernateDatasource(DATASOURCE, sessionFactory); Initialisables.initialise(datasource); MagmaEngine.get().addDatasource(datasource); datasource.drop(); } MagmaEngine.get().removeDatasource(MagmaEngine.get().getDatasource(DATASOURCE)); } catch(Throwable e) { log.warn("Cannot remove datasource", e); } } }); } private Datasource getTestDatasource() { HibernateDatasource datasource = new HibernateDatasource(DATASOURCE, sessionFactory); List<Variable> variables = Lists.newArrayList( // newVariable(VARIABLE_AGE, IntegerType.get(), PARTICIPANT).build(), // newVariable(VARIABLE_WEIGHT, IntegerType.get(), PARTICIPANT).unit("kg").build(), // newVariable(VARIABLE_HEIGHT, IntegerType.get(), PARTICIPANT).unit("cm").build()); ValueTable generatedValueTable = new GeneratedValueTable(datasource, variables, 150); Datasource viewAwareDatasource = viewManager.decorate(datasource); MagmaEngine.get().addDatasource(viewAwareDatasource); try { DatasourceCopier.Builder.newCopier().build().copy(generatedValueTable, TABLE, datasource); } catch(IOException e) { throw new RuntimeException(e); } return viewAwareDatasource; } @Test public void test_$this_vector_performance() throws Exception { transactionTemplate.execute(new TransactionCallbackWithoutResult() { @Override protected void doInTransactionWithoutResult(TransactionStatus status) { Datasource datasource = getTestDatasource(); ValueTable table = datasource.getValueTable(TABLE); Collection<Variable> variables = Lists.newArrayList( // createIntVariable("A", "$('ds.table:weight')"), // createIntVariable("B", "$this('A')"), // createIntVariable("C", "$this('B')")); View viewTemplate = View.Builder.newView("view", table).list(new VariablesClause()).build(); try(ValueTableWriter.VariableWriter variableWriter = viewTemplate.getListClause().createWriter()) { for(Variable variable : variables) { variableWriter.writeVariable(variable); } } viewManager.addView(DATASOURCE, viewTemplate, null, null); View view = viewManager.getView(DATASOURCE, "view"); Stopwatch stopwatch = Stopwatch.createStarted(); SortedSet<VariableEntity> entities = new TreeSet<>(view.getVariableEntities()); log.info("Load {} entities in {}", entities.size(), stopwatch); stopwatch.reset().start(); VariableValueSource variableValueSource = view.getVariableValueSource("C"); VectorSource vectorSource = variableValueSource.asVectorSource(); Iterable<Value> values = vectorSource.getValues(entities); for(Value viewValue : values) { viewValue.getValue(); } log.info("Load vector in {}", stopwatch.stop()); assertThat(stopwatch.elapsed(TimeUnit.SECONDS)).isLessThan(1); } }); } }