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.db.Index;
19  import com.liferay.portal.kernel.dao.jdbc.DataAccess;
20  import com.liferay.portal.kernel.io.unsync.UnsyncBufferedReader;
21  import com.liferay.portal.kernel.io.unsync.UnsyncStringReader;
22  import com.liferay.portal.kernel.util.StringBundler;
23  import com.liferay.portal.kernel.util.StringUtil;
24  import com.liferay.portal.util.PropsValues;
25  
26  import java.io.IOException;
27  
28  import java.sql.Connection;
29  import java.sql.PreparedStatement;
30  import java.sql.ResultSet;
31  import java.sql.SQLException;
32  
33  import java.util.ArrayList;
34  import java.util.List;
35  
36  /**
37   * <a href="MySQLDB.java.html"><b><i>View Source</i></b></a>
38   *
39   * @author Alexander Chow
40   * @author Sandeep Soni
41   * @author Ganesh Ram
42   */
43  public class MySQLDB extends BaseDB {
44  
45      public static DB getInstance() {
46          return _instance;
47      }
48  
49      public String buildSQL(String template) throws IOException {
50          template = convertTimestamp(template);
51          template = replaceTemplate(template, getTemplate());
52  
53          template = reword(template);
54          template = StringUtil.replace(template, "\\'", "''");
55  
56          return template;
57      }
58  
59      public List<Index> getIndexes() throws SQLException {
60          List<Index> indexes = new ArrayList<Index>();
61  
62          Connection con = null;
63          PreparedStatement ps = null;
64          ResultSet rs = null;
65  
66          try {
67              con = DataAccess.getConnection();
68  
69              StringBundler sb = new StringBundler(4);
70  
71              sb.append("select distinct(index_name), table_name, non_unique ");
72              sb.append("from information_schema.statistics where ");
73              sb.append("index_schema = database() and (index_name like ");
74              sb.append("'LIFERAY_%' or index_name like 'IX_%')");
75  
76              String sql = sb.toString();
77  
78              ps = con.prepareStatement(sql);
79  
80              rs = ps.executeQuery();
81  
82              while (rs.next()) {
83                  String indexName = rs.getString("index_name");
84                  String tableName = rs.getString("table_name");
85                  boolean unique = !rs.getBoolean("non_unique");
86  
87                  indexes.add(new Index(indexName, tableName, unique));
88              }
89          }
90          finally {
91              DataAccess.cleanUp(con, ps, rs);
92          }
93  
94          return indexes;
95      }
96  
97      public boolean isSupportsDateMilliseconds() {
98          return _SUPPORTS_DATE_MILLISECONDS;
99      }
100 
101     public boolean isSupportsUpdateWithInnerJoin() {
102         return _SUPPORTS_UPDATE_WITH_INNER_JOIN;
103     }
104 
105     protected MySQLDB() {
106         super(TYPE_MYSQL);
107     }
108 
109     protected String buildCreateFileContent(
110             String sqlDir, String databaseName, int population)
111         throws IOException {
112 
113         String suffix = getSuffix(population);
114 
115         StringBundler sb = new StringBundler(14);
116 
117         sb.append("drop database if exists ");
118         sb.append(databaseName);
119         sb.append(";\n");
120         sb.append("create database ");
121         sb.append(databaseName);
122         sb.append(" character set utf8;\n");
123         sb.append("use ");
124         sb.append(databaseName);
125         sb.append(";\n\n");
126         sb.append(
127             readFile(
128                 sqlDir + "/portal" + suffix + "/portal" + suffix +
129                     "-mysql.sql"));
130         sb.append("\n\n");
131         sb.append(readFile(sqlDir + "/indexes/indexes-mysql.sql"));
132         sb.append("\n\n");
133         sb.append(readFile(sqlDir + "/sequences/sequences-mysql.sql"));
134 
135         return sb.toString();
136     }
137 
138     protected String getServerName() {
139         return "mysql";
140     }
141 
142     protected String[] getTemplate() {
143         return _MYSQL;
144     }
145 
146     protected String reword(String data) throws IOException {
147         UnsyncBufferedReader unsyncBufferedReader = new UnsyncBufferedReader(
148             new UnsyncStringReader(data));
149 
150         boolean createTable = false;
151 
152         StringBundler sb = new StringBundler();
153 
154         String line = null;
155 
156         while ((line = unsyncBufferedReader.readLine()) != null) {
157             if (StringUtil.startsWith(line, "create table")) {
158                 createTable = true;
159             }
160             else if (line.startsWith(ALTER_COLUMN_NAME)) {
161                 String[] template = buildColumnNameTokens(line);
162 
163                 line = StringUtil.replace(
164                     "alter table @table@ change column @old-column@ " +
165                         "@new-column@ @type@;",
166                     REWORD_TEMPLATE, template);
167             }
168             else if (line.startsWith(ALTER_COLUMN_TYPE)) {
169                 String[] template = buildColumnTypeTokens(line);
170 
171                 line = StringUtil.replace(
172                     "alter table @table@ modify @old-column@ @type@;",
173                     REWORD_TEMPLATE, template);
174             }
175 
176             int pos = line.indexOf(";");
177 
178             if (createTable && (pos != -1)) {
179                 createTable = false;
180 
181                 line =
182                     line.substring(0, pos) + " engine " +
183                         PropsValues.DATABASE_MYSQL_ENGINE + line.substring(pos);
184             }
185 
186             sb.append(line);
187             sb.append("\n");
188         }
189 
190         unsyncBufferedReader.close();
191 
192         return sb.toString();
193     }
194 
195     private static String[] _MYSQL = {
196         "##", "1", "0",
197         "'1970-01-01'", "now()",
198         " blob", " tinyint", " datetime",
199         " double", " integer", " bigint",
200         " longtext", " longtext", " varchar",
201         "  auto_increment", "commit"
202     };
203 
204     private static final boolean _SUPPORTS_DATE_MILLISECONDS = false;
205 
206     private static final boolean _SUPPORTS_UPDATE_WITH_INNER_JOIN = true;
207 
208     private static MySQLDB _instance = new MySQLDB();
209 
210 }