/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * Copyright (c) 2013, MPL CodeInside http://codeinside.ru */ package ru.codeinside.gses.migrations; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import ru.codeinside.adm.database.Employee; import ru.codeinside.gses.liquibase.impl.DbConfig; import ru.codeinside.gses.liquibase.impl.LegacyMigrationService; import ru.codeinside.gses.liquibase.impl.Migration; import javax.naming.InitialContext; import javax.persistence.EntityManagerFactory; import javax.persistence.Persistence; import javax.persistence.metamodel.EmbeddableType; import javax.persistence.metamodel.EntityType; import javax.persistence.metamodel.ManagedType; import javax.persistence.metamodel.Metamodel; import javax.sql.DataSource; import javax.transaction.UserTransaction; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.ResultSet; import java.sql.SQLException; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.Map; import java.util.Set; import java.util.TreeSet; @RunWith(Arquillian.class) public class SchemaSandbox extends Assert { @Deployment public static JavaArchive createDeployment() { // можно притащить зависимость: //.addAsLibraries(DependencyResolvers //.use(MavenDependencyResolver.class) // .artifact("com.example:utils:1.0.0-SNAPSHOT") // .resolveAsFiles()); return ShrinkWrap.create(JavaArchive.class) .addPackage(Employee.class.getPackage()) .addAsResource("META-INF/persistence.xml"); } static void log(String txt) { System.err.println(txt); } static void dumpMetaModel(final Metamodel metamodel) { Set<String> entities = new TreeSet<String>(); for (final EntityType<?> entity : metamodel.getEntities()) { entities.add(entity.getName()); } log("entities " + entities); Set<String> types = new TreeSet<String>(); for (ManagedType<?> type : metamodel.getManagedTypes()) { types.add(type.getJavaType().getName()); } for (final EmbeddableType<?> type : metamodel.getEmbeddables()) { types.add(type.getJavaType().getName()); } log("types " + types); } // можно запускать внутри одной сюиты private static void dropContent(DataSource ds) throws Exception { final UserTransaction tx = (UserTransaction) InitialContext.doLookup("UserTransaction"); assertNotNull(tx); tx.begin(); Migration assistance = new LegacyMigrationService().create(); assistance.drop(new DbConfig(ds)); tx.commit(); } @Test public void autoGenerationToFiles() throws Exception { String appDir = "target"; for (final String entry : Databases.UNITS) { String createName = "createDDL_" + entry + ".jdbc"; String dropName = "dropDDL_" + entry + ".jdbc"; final Map<String, String> props = new LinkedHashMap<String, String>(); props.put("eclipselink.ddl-generation", "create-tables"); props.put("eclipselink.ddl-generation.output-mode", "sql-script"); props.put("eclipselink.logging.level", "SEVERE"); props.put("eclipselink.application-location", appDir); props.put("eclipselink.create-ddl-jdbc-file-name", createName); props.put("eclipselink.drop-ddl-jdbc-file-name", dropName); EntityManagerFactory emf = Persistence.createEntityManagerFactory(entry, props); emf.createEntityManager().close(); emf.close(); } //props.put("eclipselink.jdbc.native-sql", "true"); //props.put("eclipselink.jdbc.exclusive-connection.mode", "Transactional"); //props.put("eclipselink.jdbc.exclusive-connection.is-lazy", "true"); //props.put("eclipselink.jdbc.connections.initial", "0"); //props.put("eclipselink.jdbc.connections.min", "0"); //props.put("eclipselink.jdbc.connections.max", "1"); // До создания EMF можно изменить соединение: //props.put("javax.persistence.jdbc.url", "jdbc:h2:mem:adminka2;MODE=PostgreSQL;MVCC=true"); //props.put("javax.persistence.jdbc.user", "sa"); //props.put("javax.persistence.jdbc.password", ""); } @Test public void autoGenerarionToDb() throws Exception { DataSource ds = InitialContext.doLookup("jdbc/adminka"); if (null != System.getProperty("arquillian.launch")) { // заточено только под postgresql dropContent(ds); } else { assertTrue(introspectTables(ds, false).isEmpty()); } final Map<String, String> props = new LinkedHashMap<String, String>(); props.put("eclipselink.ddl-generation", "create-tables"); props.put("eclipselink.ddl-generation.output-mode", "database"); props.put("eclipselink.logging.level", "SEVERE"); props.put("eclipselink.jdbc.native-sql", "true"); //props.put("eclipselink.jdbc.exclusive-connection.mode", "Transactional"); //props.put("eclipselink.jdbc.exclusive-connection.is-lazy", "true"); //props.put("eclipselink.jdbc.connections.initial", "0"); //props.put("eclipselink.jdbc.connections.min", "0"); //props.put("eclipselink.jdbc.connections.max", "1"); // До создания EMF можно изменить соединение: //props.put("javax.persistence.jdbc.url", "jdbc:h2:mem:adminka3;MODE=PostgreSQL;MVCC=true"); //props.put("javax.persistence.jdbc.user", "sa"); //props.put("javax.persistence.jdbc.password", ""); EntityManagerFactory emf = Persistence.createEntityManagerFactory("myPU", props); emf.createEntityManager().close(); emf.close(); Set<String> strings = introspectTables(ds, false); assertTrue( strings.contains("EMPLOYEE") || strings.contains("employee") ); } private Set<String> introspectTables(DataSource ds, boolean dump) throws SQLException { final LinkedHashSet<String> result = new LinkedHashSet<String>(); final Connection c = ds.getConnection(); final DatabaseMetaData metaData = c.getMetaData(); if (dump) { ResultSet tableTypes = metaData.getTableTypes(); while (tableTypes.next()) { log("has type: " + tableTypes.getObject(1)); } tableTypes.close(); } if (dump) { ResultSet catalogs = metaData.getCatalogs(); while (catalogs.next()) { log("catalog: " + catalogs.getObject(1)); } catalogs.close(); } ResultSet tables = metaData.getTables("", "", null, new String[]{"TABLE", "SEQUENCE"}); final StringBuilder sb = new StringBuilder(); while (tables.next()) { if (dump) { sb.delete(0, sb.length()); sb.append("table "); for (int i = 1; i < tables.getMetaData().getColumnCount(); i++) { if (i > 1) { sb.append(','); } final Object o = tables.getObject(i); if (o != null) { sb.append(o); } } log(sb.toString()); } result.add(tables.getString(3)); } tables.close(); c.close(); return result; } }