package de.fuberlin.wiwiss.d2rq.sql.vendor;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Types;
import java.util.Properties;
import java.util.regex.Pattern;
import de.fuberlin.wiwiss.d2rq.algebra.Attribute;
import de.fuberlin.wiwiss.d2rq.algebra.RelationName;
import de.fuberlin.wiwiss.d2rq.expr.Expression;
import de.fuberlin.wiwiss.d2rq.map.Database;
import de.fuberlin.wiwiss.d2rq.sql.Quoter;
import de.fuberlin.wiwiss.d2rq.sql.Quoter.PatternDoublingQuoter;
import de.fuberlin.wiwiss.d2rq.sql.types.DataType;
import de.fuberlin.wiwiss.d2rq.sql.types.SQLApproximateNumeric;
import de.fuberlin.wiwiss.d2rq.sql.types.SQLBinary;
import de.fuberlin.wiwiss.d2rq.sql.types.SQLBit;
import de.fuberlin.wiwiss.d2rq.sql.types.SQLBoolean;
import de.fuberlin.wiwiss.d2rq.sql.types.SQLCharacterString;
import de.fuberlin.wiwiss.d2rq.sql.types.SQLDate;
import de.fuberlin.wiwiss.d2rq.sql.types.SQLExactNumeric;
import de.fuberlin.wiwiss.d2rq.sql.types.SQLTime;
import de.fuberlin.wiwiss.d2rq.sql.types.SQLTimestamp;
import de.fuberlin.wiwiss.d2rq.sql.types.UnsupportedDataType;
/**
* This base class implements SQL-92 compatible syntax. Subclasses
* can override individual methods to implement different syntax.
*
* @author Richard Cyganiak
*/
public class SQL92 implements Vendor {
private boolean useAS;
/**
* Initializes a new instance.
*
* @param useAS Use "Table AS Alias" or "Table Alias" in FROM clauses? In standard SQL, either is fine.
*/
public SQL92(boolean useAS) {
this.useAS = useAS;
}
public String getConcatenationExpression
(String[] sqlFragments
) {
for (int i = 0; i < sqlFragments.length; i++) {
if (i > 0) {
result.append(" || ");
}
result.append(sqlFragments[i]);
}
return result.toString();
}
public String getRelationNameAliasExpression
(RelationName relationName,
RelationName aliasName) {
return quoteRelationName(relationName) + (useAS ? " AS " : " ") + quoteRelationName(aliasName);
}
return quoteRelationName(attribute.relationName()) + "." +
quoteIdentifier(attribute.attributeName());
}
public String quoteRelationName
(RelationName relationName
) {
if (relationName.schemaName() == null) {
return quoteIdentifier(relationName.tableName());
}
return quoteIdentifier(relationName.schemaName()) + "." + quoteIdentifier(relationName.tableName());
}
return doubleQuoteEscaper.quote(identifier);
}
private final static Quoter doubleQuoteEscaper =
new PatternDoublingQuoter(Pattern.compile("(\")"), "\"");
return singleQuoteEscaper.quote(s);
}
private final static Quoter singleQuoteEscaper =
new PatternDoublingQuoter(Pattern.compile("(')"), "'");
return "X" + quoteStringLiteral(hexString);
}
return "DATE " + quoteStringLiteral(date);
}
return "TIME " + quoteStringLiteral(time);
}
return "TIMESTAMP " + quoteStringLiteral(timestamp);
}
public Expression getRowNumLimitAsExpression(int limit) {
return Expression.TRUE;
}
/**
* Technically speaking, SQL 92 supports NO way of limiting
* result sets (ROW_NUMBER appeared in SQL 2003). We will
* just use MySQL's LIMIT as it appears to be widely implemented.
*/
public String getRowNumLimitAsQueryAppendage
(int limit
) {
if (limit == Database.NO_LIMIT) return "";
return "LIMIT " + limit;
}
public String getRowNumLimitAsSelectModifier
(int limit
) {
return "";
}
public Properties getDefaultConnectionProperties
() {
}
public DataType getDataType
(int jdbcType,
String name,
int size
) {
// TODO: These are in java.sql.Types as of Java 6 but not yet in Java 1.5
if ("NCHAR".equals(name) || "NVARCHAR".equals(name) || "NCLOB".equals(name)) {
return new SQLCharacterString(this, name, true);
}
switch (jdbcType) {
return new SQLCharacterString(this, name, true);
return new SQLBoolean(this, name);
case Types.
LONGVARBINARY:
return new SQLBinary(this, name, true);
return new SQLBit(this, name);
return new SQLExactNumeric(this, name, jdbcType, false);
return new SQLApproximateNumeric(this, name);
return new SQLDate(this, name);
return new SQLTime(this, name);
return new SQLTimestamp(this, name);
return new UnsupportedDataType(jdbcType, name);
// TODO: What about the remaining java.sql.Types?
}
return null;
}
/**
* In most databases, we don't have to do anything because boolean
* expressions are allowed anywhere.
*/
public Expression booleanExpressionToSimpleExpression(Expression expression) {
return expression;
}
public boolean isIgnoredTable
(String schema,
String table
) {
return false;
}
// Do nothing for standard SQL 92. Subclasses can override.
}
}