Add converter for DateTime (#346)

* Add converter for DateTime

* Added to sql integration test suite

* Removed obsolete "auto update schema" property
This commit is contained in:
Michael Muller 2019-11-11 17:24:20 -05:00 committed by GitHub
parent dea7dfcf28
commit 455daae25c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 151 additions and 0 deletions

View file

@ -0,0 +1,41 @@
// Copyright 2019 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.persistence;
import static org.joda.time.DateTimeZone.UTC;
import java.sql.Timestamp;
import javax.annotation.Nullable;
import javax.persistence.AttributeConverter;
import javax.persistence.Converter;
import org.joda.time.DateTime;
/** JPA converter to for storing/retrieving {@link org.joda.time.DateTime} objects. */
@Converter(autoApply = true)
public class DateTimeConverter implements AttributeConverter<DateTime, Timestamp> {
@Override
@Nullable
public Timestamp convertToDatabaseColumn(@Nullable DateTime attribute) {
return attribute == null ? null : new Timestamp(attribute.getMillis());
}
@Override
@Nullable
public DateTime convertToEntityAttribute(@Nullable Timestamp dbData) {
DateTime result = dbData == null ? null : new DateTime(dbData.getTime(), UTC);
return result;
}
}

View file

@ -36,6 +36,7 @@
<class>google.registry.persistence.BloomFilterConverter</class> <class>google.registry.persistence.BloomFilterConverter</class>
<class>google.registry.persistence.CreateAutoTimestampConverter</class> <class>google.registry.persistence.CreateAutoTimestampConverter</class>
<class>google.registry.persistence.CurrencyUnitConverter</class> <class>google.registry.persistence.CurrencyUnitConverter</class>
<class>google.registry.persistence.DateTimeConverter</class>
<class>google.registry.persistence.UpdateAutoTimestampConverter</class> <class>google.registry.persistence.UpdateAutoTimestampConverter</class>
<class>google.registry.persistence.ZonedDateTimeConverter</class> <class>google.registry.persistence.ZonedDateTimeConverter</class>

View file

@ -0,0 +1,107 @@
// Copyright 2019 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.persistence;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.model.transaction.TransactionManagerFactory.jpaTm;
import google.registry.model.ImmutableObject;
import google.registry.model.transaction.JpaTransactionManagerRule;
import java.sql.Timestamp;
import javax.persistence.Entity;
import javax.persistence.Id;
import org.joda.time.DateTime;
import org.joda.time.format.ISODateTimeFormat;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
/** Unit tests for {@link DateTimeConverter}. */
@RunWith(JUnit4.class)
public class DateTimeConverterTest {
@Rule
public final JpaTransactionManagerRule jpaTmRule =
new JpaTransactionManagerRule.Builder().withEntityClass(TestEntity.class).build();
private final DateTimeConverter converter = new DateTimeConverter();
@Test
public void convertToDatabaseColumn_returnsNullIfInputIsNull() {
assertThat(converter.convertToDatabaseColumn(null)).isNull();
}
@Test
public void convertToDatabaseColumn_convertsCorrectly() {
DateTime dateTime = DateTime.parse("2019-09-01T01:01:01");
assertThat(converter.convertToDatabaseColumn(dateTime).getTime())
.isEqualTo(dateTime.getMillis());
}
@Test
public void convertToEntityAttribute_returnsNullIfInputIsNull() {
assertThat(converter.convertToEntityAttribute(null)).isNull();
}
@Test
public void convertToEntityAttribute_convertsCorrectly() {
DateTime dateTime = DateTime.parse("2019-09-01T01:01:01Z");
long millis = dateTime.getMillis();
assertThat(converter.convertToEntityAttribute(new Timestamp(millis))).isEqualTo(dateTime);
}
static DateTime parseDateTime(String value) {
return ISODateTimeFormat.dateTimeNoMillis().withOffsetParsed().parseDateTime(value);
}
@Test
public void converter_generatesTimestampWithNormalizedZone() {
DateTime dt = parseDateTime("2019-09-01T01:01:01Z");
TestEntity entity = new TestEntity("normalized_utc_time", dt);
jpaTm().transact(() -> jpaTm().getEntityManager().persist(entity));
TestEntity retrievedEntity =
jpaTm()
.transact(
() -> jpaTm().getEntityManager().find(TestEntity.class, "normalized_utc_time"));
assertThat(retrievedEntity.dt.toString()).isEqualTo("2019-09-01T01:01:01.000Z");
}
@Test
public void converter_convertsNonUtcZoneCorrectly() {
DateTime dt = parseDateTime("2019-09-01T01:01:01-05:00");
TestEntity entity = new TestEntity("new_york_time", dt);
jpaTm().transact(() -> jpaTm().getEntityManager().persist(entity));
TestEntity retrievedEntity =
jpaTm().transact(() -> jpaTm().getEntityManager().find(TestEntity.class, "new_york_time"));
assertThat(retrievedEntity.dt.toString()).isEqualTo("2019-09-01T06:01:01.000Z");
}
@Entity(name = "TestEntity") // Override entity name to avoid the nested class reference.
private static class TestEntity extends ImmutableObject {
@Id String name;
DateTime dt;
public TestEntity() {}
TestEntity(String name, DateTime dt) {
this.name = name;
this.dt = dt;
}
}
}

View file

@ -21,6 +21,7 @@ import google.registry.model.transaction.JpaTransactionManagerRuleTest;
import google.registry.persistence.BloomFilterConverterTest; import google.registry.persistence.BloomFilterConverterTest;
import google.registry.persistence.CreateAutoTimestampConverterTest; import google.registry.persistence.CreateAutoTimestampConverterTest;
import google.registry.persistence.CurrencyUnitConverterTest; import google.registry.persistence.CurrencyUnitConverterTest;
import google.registry.persistence.DateTimeConverterTest;
import google.registry.persistence.JodaMoneyConverterTest; import google.registry.persistence.JodaMoneyConverterTest;
import google.registry.persistence.UpdateAutoTimestampConverterTest; import google.registry.persistence.UpdateAutoTimestampConverterTest;
import google.registry.persistence.ZonedDateTimeConverterTest; import google.registry.persistence.ZonedDateTimeConverterTest;
@ -46,6 +47,7 @@ import org.junit.runners.Suite.SuiteClasses;
ClaimsListDaoTest.class, ClaimsListDaoTest.class,
CreateAutoTimestampConverterTest.class, CreateAutoTimestampConverterTest.class,
CurrencyUnitConverterTest.class, CurrencyUnitConverterTest.class,
DateTimeConverterTest.class,
JodaMoneyConverterTest.class, JodaMoneyConverterTest.class,
JpaTransactionManagerImplTest.class, JpaTransactionManagerImplTest.class,
JpaTransactionManagerRuleTest.class, JpaTransactionManagerRuleTest.class,