[jOOQ/jOOQ#2968] Added int8range support

This commit is contained in:
Lukas Eder 2022-03-01 15:33:13 +01:00
parent a8e97eff95
commit 166bbc7d2d
11 changed files with 446 additions and 13 deletions

View File

@ -1542,6 +1542,19 @@ public abstract class AbstractDatabase implements Database {
.withIncludeTypes("_int4range")
.withPriority(Integer.MIN_VALUE)
);
getConfiguredForcedTypes().add(new ForcedType()
.withUserType("org.jooq.postgres.extensions.types.LongRange")
.withBinding("org.jooq.postgres.extensions.bindings.LongRangeBinding")
.withIncludeTypes("int8range")
.withPriority(Integer.MIN_VALUE)
);
getConfiguredForcedTypes().add(new ForcedType()
.withUserType("org.jooq.postgres.extensions.types.LongRange[]")
.withBinding("org.jooq.postgres.extensions.bindings.LongRangeArrayBinding")
.withIncludeTypes("_int8range")
.withPriority(Integer.MIN_VALUE)
);
}
catch (ClassNotFoundException ignore) {
log.debug("Built in data types", "org.jooq.postgres.extensions.types.Hstore not found on classpath, ignoring built in data type extensions");

View File

@ -42,7 +42,7 @@ import org.jooq.postgres.extensions.converters.IntegerRangeConverter;
import org.jooq.postgres.extensions.types.IntegerRange;
/**
* A binding for the PostgreSQL <code>inet[]</code> data type.
* A binding for the PostgreSQL <code>int4range[]</code> data type.
*
* @author Lukas Eder
*/

View File

@ -0,0 +1,62 @@
/*
* 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.
*
* Other licenses:
* -----------------------------------------------------------------------------
* Commercial licenses for this work are available. These replace the above
* ASL 2.0 and offer limited warranties, support, maintenance, and commercial
* database integrations.
*
* For more information, please visit: http://www.jooq.org/licenses
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
package org.jooq.postgres.extensions.bindings;
import org.jooq.Converter;
import org.jooq.postgres.extensions.converters.LongRangeConverter;
import org.jooq.postgres.extensions.types.LongRange;
/**
* A binding for the PostgreSQL <code>int8range[]</code> data type.
*
* @author Lukas Eder
*/
public class LongRangeArrayBinding extends AbstractPostgresArrayBinding<LongRange> {
private static final Converter<Object[], LongRange[]> CONVERTER = new LongRangeConverter().forArrays();
@Override
public Converter<Object[], LongRange[]> converter() {
return CONVERTER;
}
@Override
protected String castType() {
return "int8range[]";
}
}

View File

@ -0,0 +1,62 @@
/*
* 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.
*
* Other licenses:
* -----------------------------------------------------------------------------
* Commercial licenses for this work are available. These replace the above
* ASL 2.0 and offer limited warranties, support, maintenance, and commercial
* database integrations.
*
* For more information, please visit: http://www.jooq.org/licenses
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
package org.jooq.postgres.extensions.bindings;
import org.jooq.Converter;
import org.jooq.postgres.extensions.converters.LongRangeConverter;
import org.jooq.postgres.extensions.types.LongRange;
/**
* A binding for the PostgreSQL <code>int8range</code> data type.
*
* @author Lukas Eder
*/
public class LongRangeBinding extends AbstractRangeBinding<LongRange> {
private static final Converter<Object, LongRange> CONVERTER = new LongRangeConverter();
@Override
public Converter<Object, LongRange> converter() {
return CONVERTER;
}
@Override
protected String castType() {
return "int8range";
}
}

View File

@ -0,0 +1,70 @@
/*
* 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.
*
* Other licenses:
* -----------------------------------------------------------------------------
* Commercial licenses for this work are available. These replace the above
* ASL 2.0 and offer limited warranties, support, maintenance, and commercial
* database integrations.
*
* For more information, please visit: http://www.jooq.org/licenses
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
package org.jooq.postgres.extensions.converters;
import static org.jooq.postgres.extensions.types.LongRange.longRange;
import org.jooq.postgres.extensions.types.IntegerRange;
import org.jooq.postgres.extensions.types.LongRange;
/**
* A converter for {@link IntegerRange}.
*
* @author Lukas Eder
*/
public class LongRangeConverter extends AbstractRangeConverter<Long, LongRange> {
public LongRangeConverter() {
super(LongRange.class);
}
@Override
final LongRange construct(String lower, boolean lowerIncluding, String upper, boolean upperIncluding) {
return longRange(
lower == null ? null : Long.valueOf(lower),
lowerIncluding,
upper == null ? null : Long.valueOf(upper),
upperIncluding
);
}
@Override
final LongRange empty() {
return longRange(0L, 0L);
}
}

View File

@ -39,6 +39,8 @@ package org.jooq.postgres.extensions.types;
import java.util.Objects;
import org.jooq.exception.DataTypeException;
/**
* A data type representing the PostgreSQL <code>range</code> type for discrete ranges.
*
@ -52,13 +54,17 @@ abstract class AbstractDiscreteRange<T, R extends AbstractDiscreteRange<T, R>> e
/**
* Given a value t, get the next value.
*
* @throws DataTypeException on overflow.
*/
abstract T next(T t);
abstract T next(T t) throws DataTypeException;
/**
* Given a value t, get the previous value.
*
* @throws DataTypeException on underflow.
*/
abstract T prev(T t);
abstract T prev(T t) throws DataTypeException;
/**
* Construct a new instance of this type.
@ -79,9 +85,6 @@ abstract class AbstractDiscreteRange<T, R extends AbstractDiscreteRange<T, R>> e
if (!lowerIncluding() && l != null)
l = next(l);
// This can overflow for Integer and Long. In PostgreSQL, an overflow
// will cause an error. We might deal with this too, in the future
if (upperIncluding() && u != null)
u = next(u);

View File

@ -37,6 +37,8 @@
*/
package org.jooq.postgres.extensions.types;
import org.jooq.exception.DataTypeException;
/**
* A data type representing the PostgreSQL <code>int4range</code> type.
*
@ -70,11 +72,21 @@ public final class IntegerRange extends AbstractDiscreteRange<Integer, IntegerRa
@Override
final Integer next(Integer t) {
return t.intValue() + 1;
int l = t.intValue();
if (l == Integer.MAX_VALUE)
throw new DataTypeException("Integer overflow: " + this);
else
return l + 1;
}
@Override
final Integer prev(Integer t) {
return t.intValue() - 1;
int l = t.intValue();
if (l == Integer.MIN_VALUE)
throw new DataTypeException("Integer underflow: " + this);
else
return l - 1;
}
}

View File

@ -0,0 +1,92 @@
/*
* 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.
*
* Other licenses:
* -----------------------------------------------------------------------------
* Commercial licenses for this work are available. These replace the above
* ASL 2.0 and offer limited warranties, support, maintenance, and commercial
* database integrations.
*
* For more information, please visit: http://www.jooq.org/licenses
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
package org.jooq.postgres.extensions.types;
import org.jooq.exception.DataTypeException;
/**
* A data type representing the PostgreSQL <code>int8range</code> type.
*
* @author Lukas Eder
*/
public final class LongRange extends AbstractDiscreteRange<Long, LongRange> {
private LongRange(Long lower, boolean lowerIncluding, Long upper, boolean upperIncluding) {
super(lower, lowerIncluding, upper, upperIncluding);
}
/**
* Create a new {@link LongRange} with a inclusive lower bound and an
* exclusive upper bound.
*/
public static final LongRange longRange(Long lower, Long upper) {
return new LongRange(lower, true, upper, false);
}
/**
* Create a new {@link LongRange}.
*/
public static final LongRange longRange(Long lower, boolean lowerIncluding, Long upper, boolean upperIncluding) {
return new LongRange(lower, lowerIncluding, upper, upperIncluding);
}
@Override
final LongRange construct(Long lower, Long upper) {
return new LongRange(lower, true, upper, false);
}
@Override
final Long next(Long t) {
long l = t.longValue();
if (l == Long.MAX_VALUE)
throw new DataTypeException("Long overflow: " + this);
else
return l + 1L;
}
@Override
final Long prev(Long t) {
long l = t.longValue();
if (l == Long.MIN_VALUE)
throw new DataTypeException("Long underflow: " + this);
else
return l - 1L;
}
}

View File

@ -37,6 +37,7 @@
*/
package org.jooq.postgres.extensions.test;
import static org.jooq.postgres.extensions.test.RangeTestUtils.assertEqualsHashCode;
import static org.jooq.postgres.extensions.types.IntegerRange.integerRange;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
@ -71,9 +72,4 @@ public class IntegerRangeTest {
assertNotEquals(integerRange(0, 1), integerRange(1, 0));
}
private void assertEqualsHashCode(Object expected, Object actual) {
assertEquals(expected, actual);
assertEquals(expected.hashCode(), actual.hashCode());
}
}

