1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * The contents of this file are subject to the terms of the Liferay Enterprise
5    * Subscription License ("License"). You may not use this file except in
6    * compliance with the License. You can obtain a copy of the License by
7    * contacting Liferay, Inc. See the License for the specific language governing
8    * permissions and limitations under the License, including but not limited to
9    * distribution rights of the Software.
10   *
11   *
12   *
13   */
14  
15  package com.liferay.portal.dao.db;
16  
17  import com.liferay.portal.kernel.dao.db.DB;
18  import com.liferay.portal.kernel.dao.jdbc.DataAccess;
19  import com.liferay.portal.kernel.io.unsync.UnsyncBufferedReader;
20  import com.liferay.portal.kernel.io.unsync.UnsyncStringReader;
21  import com.liferay.portal.kernel.util.StringBundler;
22  import com.liferay.portal.kernel.util.StringPool;
23  import com.liferay.portal.kernel.util.StringUtil;
24  
25  import java.io.IOException;
26  
27  import java.sql.CallableStatement;
28  import java.sql.Connection;
29  import java.sql.SQLException;
30  
31  import java.util.HashSet;
32  import java.util.Set;
33  
34  /**
35   * <a href="DB2DB.java.html"><b><i>View Source</i></b></a>
36   *
37   * @author Alexander Chow
38   * @author Bruno Farache
39   * @author Sandeep Soni
40   * @author Ganesh Ram
41   */
42  public class DB2DB extends BaseDB {
43  
44      public static DB getInstance() {
45          return _instance;
46      }
47  
48      public String buildSQL(String template) throws IOException {
49          template = convertTimestamp(template);
50          template = replaceTemplate(template, getTemplate());
51  
52          template = reword(template);
53          template = removeLongInserts(template);
54          template = removeNull(template);
55          template = StringUtil.replace(template, "\\'", "''");
56  
57          return template;
58      }
59  
60      public boolean isSupportsAlterColumnType() {
61          return _SUPPORTS_ALTER_COLUMN_TYPE;
62      }
63  
64      public boolean isSupportsInlineDistinct() {
65          return _SUPPORTS_INLINE_DISTINCT;
66      }
67  
68      public boolean isSupportsScrollableResults() {
69          return _SUPPORTS_SCROLLABLE_RESULTS;
70      }
71  
72      public void runSQL(String template) throws IOException, SQLException {
73          if (template.startsWith(ALTER_COLUMN_NAME) ||
74              template.startsWith(ALTER_COLUMN_TYPE)) {
75  
76              String sql = buildSQL(template);
77  
78              String[] alterSqls = StringUtil.split(sql, StringPool.SEMICOLON);
79  
80              for (String alterSql : alterSqls) {
81                  if (!alterSql.startsWith("-- ")) {
82                      runSQL(alterSql);
83                  }
84              }
85          }
86          else {
87              super.runSQL(template);
88          }
89      }
90  
91      public void runSQL(String[] templates) throws IOException, SQLException {
92          super.runSQL(templates);
93  
94          _reorgTables(templates);
95      }
96  
97      protected DB2DB() {
98          super(TYPE_DB2);
99      }
100 
101     protected String buildCreateFileContent(
102             String sqlDir, String databaseName, int population)
103         throws IOException {
104 
105         String suffix = getSuffix(population);
106 
107         StringBundler sb = new StringBundler(14);
108 
109         sb.append("drop database ");
110         sb.append(databaseName);
111         sb.append(";\n");
112         sb.append("create database ");
113         sb.append(databaseName);
114         sb.append(";\n");
115         sb.append("connect to ");
116         sb.append(databaseName);
117         sb.append(";\n");
118         sb.append(
119             readFile(
120                 sqlDir + "/portal" + suffix + "/portal" + suffix + "-db2.sql"));
121         sb.append("\n\n");
122         sb.append(readFile(sqlDir + "/indexes/indexes-db2.sql"));
123         sb.append("\n\n");
124         sb.append(readFile(sqlDir + "/sequences/sequences-db2.sql"));
125 
126         return sb.toString();
127     }
128 
129     protected String getServerName() {
130         return "db2";
131     }
132 
133     protected String[] getTemplate() {
134         return _DB2;
135     }
136 
137     protected String reword(String data) throws IOException {
138         UnsyncBufferedReader unsyncBufferedReader = new UnsyncBufferedReader(
139             new UnsyncStringReader(data));
140 
141         StringBundler sb = new StringBundler();
142 
143         String line = null;
144 
145         while ((line = unsyncBufferedReader.readLine()) != null) {
146             if (line.startsWith(ALTER_COLUMN_NAME)) {
147                 String[] template = buildColumnNameTokens(line);
148 
149                 line = StringUtil.replace(
150                     "alter table @table@ add column @new-column@ @type@;\n",
151                     REWORD_TEMPLATE, template);
152 
153                 line = line + StringUtil.replace(
154                     "update @table@ set @new-column@ = @old-column@;\n",
155                     REWORD_TEMPLATE, template);
156 
157                 line = line + StringUtil.replace(
158                     "alter table @table@ drop column @old-column@",
159                     REWORD_TEMPLATE, template);
160             }
161             else if (line.startsWith(ALTER_COLUMN_TYPE)) {
162                 line = "-- " + line;
163             }
164             else if (line.indexOf(DROP_INDEX) != -1) {
165                 String[] tokens = StringUtil.split(line, " ");
166 
167                 line = StringUtil.replace(
168                     "drop index @index@;", "@index@", tokens[2]);
169             }
170 
171             sb.append(line);
172             sb.append("\n");
173         }
174 
175         unsyncBufferedReader.close();
176 
177         return sb.toString();
178     }
179 
180     private void _reorgTables(String[] templates) throws SQLException {
181         Set<String> tableNames = new HashSet<String>();
182 
183         for (String template : templates) {
184             if (template.startsWith("alter table")) {
185                 tableNames.add(template.split(" ")[2]);
186             }
187         }
188 
189         if (tableNames.size() == 0) {
190             return;
191         }
192 
193         Connection con = null;
194         CallableStatement callStmt = null;
195 
196         try {
197             con = DataAccess.getConnection();
198 
199             for (String tableName : tableNames) {
200                 String sql = "call sysproc.admin_cmd(?)";
201 
202                 callStmt = con.prepareCall(sql);
203 
204                 String param = "reorg table " + tableName;
205 
206                 callStmt.setString(1, param);
207 
208                 callStmt.execute();
209             }
210         }
211         finally {
212             DataAccess.cleanUp(con, callStmt);
213         }
214     }
215 
216     private static String[] _DB2 = {
217         "--", "1", "0",
218         "'1970-01-01-00.00.00.000000'", "current timestamp",
219         " blob(2000)", " smallint", " timestamp",
220         " double", " integer", " bigint",
221         " varchar(500)", " clob", " varchar",
222         " generated always as identity", "commit"
223     };
224 
225     private static final boolean _SUPPORTS_ALTER_COLUMN_TYPE = false;
226 
227     private static final boolean _SUPPORTS_INLINE_DISTINCT = false;
228 
229     private static final boolean _SUPPORTS_SCROLLABLE_RESULTS = false;
230 
231     private static DB2DB _instance = new DB2DB();
232 
233 }