diff --git a/api/src/org/labkey/api/data/NowTimestamp.java b/api/src/org/labkey/api/data/NowTimestamp.java new file mode 100644 index 00000000000..812b884e986 --- /dev/null +++ b/api/src/org/labkey/api/data/NowTimestamp.java @@ -0,0 +1,59 @@ +package org.labkey.api.data; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonToken; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +import java.io.IOException; +import java.sql.Timestamp; + +/** + * Marker interface to hint that this value may be replaced by CURRENT_TIMESTAMP. + */ +@JsonDeserialize(using = NowTimestamp.NowTimestampDeserializer.class) +public class NowTimestamp extends java.sql.Timestamp +{ + public NowTimestamp() + { + this(System.currentTimeMillis()); + } + + public NowTimestamp(long ms) + { + super(ms); + } + + public static class NowTimestampDeserializer extends JsonDeserializer + { + @Override + public NowTimestamp deserialize(JsonParser p, DeserializationContext ctx) throws IOException + { + JsonToken token = p.getCurrentToken(); + + if (token == JsonToken.VALUE_STRING) + { + String text = p.getText().trim(); + + try + { + Timestamp ts = Timestamp.valueOf(text); + return new NowTimestamp(ts.getTime()); + } + catch (IllegalArgumentException ex) + { + throw ctx.weirdStringException(text, NowTimestamp.class, "Expected a valid timestamp string."); + } + } + + if (token == JsonToken.VALUE_NUMBER_INT) + { + long milliseconds = p.getLongValue(); + return new NowTimestamp(milliseconds); + } + + throw ctx.wrongTokenException(p, NowTimestamp.class, JsonToken.VALUE_STRING, "Expected timestamp as String or long."); + } + } +} diff --git a/api/src/org/labkey/api/data/SQLFragment.java b/api/src/org/labkey/api/data/SQLFragment.java index 744d025f7db..f0fe937f876 100644 --- a/api/src/org/labkey/api/data/SQLFragment.java +++ b/api/src/org/labkey/api/data/SQLFragment.java @@ -1342,18 +1342,4 @@ public static SQLFragment join(Iterable fragments, String separator return new SQLFragment(sql, params); } - - // Marker interface to hint that this value may be replaced by CURRENT_TIMESTAMP - public static class NowTimestamp extends java.sql.Timestamp - { - public NowTimestamp() - { - this(System.currentTimeMillis()); - } - - public NowTimestamp(long ms) - { - super(ms); - } - } } diff --git a/api/src/org/labkey/api/data/StatementUtils.java b/api/src/org/labkey/api/data/StatementUtils.java index 580a3432ad1..70945ac1a19 100644 --- a/api/src/org/labkey/api/data/StatementUtils.java +++ b/api/src/org/labkey/api/data/StatementUtils.java @@ -1240,7 +1240,7 @@ private void toLiteral(SQLFragment f, Object value) f.append(value.toString()); return; } - if (value instanceof SQLFragment.NowTimestamp now) + if (value instanceof NowTimestamp now) { f.appendValue(now); return; @@ -1405,7 +1405,7 @@ public void testToLiteral() assertEquals(new SQLFragment("1234567890"), actual); // NowTimestamp - var now = new SQLFragment.NowTimestamp(dateLong); + var now = new NowTimestamp(dateLong); actual = runToLiteral.apply(now); assertEquals(new SQLFragment().appendValue(now), actual); diff --git a/api/src/org/labkey/api/data/Table.java b/api/src/org/labkey/api/data/Table.java index d28580ad7a7..5b3b76d7b44 100644 --- a/api/src/org/labkey/api/data/Table.java +++ b/api/src/org/labkey/api/data/Table.java @@ -705,7 +705,7 @@ static String _trimRight(String s) return StringUtils.stripEnd(s, "\t\r\n "); } - protected static void _insertSpecialFields(User user, TableInfo table, Map fields, SQLFragment.NowTimestamp now) + protected static void _insertSpecialFields(User user, TableInfo table, Map fields, NowTimestamp now) { ColumnInfo col = table.getColumn(OWNER_COLUMN_NAME); if (null != col && null != user) @@ -741,7 +741,7 @@ protected static void _copyInsertSpecialFields(Object returnObject, Map fields, SQLFragment.NowTimestamp now) + protected static void _updateSpecialFields(@Nullable User user, TableInfo table, Map fields, NowTimestamp now) { ColumnInfo colModifiedBy = table.getColumn(MODIFIED_BY_COLUMN_NAME); if (null != colModifiedBy && null != user) @@ -826,7 +826,7 @@ public static K insert(@Nullable User user, TableInfo table, K fieldsIn) Map fields = fieldsIn instanceof Map ? _getTableData(table, (Map)fieldsIn, true) : _getTableData(table, fieldsIn, true); - SQLFragment.NowTimestamp now = new SQLFragment.NowTimestamp(); + NowTimestamp now = new NowTimestamp(); _insertSpecialFields(user, table, fields, now); _updateSpecialFields(user, table, fields, now); @@ -860,7 +860,7 @@ else if (column.isAutoIncrement()) valueSQL.append(comma); if (null == value || value instanceof String s && s.isEmpty()) valueSQL.append("NULL"); - else if (value instanceof SQLFragment.NowTimestamp ts) + else if (value instanceof NowTimestamp ts) valueSQL.appendValue(ts); else { @@ -1020,7 +1020,7 @@ else if (pkVals instanceof Map) Map fields = fieldsIn instanceof Map ? _getTableData(table, (Map)fieldsIn, true) : _getTableData(table, fieldsIn, true); - _updateSpecialFields(user, table, fields, new SQLFragment.NowTimestamp()); + _updateSpecialFields(user, table, fields, new NowTimestamp()); List columns = table.getColumns(); ColumnInfo colModified = table.getColumn(MODIFIED_COLUMN_NAME); @@ -1064,7 +1064,7 @@ else if (pkVals instanceof Map) if (null == value || value instanceof String s && s.isEmpty()) setSQL.append("NULL"); - else if (value instanceof SQLFragment.NowTimestamp ts) + else if (value instanceof NowTimestamp ts) setSQL.appendValue(ts); else { diff --git a/api/src/org/labkey/api/dataiterator/SimpleTranslator.java b/api/src/org/labkey/api/dataiterator/SimpleTranslator.java index 803c2663799..4fe081a51d9 100644 --- a/api/src/org/labkey/api/dataiterator/SimpleTranslator.java +++ b/api/src/org/labkey/api/dataiterator/SimpleTranslator.java @@ -48,7 +48,7 @@ import org.labkey.api.data.LookupResolutionType; import org.labkey.api.data.MultiValuedForeignKey; import org.labkey.api.data.MvUtil; -import org.labkey.api.data.SQLFragment; +import org.labkey.api.data.NowTimestamp; import org.labkey.api.data.SimpleFilter; import org.labkey.api.data.TableDescription; import org.labkey.api.data.TableInfo; @@ -59,7 +59,6 @@ import org.labkey.api.exp.PropertyDescriptor; import org.labkey.api.exp.PropertyType; import org.labkey.api.files.FileContentService; -import org.labkey.api.gwt.client.model.PropertyValidatorType; import org.labkey.api.ontology.Unit; import org.labkey.api.query.AbstractQueryUpdateService; import org.labkey.api.query.BatchValidationException; @@ -72,7 +71,6 @@ import org.labkey.api.query.ValidationException; import org.labkey.api.security.User; import org.labkey.api.security.permissions.UpdatePermission; -import org.labkey.api.settings.OptionalFeatureService; import org.labkey.api.util.GUID; import org.labkey.api.util.IntegerUtils; import org.labkey.api.util.JunitUtil; @@ -1057,7 +1055,7 @@ private class TimestampColumn implements Supplier public Object get() { if (null == _ts) - _ts = new SQLFragment.NowTimestamp(); + _ts = new NowTimestamp(); return _ts; } } @@ -2005,7 +2003,7 @@ public Object getConstantValue(int i) if (c instanceof SimpleConvertColumn scc) return scc.convert(_data.getConstantValue(scc.index)); if (c instanceof TimestampColumn) - return new SQLFragment.NowTimestamp(); + return new NowTimestamp(); throw new IllegalStateException("shouldn't call this method unless isConstant()==true"); }