View File

@ -0,0 +1,75 @@
/*
* 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.
*
* Other licenses:
* -----------------------------------------------------------------------------
* Commercial licenses for this work are available. These replace the above
* ASL 2.0 and offer limited warranties, support, maintenance, and commercial
* database integrations.
*
* For more information, please visit: http://www.jooq.org/licenses
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
package org.jooq.postgres.extensions.test;
import static org.jooq.postgres.extensions.test.RangeTestUtils.assertEqualsHashCode;
import static org.jooq.postgres.extensions.types.LongRange.longRange;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import org.junit.Test;
public class LongRangeTest {
@Test
public void testEqualsHashCode() {
assertEqualsHashCode(longRange(0L, 0L), longRange(0L, 0L));
assertEqualsHashCode(longRange(0L, 1L), longRange(0L, 1L));
assertEqualsHashCode(longRange(0L, 2L), longRange(0L, true, 1L, true));
assertEqualsHashCode(longRange(0L, 2L), longRange(0L, true, 2L, false));
assertEqualsHashCode(longRange(0L, 2L), longRange(-1L, false, 1L, true));
assertEqualsHashCode(longRange(0L, 2L), longRange(-1L, false, 2L, false));
assertEqualsHashCode(longRange(0L, null), longRange(0L, true, null, true));
assertEqualsHashCode(longRange(0L, null), longRange(0L, true, null, false));
assertEqualsHashCode(longRange(0L, null), longRange(-1L, false, null, true));
assertEqualsHashCode(longRange(0L, null), longRange(-1L, false, null, false));
assertEqualsHashCode(longRange(null, 2L), longRange(null, true, 1L, true));
assertEqualsHashCode(longRange(null, 2L), longRange(null, true, 2L, false));
assertEqualsHashCode(longRange(null, 2L), longRange(null, false, 1L, true));
assertEqualsHashCode(longRange(null, 2L), longRange(null, false, 2L, false));
assertEqualsHashCode(longRange(null, null), longRange(null, true, null, true));
assertEqualsHashCode(longRange(null, null), longRange(null, true, null, false));
assertEqualsHashCode(longRange(null, null), longRange(null, false, null, true));
assertEqualsHashCode(longRange(null, null), longRange(null, false, null, false));
assertNotEquals(longRange(0L, 1L), longRange(1L, 0L));
}
}

View File

@ -0,0 +1,48 @@
/*
* 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.
*
* Other licenses:
* -----------------------------------------------------------------------------
* Commercial licenses for this work are available. These replace the above
* ASL 2.0 and offer limited warranties, support, maintenance, and commercial
* database integrations.
*
* For more information, please visit: http://www.jooq.org/licenses
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
package org.jooq.postgres.extensions.test;
import static org.junit.Assert.assertEquals;
public class RangeTestUtils {
public static void assertEqualsHashCode(Object expected, Object actual) {
assertEquals(expected, actual);
assertEquals(expected.hashCode(), actual.hashCode());
}
}