Introduce 'null object' timestamp and also parse it from JSON
In Gerrit, it is common practice to use empty Strings to unset a value in contexts where using null is not possible. We need something similar for timestamps as well. Inside of the Gerrit backend, we introduce TimeUtil.never() to indicate this value. For users of Gerrit's REST API, we introduce another mapping for convenience: an empty timestamp string in JSON will be mapped to the magic value. We deliberately don't add the reverse mapping as proper implementations in Gerrit should never set this value internally and hence it should never be returned to the user. Change-Id: I533b793227de4315893ee99750b20a442ff3c081
This commit is contained in:
@@ -44,7 +44,15 @@ class SqlTimestampDeserializer implements JsonDeserializer<Timestamp>, JsonSeria
|
||||
throw new JsonParseException("Expected string for timestamp type");
|
||||
}
|
||||
|
||||
return JavaSqlTimestampHelper.parseTimestamp(p.getAsString());
|
||||
String input = p.getAsString();
|
||||
if (input.trim().isEmpty()) {
|
||||
// Magic timestamp to indicate no timestamp. (-> null object)
|
||||
// Always create a new object as timestamps are mutable. Don't use TimeUtil.never() to not
|
||||
// introduce an undesired dependency.
|
||||
return new Timestamp(0);
|
||||
}
|
||||
|
||||
return JavaSqlTimestampHelper.parseTimestamp(input);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -3,6 +3,7 @@ java_library(
|
||||
srcs = glob(["**/*.java"]),
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//java/com/google/gerrit/common:annotations",
|
||||
"//lib:guava",
|
||||
"//lib/jgit/org.eclipse.jgit:jgit",
|
||||
],
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
package com.google.gerrit.server.util.time;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.gerrit.common.UsedAt;
|
||||
import com.google.gerrit.common.UsedAt.Project;
|
||||
import java.sql.Timestamp;
|
||||
import java.time.Instant;
|
||||
import java.util.function.LongSupplier;
|
||||
@@ -43,6 +45,17 @@ public class TimeUtil {
|
||||
return new Timestamp(nowMs());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the magic timestamp representing no specific time.
|
||||
*
|
||||
* <p>This "null object" is helpful in contexts where using {@code null} directly is not possible.
|
||||
*/
|
||||
@UsedAt(Project.PLUGIN_CHECKS)
|
||||
public static Timestamp never() {
|
||||
// Always create a new object as timestamps are mutable.
|
||||
return new Timestamp(0);
|
||||
}
|
||||
|
||||
public static Timestamp truncateToSecond(Timestamp t) {
|
||||
return new Timestamp((t.getTime() / 1000) * 1000);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user