1   /**
2    * Copyright (c) 2000-2009 Liferay, Inc. All rights reserved.
3    *
4    *
5    *
6    *
7    * The contents of this file are subject to the terms of the Liferay Enterprise
8    * Subscription License ("License"). You may not use this file except in
9    * compliance with the License. You can obtain a copy of the License by
10   * contacting Liferay, Inc. See the License for the specific language governing
11   * permissions and limitations under the License, including but not limited to
12   * distribution rights of the Software.
13   *
14   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20   * SOFTWARE.
21   */
22  
23  package com.liferay.portal.dao.db;
24  
25  import com.liferay.portal.kernel.dao.db.DB;
26  import com.liferay.portal.kernel.dao.db.Index;
27  import com.liferay.portal.kernel.dao.jdbc.DataAccess;
28  import com.liferay.portal.kernel.io.unsync.UnsyncBufferedReader;
29  import com.liferay.portal.kernel.io.unsync.UnsyncStringReader;
30  import com.liferay.portal.kernel.util.FileUtil;
31  import com.liferay.portal.kernel.util.StringUtil;
32  import com.liferay.portal.util.PropsValues;
33  
34  import java.io.IOException;
35  
36  import java.sql.Connection;
37  import java.sql.PreparedStatement;
38  import java.sql.ResultSet;
39  import java.sql.SQLException;
40  
41  import java.util.ArrayList;
42  import java.util.List;
43  
44  /**
45   * <a href="MySQLDB.java.html"><b><i>View Source</i></b></a>
46   *
47   * @author Alexander Chow
48   * @author Sandeep Soni
49   * @author Ganesh Ram
50   */
51  public class MySQLDB extends BaseDB {
52  
53      public static DB getInstance() {
54          return _instance;
55      }
56  
57      public String buildSQL(String template) throws IOException {
58          template = convertTimestamp(template);
59          template = replaceTemplate(template, getTemplate());
60  
61          template = reword(template);
62          template = StringUtil.replace(template, "\\'", "''");
63  
64          return template;
65      }
66  
67      public List<Index> getIndexes() throws SQLException {
68          List<Index> indexes = new ArrayList<Index>();
69  
70          Connection con = null;
71          PreparedStatement ps = null;
72          ResultSet rs = null;
73  
74          try {
75              con = DataAccess.getConnection();
76  
77              StringBuilder sb = new StringBuilder();
78  
79              sb.append("select distinct(index_name), table_name, non_unique ");
80              sb.append("from information_schema.statistics where ");
81              sb.append("index_schema = database() and (index_name like ");
82              sb.append("'LIFERAY_%' or index_name like 'IX_%')");
83  
84              String sql = sb.toString();
85  
86              ps = con.prepareStatement(sql);
87  
88              rs = ps.executeQuery();
89  
90              while (rs.next()) {
91                  String indexName = rs.getString("index_name");
92                  String tableName = rs.getString("table_name");
93                  boolean unique = !rs.getBoolean("non_unique");
94  
95                  indexes.add(new Index(indexName, tableName, unique));
96              }
97          }
98          finally {
99              DataAccess.cleanUp(con, ps, rs);
100         }
101 
102         return indexes;
103     }
104 
105     public boolean isSupportsDateMilliseconds() {
106         return _SUPPORTS_DATE_MILLISECONDS;
107     }
108 
109     public boolean isSupportsUpdateWithInnerJoin() {
110         return _SUPPORTS_UPDATE_WITH_INNER_JOIN;
111     }
112 
113     protected MySQLDB() {
114         super(TYPE_MYSQL);
115     }
116 
117     protected String buildCreateFileContent(String databaseName, int population)
118         throws IOException {
119 
120         String suffix = getSuffix(population);
121 
122         StringBuilder sb = new StringBuilder();
123 
124         sb.append("drop database if exists " + databaseName + ";\n");
125         sb.append("create database " + databaseName + " character set utf8;\n");
126         sb.append("use ");
127         sb.append(databaseName);
128         sb.append(";\n\n");
129         sb.append(
130             FileUtil.read(
131                 "../sql/portal" + suffix + "/portal" + suffix + "-mysql.sql"));
132         sb.append("\n\n");
133         sb.append(FileUtil.read("../sql/indexes/indexes-mysql.sql"));
134         sb.append("\n\n");
135         sb.append(FileUtil.read("../sql/sequences/sequences-mysql.sql"));
136 
137         return sb.toString();
138     }
139 
140     protected String getServerName() {
141         return "mysql";
142     }
143 
144     protected String[] getTemplate() {
145         return _MYSQL;
146     }
147 
148     protected String reword(String data) throws IOException {
149         UnsyncBufferedReader unsyncBufferedReader = new UnsyncBufferedReader(
150             new UnsyncStringReader(data));
151 
152         boolean createTable = false;
153 
154         StringBuilder sb = new StringBuilder();
155 
156         String line = null;
157 
158         while ((line = unsyncBufferedReader.readLine()) != null) {
159             if (StringUtil.startsWith(line, "create table")) {
160                 createTable = true;
161             }
162             else if (line.startsWith(ALTER_COLUMN_NAME)) {
163                 String[] template = buildColumnNameTokens(line);
164 
165                 line = StringUtil.replace(
166                     "alter table @table@ change column @old-column@ " +
167                         "@new-column@ @type@;",
168                     REWORD_TEMPLATE, template);
169             }
170             else if (line.startsWith(ALTER_COLUMN_TYPE)) {
171                 String[] template = buildColumnTypeTokens(line);
172 
173                 line = StringUtil.replace(
174                     "alter table @table@ modify @old-column@ @type@;",
175                     REWORD_TEMPLATE, template);
176             }
177 
178             int pos = line.indexOf(";");
179 
180             if (createTable && (pos != -1)) {
181                 createTable = false;
182 
183                 line =
184                     line.substring(0, pos) + " engine " +
185                         PropsValues.DATABASE_MYSQL_ENGINE + line.substring(pos);
186             }
187 
188             sb.append(line);
189             sb.append("\n");
190         }
191 
192         unsyncBufferedReader.close();
193 
194         return sb.toString();
195     }
196 
197     private static String[] _MYSQL = {
198         "##", "1", "0",
199         "'1970-01-01'", "now()",
200         " blob", " tinyint", " datetime",
201         " double", " integer", " bigint",
202         " longtext", " longtext", " varchar",
203         "  auto_increment", "commit"
204     };
205 
206     private static boolean _SUPPORTS_DATE_MILLISECONDS = false;
207 
208     private static boolean _SUPPORTS_UPDATE_WITH_INNER_JOIN = true;
209 
210     private static MySQLDB _instance = new MySQLDB();
211 
212 }