ConverterColumnNative.java
/*
* SPDX-FileCopyrightText: 2025 kaumei.io
* SPDX-License-Identifier: Apache-2.0
*/
package io.kaumei.jdbc.anno.jdbc2java;
import com.palantir.javapoet.CodeBlock;
import io.kaumei.jdbc.anno.gen.TargetMethod;
import io.kaumei.jdbc.anno.model.*;
import io.kaumei.jdbc.anno.store.SourceDV;
import org.jspecify.annotations.Nullable;
import javax.lang.model.type.TypeMirror;
import java.sql.JDBCType;
import java.util.Map;
import java.util.Optional;
import static java.util.Objects.requireNonNull;
final class ConverterColumnNative extends Jdbc2JavaConverter.ColumnConverter implements Jdbc2JavaConverter.Callable {
static ConverterColumnNative fromResultSet(TypeMirror type, String methodName, JDBCType jdbcType) {
var source = SourceDV.generic("ResultSet." + methodName);
return new ConverterColumnNative(type, source, null, methodName, SQLTypeDV.of(jdbcType));
}
static ConverterColumnNative fromStatic(TypeMirror type, Class<?> cls, String methodName, JDBCType jdbcType) {
var source = SourceDV.generic(cls.getSimpleName() + "." + methodName);
return new ConverterColumnNative(type, source, cls, methodName, SQLTypeDV.of(jdbcType));
}
// ------------------------------------------------------------------------
private final @Nullable Class<?> cls;
private final String methodName;
private final boolean isPrimitive;
private final SQLTypeDV sqlType;
private ConverterColumnNative(TypeMirror type, SourceDV source, @Nullable Class<?> cls, String methodName, SQLTypeDV sqlType) {
super(type, source, Visibility.PUBLIC_VISIBILITY);
this.cls = cls;
this.methodName = requireNonNull(methodName);
this.isPrimitive = this.type().getKind().isPrimitive();
this.sqlType = sqlType;
}
// ------------------------------------------------------------------------
@Override
public boolean hasSqlType() {
return true;
}
@Override
public SQLTypeDV sqlType() {
return sqlType;
}
@Override
public CodeBlock columnNullCheck(String varName) {
return this.isPrimitive
? CodeBlock.of("rs.wasNull()")
: CodeBlock.of("($L == null || rs.wasNull())", varName);
}
@Override
public CodeBlock callNullCheck(String varName) {
return this.isPrimitive
? CodeBlock.of("stmt.wasNull()")
: CodeBlock.of("($L == null || stmt.wasNull())", varName);
}
@Override
public void addColumnByIndex(TargetMethod builder, String localVarName, ColumnIndex index, OptionalFlag optional) {
builder.addComment("ConverterColumnNative.addColumnByIndex", "type", type(), "optional", optional);
if (cls == null) {
setLocalVar(builder, localVarName, optional, CodeBlock.of("rs.$N($L)", methodName, index.columnIndexVar()));
} else {
setLocalVar(builder, localVarName, optional, CodeBlock.of("$T.$N(rs, $L)", cls, methodName, index.columnIndexVar()));
}
if (optional.isNonNull()) {
builder.beginControlFlow("if($L)", columnNullCheck(localVarName));
builder.addThrowColumnWasNull(index);
builder.endControlFlow();
}
}
@Override
public void addColumnByName(TargetMethod builder, String localVarName, SQLNameDV columnName, OptionalFlag optional) {
builder.addComment("ConverterColumnNative.addColumnByName", "type", type(), "optional", optional);
if (cls == null) {
setLocalVar(builder, localVarName, optional, CodeBlock.of("rs.$N($S)", methodName, columnName.value()));
} else {
setLocalVar(builder, localVarName, optional, CodeBlock.of("$T.$N(rs, $S)", cls, methodName, columnName.value()));
}
if (optional.isNonNull()) {
builder.beginControlFlow("if($L)", columnNullCheck(localVarName));
builder.addStatement("throw new $T($S)", NullPointerException.class, "JDBC column was null on name: " + columnName.value());
builder.endControlFlow();
}
}
@Override
public void addCallToRow(TargetMethod builder, String localVarName, OptionalFlag optional, Map<String, ColumnIndex> map) {
builder.addComment("ConverterColumnNative.addCallableOutput", "type", type(), "map", map, "optional", optional);
var index = map.values().iterator().next();
if (cls == null) {
setLocalVar(builder, localVarName, optional, CodeBlock.of("stmt.$N($L)", methodName, index.columnIndexVar()));
} else {
setLocalVar(builder, localVarName, optional, CodeBlock.of("$T.$N(stmt, $L)", cls, methodName, index.columnIndexVar()));
}
if (optional.isNonNull()) {
builder.beginControlFlow("if($L)", callNullCheck(localVarName));
builder.addThrowColumnWasNull(index);
builder.endControlFlow();
}
}
private void setLocalVar(TargetMethod builder, String localVarName, OptionalFlag optional, CodeBlock code) {
if (optional.isOptionalType()) {
builder.addStatement("var $L = $T.ofNullable($L)", localVarName, Optional.class, code);
} else {
builder.addStatement("var $L = $L", localVarName, code);
}
}
}