EMPIREDB-314
SQL-format function support
diff --git a/empire-db/src/main/java/org/apache/empire/db/DBColumnExpr.java b/empire-db/src/main/java/org/apache/empire/db/DBColumnExpr.java
index 3c2b33e..61e6492 100644
--- a/empire-db/src/main/java/org/apache/empire/db/DBColumnExpr.java
+++ b/empire-db/src/main/java/org/apache/empire/db/DBColumnExpr.java
@@ -864,6 +864,18 @@
}
/**
+ * Formats a column-expression using a format string
+ * This function is intended for formatting numbers.
+ * Formatting any other data types may not supported and be database specific
+ * @param format the format string. Beware: This is passed to the database "as is" and hence may be database specific.
+ * @return a string expression representing the formatted value
+ */
+ public DBColumnExpr format(String format)
+ {
+ return getExprFromPhrase(DBDatabaseDriver.SQL_FUNC_FORMAT, new Object[] { format }, getUpdateColumn(), false, DataType.VARCHAR);
+ }
+
+ /**
* Creates and returns a sql-expression that returns the string length of this expression.
* @return the new DBFuncExpr object
diff --git a/empire-db/src/main/java/org/apache/empire/db/DBCommand.java b/empire-db/src/main/java/org/apache/empire/db/DBCommand.java
index 74778b3..caffa5a 100644
--- a/empire-db/src/main/java/org/apache/empire/db/DBCommand.java
+++ b/empire-db/src/main/java/org/apache/empire/db/DBCommand.java
@@ -778,11 +778,11 @@
return;
removeConstraintOn(where, col);
}
-
+
/**
* Returns a copy of the defined joins.
*
- * @return vector of joins
+ * @return the list of joins
*/
public List<DBJoinExpr> getJoins()
{
@@ -813,9 +813,29 @@
having = new ArrayList<DBCompareExpr>();
setConstraint(having, expr);
}
+
+ /**
+ * Returns true if the command has having-constraints or false if not.
+ *
+ * @return true if constraints have been set on the command
+ */
+ public boolean hasHavingConstraints()
+ {
+ return (having!=null && having.size()>0);
+ }
+
+ /**
+ * Returns a copy of the defined having clauses.
+ *
+ * @return list of having constraints
+ */
+ public List<DBCompareExpr> getHavingConstraints()
+ {
+ return (this.having!=null ? Collections.unmodifiableList(this.having) : null);
+ }
/**
- * removes a constraint on a particular column from the where clause
+ * removes a constraint on a particular column from the having clause
* @param col the column expression for which to remove the constraint
*/
public void removeHavingConstraintOn(DBColumnExpr col)
diff --git a/empire-db/src/main/java/org/apache/empire/db/DBDatabaseDriver.java b/empire-db/src/main/java/org/apache/empire/db/DBDatabaseDriver.java
index 44b09c9..4aacd7b 100644
--- a/empire-db/src/main/java/org/apache/empire/db/DBDatabaseDriver.java
+++ b/empire-db/src/main/java/org/apache/empire/db/DBDatabaseDriver.java
@@ -94,6 +94,7 @@
public static final int SQL_FUNC_FLOOR = 123; // Oracle: floor(?)
public static final int SQL_FUNC_CEILING = 124; // Oracle: ceil(?)
public static final int SQL_FUNC_MODULO = 125; // Oracle: mod(?)
+ public static final int SQL_FUNC_FORMAT = 126; // Oracle: TO_CHAR(?)
// Date
public static final int SQL_FUNC_DAY = 132; // MSSQL: month(?)
public static final int SQL_FUNC_MONTH = 133; // MSSQL: month(?)
diff --git a/empire-db/src/main/java/org/apache/empire/db/derby/DBDatabaseDriverDerby.java b/empire-db/src/main/java/org/apache/empire/db/derby/DBDatabaseDriverDerby.java
index e60b6a8..8eed386 100644
--- a/empire-db/src/main/java/org/apache/empire/db/derby/DBDatabaseDriverDerby.java
+++ b/empire-db/src/main/java/org/apache/empire/db/derby/DBDatabaseDriverDerby.java
@@ -220,6 +220,8 @@
case SQL_FUNC_TRUNC: return "truncate(?,{0})";
case SQL_FUNC_CEILING: return "ceiling(?)";
case SQL_FUNC_FLOOR: return "floor(?)";
+ case SQL_FUNC_MODULO: return "mod(?,{0})";
+ case SQL_FUNC_FORMAT: return "format(?, {0:VARCHAR})";
// Date
case SQL_FUNC_DAY: return "day(?)";
case SQL_FUNC_MONTH: return "month(?)";
diff --git a/empire-db/src/main/java/org/apache/empire/db/expr/column/DBAbstractFuncExpr.java b/empire-db/src/main/java/org/apache/empire/db/expr/column/DBAbstractFuncExpr.java
index ffff472..d89fd3d 100644
--- a/empire-db/src/main/java/org/apache/empire/db/expr/column/DBAbstractFuncExpr.java
+++ b/empire-db/src/main/java/org/apache/empire/db/expr/column/DBAbstractFuncExpr.java
@@ -27,7 +27,10 @@
import org.apache.empire.db.DBColumnExpr;
import org.apache.empire.db.DBDatabase;
import org.apache.empire.db.DBDatabaseDriver;
+import org.apache.empire.exceptions.InvalidArgumentException;
import org.apache.empire.xml.XMLUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.w3c.dom.Element;
@@ -37,6 +40,7 @@
public abstract class DBAbstractFuncExpr extends DBColumnExpr
{
private final static long serialVersionUID = 1L;
+ private static final Logger log = LoggerFactory.getLogger(DBAbstractFuncExpr.class);
protected final DBColumnExpr expr;
protected final DBColumn updateColumn; // optional
@@ -156,13 +160,37 @@
{
// Get Template
if (params != null)
- { // Replace Params
- DataType dataType = expr.getDataType();
+ { // Replace Params
for (int i = 0; i < params.length; i++)
- { // String test =(params[i] != null) ? params[i].toString() : "";
- String value = getObjectValue(dataType, params[i], CTX_DEFAULT, ",");
+ { // Detect placeholder and data type
+ DataType paramDataType = expr.getDataType();
+ int idx;
+ String ph = "{"+String.valueOf(i);
+ if ((idx=template.indexOf(ph))>=0) {
+ // param found
+ idx += ph.length();
+ int end = template.indexOf('}', idx);
+ if (end<idx)
+ throw new InvalidArgumentException("template", template);
+ // check if type is specified
+ if (template.charAt(idx)==':')
+ { // DataType is specified
+ String typeName = ((end>=idx) ? template.substring(idx+1, end) : null);
+ DataType dataType = ((typeName!=null) ? DataType.valueOf(typeName) : null);
+ if (dataType!=null)
+ paramDataType = dataType;
+ }
+ // complete placeholder
+ ph += template.substring(idx, end+1);
+
+ } else {
+ log.warn("No placeholder found in template {} for paramter {}", template, i);
+ continue;
+ }
+ // get param and replace
+ String paramAsString = getObjectValue(paramDataType, params[i], CTX_DEFAULT, ",");
// template = template.replaceAll("\\{" + String.valueOf(i) + "\\}", value);
- template = StringUtils.replaceAll(template, "{"+ String.valueOf(i) + "}", value);
+ template = StringUtils.replaceAll(template, ph, paramAsString);
}
}
// Get Prefix and Postfix
diff --git a/empire-db/src/main/java/org/apache/empire/db/h2/DBDatabaseDriverH2.java b/empire-db/src/main/java/org/apache/empire/db/h2/DBDatabaseDriverH2.java
index 5b168ba..67289ec 100644
--- a/empire-db/src/main/java/org/apache/empire/db/h2/DBDatabaseDriverH2.java
+++ b/empire-db/src/main/java/org/apache/empire/db/h2/DBDatabaseDriverH2.java
@@ -268,6 +268,7 @@
case SQL_FUNC_CEILING: return "ceiling(?)";
case SQL_FUNC_FLOOR: return "floor(?)";
case SQL_FUNC_MODULO: return "mod(?,{0})";
+ case SQL_FUNC_FORMAT: return "format(?, {0:VARCHAR})";
// Date
case SQL_FUNC_DAY: return "day(?)";
case SQL_FUNC_MONTH: return "month(?)";
diff --git a/empire-db/src/main/java/org/apache/empire/db/hsql/DBDatabaseDriverHSql.java b/empire-db/src/main/java/org/apache/empire/db/hsql/DBDatabaseDriverHSql.java
index 1ae3104..72a2f03 100644
--- a/empire-db/src/main/java/org/apache/empire/db/hsql/DBDatabaseDriverHSql.java
+++ b/empire-db/src/main/java/org/apache/empire/db/hsql/DBDatabaseDriverHSql.java
@@ -160,6 +160,7 @@
case SQL_FUNC_CEILING: return "ceiling(?)";
case SQL_FUNC_FLOOR: return "floor(?)";
case SQL_FUNC_MODULO: return "mod(?,{0})";
+ case SQL_FUNC_FORMAT: return "TO_CHAR(?, {0:VARCHAR})";
// Date
case SQL_FUNC_DAY: return "day(?)";
case SQL_FUNC_MONTH: return "month(?)";
diff --git a/empire-db/src/main/java/org/apache/empire/db/mysql/DBDatabaseDriverMySQL.java b/empire-db/src/main/java/org/apache/empire/db/mysql/DBDatabaseDriverMySQL.java
index 7b57ba5..11c9859 100644
--- a/empire-db/src/main/java/org/apache/empire/db/mysql/DBDatabaseDriverMySQL.java
+++ b/empire-db/src/main/java/org/apache/empire/db/mysql/DBDatabaseDriverMySQL.java
@@ -1028,6 +1028,7 @@
case SQL_FUNC_CEILING: return "ceiling(?)";
case SQL_FUNC_FLOOR: return "floor(?)";
case SQL_FUNC_MODULO: return "mod(?,{0})";
+ case SQL_FUNC_FORMAT: return "format(?, {0:INTEGER})"; /* TODO: supports only decimal places. Add support for a format string */
// Date
case SQL_FUNC_DAY: return "day(?)";
case SQL_FUNC_MONTH: return "month(?)";
diff --git a/empire-db/src/main/java/org/apache/empire/db/oracle/DBDatabaseDriverOracle.java b/empire-db/src/main/java/org/apache/empire/db/oracle/DBDatabaseDriverOracle.java
index 32556df..c25e7b9 100644
--- a/empire-db/src/main/java/org/apache/empire/db/oracle/DBDatabaseDriverOracle.java
+++ b/empire-db/src/main/java/org/apache/empire/db/oracle/DBDatabaseDriverOracle.java
@@ -189,6 +189,7 @@
case SQL_FUNC_CEILING: return "ceil(?)";
case SQL_FUNC_FLOOR: return "floor(?)";
case SQL_FUNC_MODULO: return "mod(?,{0})";
+ case SQL_FUNC_FORMAT: return "TO_CHAR(?, {0:VARCHAR})";
// Date
case SQL_FUNC_DAY: return oracle8Compatibilty ? "to_number(to_char(?,'DD'))" : "extract(day from ?)";
case SQL_FUNC_MONTH: return oracle8Compatibilty ? "to_number(to_char(?,'MM'))" : "extract(month from ?)";
diff --git a/empire-db/src/main/java/org/apache/empire/db/postgresql/DBDatabaseDriverPostgreSQL.java b/empire-db/src/main/java/org/apache/empire/db/postgresql/DBDatabaseDriverPostgreSQL.java
index ce279b5..39965e5 100644
--- a/empire-db/src/main/java/org/apache/empire/db/postgresql/DBDatabaseDriverPostgreSQL.java
+++ b/empire-db/src/main/java/org/apache/empire/db/postgresql/DBDatabaseDriverPostgreSQL.java
@@ -368,6 +368,7 @@
case SQL_FUNC_CEILING: return "ceiling(?)";
case SQL_FUNC_FLOOR: return "floor(?)";
case SQL_FUNC_MODULO: return "mod(?,{0})";
+ case SQL_FUNC_FORMAT: return "format({0:VARCHAR}, ?)";
// Date
case SQL_FUNC_DAY: return "extract(day from ?)";
case SQL_FUNC_MONTH: return "extract(month from ?)";
diff --git a/empire-db/src/main/java/org/apache/empire/db/sqlite/DBDatabaseDriverSQLite.java b/empire-db/src/main/java/org/apache/empire/db/sqlite/DBDatabaseDriverSQLite.java
index a516c1e..d038427 100644
--- a/empire-db/src/main/java/org/apache/empire/db/sqlite/DBDatabaseDriverSQLite.java
+++ b/empire-db/src/main/java/org/apache/empire/db/sqlite/DBDatabaseDriverSQLite.java
@@ -349,6 +349,7 @@
case SQL_FUNC_CEILING: return "ceiling(?)";
case SQL_FUNC_FLOOR: return "floor(?)";
case SQL_FUNC_MODULO: return "mod(?,{0})";
+ case SQL_FUNC_FORMAT: return "printf({0:VARCHAR}, ?)";
// Date
case SQL_FUNC_DAY: return "day(?)";
case SQL_FUNC_MONTH: return "month(?)";
diff --git a/empire-db/src/main/java/org/apache/empire/db/sqlserver/DBDatabaseDriverMSSQL.java b/empire-db/src/main/java/org/apache/empire/db/sqlserver/DBDatabaseDriverMSSQL.java
index 4804f5c..d013245 100644
--- a/empire-db/src/main/java/org/apache/empire/db/sqlserver/DBDatabaseDriverMSSQL.java
+++ b/empire-db/src/main/java/org/apache/empire/db/sqlserver/DBDatabaseDriverMSSQL.java
@@ -337,6 +337,7 @@
case SQL_FUNC_CEILING: return "ceiling(?)";
case SQL_FUNC_FLOOR: return "floor(?)";
case SQL_FUNC_MODULO: return "((?) % {0})";
+ case SQL_FUNC_FORMAT: return "format(?, {0:VARCHAR})";
// Date
case SQL_FUNC_DAY: return "day(?)";
case SQL_FUNC_MONTH: return "month(?)";