001package org.atteo.moonshine.hsqldb;
002
003import java.sql.SQLException;
004
005import javax.inject.Inject;
006import javax.sql.DataSource;
007import javax.xml.bind.annotation.XmlElement;
008import javax.xml.bind.annotation.XmlIDREF;
009import javax.xml.bind.annotation.XmlRootElement;
010
011import org.atteo.moonshine.database.DatabaseService;
012import org.atteo.moonshine.jta.JtaDataSourceWrapper;
013import org.atteo.moonshine.jta.JtaService;
014import org.atteo.moonshine.jta.PoolOptions;
015import org.atteo.moonshine.services.ImportService;
016import org.hsqldb.jdbc.pool.JDBCXADataSource;
017
018import com.google.inject.AbstractModule;
019import com.google.inject.Module;
020import com.google.inject.Provider;
021import com.google.inject.Singleton;
022
023/**
024 * Starts HSQLDB database.
025 */
026@XmlRootElement(name = "hsqldb")
027public class Hsqldb extends DatabaseService {
028    @XmlIDREF
029    @XmlElement
030    @ImportService
031    private JtaService jtaService;
032    @XmlElement
033    private String url = "jdbc:hsqldb:mem:mymemdb";
034
035    /**
036     * Connection pool options.
037     */
038    @XmlElement
039    private PoolOptions pool;
040
041    @XmlElement
042    private String testQuery = "VALUES 1";
043
044    @Inject
045    private JtaDataSourceWrapper wrapper;
046
047    private DataSource dataSource;
048
049    @Singleton
050    private class DataSourceProvider implements Provider<DataSource> {
051        @Inject
052        private JtaDataSourceWrapper wrapper;
053
054        @Override
055        public DataSource get() {
056            final JDBCXADataSource xaDataSource;
057            try {
058                xaDataSource = new JDBCXADataSource();
059            } catch (SQLException e) {
060                throw new RuntimeException("Cannot create data source", e);
061            }
062            String name = "defaultDataSource";
063            if (getId() != null) {
064                name = getId();
065            }
066            xaDataSource.setUrl(url);
067            dataSource = wrapper.wrap(name, xaDataSource, pool, testQuery);
068
069            executeMigrations(dataSource);
070            return dataSource;
071        }
072    }
073
074    @Override
075    public Module configure() {
076        return new AbstractModule() {
077            @Override
078            public void configure() {
079                bind(DataSource.class).toProvider(new DataSourceProvider()).in(Singleton.class);
080            }
081        };
082    }
083
084    @Override
085    public void close() {
086        if (dataSource != null) {
087            wrapper.close(dataSource);
088        }
089    }
090}