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.orm.common;
16  
17  import com.liferay.portal.kernel.dao.db.DB;
18  import com.liferay.portal.kernel.dao.db.DBFactoryUtil;
19  import com.liferay.portal.kernel.log.Log;
20  import com.liferay.portal.kernel.log.LogFactoryUtil;
21  import com.liferay.portal.kernel.util.StringPool;
22  
23  import java.util.regex.Matcher;
24  import java.util.regex.Pattern;
25  
26  /**
27   * <a href="SQLTransformer.java.html"><b><i>View Source</i></b></a>
28   *
29   * @author Brian Wing Shun Chan
30   */
31  public class SQLTransformer {
32  
33      public static String transform(String sql) {
34          return _instance._transform(sql);
35      }
36  
37      private SQLTransformer() {
38          DB db = DBFactoryUtil.getDB();
39  
40          if (db.getType().equals(DB.TYPE_MYSQL)) {
41              _vendorMySQL = true;
42          }
43          else if (db.getType().equals(DB.TYPE_SQLSERVER)) {
44              _vendorSQLServer = true;
45          }
46      }
47  
48      private String _removeLower(String sql) {
49          int x = sql.indexOf(_LOWER_OPEN);
50  
51          if (x == -1) {
52              return sql;
53          }
54  
55          StringBuilder sb = new StringBuilder(sql.length());
56  
57          int y = 0;
58  
59          while (true) {
60              sb.append(sql.substring(y, x));
61  
62              y = sql.indexOf(_LOWER_CLOSE, x);
63  
64              if (y == -1) {
65                  sb.append(sql.substring(x));
66  
67                  break;
68              }
69  
70              sb.append(sql.substring(x + _LOWER_OPEN.length(), y));
71  
72              y++;
73  
74              x = sql.indexOf(_LOWER_OPEN, y);
75  
76              if (x == -1) {
77                  sb.append(sql.substring(y));
78  
79                  break;
80              }
81          }
82  
83          sql = sb.toString();
84  
85          return sql;
86      }
87  
88      private String _replaceMod(String sql) {
89          Matcher matcher = _modPattern.matcher(sql);
90  
91          return matcher.replaceAll("$1 % $2");
92      }
93  
94      private String _transform(String sql) {
95          if (sql == null) {
96              return sql;
97          }
98  
99          String newSQL = sql;
100 
101         if (_vendorMySQL) {
102             DB db = DBFactoryUtil.getDB();
103 
104             if (!db.isSupportsStringCaseSensitiveQuery()) {
105                 newSQL = _removeLower(newSQL);
106             }
107         }
108         else if (_vendorSQLServer) {
109             newSQL = _replaceMod(newSQL);
110         }
111 
112         if (_log.isDebugEnabled()) {
113             _log.debug("Original SQL " + sql);
114             _log.debug("Modified SQL " + newSQL);
115         }
116 
117         return newSQL;
118     }
119 
120     private static final String _LOWER_CLOSE = StringPool.CLOSE_PARENTHESIS;
121 
122     private static final String _LOWER_OPEN = "lower(";
123 
124     private static Log _log = LogFactoryUtil.getLog(SQLTransformer.class);
125 
126     private static SQLTransformer _instance = new SQLTransformer();
127 
128     private static Pattern _modPattern = Pattern.compile(
129         "mod\\((.+?),(.+?)\\)", Pattern.CASE_INSENSITIVE);
130 
131     private boolean _vendorMySQL;
132     private boolean _vendorSQLServer;
133 
134 }