Skip to content

Commit

Permalink
feat: smallint[] support through ListArrayType
Browse files Browse the repository at this point in the history
  • Loading branch information
tizba committed Jan 19, 2025
1 parent a533c18 commit ecc2cdb
Show file tree
Hide file tree
Showing 5 changed files with 382 additions and 265 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,22 @@
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Properties;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.UUID;

/**
* @author Vlad Mihalcea
* @author Baptiste Masoud
*/
public class ListArrayTypeDescriptor extends AbstractArrayTypeDescriptor<Collection> {

Expand Down Expand Up @@ -106,14 +119,16 @@ public void setParameterValues(Properties parameters) {
}
Class arrayElementClass = ReflectionUtils.getClass(genericType.getTypeName());
setArrayObjectClass(
arrayElementClass.isArray() ?
arrayElementClass :
ArrayUtil.toArrayClass(arrayElementClass)
arrayElementClass.isArray() ?
arrayElementClass :
ArrayUtil.toArrayClass(arrayElementClass)
);
sqlArrayType = parameters.getProperty(AbstractArrayType.SQL_ARRAY_TYPE);
if (sqlArrayType == null) {
if (Integer.class.isAssignableFrom(arrayElementClass)) {
sqlArrayType = "integer";
} else if (Short.class.isAssignableFrom(arrayElementClass)) {
sqlArrayType = "smallint";
} else if (Long.class.isAssignableFrom(arrayElementClass)) {
sqlArrayType = "bigint";
} else if (Double.class.isAssignableFrom(arrayElementClass)) {
Expand All @@ -137,7 +152,7 @@ public void setParameterValues(Properties parameters) {
} else {
throw new UnsupportedOperationException("The property " + propertyName + " in the " + entityClass + " entity is not parameterized!");
}
}
}

private Collection newPropertyCollectionInstance() {
if (propertyClass == null || List.class.isAssignableFrom(propertyClass)) {
Expand All @@ -149,4 +164,4 @@ private Collection newPropertyCollectionInstance() {
}
throw new UnsupportedOperationException("The property " + propertyName + " in the " + entityClass + " entity is not supported by the ListArrayType!");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,27 +9,23 @@
import org.hibernate.annotations.Type;
import org.junit.Test;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.fail;

/**
* @author Vlad Mihalcea
* @author Baptiste Masoud
*/
public class DefaultEmptyListArrayTypeTest extends AbstractPostgreSQLIntegrationTest {

@Override
protected Class<?>[] entities() {
return new Class<?>[]{
Event.class,
Event.class,
};
}

Expand Down Expand Up @@ -59,6 +55,7 @@ public void testEmptyArrays() {
assertArrayEquals(new UUID[]{}, event.getSensorIds().toArray());
assertArrayEquals(new String[]{}, event.getSensorNames().toArray());
assertArrayEquals(new Integer[]{}, event.getSensorValues().toArray());
assertArrayEquals(new Short[]{}, event.getSensorShortValues().toArray());
assertArrayEquals(new Long[]{}, event.getSensorLongValues().toArray());
assertArrayEquals(new SensorState[]{}, event.getSensorStates().toArray());
assertArrayEquals(new Date[]{}, event.getDateValues().toArray());
Expand All @@ -75,30 +72,34 @@ public static class Event extends BaseEntity {

@Type(ListArrayType.class)
@Column(name = "sensor_names", columnDefinition = "text[]")
private List<String> sensorNames = new ArrayList<>();;
private List<String> sensorNames = new ArrayList<>();

@Type(ListArrayType.class)
@Column(name = "sensor_values", columnDefinition = "integer[]")
private List<Integer> sensorValues = new ArrayList<>();;
private List<Integer> sensorValues = new ArrayList<>();

@Type(ListArrayType.class)
@Column(name = "sensor_short_values", columnDefinition = "smallint[]")
private List<Short> sensorShortValues = new ArrayList<>();

@Type(ListArrayType.class)
@Column(name = "sensor_long_values", columnDefinition = "bigint[]")
private List<Long> sensorLongValues = new ArrayList<>();;
private List<Long> sensorLongValues = new ArrayList<>();

@Type(
value = ListArrayType.class,
parameters = @Parameter(name = ListArrayType.SQL_ARRAY_TYPE, value = "sensor_state")
value = ListArrayType.class,
parameters = @Parameter(name = ListArrayType.SQL_ARRAY_TYPE, value = "sensor_state")
)
@Column(name = "sensor_states", columnDefinition = "sensor_state[]")
private List<SensorState> sensorStates = new ArrayList<>();;
private List<SensorState> sensorStates = new ArrayList<>();

@Type(ListArrayType.class)
@Column(name = "date_values", columnDefinition = "date[]")
private List<Date> dateValues = new ArrayList<>();;
private List<Date> dateValues = new ArrayList<>();

@Type(ListArrayType.class)
@Column(name = "timestamp_values", columnDefinition = "timestamp[]")
private List<Date> timestampValues = new ArrayList<>();;
private List<Date> timestampValues = new ArrayList<>();

public List<UUID> getSensorIds() {
return sensorIds;
Expand All @@ -124,6 +125,14 @@ public void setSensorValues(List<Integer> sensorValues) {
this.sensorValues = sensorValues;
}

public List<Short> getSensorShortValues() {
return sensorShortValues;
}

public void setSensorShortValues(List<Short> sensorShortValues) {
this.sensorShortValues = sensorShortValues;
}

public List<Long> getSensorLongValues() {
return sensorLongValues;
}
Expand Down Expand Up @@ -160,4 +169,4 @@ public void setTimestampValues(List<Date> timestampValues) {
public enum SensorState {
ONLINE, OFFLINE, UNKNOWN;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,38 @@

import io.hypersistence.utils.hibernate.type.model.BaseEntity;
import io.hypersistence.utils.hibernate.util.AbstractPostgreSQLIntegrationTest;
import jakarta.persistence.*;
import jakarta.persistence.Cacheable;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Table;
import jakarta.persistence.Tuple;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.annotations.Parameter;
import org.hibernate.annotations.Type;
import org.junit.Test;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.*;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import java.util.UUID;

import static org.junit.Assert.*;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;

/**
* @author Vlad Mihalcea
* @author Baptiste Masoud
*/
public class EhcacheListArrayTypeTest extends AbstractPostgreSQLIntegrationTest {

@Override
protected Class<?>[] entities() {
return new Class<?>[]{
Event.class,
Event.class,
};
}

Expand Down Expand Up @@ -59,6 +66,7 @@ public void test() {
event.setSensorIds(Arrays.asList(UUID.fromString("c65a3bcb-8b36-46d4-bddb-ae96ad016eb1"), UUID.fromString("72e95717-5294-4c15-aa64-a3631cf9a800")));
event.setSensorNames(Arrays.asList("Temperature", "Pressure"));
event.setSensorValues(Arrays.asList(12, 756));
event.setSensorShortValues(Arrays.asList((short) 42, (short) 69));
event.setSensorLongValues(Arrays.asList(42L, 9223372036854775800L));
event.setSensorStates(Arrays.asList(SensorState.ONLINE, SensorState.OFFLINE, SensorState.ONLINE, SensorState.UNKNOWN));
event.setDateValues(Arrays.asList(date1, date2));
Expand All @@ -72,6 +80,7 @@ public void test() {
assertArrayEquals(new UUID[]{UUID.fromString("c65a3bcb-8b36-46d4-bddb-ae96ad016eb1"), UUID.fromString("72e95717-5294-4c15-aa64-a3631cf9a800")}, event.getSensorIds().toArray());
assertArrayEquals(new String[]{"Temperature", "Pressure"}, event.getSensorNames().toArray());
assertArrayEquals(new Integer[]{12, 756}, event.getSensorValues().toArray());
assertArrayEquals(new Short[]{42, 69}, event.getSensorShortValues().toArray());
assertArrayEquals(new Long[]{42L, 9223372036854775800L}, event.getSensorLongValues().toArray());
assertArrayEquals(new SensorState[]{SensorState.ONLINE, SensorState.OFFLINE, SensorState.ONLINE, SensorState.UNKNOWN}, event.getSensorStates().toArray());
assertArrayEquals(new Date[]{date1, date2}, event.getDateValues().toArray());
Expand All @@ -80,19 +89,19 @@ public void test() {

doInJPA(entityManager -> {
List<Tuple> events = entityManager.createNativeQuery(
"select " +
" id, " +
" sensor_ids, " +
" sensor_names, " +
" sensor_values " +
"from event " +
"where id >= :id", Tuple.class)
.setParameter("id", 0)
.unwrap(org.hibernate.query.NativeQuery.class)
.addScalar("sensor_ids", UUID[].class)
.addScalar("sensor_names", String[].class)
.addScalar("sensor_values", int[].class)
.getResultList();
"select " +
" id, " +
" sensor_ids, " +
" sensor_names, " +
" sensor_values " +
"from event " +
"where id >= :id", Tuple.class)
.setParameter("id", 0)
.unwrap(org.hibernate.query.NativeQuery.class)
.addScalar("sensor_ids", UUID[].class)
.addScalar("sensor_names", String[].class)
.addScalar("sensor_values", int[].class)
.getResultList();

assertEquals(2, events.size());
});
Expand All @@ -113,6 +122,7 @@ public void testMixingNullValues() {
event.setSensorIds(Arrays.asList(null, UUID.fromString("72e95717-5294-4c15-aa64-a3631cf9a800")));
event.setSensorNames(Arrays.asList("Temperature", null));
event.setSensorValues(Arrays.asList(null, 756));
event.setSensorShortValues(Arrays.asList(null, (short) 69));
event.setSensorLongValues(Arrays.asList(null, 9223372036854775800L));
event.setSensorStates(Arrays.asList(null, SensorState.OFFLINE, SensorState.ONLINE, null));
event.setDateValues(Arrays.asList(null, date));
Expand All @@ -126,16 +136,17 @@ public void testMixingNullValues() {
assertArrayEquals(new UUID[]{null, UUID.fromString("72e95717-5294-4c15-aa64-a3631cf9a800")}, event.getSensorIds().toArray());
assertArrayEquals(new String[]{"Temperature", null}, event.getSensorNames().toArray());
assertArrayEquals(new Integer[]{null, 756}, event.getSensorValues().toArray());
assertArrayEquals(new Short[]{null, 69}, event.getSensorShortValues().toArray());
assertArrayEquals(new Long[]{null, 9223372036854775800L}, event.getSensorLongValues().toArray());
assertArrayEquals(new SensorState[]{null, SensorState.OFFLINE, SensorState.ONLINE, null}, event.getSensorStates().toArray());
assertArrayEquals(new Date[]{null, date}, event.getDateValues().toArray());
assertArrayEquals(new Date[]{null, date}, event.getTimestampValues().toArray());
});
}

@Test
public void testNullValues() {

doInJPA(entityManager -> {
Event nullEvent = new Event();
nullEvent.setId(0L);
Expand All @@ -146,6 +157,7 @@ public void testNullValues() {
event.setSensorIds(Arrays.asList(null, null));
event.setSensorNames(Arrays.asList(null, null));
event.setSensorValues(Arrays.asList(null, null));
event.setSensorShortValues(Arrays.asList(null, null));
event.setSensorLongValues(Arrays.asList(null, null));
event.setSensorStates(Arrays.asList(null, null));
event.setDateValues(Arrays.asList(null, null));
Expand All @@ -159,6 +171,7 @@ public void testNullValues() {
assertArrayEquals(new UUID[]{null, null}, event.getSensorIds().toArray());
assertArrayEquals(new String[]{null, null}, event.getSensorNames().toArray());
assertArrayEquals(new Integer[]{null, null}, event.getSensorValues().toArray());
assertArrayEquals(new Short[]{null, null}, event.getSensorShortValues().toArray());
assertArrayEquals(new Long[]{null, null}, event.getSensorLongValues().toArray());
assertArrayEquals(new SensorState[]{null, null}, event.getSensorStates().toArray());
assertArrayEquals(new Date[]{null, null}, event.getDateValues().toArray());
Expand All @@ -179,6 +192,7 @@ public void testEmptyArrays() {
event.setSensorIds(Collections.emptyList());
event.setSensorNames(Collections.emptyList());
event.setSensorValues(Collections.emptyList());
event.setSensorShortValues(Collections.emptyList());
event.setSensorLongValues(Collections.emptyList());
event.setSensorStates(Collections.emptyList());
event.setDateValues(Collections.emptyList());
Expand All @@ -192,6 +206,7 @@ public void testEmptyArrays() {
assertArrayEquals(new UUID[]{}, event.getSensorIds().toArray());
assertArrayEquals(new String[]{}, event.getSensorNames().toArray());
assertArrayEquals(new Integer[]{}, event.getSensorValues().toArray());
assertArrayEquals(new Short[]{}, event.getSensorShortValues().toArray());
assertArrayEquals(new Long[]{}, event.getSensorLongValues().toArray());
assertArrayEquals(new SensorState[]{}, event.getSensorStates().toArray());
assertArrayEquals(new Date[]{}, event.getDateValues().toArray());
Expand All @@ -217,6 +232,8 @@ public void testNullArrays() {

assertEquals(null, event.getSensorIds());
assertEquals(null, event.getSensorNames());
assertEquals(null, event.getSensorValues());
assertEquals(null, event.getSensorShortValues());
assertEquals(null, event.getSensorLongValues());
assertEquals(null, event.getSensorStates());
assertEquals(null, event.getDateValues());
Expand All @@ -241,13 +258,17 @@ public static class Event extends BaseEntity {
@Column(name = "sensor_values", columnDefinition = "integer[]")
private List<Integer> sensorValues;

@Type(ListArrayType.class)
@Column(name = "sensor_short_values", columnDefinition = "smallint[]")
private List<Short> sensorShortValues;

@Type(ListArrayType.class)
@Column(name = "sensor_long_values", columnDefinition = "bigint[]")
private List<Long> sensorLongValues;

@Type(
value = ListArrayType.class,
parameters = @Parameter(name = ListArrayType.SQL_ARRAY_TYPE, value = "sensor_state")
value = ListArrayType.class,
parameters = @Parameter(name = ListArrayType.SQL_ARRAY_TYPE, value = "sensor_state")
)
@Column(name = "sensor_states", columnDefinition = "sensor_state[]")
private List<SensorState> sensorStates;
Expand Down Expand Up @@ -284,6 +305,14 @@ public void setSensorValues(List<Integer> sensorValues) {
this.sensorValues = sensorValues;
}

public List<Short> getSensorShortValues() {
return sensorShortValues;
}

public void setSensorShortValues(List<Short> sensorShortValues) {
this.sensorShortValues = sensorShortValues;
}

public List<Long> getSensorLongValues() {
return sensorLongValues;
}
Expand Down Expand Up @@ -320,4 +349,4 @@ public void setTimestampValues(List<Date> timestampValues) {
public enum SensorState {
ONLINE, OFFLINE, UNKNOWN;
}
}
}
Loading

0 comments on commit ecc2cdb

Please sign in to comment.