diff --git a/core/src/main/java/lucee/commons/io/log/LogUtil.java b/core/src/main/java/lucee/commons/io/log/LogUtil.java index f032beb9e8..3380410734 100644 --- a/core/src/main/java/lucee/commons/io/log/LogUtil.java +++ b/core/src/main/java/lucee/commons/io/log/LogUtil.java @@ -28,10 +28,14 @@ import lucee.commons.io.res.Resource; import lucee.commons.io.res.util.ResourceUtil; import lucee.commons.lang.ExceptionUtil; +import lucee.commons.lang.StringUtil; import lucee.commons.lang.SystemOut; import lucee.loader.engine.CFMLEngine; import lucee.runtime.PageContext; +import lucee.runtime.PageContextImpl; +import lucee.runtime.PageSource; import lucee.runtime.config.Config; +import lucee.runtime.config.ConfigWeb; import lucee.runtime.config.ConfigWebUtil; import lucee.runtime.engine.ThreadLocalPageContext; @@ -187,4 +191,38 @@ public static void logGlobal(Config config, String type, Throwable t) { public static void logGlobal(Config config, String type, String msg, Throwable t) { logGlobal(config, Log.LEVEL_ERROR, type, msg + ";" + ExceptionUtil.getStacktrace(t, true)); } + + public static String caller(PageContext pc, String defaultValue) { + Exception t = new Exception("Stack trace"); + StackTraceElement[] traces = t.getStackTrace(); + + String template; + for (StackTraceElement trace: traces) { + template = trace.getFileName(); + if (trace.getLineNumber() <= 0 || template == null || ResourceUtil.getExtension(template, "").equals("java")) continue; + + return abs(pc, template) + ":" + trace.getLineNumber(); + } + return defaultValue; + } + + private static String abs(PageContext pc, String template) { + try { + ConfigWeb config = pc.getConfig(); + Resource res = config.getResource(template); + if (res.exists()) return template; + String tmp; + PageSource ps = pc == null ? null : ((PageContextImpl) pc).getPageSource(template); + res = ps == null ? null : ps.getPhyscalFile(); + if (res == null || !res.exists()) { + tmp = ps.getDisplayPath(); + res = StringUtil.isEmpty(tmp) ? null : config.getResource(tmp); + if (res != null && res.exists()) return res.getAbsolutePath(); + } + else return res.getAbsolutePath(); + } + catch (Exception e) { + } + return template; + } } \ No newline at end of file diff --git a/core/src/main/java/lucee/runtime/db/SQLCaster.java b/core/src/main/java/lucee/runtime/db/SQLCaster.java index 521b72332c..0d3dd808ac 100755 --- a/core/src/main/java/lucee/runtime/db/SQLCaster.java +++ b/core/src/main/java/lucee/runtime/db/SQLCaster.java @@ -35,6 +35,8 @@ import lucee.commons.date.JREDateTimeUtil; import lucee.commons.io.IOUtil; +import lucee.commons.io.log.Log; +import lucee.commons.io.log.LogUtil; import lucee.commons.lang.ExceptionUtil; import lucee.commons.lang.StringUtil; import lucee.commons.sql.SQLUtil; @@ -155,23 +157,61 @@ public static void setValue(PageContext pc, TimeZone tz, PreparedStatement stat, * case Types.ARRAY: stat.setArray(parameterIndex,toArray(item.getValue())); return; */ case Types.BIGINT: - stat.setLong(parameterIndex, Caster.toLongValue(value)); + try { + stat.setLong(parameterIndex, Caster.toLongValue(value)); + } + catch (PageException pe) { + // FUTURE remove this if + if (!NullSupportHelper.full(pc) && value instanceof String && StringUtil.isEmpty((String) value)) { + LogUtil.log(Log.LEVEL_WARN, "datasource", "conversion", "Deprecated functionality used at [" + LogUtil.caller(pc, "") + + "]. An empty string was passed as a value for type BIGINT. Currently, this is treated as null, but it will be rejected in future releases."); + stat.setNull(parameterIndex, item.getType()); + } + else throw pe; + } return; case Types.BIT: - stat.setBoolean(parameterIndex, Caster.toBooleanValue(value)); + try { + stat.setBoolean(parameterIndex, Caster.toBooleanValue(value)); + } + catch (PageException pe) { + // FUTURE remove this if + if (!NullSupportHelper.full(pc) && value instanceof String && StringUtil.isEmpty((String) value)) { + LogUtil.log(Log.LEVEL_WARN, "datasource", "conversion", "Deprecated functionality used at [" + LogUtil.caller(pc, "") + + "]. An empty string was passed as a value for type BIT. Currently, this is treated as null, but it will be rejected in future releases."); + stat.setNull(parameterIndex, item.getType()); + } + else throw pe; + } return; case Types.BLOB: - stat.setBlob(parameterIndex, SQLUtil.toBlob(stat.getConnection(), value)); + try { + stat.setBlob(parameterIndex, SQLUtil.toBlob(stat.getConnection(), value)); + } + catch (PageException pe) { + // FUTURE remove this if + if (!NullSupportHelper.full(pc) && value instanceof String && StringUtil.isEmpty((String) value)) { + LogUtil.log(Log.LEVEL_WARN, "datasource", "conversion", "Deprecated functionality used at [" + LogUtil.caller(pc, "") + + "]. An empty string was passed as a value for type BLOB. Currently, this is treated as null, but it will be rejected in future releases."); + stat.setNull(parameterIndex, item.getType()); + } + else throw pe; + } + return; case Types.CLOB: - stat.setClob(parameterIndex, SQLUtil.toClob(stat.getConnection(), value)); - /* - * if(value instanceof String) { try{ stat.setString(parameterIndex,Caster.toString(value)); } - * catch(Throwable t){ExceptionUtil.rethrowIfNecessary(t); - * stat.setClob(parameterIndex,SQLUtil.toClob(stat.getConnection(),value)); } - * - * } else stat.setClob(parameterIndex,SQLUtil.toClob(stat.getConnection(),value)); - */ + try { + stat.setClob(parameterIndex, SQLUtil.toClob(stat.getConnection(), value)); + } + catch (PageException pe) { + // FUTURE remove this if + if (!NullSupportHelper.full(pc) && value instanceof String && StringUtil.isEmpty((String) value)) { + LogUtil.log(Log.LEVEL_WARN, "datasource", "conversion", "Deprecated functionality used at [" + LogUtil.caller(pc, "") + + "]. An empty string was passed as a value for type CLOB. Currently, this is treated as null, but it will be rejected in future releases."); + stat.setNull(parameterIndex, item.getType()); + } + else throw pe; + } return; case Types.CHAR: String str = Caster.toString(value); @@ -181,36 +221,109 @@ public static void setValue(PageContext pc, TimeZone tz, PreparedStatement stat, return; case Types.DECIMAL: case Types.NUMERIC: + try { + stat.setDouble(parameterIndex, (Caster.toDoubleValue(value))); + } + catch (PageException pe) { + // FUTURE remove this if + if (!NullSupportHelper.full(pc) && value instanceof String && StringUtil.isEmpty((String) value)) { + LogUtil.log(Log.LEVEL_WARN, "datasource", "conversion", "Deprecated functionality used at [" + LogUtil.caller(pc, "") + + "]. An empty string was passed as a value for type NUMERIC|DECIMAL. Currently, this is treated as null, but it will be rejected in future releases."); + stat.setNull(parameterIndex, item.getType()); + } + else throw pe; + } stat.setDouble(parameterIndex, (Caster.toDoubleValue(value))); return; case Types.DOUBLE: case Types.FLOAT: - if (type == Types.FLOAT) stat.setFloat(parameterIndex, Caster.toFloatValue(value)); - else if (type == Types.DOUBLE) stat.setDouble(parameterIndex, Caster.toDoubleValue(value)); - else stat.setObject(parameterIndex, Caster.toDouble(value), type); + try { + if (type == Types.FLOAT) stat.setFloat(parameterIndex, Caster.toFloatValue(value)); + else if (type == Types.DOUBLE) stat.setDouble(parameterIndex, Caster.toDoubleValue(value)); + else stat.setObject(parameterIndex, Caster.toDouble(value), type); + } + catch (PageException pe) { + // FUTURE remove this if + if (!NullSupportHelper.full(pc) && value instanceof String && StringUtil.isEmpty((String) value)) { + LogUtil.log(Log.LEVEL_WARN, "datasource", "conversion", "Deprecated functionality used at [" + LogUtil.caller(pc, "") + + "]. An empty string was passed as a value for type DOUBLE|FLOAT. Currently, this is treated as null, but it will be rejected in future releases."); + stat.setNull(parameterIndex, item.getType()); + } + else throw pe; + } return; case Types.VARBINARY: case Types.LONGVARBINARY: case Types.BINARY: - stat.setObject(parameterIndex, Caster.toBinary(value), type); - //// stat.setBytes(parameterIndex,Caster.toBinary(value)); + try { + stat.setObject(parameterIndex, Caster.toBinary(value), type); + } + catch (PageException pe) { + // FUTURE remove this if + if (!NullSupportHelper.full(pc) && value instanceof String && StringUtil.isEmpty((String) value)) { + LogUtil.log(Log.LEVEL_WARN, "datasource", "conversion", "Deprecated functionality used at [" + LogUtil.caller(pc, "") + + "]. An empty string was passed as a value for type VARBINARY|LONGVARBINARY|BINARY. Currently, this is treated as null, but it will be rejected in future releases."); + stat.setNull(parameterIndex, item.getType()); + } + else throw pe; + } return; case Types.REAL: - stat.setObject(parameterIndex, Caster.toFloat(value), type); - //// stat.setFloat(parameterIndex,Caster.toFloatValue(value)); + try { + stat.setObject(parameterIndex, Caster.toFloat(value), type); + } + catch (PageException pe) { + // FUTURE remove this if + if (!NullSupportHelper.full(pc) && value instanceof String && StringUtil.isEmpty((String) value)) { + LogUtil.log(Log.LEVEL_WARN, "datasource", "conversion", "Deprecated functionality used at [" + LogUtil.caller(pc, "") + + "]. An empty string was passed as a value for type REAL. Currently, this is treated as null, but it will be rejected in future releases."); + stat.setNull(parameterIndex, item.getType()); + } + else throw pe; + } return; case Types.TINYINT: - stat.setObject(parameterIndex, Caster.toByte(value), type); - //// stat.setByte(parameterIndex,Caster.toByteValue(value)); + try { + stat.setObject(parameterIndex, Caster.toByte(value), type); + } + catch (PageException pe) { + // FUTURE remove this if + if (!NullSupportHelper.full(pc) && value instanceof String && StringUtil.isEmpty((String) value)) { + LogUtil.log(Log.LEVEL_WARN, "datasource", "conversion", "Deprecated functionality used at [" + LogUtil.caller(pc, "") + + "]. An empty string was passed as a value for type TINYINT. Currently, this is treated as null, but it will be rejected in future releases."); + stat.setNull(parameterIndex, item.getType()); + } + else throw pe; + } return; case Types.SMALLINT: - stat.setObject(parameterIndex, Caster.toShort(value), type); - //// stat.setShort(parameterIndex,Caster.toShortValue(value)); + try { + stat.setObject(parameterIndex, Caster.toShort(value), type); + } + catch (PageException pe) { + // FUTURE remove this if + if (!NullSupportHelper.full(pc) && value instanceof String && StringUtil.isEmpty((String) value)) { + LogUtil.log(Log.LEVEL_WARN, "datasource", "conversion", "Deprecated functionality used at [" + LogUtil.caller(pc, "") + + "]. An empty string was passed as a value for type SMALLINT. Currently, this is treated as null, but it will be rejected in future releases."); + stat.setNull(parameterIndex, item.getType()); + } + else throw pe; + } return; case Types.INTEGER: - stat.setObject(parameterIndex, Caster.toInteger(value), type); - //// stat.setInt(parameterIndex,Caster.toIntValue(value)); + try { + stat.setObject(parameterIndex, Caster.toInteger(value), type); + } + catch (PageException pe) { + // FUTURE remove this if + if (!NullSupportHelper.full(pc) && value instanceof String && StringUtil.isEmpty((String) value)) { + LogUtil.log(Log.LEVEL_WARN, "datasource", "conversion", "Deprecated functionality used at [" + LogUtil.caller(pc, "") + + "]. An empty string was passed as a value for type INTEGER. Currently, this is treated as null, but it will be rejected in future releases."); + stat.setNull(parameterIndex, item.getType()); + } + else throw pe; + } return; case Types.SQLXML: @@ -239,23 +352,48 @@ public static void setValue(PageContext pc, TimeZone tz, PreparedStatement stat, case Types.NVARCHAR: case CFTypes.VARCHAR2: stat.setObject(parameterIndex, Caster.toString(value), type); - //// stat.setString(parameterIndex,Caster.toString(value)); return; case Types.DATE: - - stat.setDate(parameterIndex, new Date(Caster.toDate(value, tz).getTime()), JREDateTimeUtil.getThreadCalendar(tz)); - // stat.setDate(parameterIndex,new Date((Caster.toDate(value,null).getTime()))); + try { + stat.setDate(parameterIndex, new Date(Caster.toDate(value, tz).getTime()), JREDateTimeUtil.getThreadCalendar(tz)); + } + catch (PageException pe) { + // FUTURE remove this if + if (!NullSupportHelper.full(pc) && value instanceof String && StringUtil.isEmpty((String) value)) { + LogUtil.log(Log.LEVEL_WARN, "datasource", "conversion", "Deprecated functionality used at [" + LogUtil.caller(pc, "") + + "]. An empty string was passed as a value for type DATE. Currently, this is treated as null, but it will be rejected in future releases."); + stat.setNull(parameterIndex, item.getType()); + } + else throw pe; + } return; case Types.TIME: - // stat.setObject(parameterIndex, new Time((Caster.toDate(value,null).getTime())), - // type); - stat.setTime(parameterIndex, new Time(Caster.toDate(value, tz).getTime()), JREDateTimeUtil.getThreadCalendar(tz)); + try { + stat.setTime(parameterIndex, new Time(Caster.toDate(value, tz).getTime()), JREDateTimeUtil.getThreadCalendar(tz)); + } + catch (PageException pe) { + // FUTURE remove this if + if (!NullSupportHelper.full(pc) && value instanceof String && StringUtil.isEmpty((String) value)) { + LogUtil.log(Log.LEVEL_WARN, "datasource", "conversion", "Deprecated functionality used at [" + LogUtil.caller(pc, "") + + "]. An empty string was passed as a value for type TIME. Currently, this is treated as null, but it will be rejected in future releases."); + stat.setNull(parameterIndex, item.getType()); + } + else throw pe; + } return; case Types.TIMESTAMP: - // stat.setObject(parameterIndex, new - // Timestamp((Caster.toDate(value,null).getTime())), type); - // stat.setObject(parameterIndex, value, type); - stat.setTimestamp(parameterIndex, new Timestamp(Caster.toDate(value, tz).getTime()), JREDateTimeUtil.getThreadCalendar(tz)); + try { + stat.setTimestamp(parameterIndex, new Timestamp(Caster.toDate(value, tz).getTime()), JREDateTimeUtil.getThreadCalendar(tz)); + } + catch (PageException pe) { + // FUTURE remove this if + if (!NullSupportHelper.full(pc) && value instanceof String && StringUtil.isEmpty((String) value)) { + LogUtil.log(Log.LEVEL_WARN, "datasource", "conversion", "Deprecated functionality used at [" + LogUtil.caller(pc, "") + + "]. An empty string was passed as a value for type TIMESTAMP. Currently, this is treated as null, but it will be rejected in future releases."); + stat.setNull(parameterIndex, item.getType()); + } + else throw pe; + } return; case Types.OTHER: stat.setObject(parameterIndex, value, Types.OTHER); diff --git a/loader/build.xml b/loader/build.xml index 171d90b33b..dadbcf6b8a 100644 --- a/loader/build.xml +++ b/loader/build.xml @@ -2,7 +2,7 @@ - + diff --git a/loader/pom.xml b/loader/pom.xml index 5f8a963644..cced2f2f8c 100644 --- a/loader/pom.xml +++ b/loader/pom.xml @@ -3,7 +3,7 @@ org.lucee lucee - 6.0.4.1-SNAPSHOT + 6.0.4.2-SNAPSHOT jar Lucee Loader Build