?? escapeprocessor.java
字號:
/*
Copyright (C) 2002 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/**
* EscapeProcessor performs all escape code processing as outlined
* in the JDBC spec by JavaSoft.
*
* @author Mark Matthews
* @version $Id: EscapeProcessor.java,v 1.9.2.8 2003/12/24 05:16:25 mmatthew Exp $
*/
package com.mysql.jdbc;
import java.sql.SQLException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;
class EscapeProcessor {
/**
* Escape process one string
*
* @param SQL the SQL to escape process.
* @param serverSupportsConvertFn does the server support CONVERT() or CAST()?
*
* @return the SQL after it has been escape processed.
*/
public static final String escapeSQL(String sql, boolean serverSupportsConvertFn)
throws java.sql.SQLException {
boolean replaceEscapeSequence = false;
String escapeSequence = null;
StringBuffer newSql = new StringBuffer();
if (sql == null) {
return null;
}
/*
* Short circuit this code if we don't have a matching pair of
* "{}". - Suggested by Ryan Gustafason
*/
int beginBrace = sql.indexOf('{');
int nextEndBrace = (beginBrace == -1) ? (-1)
: sql.indexOf('}', beginBrace);
if (nextEndBrace == -1) {
return sql;
}
EscapeTokenizer escapeTokenizer = new EscapeTokenizer(sql);
while (escapeTokenizer.hasMoreTokens()) {
String token = escapeTokenizer.nextToken();
if (token.startsWith("{")) { // It's an escape code
if (!token.endsWith("}")) {
throw new java.sql.SQLException(
"Not a valid escape sequence: " + token);
}
if (token.length() > 2) {
int nestedBrace = token.indexOf('{', 2);
if (nestedBrace != -1) {
StringBuffer buf = new StringBuffer(token.substring(0, 1));
String remaining = escapeSQL(token.substring(1,
token.length() - 1), serverSupportsConvertFn);
buf.append(remaining);
buf.append('}');
token = buf.toString();
}
}
// nested escape code
// Compare to tokens with _no_ whitespace
String collapsedToken = removeWhitespace(token);
/*
* Process the escape code
*/
if (StringUtils.startsWithIgnoreCase(collapsedToken, "{escape")) {
try {
StringTokenizer st = new StringTokenizer(token, " '");
st.nextToken(); // eat the "escape" token
escapeSequence = st.nextToken();
if (escapeSequence.length() < 3) {
throw new java.sql.SQLException(
"Syntax error for escape sequence '" + token
+ "'", SQLError.SQL_STATE_SYNTAX_ERROR);
}
escapeSequence = escapeSequence.substring(1,
escapeSequence.length() - 1);
replaceEscapeSequence = true;
} catch (java.util.NoSuchElementException e) {
throw new java.sql.SQLException(
"Syntax error for escape sequence '" + token + "'",
SQLError.SQL_STATE_SYNTAX_ERROR);
}
} else if (StringUtils.startsWithIgnoreCase(collapsedToken, "{fn")) {
int startPos = token.toLowerCase().indexOf("fn ") + 3;
int endPos = token.length() - 1; // no }
String fnToken = token.substring(startPos, endPos);
// We need to handle 'convert' by ourselves
if (StringUtils.startsWithIgnoreCaseAndWs(fnToken, "convert")) {
newSql.append(processConvertToken(fnToken, serverSupportsConvertFn));
} else {
// just pass functions right to the DB
newSql.append(fnToken);
}
} else if (StringUtils.startsWithIgnoreCase(collapsedToken, "{d")) {
int startPos = token.indexOf('\'') + 1;
int endPos = token.lastIndexOf('\''); // no }
if ((startPos == -1) || (endPos == -1)) {
throw new java.sql.SQLException(
"Syntax error for DATE escape sequence '" + token
+ "'", SQLError.SQL_STATE_SYNTAX_ERROR);
}
String argument = token.substring(startPos, endPos);
try {
StringTokenizer st = new StringTokenizer(argument, " -");
String year4 = st.nextToken();
String month2 = st.nextToken();
String day2 = st.nextToken();
String dateString = "'" + year4 + "-" + month2 + "-"
+ day2 + "'";
newSql.append(dateString);
} catch (java.util.NoSuchElementException e) {
throw new java.sql.SQLException(
"Syntax error for DATE escape sequence '"
+ argument + "'", SQLError.SQL_STATE_SYNTAX_ERROR);
}
} else if (StringUtils.startsWithIgnoreCase(collapsedToken, "{ts")) {
int startPos = token.indexOf('\'') + 1;
int endPos = token.lastIndexOf('\''); // no }
if ((startPos == -1) || (endPos == -1)) {
throw new java.sql.SQLException(
"Syntax error for TIMESTAMP escape sequence '"
+ token + "'", SQLError.SQL_STATE_SYNTAX_ERROR);
}
String argument = token.substring(startPos, endPos);
try {
StringTokenizer st = new StringTokenizer(argument,
" .-:");
String year4 = st.nextToken();
String month2 = st.nextToken();
String day2 = st.nextToken();
String hour = st.nextToken();
String minute = st.nextToken();
String second = st.nextToken();
/*
* For now, we get the fractional seconds
* part, but we don't use it, as MySQL doesn't
* support it in it's TIMESTAMP data type
*
String fractionalSecond = "";
if (st.hasMoreTokens()) {
fractionalSecond = st.nextToken();
}
*/
/*
* Use the full format because number format
* will not work for "between" clauses.
*
* Ref. Mysql Docs
*
* You can specify DATETIME, DATE and TIMESTAMP values
* using any of a common set of formats:
*
* As a string in either 'YYYY-MM-DD HH:MM:SS' or
* 'YY-MM-DD HH:MM:SS' format.
*
* Thanks to Craig Longman for pointing out this bug
*/
newSql.append("'").append(year4).append("-")
.append(month2).append("-").append(day2)
.append(" ").append(hour).append(":")
.append(minute).append(":").append(second).append("'");
} catch (java.util.NoSuchElementException e) {
throw new java.sql.SQLException(
"Syntax error for TIMESTAMP escape sequence '"
+ argument + "'", SQLError.SQL_STATE_SYNTAX_ERROR);
}
} else if (StringUtils.startsWithIgnoreCase(collapsedToken, "{t")) {
int startPos = token.indexOf('\'') + 1;
int endPos = token.lastIndexOf('\''); // no }
if ((startPos == -1) || (endPos == -1)) {
throw new java.sql.SQLException(
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -