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