Skip to content

Commit

Permalink
Enable direct mapping of external domain types to database (#1252)
Browse files Browse the repository at this point in the history
  • Loading branch information
nakamura-to authored Dec 30, 2024
2 parents a090a27 + b5a9a75 commit 161384c
Show file tree
Hide file tree
Showing 27 changed files with 295 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import org.seasar.doma.jdbc.OutParameter;
import org.seasar.doma.jdbc.Reference;
import org.seasar.doma.jdbc.SqlParameterVisitor;
import org.seasar.doma.jdbc.type.JdbcType;
import org.seasar.doma.wrapper.Wrapper;

public class ScalarInOutParameter<BASIC, CONTAINER>
Expand Down Expand Up @@ -44,6 +45,11 @@ public Optional<Class<?>> getDomainClass() {
return scalar.getDomainClass();
}

@Override
public Optional<JdbcType<Object>> getJdbcType() {
return scalar.getJdbcType();
}

@Override
public <R, P, TH extends Throwable> R accept(SqlParameterVisitor<R, P, TH> visitor, P p)
throws TH {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import org.seasar.doma.internal.jdbc.scalar.Scalar;
import org.seasar.doma.jdbc.InParameter;
import org.seasar.doma.jdbc.SqlParameterVisitor;
import org.seasar.doma.jdbc.type.JdbcType;
import org.seasar.doma.wrapper.Wrapper;

public class ScalarInParameter<BASIC, CONTAINER> implements InParameter<BASIC> {
Expand Down Expand Up @@ -38,6 +39,11 @@ public Optional<Class<?>> getDomainClass() {
return scalar.getDomainClass();
}

@Override
public Optional<JdbcType<Object>> getJdbcType() {
return scalar.getJdbcType();
}

@Override
public <R, P, TH extends Throwable> R accept(SqlParameterVisitor<R, P, TH> visitor, P p)
throws TH {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import org.seasar.doma.jdbc.OutParameter;
import org.seasar.doma.jdbc.Reference;
import org.seasar.doma.jdbc.SqlParameterVisitor;
import org.seasar.doma.jdbc.type.JdbcType;
import org.seasar.doma.wrapper.Wrapper;

public class ScalarOutParameter<BASIC, CONTAINER> implements OutParameter<BASIC> {
Expand Down Expand Up @@ -41,6 +42,11 @@ public Optional<Class<?>> getDomainClass() {
return scalar.getDomainClass();
}

@Override
public Optional<JdbcType<Object>> getJdbcType() {
return scalar.getJdbcType();
}

@Override
public <R, P, TH extends Throwable> R accept(SqlParameterVisitor<R, P, TH> visitor, P p)
throws TH {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import org.seasar.doma.internal.jdbc.scalar.Scalar;
import org.seasar.doma.jdbc.SingleResultParameter;
import org.seasar.doma.jdbc.SqlParameterVisitor;
import org.seasar.doma.jdbc.type.JdbcType;
import org.seasar.doma.wrapper.Wrapper;

public class ScalarSingleResultParameter<BASIC, CONTAINER>
Expand Down Expand Up @@ -38,6 +39,11 @@ public Optional<Class<?>> getDomainClass() {
return scalar.getDomainClass();
}

@Override
public Optional<JdbcType<Object>> getJdbcType() {
return scalar.getJdbcType();
}

@Override
public <R, P, TH extends Throwable> R accept(SqlParameterVisitor<R, P, TH> visitor, P p)
throws TH {
Expand Down
10 changes: 10 additions & 0 deletions doma-core/src/main/java/org/seasar/doma/jdbc/JdbcMappingHint.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.seasar.doma.jdbc;

import java.util.Optional;
import org.seasar.doma.jdbc.type.JdbcType;

/** A hint about mapping. */
public interface JdbcMappingHint {
Expand All @@ -11,4 +12,13 @@ public interface JdbcMappingHint {
* @return the domain class
*/
Optional<Class<?>> getDomainClass();

/**
* Returns the JDBC type if the target value is mapped to the JDBC type.
*
* @return the JDBC type
*/
default Optional<JdbcType<Object>> getJdbcType() {
return Optional.empty();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import org.seasar.doma.jdbc.entity.EntityPropertyType;
import org.seasar.doma.jdbc.entity.NamingType;
import org.seasar.doma.jdbc.entity.Property;
import org.seasar.doma.jdbc.type.JdbcType;
import org.seasar.doma.wrapper.BigDecimalWrapper;
import org.seasar.doma.wrapper.BigIntegerWrapper;
import org.seasar.doma.wrapper.BooleanWrapper;
Expand Down Expand Up @@ -143,6 +144,11 @@ public Wrapper<BASIC> getWrapper() {
public Optional<Class<?>> getDomainClass() {
return scalar.getDomainClass();
}

@Override
public Optional<JdbcType<Object>> getJdbcType() {
return scalar.getJdbcType();
}
}

class BigDecimalPropertyType extends BasicPropertyType<BigDecimal> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -563,7 +563,8 @@ public Void visitUtilDateWrapper(
@Override
public Void visitObjectWrapper(ObjectWrapper wrapper, JdbcMappingFunction p, JdbcMappingHint q)
throws SQLException {
return p.apply(wrapper, JdbcTypes.OBJECT);
JdbcType<Object> jdbcType = q.getJdbcType().orElse(JdbcTypes.OBJECT);
return p.apply(wrapper, jdbcType);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,24 @@
import java.util.function.Supplier;
import org.seasar.doma.internal.jdbc.scalar.Scalar;
import org.seasar.doma.internal.util.AssertionUtil;
import org.seasar.doma.jdbc.type.JdbcType;
import org.seasar.doma.wrapper.Wrapper;

public abstract class AbstractDomainType<BASIC, DOMAIN> implements DomainType<BASIC, DOMAIN> {

protected final Supplier<Wrapper<BASIC>> wrapperSupplier;

protected final Supplier<JdbcType<?>> jdbcTypeSupplier;

protected AbstractDomainType(Supplier<Wrapper<BASIC>> wrapperSupplier) {
AssertionUtil.assertNotNull(wrapperSupplier);
this(wrapperSupplier, () -> null);
}

protected AbstractDomainType(
Supplier<Wrapper<BASIC>> wrapperSupplier, Supplier<JdbcType<?>> jdbcTypeSupplier) {
AssertionUtil.assertNotNull(wrapperSupplier, jdbcTypeSupplier);
this.wrapperSupplier = wrapperSupplier;
this.jdbcTypeSupplier = jdbcTypeSupplier;
}

protected abstract DOMAIN newDomain(BASIC value);
Expand All @@ -21,34 +30,36 @@ protected AbstractDomainType(Supplier<Wrapper<BASIC>> wrapperSupplier) {

@Override
public DomainScalar createScalar() {
return new DomainScalar(wrapperSupplier.get());
return new DomainScalar(wrapperSupplier.get(), jdbcTypeSupplier.get());
}

@Override
public DomainScalar createScalar(DOMAIN value) {
Wrapper<BASIC> wrapper = wrapperSupplier.get();
wrapper.set(getBasicValue(value));
return new DomainScalar(wrapper);
return new DomainScalar(wrapper, jdbcTypeSupplier.get());
}

@Override
public OptionalDomainScalar createOptionalScalar() {
return new OptionalDomainScalar(wrapperSupplier.get());
return new OptionalDomainScalar(wrapperSupplier.get(), jdbcTypeSupplier.get());
}

@Override
public OptionalDomainScalar createOptionalScalar(DOMAIN value) {
Wrapper<BASIC> wrapper = wrapperSupplier.get();
wrapper.set(getBasicValue(value));
return new OptionalDomainScalar(wrapper);
return new OptionalDomainScalar(wrapper, jdbcTypeSupplier.get());
}

protected class DomainScalar implements Scalar<BASIC, DOMAIN> {

protected final Wrapper<BASIC> wrapper;
protected final JdbcType<?> jdbcType;

protected DomainScalar(Wrapper<BASIC> wrapper) {
protected DomainScalar(Wrapper<BASIC> wrapper, JdbcType<?> jdbcType) {
this.wrapper = wrapper;
this.jdbcType = jdbcType;
}

@Override
Expand All @@ -57,6 +68,12 @@ public Optional<Class<?>> getDomainClass() {
return Optional.of(c);
}

@SuppressWarnings("unchecked")
@Override
public Optional<JdbcType<Object>> getJdbcType() {
return Optional.ofNullable((JdbcType<Object>) jdbcType);
}

@Override
public DOMAIN cast(Object value) {
return AbstractDomainType.this.getDomainClass().cast(value);
Expand Down Expand Up @@ -97,9 +114,11 @@ public String toString() {
protected class OptionalDomainScalar implements Scalar<BASIC, Optional<DOMAIN>> {

protected final Wrapper<BASIC> wrapper;
protected final JdbcType<?> jdbcType;

protected OptionalDomainScalar(Wrapper<BASIC> wrapper) {
protected OptionalDomainScalar(Wrapper<BASIC> wrapper, JdbcType<?> jdbcType) {
this.wrapper = wrapper;
this.jdbcType = jdbcType;
}

@Override
Expand All @@ -108,6 +127,12 @@ public Optional<Class<?>> getDomainClass() {
return Optional.of(clazz);
}

@SuppressWarnings("unchecked")
@Override
public Optional<JdbcType<Object>> getJdbcType() {
return Optional.ofNullable((JdbcType<Object>) jdbcType);
}

@SuppressWarnings("unchecked")
@Override
public Optional<DOMAIN> cast(Object value) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package org.seasar.doma.jdbc.domain;

import org.seasar.doma.jdbc.type.JdbcType;

/**
* A JDBC type provider for a domain type.
*
* @param <DOMAIN> the domain type
*/
public abstract class JdbcTypeProvider<DOMAIN> implements DomainConverter<DOMAIN, Object> {

@Override
public final Object fromDomainToValue(DOMAIN domain) {
return domain;
}

@SuppressWarnings("unchecked")
@Override
public final DOMAIN fromValueToDomain(Object value) {
return (DOMAIN) value;
}

/**
* Returns the JDBC type.
*
* @return the JDBC type
*/
public abstract JdbcType<DOMAIN> getJdbcType();
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import org.seasar.doma.internal.jdbc.sql.ScalarInParameter;
import org.seasar.doma.jdbc.InParameter;
import org.seasar.doma.jdbc.Naming;
import org.seasar.doma.jdbc.type.JdbcType;
import org.seasar.doma.wrapper.Wrapper;
import org.seasar.doma.wrapper.WrapperVisitor;

Expand Down Expand Up @@ -233,6 +234,11 @@ public Optional<Class<?>> getDomainClass() {
return scalar.getDomainClass();
}

@Override
public Optional<JdbcType<Object>> getJdbcType() {
return scalar.getJdbcType();
}

@Override
public String toString() {
return scalar.toString();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import org.seasar.doma.internal.apt.cttype.BasicCtType;
import org.seasar.doma.internal.apt.meta.domain.ExternalDomainMeta;
import org.seasar.doma.jdbc.domain.AbstractDomainType;
import org.seasar.doma.jdbc.type.JdbcType;

public class ExternalDomainTypeGenerator extends AbstractGenerator {

Expand Down Expand Up @@ -77,19 +78,25 @@ private void printDomainTypeImplementation() {
}

private void printFields() {
iprint("private static final %1$s converter = new %1$s();%n", domainMeta.getConverterElement());
print("%n");
if (domainMeta.isParameterized()) {
iprint("@SuppressWarnings(\"rawtypes\")%n");
}
iprint("private static final %1$s singleton = new %1$s();%n", simpleName);
print("%n");
iprint("private static final %1$s converter = new %1$s();%n", domainMeta.getConverterElement());
print("%n");
}

private void printConstructors() {
BasicCtType basicCtType = domainMeta.getBasicCtType();
iprint("private %1$s() {%n", simpleName);
iprint(" super(%1$s);%n", basicCtType.getWrapperSupplierCode());
if (domainMeta.isJdbcTypeProvider()) {
iprint(
" super(%1$s, () -> converter.getJdbcType());%n",
basicCtType.getWrapperSupplierCode(), JdbcType.class);
} else {
iprint(" super(%1$s);%n", basicCtType.getWrapperSupplierCode());
}
iprint("}%n");
print("%n");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ public class ExternalDomainMeta implements TypeElementMeta {

private final TypeElement converterElement;

private final boolean isJdbcTypeProvider;

private BasicCtType basicCtType;

private TypeMirror valueType;
Expand All @@ -23,15 +25,20 @@ public class ExternalDomainMeta implements TypeElementMeta {

private TypeParametersDef typeParametersDef;

public ExternalDomainMeta(TypeElement converterElement) {
public ExternalDomainMeta(TypeElement converterElement, boolean isJdbcTypeProvider) {
assertNotNull(converterElement);
this.converterElement = converterElement;
this.isJdbcTypeProvider = isJdbcTypeProvider;
}

public TypeElement getConverterElement() {
return converterElement;
}

public boolean isJdbcTypeProvider() {
return isJdbcTypeProvider;
}

public BasicCtType getBasicCtType() {
return basicCtType;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import org.seasar.doma.internal.apt.def.TypeParametersDef;
import org.seasar.doma.internal.apt.meta.TypeElementMetaFactory;
import org.seasar.doma.jdbc.domain.DomainConverter;
import org.seasar.doma.jdbc.domain.JdbcTypeProvider;
import org.seasar.doma.message.Message;

public class ExternalDomainMetaFactory implements TypeElementMetaFactory<ExternalDomainMeta> {
Expand All @@ -43,7 +44,10 @@ public ExternalDomainMeta createTypeElementMeta(TypeElement converterElement) {
throw new AptIllegalStateException(
"converter doesn't have type args: " + converterElement.getQualifiedName());
}
ExternalDomainMeta meta = new ExternalDomainMeta(converterElement);
boolean isJdbcTypeProvider =
ctx.getMoreTypes()
.isAssignableWithErasure(converterElement.asType(), JdbcTypeProvider.class);
ExternalDomainMeta meta = new ExternalDomainMeta(converterElement, isJdbcTypeProvider);
doDomainType(converterElement, argTypes[0], meta);
doValueType(converterElement, argTypes[1], meta);
return meta;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package org.seasar.doma.internal.apt.processor.domain;

public class Box {}
Loading

0 comments on commit 161384c

Please sign in to comment.