001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.tools;
016    
017    import com.liferay.portal.kernel.io.unsync.UnsyncBufferedReader;
018    import com.liferay.portal.kernel.io.unsync.UnsyncByteArrayInputStream;
019    import com.liferay.portal.kernel.io.unsync.UnsyncByteArrayOutputStream;
020    import com.liferay.portal.kernel.io.unsync.UnsyncStringReader;
021    import com.liferay.portal.kernel.util.StringBundler;
022    import com.liferay.portal.kernel.util.StringPool;
023    import com.liferay.portal.kernel.util.StringUtil;
024    import com.liferay.portal.kernel.util.Validator;
025    import com.liferay.portal.util.FileImpl;
026    
027    import java.io.FileReader;
028    
029    import java.sql.Connection;
030    import java.sql.DriverManager;
031    import java.sql.PreparedStatement;
032    import java.sql.SQLException;
033    import java.sql.Statement;
034    
035    import java.util.Map;
036    
037    import org.apache.derby.tools.ij;
038    
039    /**
040     * @author Brian Wing Shun Chan
041     */
042    public class DBLoader {
043    
044            public static void loadHypersonic(Connection con, String fileName)
045                    throws Exception {
046    
047                    StringBundler sb = new StringBundler();
048    
049                    UnsyncBufferedReader unsyncBufferedReader = new UnsyncBufferedReader(
050                            new FileReader(fileName));
051    
052                    String line = null;
053    
054                    while ((line = unsyncBufferedReader.readLine()) != null) {
055                            if (!line.startsWith("//")) {
056                                    sb.append(line);
057    
058                                    if (line.endsWith(";")) {
059                                            String sql = sb.toString();
060    
061                                            sql = StringUtil.replace(
062                                                    sql, new String[] {"\\\"", "\\\\", "\\n", "\\r"},
063                                                    new String[] {"\"", "\\", "\\u000a", "\\u000a"});
064    
065                                            sb.setIndex(0);
066    
067                                            try {
068                                                    PreparedStatement ps = con.prepareStatement(sql);
069    
070                                                    ps.executeUpdate();
071    
072                                                    ps.close();
073                                            }
074                                            catch (Exception e) {
075                                                    System.out.println(sql);
076    
077                                                    throw e;
078                                            }
079                                    }
080                            }
081                    }
082    
083                    unsyncBufferedReader.close();
084            }
085    
086            public static void main(String[] args) {
087                    Map<String, String> arguments = ArgumentsUtil.parseArguments(args);
088    
089                    String databaseName = arguments.get("db.database.name");
090                    String databaseType = arguments.get("db.database.type");
091                    String sqlDir = arguments.get("db.sql.dir");
092                    String fileName = arguments.get("db.file.name");
093    
094                    new DBLoader(databaseName, databaseType, sqlDir, fileName);
095            }
096    
097            public DBLoader(
098                    String databaseName, String databaseType, String sqlDir,
099                    String fileName) {
100    
101                    try {
102                            _databaseName = databaseName;
103                            _databaseType = databaseType;
104                            _sqlDir = sqlDir;
105                            _fileName = fileName;
106    
107                            if (_databaseType.equals("derby")) {
108                                    _loadDerby();
109                            }
110                            else if (_databaseType.equals("hypersonic")) {
111                                    _loadHypersonic();
112                            }
113                    }
114                    catch (Exception e) {
115                            e.printStackTrace();
116                    }
117            }
118    
119            private void _loadDerby() throws Exception {
120                    Class.forName("org.apache.derby.jdbc.EmbeddedDriver");
121    
122                    Connection con = null;
123    
124                    try {
125                            con = DriverManager.getConnection(
126                                    "jdbc:derby:" + _sqlDir + "/" + _databaseName + ";create=true",
127                                    "", "");
128    
129                            if (Validator.isNull(_fileName)) {
130                                    _loadDerby(con, _sqlDir + "/portal/portal-derby.sql");
131                                    _loadDerby(con, _sqlDir + "/indexes.sql");
132                            }
133                            else {
134                                    _loadDerby(con, _sqlDir + "/" + _fileName);
135                            }
136                    }
137                    finally {
138                            if (con != null) {
139                                    con.close();
140                            }
141                    }
142    
143                    try {
144                            con = DriverManager.getConnection(
145                                    "jdbc:derby:" + _sqlDir + "/" + _databaseName +
146                                            ";shutdown=true",
147                                    "", "");
148                    }
149                    catch (SQLException sqle) {
150                            String sqlState = sqle.getSQLState();
151    
152                            if (!sqlState.equals("08006")) {
153                                    throw sqle;
154                            }
155                    }
156                    finally {
157                            if (con != null) {
158                                    con.close();
159                            }
160                    }
161            }
162    
163            private void _loadDerby(Connection con, String fileName) throws Exception {
164                    StringBundler sb = new StringBundler();
165    
166                    UnsyncBufferedReader unsyncBufferedReader = new UnsyncBufferedReader(
167                            new UnsyncStringReader(_fileUtil.read(fileName)));
168    
169                    String line = null;
170    
171                    while ((line = unsyncBufferedReader.readLine()) != null) {
172                            if (!line.startsWith("--")) {
173                                    sb.append(line);
174    
175                                    if (line.endsWith(";")) {
176                                            String sql = sb.toString();
177    
178                                            sql = StringUtil.replace(
179                                                    sql, new String[] {"\\'", "\\\"", "\\\\", "\\n", "\\r"},
180                                                    new String[] {"''", "\"", "\\", "\n", "\r"});
181    
182                                            sql = sql.substring(0, sql.length() - 1);
183    
184                                            sb.setIndex(0);
185    
186                                            if (sql.startsWith("commit")) {
187                                                    continue;
188                                            }
189    
190                                            ij.runScript(
191                                                    con,
192                                                    new UnsyncByteArrayInputStream(
193                                                            sql.getBytes(StringPool.UTF8)),
194                                                    StringPool.UTF8, new UnsyncByteArrayOutputStream(),
195                                                    StringPool.UTF8);
196                                    }
197                            }
198                    }
199    
200                    unsyncBufferedReader.close();
201            }
202    
203            private void _loadHypersonic() throws Exception {
204                    Class.forName("org.hsqldb.jdbcDriver");
205    
206                    // See LEP-2927. Appending ;shutdown=true to the database connection URL
207                    // guarantees that ${_databaseName}.log is purged.
208    
209                    Connection con = null;
210    
211                    try {
212                            con = DriverManager.getConnection(
213                                    "jdbc:hsqldb:" + _sqlDir + "/" + _databaseName +
214                                            ";shutdown=true",
215                                    "sa", "");
216    
217                            if (Validator.isNull(_fileName)) {
218                                    loadHypersonic(con, _sqlDir + "/portal/portal-hypersonic.sql");
219                                    loadHypersonic(con, _sqlDir + "/indexes.sql");
220                            }
221                            else {
222                                    loadHypersonic(con, _sqlDir + "/" + _fileName);
223                            }
224    
225                            // Shutdown Hypersonic
226    
227                            Statement statement = con.createStatement();
228    
229                            statement.execute("SHUTDOWN COMPACT");
230    
231                            statement.close();
232                    }
233                    finally {
234                            if (con != null) {
235                                    con.close();
236                            }
237                    }
238    
239                    // Hypersonic will encode unicode characters twice, this will undo it
240    
241                    String content = _fileUtil.read(
242                            _sqlDir + "/" + _databaseName + ".script");
243    
244                    content = StringUtil.replace(content, "\\u005cu", "\\u");
245    
246                    _fileUtil.write(_sqlDir + "/" + _databaseName + ".script", content);
247            }
248    
249            private static FileImpl _fileUtil = FileImpl.getInstance();
250    
251            private String _databaseName;
252            private String _databaseType;
253            private String _fileName;
254            private String _sqlDir;
255    
256    }