001
014
015 package com.liferay.portal.dao.orm.common;
016
017 import com.liferay.portal.kernel.dao.db.DB;
018 import com.liferay.portal.kernel.dao.db.DBFactoryUtil;
019 import com.liferay.portal.kernel.log.Log;
020 import com.liferay.portal.kernel.log.LogFactoryUtil;
021 import com.liferay.portal.kernel.util.StringPool;
022
023 import java.util.regex.Matcher;
024 import java.util.regex.Pattern;
025
026
029 public class SQLTransformer {
030
031 public static String transform(String sql) {
032 return _instance._transform(sql);
033 }
034
035 private SQLTransformer() {
036 DB db = DBFactoryUtil.getDB();
037
038 if (db.getType().equals(DB.TYPE_MYSQL)) {
039 _vendorMySQL = true;
040 }
041 else if (db.getType().equals(DB.TYPE_POSTGRESQL)) {
042 _vendorPostgreSQL = true;
043 }
044 else if (db.getType().equals(DB.TYPE_SQLSERVER)) {
045 _vendorSQLServer = true;
046 }
047 }
048
049 private String _removeLower(String sql) {
050 int x = sql.indexOf(_LOWER_OPEN);
051
052 if (x == -1) {
053 return sql;
054 }
055
056 StringBuilder sb = new StringBuilder(sql.length());
057
058 int y = 0;
059
060 while (true) {
061 sb.append(sql.substring(y, x));
062
063 y = sql.indexOf(_LOWER_CLOSE, x);
064
065 if (y == -1) {
066 sb.append(sql.substring(x));
067
068 break;
069 }
070
071 sb.append(sql.substring(x + _LOWER_OPEN.length(), y));
072
073 y++;
074
075 x = sql.indexOf(_LOWER_OPEN, y);
076
077 if (x == -1) {
078 sb.append(sql.substring(y));
079
080 break;
081 }
082 }
083
084 sql = sb.toString();
085
086 return sql;
087 }
088
089 private String _replaceCastText(String sql) {
090 Matcher matcher = _castTextPattern.matcher(sql);
091
092 if (_vendorPostgreSQL) {
093 return matcher.replaceAll("CAST($1 AS TEXT)");
094 }
095 else {
096 return matcher.replaceAll("$1");
097 }
098 }
099
100 private String _replaceMod(String sql) {
101 Matcher matcher = _modPattern.matcher(sql);
102
103 return matcher.replaceAll("$1 % $2");
104 }
105
106 private String _transform(String sql) {
107 if (sql == null) {
108 return sql;
109 }
110
111 String newSQL = sql;
112
113 if (_vendorMySQL) {
114 DB db = DBFactoryUtil.getDB();
115
116 if (!db.isSupportsStringCaseSensitiveQuery()) {
117 newSQL = _removeLower(newSQL);
118 }
119 }
120 else if (_vendorSQLServer) {
121 newSQL = _replaceMod(newSQL);
122 }
123
124 newSQL = _replaceCastText(newSQL);
125
126 if (_log.isDebugEnabled()) {
127 _log.debug("Original SQL " + sql);
128 _log.debug("Modified SQL " + newSQL);
129 }
130
131 return newSQL;
132 }
133
134 private static final String _LOWER_CLOSE = StringPool.CLOSE_PARENTHESIS;
135
136 private static final String _LOWER_OPEN = "lower(";
137
138 private static Log _log = LogFactoryUtil.getLog(SQLTransformer.class);
139
140 private static SQLTransformer _instance = new SQLTransformer();
141
142 private static Pattern _castTextPattern = Pattern.compile(
143 "CAST_TEXT\\((.+?)\\)", Pattern.CASE_INSENSITIVE);
144 private static Pattern _modPattern = Pattern.compile(
145 "MOD\\((.+?),(.+?)\\)", Pattern.CASE_INSENSITIVE);
146
147 private boolean _vendorMySQL;
148 private boolean _vendorPostgreSQL;
149 private boolean _vendorSQLServer;
150
151 }