001    /**
002     * Copyright (c) 2000-2012 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 =
062                                                    StringUtil.replace(
063                                                            sql,
064                                                            new String[] {
065                                                                    "\\\"",
066                                                                    "\\\\",
067                                                                    "\\n",
068                                                                    "\\r"
069                                                            },
070                                                            new String[] {
071                                                                    "\"",
072                                                                    "\\",
073                                                                    "\\u000a",
074                                                                    "\\u000a"
075                                                            });
076    
077                                            sb.setIndex(0);
078    
079                                            try {
080                                                    PreparedStatement ps = con.prepareStatement(sql);
081    
082                                                    ps.executeUpdate();
083    
084                                                    ps.close();
085                                            }
086                                            catch (Exception e) {
087                                                    System.out.println(sql);
088    
089                                                    throw e;
090                                            }
091                                    }
092                            }
093                    }
094    
095                    unsyncBufferedReader.close();
096            }
097    
098            public static void main(String[] args) {
099                    Map<String, String> arguments = ArgumentsUtil.parseArguments(args);
100    
101                    String databaseName = arguments.get("db.database.name");
102                    String databaseType = arguments.get("db.database.type");
103                    String sqlDir = arguments.get("db.sql.dir");
104                    String fileName = arguments.get("db.file.name");
105    
106                    new DBLoader(databaseName, databaseType, sqlDir, fileName);
107            }
108    
109            public DBLoader(
110                    String databaseName, String databaseType, String sqlDir,
111                    String fileName) {
112    
113                    try {
114                            _databaseName = databaseName;
115                            _databaseType = databaseType;
116                            _sqlDir = sqlDir;
117                            _fileName = fileName;
118    
119                            if (_databaseType.equals("derby")) {
120                                    _loadDerby();
121                            }
122                            else if (_databaseType.equals("hypersonic")) {
123                                    _loadHypersonic();
124                            }
125                    }
126                    catch (Exception e) {
127                            e.printStackTrace();
128                    }
129            }
130    
131            private void _loadDerby() throws Exception {
132                    Class.forName("org.apache.derby.jdbc.EmbeddedDriver");
133    
134                    Connection con = DriverManager.getConnection(
135                            "jdbc:derby:" + _sqlDir + "/" + _databaseName + ";create=true", "",
136                            "");
137    
138                    if (Validator.isNull(_fileName)) {
139                            _loadDerby(con, _sqlDir + "/portal/portal-derby.sql");
140                            _loadDerby(con, _sqlDir + "/indexes.sql");
141                    }
142                    else {
143                            _loadDerby(con, _sqlDir + "/" + _fileName);
144                    }
145    
146                    con.close();
147    
148                    try {
149                            con = DriverManager.getConnection(
150                                    "jdbc:derby:" + _sqlDir + "/" + _databaseName +
151                                            ";shutdown=true",
152                                    "", "");
153                    }
154                    catch (SQLException sqle) {
155                            String sqlState = sqle.getSQLState();
156    
157                            if (!sqlState.equals("08006")) {
158                                    throw sqle;
159                            }
160                    }
161            }
162    
163            private void _loadDerby(Connection con, String fileName)
164                    throws Exception {
165    
166                    StringBundler sb = new StringBundler();
167    
168                    UnsyncBufferedReader unsyncBufferedReader = new UnsyncBufferedReader(
169                            new UnsyncStringReader(_fileUtil.read(fileName)));
170    
171                    String line = null;
172    
173                    while ((line = unsyncBufferedReader.readLine()) != null) {
174                            if (!line.startsWith("--")) {
175                                    sb.append(line);
176    
177                                    if (line.endsWith(";")) {
178                                            String sql = sb.toString();
179    
180                                            sql =
181                                                    StringUtil.replace(
182                                                            sql,
183                                                            new String[] {
184                                                                    "\\'",
185                                                                    "\\\"",
186                                                                    "\\\\",
187                                                                    "\\n",
188                                                                    "\\r"
189                                                            },
190                                                            new String[] {
191                                                                    "''",
192                                                                    "\"",
193                                                                    "\\",
194                                                                    "\n",
195                                                                    "\r"
196                                                            });
197    
198                                            sql = sql.substring(0, sql.length() - 1);
199    
200                                            sb.setIndex(0);
201    
202                                            if (sql.startsWith("commit")) {
203                                                    continue;
204                                            }
205    
206                                            ij.runScript(
207                                                    con,
208                                                    new UnsyncByteArrayInputStream(
209                                                            sql.getBytes(StringPool.UTF8)),
210                                                    StringPool.UTF8, new UnsyncByteArrayOutputStream(),
211                                                    StringPool.UTF8);
212                                    }
213                            }
214                    }
215    
216                    unsyncBufferedReader.close();
217            }
218    
219            private void _loadHypersonic() throws Exception {
220                    Class.forName("org.hsqldb.jdbcDriver");
221    
222                    // See LEP-2927. Appending ;shutdown=true to the database connection URL
223                    // guarantees that ${_databaseName}.log is purged.
224    
225                    Connection con = DriverManager.getConnection(
226                            "jdbc:hsqldb:" + _sqlDir + "/" + _databaseName + ";shutdown=true",
227                            "sa", "");
228    
229                    if (Validator.isNull(_fileName)) {
230                            loadHypersonic(con, _sqlDir + "/portal/portal-hypersonic.sql");
231                            loadHypersonic(con, _sqlDir + "/indexes.sql");
232                    }
233                    else {
234                            loadHypersonic(con, _sqlDir + "/" + _fileName);
235                    }
236    
237                    // Shutdown Hypersonic
238    
239                    Statement statement = con.createStatement();
240    
241                    statement.execute("SHUTDOWN COMPACT");
242    
243                    statement.close();
244    
245                    con.close();
246    
247                    // Hypersonic will encode unicode characters twice, this will undo
248                    // it
249    
250                    String content = _fileUtil.read(
251                            _sqlDir + "/" + _databaseName + ".script");
252    
253                    content = StringUtil.replace(content, "\\u005cu", "\\u");
254    
255                    _fileUtil.write(_sqlDir + "/" + _databaseName + ".script", content);
256            }
257    
258            private static FileImpl _fileUtil = FileImpl.getInstance();
259    
260            private String _databaseName;
261            private String _databaseType;
262            private String _fileName;
263            private String _sqlDir;
264    
265    }