001/**
002 * HSQLDBserver.java
003 * jCOLIBRI2 framework. 
004 * @author Juan A. Recio-Garc�a.
005 * GAIA - Group for Artificial Intelligence Applications
006 * http://gaia.fdi.ucm.es
007 * 04/07/2007
008 */
009package es.ucm.fdi.gaia.jcolibri.test.database;
010
011import java.io.File;
012import java.io.PrintStream;
013import java.io.PrintWriter;
014import java.sql.Connection;
015import java.sql.DriverManager;
016import java.sql.Statement;
017import java.util.HashMap;
018
019import org.apache.log4j.LogManager;
020import org.hsqldb.Server;
021
022import es.ucm.fdi.gaia.jcolibri.util.FileIO;
023
024/**
025 * Creates a data base server.<br>
026 * Server can be persistent (saved into the file system) or not (just in memory).<br>
027 * User can load several sql files to import the data.
028 * @author Juan A. Recio-Garcia
029 * @version 1.0
030 */
031public class ConfigurableHSQLDBserver
032{
033    static boolean initialized = false;
034
035    private static Server server;
036    
037    private static PrintStream outStream = new PrintStream(System.out);
038    private static PrintWriter out = new PrintWriter(outStream);
039    private static String dataBaseName;
040
041    /**
042     * Initialize the server using a non persistent data base in memory 
043     * @param databaseName is the name of the data base
044     * @param showLog indicates if log comments must be shown
045     */
046    public static void initInMemory(String databaseName, boolean showLog)
047    {
048        if (initialized)
049            return;
050        
051        LogManager.getLogger(ConfigurableHSQLDBserver.class).info("Creating data base ...");
052
053        dataBaseName = databaseName;
054        
055        server = new Server();
056        server.setDatabaseName(0, databaseName);
057        server.setDatabasePath(0, "mem:"+databaseName+";sql.enforce_strict_size=true");
058
059        if(showLog)
060        {
061            server.setLogWriter(out);
062            server.setErrWriter(out);
063        }
064        else
065        {
066            server.setLogWriter(null);
067            server.setErrWriter(null);
068        }
069        server.setSilent(!showLog);
070        server.setTrace(showLog);
071        
072        server.start();
073        
074        initialized = true;
075    }
076    
077    /**
078     * Initialize the server using a persistent data base in the file system <p>
079     * This persistent data base contains HSQLDB MEMORY tables.
080     * Memory tables are the default type when the CREATE TABLE command is used. 
081     * Their data is held entirely in memory but any change to their structure or contents is written to the <dbname>.script file. 
082     * The script file is read the next time the database is opened, and the MEMORY tables are recreated with all their contents. 
083     * So MEMORY tables are persistent.
084     * <p>
085     * More info: <a href="http://hsqldb.org/doc/guide/ch01.html">http://hsqldb.org/doc/guide/ch01.html</a>
086     * 
087     * @param databaseName is the name of the data base
088     * @param showLog indicates if log comments must be shown
089     * @param directory where the data base must be created or loaded from. This directory must exist.
090     */
091    public static void initInFileSystem(String databaseName, boolean showLog, String directory)
092    {
093        if (initialized)
094            return;
095        
096        LogManager.getLogger(ConfigurableHSQLDBserver.class).info("Creating data base in file system...");
097
098        dataBaseName = databaseName;
099        
100        server = new Server();
101        
102        server.setDatabaseName(0, databaseName);
103        server.setDatabasePath(0, "file:"+directory+File.separator+databaseName+";sql.enforce_strict_size=true");
104
105        if(showLog)
106        {
107            server.setLogWriter(out);
108            server.setErrWriter(out);
109        }
110        else
111        {
112            server.setLogWriter(null);
113            server.setErrWriter(null);
114        }
115        server.setSilent(!showLog);
116        server.setTrace(showLog);
117        
118        server.start();
119        
120        initialized = true;
121    }
122    
123    /**
124     * Loads the given sql file.
125     * @param sqlfile to be loaded
126     */
127    public static void loadSQLFile(String sqlfile)
128    {
129        if (!initialized)
130        {
131            LogManager.getLogger(ConfigurableHSQLDBserver.class).warn("Server must be initialized before loading SQL files.");
132            return;
133        }
134
135        try
136        {
137            Class.forName("org.hsqldb.jdbcDriver");
138
139            Connection conn = DriverManager.getConnection("jdbc:hsqldb:hsql://localhost/"+dataBaseName, "sa", "");
140            File f = new File( FileIO.findFile(sqlfile).getFile() );
141            SqlFile file = new SqlFile(f,false,new HashMap<Object,Object>());
142            file.execute(conn,outStream,outStream, true);
143
144            LogManager.getLogger(ConfigurableHSQLDBserver.class).info("SQL file: "+sqlfile+" loaded");
145            
146        } catch (Exception e)
147        {
148            LogManager.getLogger(ConfigurableHSQLDBserver.class).error(e);
149        }
150
151    }
152
153    /**
154     * Shutdown the server
155     */
156    public static void shutDown()
157    {
158        if (!initialized)
159            return;
160        
161        try
162        {
163            Connection conn = DriverManager.getConnection("jdbc:hsqldb:hsql://localhost/"+dataBaseName, "sa", "");
164            Statement st = conn.createStatement();
165            st.execute("SHUTDOWN");
166            server.stop();
167            initialized = false;
168        } catch (Exception e)
169        {
170            LogManager.getLogger(ConfigurableHSQLDBserver.class).error(e);
171            
172        }
173
174        
175    }
176
177    /**
178     * Testing method
179     */
180    public static void main(String[] args)
181    {
182        ConfigurableHSQLDBserver.initInMemory("travel", true);
183        ConfigurableHSQLDBserver.loadSQLFile("es/ucm/fdi/gaia/jcolibri/test/database/travel.sql");
184        ConfigurableHSQLDBserver.shutDown();
185        System.exit(0);
186        
187    }
188
189}