001: /**
002: * Copyright (c) 2000-2008 Liferay, Inc. All rights reserved.
003: *
004: * Permission is hereby granted, free of charge, to any person obtaining a copy
005: * of this software and associated documentation files (the "Software"), to deal
006: * in the Software without restriction, including without limitation the rights
007: * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
008: * copies of the Software, and to permit persons to whom the Software is
009: * furnished to do so, subject to the following conditions:
010: *
011: * The above copyright notice and this permission notice shall be included in
012: * all copies or substantial portions of the Software.
013: *
014: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
015: * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
016: * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
017: * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
018: * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
019: * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
020: * SOFTWARE.
021: */package com.liferay.portal.tools;
022:
023: import Zql.ZConstant;
024: import Zql.ZInsert;
025: import Zql.ZStatement;
026: import Zql.ZqlParser;
027:
028: import com.liferay.portal.kernel.util.StringMaker;
029: import com.liferay.portal.kernel.util.StringPool;
030: import com.liferay.portal.kernel.util.StringUtil;
031: import com.liferay.portal.kernel.util.Validator;
032: import com.liferay.util.FileUtil;
033:
034: import java.io.BufferedReader;
035: import java.io.ByteArrayInputStream;
036: import java.io.StringReader;
037:
038: import java.sql.Connection;
039: import java.sql.DriverManager;
040: import java.sql.PreparedStatement;
041: import java.sql.Statement;
042: import java.sql.Timestamp;
043:
044: import java.util.List;
045:
046: /**
047: * <a href="DBLoader.java.html"><b><i>View Source</i></b></a>
048: *
049: * @author Brian Wing Shun Chan
050: *
051: */
052: public class DBLoader {
053:
054: public static void main(String[] args) {
055: if (args.length == 2) {
056: new DBLoader(args[0], args[1], StringPool.BLANK);
057: } else if (args.length == 3) {
058: new DBLoader(args[0], args[1], args[2]);
059: } else {
060: throw new IllegalArgumentException();
061: }
062: }
063:
064: public DBLoader(String databaseType, String databaseName,
065: String fileName) {
066: try {
067: _databaseType = databaseType;
068: _databaseName = databaseName;
069: _fileName = fileName;
070:
071: if (_databaseType.equals("derby")) {
072: _loadDerby();
073: } else if (_databaseType.equals("hypersonic")) {
074: _loadHypersonic();
075: }
076: } catch (Exception e) {
077: e.printStackTrace();
078: }
079: }
080:
081: private PreparedStatement _getStatementDerby(Connection con,
082: String sql) throws Exception {
083:
084: sql = StringUtil.replace(sql, "current timestamp",
085: "'current timestamp'");
086:
087: sql += ";";
088:
089: ZqlParser zParser = new ZqlParser(new ByteArrayInputStream(sql
090: .getBytes()));
091:
092: ZStatement zStatement = zParser.readStatement();
093:
094: ZInsert zInsert = (ZInsert) zStatement;
095:
096: sql = "insert into " + zInsert.getTable() + " (";
097:
098: List columns = zInsert.getColumns();
099:
100: for (int i = 0; i < columns.size(); i++) {
101: sql += columns.get(i);
102:
103: if ((i + 1) < columns.size()) {
104: sql += ", ";
105: }
106: }
107:
108: sql += ") values (";
109:
110: for (int i = 0; i < columns.size(); i++) {
111: sql += "?";
112:
113: if ((i + 1) < columns.size()) {
114: sql += ", ";
115: }
116: }
117:
118: sql += ")";
119:
120: PreparedStatement ps = con.prepareStatement(sql);
121:
122: List values = zInsert.getValues();
123:
124: for (int i = 0; i < values.size(); i++) {
125: ZConstant zConstant = (ZConstant) values.get(i);
126:
127: int pos = i + 1;
128:
129: String value = (String) zConstant.getValue();
130:
131: if (value.equals("current timestamp")) {
132: ps.setTimestamp(pos, new Timestamp(System
133: .currentTimeMillis()));
134: } else if (value.length() < 32000) {
135: ps.setString(pos, zConstant.getValue());
136: } else {
137: ps.setCharacterStream(pos, new StringReader(value),
138: value.length());
139: }
140: }
141:
142: return ps;
143: }
144:
145: private void _loadDerby() throws Exception {
146: Class.forName("org.apache.derby.jdbc.EmbeddedDriver");
147:
148: Connection con = DriverManager.getConnection("jdbc:derby:"
149: + _databaseName + ";create=true", "", "");
150:
151: if (Validator.isNull(_fileName)) {
152: _loadDerby(con, "../sql/portal/portal-derby.sql");
153: _loadDerby(con, "../sql/indexes.sql");
154: } else {
155: _loadDerby(con, _fileName);
156: }
157: }
158:
159: private void _loadDerby(Connection con, String fileName)
160: throws Exception {
161:
162: StringMaker sm = new StringMaker();
163:
164: BufferedReader br = new BufferedReader(new StringReader(
165: FileUtil.read(fileName)));
166:
167: String line = null;
168:
169: while ((line = br.readLine()) != null) {
170: if (!line.startsWith("--")) {
171: sm.append(line);
172:
173: if (line.endsWith(";")) {
174: String sql = sm.toString();
175:
176: sql = StringUtil
177: .replace(sql, new String[] { "\\'", "\\\"",
178: "\\\\", "\\n", "\\r" },
179: new String[] { "''", "\"", "\\",
180: "\n", "\r" });
181:
182: sql = sql.substring(0, sql.length() - 1);
183:
184: sm = new StringMaker();
185:
186: if (sql.startsWith("commit")) {
187: continue;
188: }
189:
190: PreparedStatement ps = null;
191:
192: if (sql.startsWith("insert into Image (")
193: || sql
194: .startsWith("insert into JournalArticle (")
195: || sql
196: .startsWith("insert into JournalStructure (")
197: || sql
198: .startsWith("insert into JournalTemplate (")
199: || sql.startsWith("insert into Layout (")
200: || sql
201: .startsWith("insert into PortletPreferences (")) {
202:
203: // Derby isn't able to process long inserts. Zql parses
204: // the SQL statement so that we can manually set the
205: // insert statement. Zql also isn't able to properly
206: // parse certain unicode characters.
207:
208: sql = StringUtil.replace(sql, new String[] {
209: "\u0161", "\u017e", "\u2013", "\u2014",
210: "\u2015", "\u2019", "\u2022", "\u201c",
211: "\u2122" }, new String[] {
212: StringPool.BLANK, StringPool.BLANK,
213: StringPool.BLANK, StringPool.BLANK,
214: StringPool.BLANK, StringPool.BLANK,
215: StringPool.BLANK, StringPool.BLANK,
216: StringPool.BLANK });
217:
218: try {
219: ps = _getStatementDerby(con, sql);
220: } catch (Exception e) {
221: System.out
222: .println("Unable to parse " + sql);
223:
224: e.printStackTrace();
225:
226: throw e;
227: }
228: } else {
229: ps = con.prepareStatement(sql);
230: }
231:
232: try {
233: ps.executeUpdate();
234: } catch (Exception e) {
235: System.out.println("Unable to execute " + sql);
236:
237: e.printStackTrace();
238:
239: throw e;
240: } finally {
241: if (ps != null) {
242: ps.close();
243: }
244: }
245: }
246: }
247: }
248:
249: br.close();
250: }
251:
252: private void _loadHypersonic() throws Exception {
253: Class.forName("org.hsqldb.jdbcDriver");
254:
255: // See LEP-2927. Appending ;shutdown=true to the database connection URL
256: // guarantees that ${_databaseName}.log is purged.
257:
258: Connection con = DriverManager.getConnection("jdbc:hsqldb:"
259: + _databaseName + ";shutdown=true", "sa", "");
260:
261: if (Validator.isNull(_fileName)) {
262: _loadHypersonic(con, "../sql/portal/portal-hypersonic.sql");
263: _loadHypersonic(con, "../sql/indexes.sql");
264: } else {
265: _loadHypersonic(con, _fileName);
266: }
267:
268: // Shutdown Hypersonic
269:
270: Statement statement = con.createStatement();
271:
272: statement.execute("SHUTDOWN COMPACT");
273:
274: statement.close();
275:
276: con.close();
277:
278: // Hypersonic will encode unicode characters twice, this will undo
279: // it
280:
281: String content = FileUtil.read(_databaseName + ".script");
282:
283: content = StringUtil.replace(content, "\\u005cu", "\\u");
284:
285: FileUtil.write(_databaseName + ".script", content);
286: }
287:
288: private void _loadHypersonic(Connection con, String fileName)
289: throws Exception {
290:
291: StringMaker sm = new StringMaker();
292:
293: BufferedReader br = new BufferedReader(new StringReader(
294: FileUtil.read(fileName)));
295:
296: String line = null;
297:
298: while ((line = br.readLine()) != null) {
299: if (!line.startsWith("//")) {
300: sm.append(line);
301:
302: if (line.endsWith(";")) {
303: String sql = sm.toString();
304:
305: sql = StringUtil.replace(sql, new String[] {
306: "\\\"", "\\\\", "\\n", "\\r" },
307: new String[] { "\"", "\\", "\\u000a",
308: "\\u000a" });
309:
310: sm = new StringMaker();
311:
312: PreparedStatement ps = con.prepareStatement(sql);
313:
314: ps.executeUpdate();
315:
316: ps.close();
317: }
318: }
319: }
320:
321: br.close();
322: }
323:
324: private String _databaseType;
325: private String _databaseName;
326: private String _fileName;
327:
328: }
|