| package grails.test.hibernate |
| |
| import grails.config.Config |
| import groovy.transform.CompileStatic |
| import org.grails.config.PropertySourcesConfig |
| import org.grails.orm.hibernate.HibernateDatastore |
| import org.grails.orm.hibernate.cfg.Settings |
| import org.hibernate.Session |
| import org.hibernate.SessionFactory |
| import org.springframework.boot.env.PropertySourceLoader |
| import org.springframework.core.env.MapPropertySource |
| import org.springframework.core.env.MutablePropertySources |
| import org.springframework.core.env.PropertyResolver |
| import org.springframework.core.env.PropertySource |
| import org.springframework.core.io.DefaultResourceLoader |
| import org.springframework.core.io.Resource |
| import org.springframework.core.io.ResourceLoader |
| import org.springframework.core.io.support.SpringFactoriesLoader |
| import org.springframework.transaction.PlatformTransactionManager |
| import org.springframework.transaction.TransactionStatus |
| import org.springframework.transaction.interceptor.DefaultTransactionAttribute |
| import spock.lang.AutoCleanup |
| import spock.lang.Shared |
| import spock.lang.Specification |
| |
| /** |
| * Specification for Hibernate tests |
| * |
| * @author Graeme Rocher |
| * @since 6.0 |
| */ |
| @CompileStatic |
| abstract class HibernateSpec extends Specification { |
| |
| @Shared @AutoCleanup HibernateDatastore hibernateDatastore |
| @Shared PlatformTransactionManager transactionManager |
| |
| void setupSpec() { |
| |
| List<PropertySourceLoader> propertySourceLoaders = SpringFactoriesLoader.loadFactories(PropertySourceLoader.class, getClass().getClassLoader()) |
| ResourceLoader resourceLoader = new DefaultResourceLoader() |
| MutablePropertySources propertySources = new MutablePropertySources() |
| PropertySourceLoader ymlLoader = propertySourceLoaders.find { it.getFileExtensions().toList().contains("yml") } |
| if (ymlLoader) { |
| load(resourceLoader, ymlLoader, "application.yml").each { |
| propertySources.addLast(it) |
| } |
| } |
| PropertySourceLoader groovyLoader = propertySourceLoaders.find { it.getFileExtensions().toList().contains("groovy") } |
| if (groovyLoader) { |
| load(resourceLoader, groovyLoader, "application.groovy").each { |
| propertySources.addLast(it) |
| } |
| } |
| propertySources.addFirst(new MapPropertySource("defaults", getConfiguration())) |
| Config config = new PropertySourcesConfig(propertySources) |
| List<Class> domainClasses = getDomainClasses() |
| String packageName = getPackageToScan(config) |
| |
| if (!domainClasses) { |
| Package packageToScan = Package.getPackage(packageName) ?: getClass().getPackage() |
| hibernateDatastore = new HibernateDatastore((PropertyResolver) config, packageToScan) |
| } else { |
| hibernateDatastore = new HibernateDatastore((PropertyResolver) config, domainClasses as Class[]) |
| } |
| transactionManager = hibernateDatastore.getTransactionManager() |
| } |
| |
| /** |
| * The transaction status |
| */ |
| TransactionStatus transactionStatus |
| |
| void setup() { |
| transactionStatus = transactionManager.getTransaction(new DefaultTransactionAttribute()) |
| } |
| |
| void cleanup() { |
| if (isRollback()) { |
| transactionManager.rollback(transactionStatus) |
| } else { |
| transactionManager.commit(transactionStatus) |
| } |
| } |
| |
| /** |
| * @return The configuration |
| */ |
| Map getConfiguration() { |
| Collections.singletonMap(Settings.SETTING_DB_CREATE, "create-drop") |
| } |
| |
| /** |
| * @return the current session factory |
| */ |
| SessionFactory getSessionFactory() { |
| hibernateDatastore.getSessionFactory() |
| } |
| |
| /** |
| * @return the current Hibernate session |
| */ |
| Session getHibernateSession() { |
| getSessionFactory().getCurrentSession() |
| } |
| |
| /** |
| * Whether to rollback on each test (defaults to true) |
| */ |
| boolean isRollback() { |
| return true |
| } |
| |
| /** |
| * @return The domain classes |
| */ |
| List<Class> getDomainClasses() { [] } |
| |
| /** |
| * Obtains the default package to scan |
| * |
| * @param config The configuration |
| * @return The package to scan |
| */ |
| protected String getPackageToScan(Config config) { |
| config.getProperty('grails.codegen.defaultPackage', getClass().package.name) |
| } |
| |
| private List<PropertySource> load(ResourceLoader resourceLoader, PropertySourceLoader loader, String filename) { |
| if (canLoadFileExtension(loader, filename)) { |
| Resource appYml = resourceLoader.getResource(filename) |
| return loader.load(appYml.getDescription(), appYml) as List<PropertySource> |
| } else { |
| return Collections.emptyList() |
| } |
| } |
| |
| private boolean canLoadFileExtension(PropertySourceLoader loader, String name) { |
| return Arrays |
| .stream(loader.fileExtensions) |
| .map { String extension -> extension.toLowerCase() } |
| .anyMatch { String extension -> name.toLowerCase().endsWith(extension) } |
| } |
| } |