Skip to content

Commit

Permalink
SqlUpdate
Browse files Browse the repository at this point in the history
  • Loading branch information
edward3h committed Sep 20, 2024
1 parent 88c8a18 commit 8d49679
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 9 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package org.ethelred.kiwiproc.processor;

import static org.ethelred.kiwiproc.processor.QueryMethodKind.DEFAULT;
import static org.ethelred.kiwiproc.processor.QueryMethodKind.QUERY;
import static org.ethelred.kiwiproc.processor.QueryMethodKind.*;

import com.karuslabs.utilitary.AnnotationProcessor;
import io.avaje.jsonb.JsonType;
Expand All @@ -22,6 +21,7 @@
import org.ethelred.kiwiproc.meta.ColumnMetaData;
import org.ethelred.kiwiproc.meta.DatabaseWrapper;
import org.ethelred.kiwiproc.meta.ParsedQuery;
import org.ethelred.kiwiproc.meta.QueryMetaData;
import org.ethelred.kiwiproc.processor.generator.PoetDAOGenerator;
import org.ethelred.kiwiproc.processor.types.ContainerType;
import org.ethelred.kiwiproc.processor.types.RecordType;
Expand Down Expand Up @@ -120,8 +120,15 @@ public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment
String daoName, QueryMethodKind kind, DatabaseWrapper databaseWrapper, ExecutableElement methodElement)
throws SQLException {
var parsedSql = ParsedQuery.parse(kind.getSql(methodElement));
var queryMetaData = databaseWrapper.getQueryMetaData(parsedSql.parsedSql());
var parameterInfo = MethodParameterInfo.fromElements(typeUtils, methodElement.getParameters());
QueryMetaData queryMetaData;
try {
queryMetaData = databaseWrapper.getQueryMetaData(parsedSql.parsedSql());
} catch (SQLException e) {
logger.error(methodElement, "\n" + e.getMessage());
return null;
}
var parameterInfo =
MethodParameterInfo.fromElements(Objects.requireNonNull(typeUtils), methodElement.getParameters());
Map<ColumnMetaData, MethodParameterInfo> parameterMapping =
mapParameters(methodElement, parsedSql.parameterNames(), queryMetaData.parameters(), parameterInfo);
var typeValidator = new TypeValidator(logger, methodElement);
Expand Down Expand Up @@ -222,11 +229,15 @@ private void processInterface(TypeElement interfaceElement) throws SQLException
} else if (kinds.size() > 1) {
logger.error(methodElement, "May only have one Sql annotation, or be default.");
}
var kind = kinds.iterator().next();
var kind = kinds.iterator().next(); // get first element
if (kind == DEFAULT) {
continue;
}

if (kind == BATCH) {
logger.error(methodElement, "@SqlBatch is not supported yet. It is planned for Milestone 2.");
}

DAOMethodInfo methodInfo = processMethod(daoName, kinds.iterator().next(), databaseWrapper, methodElement);
if (methodInfo != null) {
builderStage.addMethods(methodInfo);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import org.ethelred.kiwiproc.processor.types.ContainerType;
import org.ethelred.kiwiproc.processor.types.KiwiType;
import org.ethelred.kiwiproc.processor.types.PrimitiveKiwiType;
import org.ethelred.kiwiproc.processor.types.VoidType;

public class InstanceGenerator {

Expand Down Expand Up @@ -80,10 +81,12 @@ private CodeBlock updateMethodBody(DAOMethodInfo methodInfo) {
var builder = builderWithParameters(methodInfo);
builder.addStatement("var rawResult = statement.executeUpdate()");
KiwiType returnType = methodInfo.signature().returnType();
var conversion = lookupConversion(
methodInfo::methodElement, new TypeMapping(new PrimitiveKiwiType("int", false), returnType));
buildConversion(builder, conversion, returnType, "result", "rawResult", true);
builder.addStatement("return result");
if (!(returnType instanceof VoidType)) {
var conversion = lookupConversion(
methodInfo::methodElement, new TypeMapping(new PrimitiveKiwiType("int", false), returnType));
buildConversion(builder, conversion, returnType, "result", "rawResult", true);
builder.addStatement("return result");
}
return builder.build();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@

import java.sql.Connection;
import java.sql.SQLException;
import java.util.regex.Pattern;
import javax.sql.DataSource;
import org.ethelred.kiwiproc.processorconfig.DataSourceConfig;
import org.jspecify.annotations.Nullable;
import org.postgresql.ds.PGSimpleDataSource;

public class DatabaseWrapper {
private static final Pattern SQL_EXCEPTION_POSITION = Pattern.compile("Position: (\\d+)", Pattern.MULTILINE);

@Nullable private Boolean valid;

private DatabaseWrapperException error;
Expand Down Expand Up @@ -68,7 +71,36 @@ public QueryMetaData getQueryMetaData(String sql) throws SQLException {
builder.addParameters(ColumnMetaData.from(connection, index, pmd));
}
return builder.build();
} catch (SQLException e) {
var matcher = SQL_EXCEPTION_POSITION.matcher(e.getMessage());
if (matcher.find()) {
var position = Integer.parseInt(matcher.group(
1)); // NumberFormatException is not expected because the pattern extracts only digits.
var newMessage = insertPosition(position, sql, e.getMessage());
throw new SQLException(newMessage, e);
}
throw e;
}
}

private String insertPosition(int position, String sql, String message) {
var buf = new StringBuilder();
int accumulatedSqlLength = 0;
int lastLineLength = 0;
for (var line : sql.split("\\R")) {
int before = accumulatedSqlLength;
accumulatedSqlLength += line.length() + 1;
lastLineLength = line.length();
buf.append(line).append("\n");
if (before <= position && accumulatedSqlLength >= position) {
buf.append(" ".repeat(position - before - 1)).append("^").append("\n");
}
}
if (position > accumulatedSqlLength) {
buf.append(" ".repeat(lastLineLength)).append("^\n");
}
buf.append(message);
return buf.toString();
}

private void testConnection() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,4 +73,9 @@ INSERT INTO visits (pet_id, visit_date, description)
SET description = :description
WHERE id = :id""")
int setVisitDescription(int id, String description);

@SqlUpdate("""
INSERT INTO vets(first_name, last_name)
VALUES (:firstName, :lastName)""")
void addVet(String firstName, String lastName);
}
1 change: 1 addition & 0 deletions test-spring/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Spring testing is planned for Milestone 2.

0 comments on commit 8d49679

Please sign in to comment.