diff --git a/.github/workflows/formatting.yml b/.github/workflows/formatting.yml
new file mode 100644
index 0000000..4c72b35
--- /dev/null
+++ b/.github/workflows/formatting.yml
@@ -0,0 +1,35 @@
+name: Formatting
+
+on:
+ pull_request:
+ branches:
+ - master
+
+permissions:
+ contents: read
+
+concurrency:
+ group: formatting-${{ github.event.pull_request.number }}
+ cancel-in-progress: true
+
+jobs:
+ spotless:
+ name: Spotless check
+ runs-on: ubuntu-latest
+ timeout-minutes: 10
+ steps:
+ - name: Check out repository
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
+ with:
+ persist-credentials: false
+
+ - name: Set up Java 21
+ uses: actions/setup-java@de7274f081f381c8f8158605e0321c36c376e2e6
+ with:
+ distribution: temurin
+ java-version: "21"
+ cache: maven
+ cache-dependency-path: pom.xml
+
+ - name: Check formatting
+ run: mvn --batch-mode --no-transfer-progress spotless:check
diff --git a/config/eclipse-java-formatter.xml b/config/eclipse-java-formatter.xml
new file mode 100644
index 0000000..fa39f02
--- /dev/null
+++ b/config/eclipse-java-formatter.xml
@@ -0,0 +1,528 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pom.xml b/pom.xml
index 5f859c4..5354a50 100644
--- a/pom.xml
+++ b/pom.xml
@@ -14,6 +14,8 @@
21
UTF-8
+ 3.10.2
+ 4.40
@@ -48,6 +50,35 @@
+
+ com.diffplug.spotless
+ spotless-maven-plugin
+ ${spotless.plugin.version}
+
+
+
+ ${spotless.eclipse.version}
+ ${project.basedir}/config/eclipse-java-formatter.xml
+
+
+
+ module |,jakarta|javax|java,\#
+
+
+
+
+
+
+
+
+ spotless-check
+ validate
+
+ check
+
+
+
+
org.apache.maven.plugins
maven-jar-plugin
diff --git a/src/main/java/dev/sqlcj/analysis/QueryAnalyzer.java b/src/main/java/dev/sqlcj/analysis/QueryAnalyzer.java
index e5c1a8c..a836b11 100644
--- a/src/main/java/dev/sqlcj/analysis/QueryAnalyzer.java
+++ b/src/main/java/dev/sqlcj/analysis/QueryAnalyzer.java
@@ -47,43 +47,38 @@ public QueryModel analyze(Query query, Statement statement, Schema schema) {
}
throw new UnsupportedOperationException(
- statement.getClass().getSimpleName()
+ statement.getClass().getSimpleName()
);
}
- private QueryModel analyzeSelect(
- Query query,
- Select select,
- Schema schema
- ) {
+ private QueryModel analyzeSelect(Query query, Select select, Schema schema) {
PlainSelect plainSelect = select.getPlainSelect();
Table table = getTable(plainSelect);
List columns = resolveColumns(
- plainSelect,
- schema,
- table
+ plainSelect,
+ schema,
+ table
);
- List bindingParameters =
- resolveBindingParameters(plainSelect, schema, table);
+ List bindingParameters = resolveBindingParameters(plainSelect, schema, table);
List bindingParameterIndexes = bindingParameters.stream()
- .map(QueryParameter::index)
- .toList();
+ .map(QueryParameter::index)
+ .toList();
List parameters = bindingParameters.stream()
- .sorted(Comparator.comparingInt(QueryParameter::index))
- .toList();
+ .sorted(Comparator.comparingInt(QueryParameter::index))
+ .toList();
return new QueryModel(
- query.name(),
- query.type(),
- table.getName(),
- toExecutableSql(query.sql()),
- bindingParameterIndexes,
- columns,
- parameters
+ query.name(),
+ query.type(),
+ table.getName(),
+ toExecutableSql(query.sql()),
+ bindingParameterIndexes,
+ columns,
+ parameters
);
}
@@ -104,33 +99,28 @@ private Table getTable(PlainSelect plainSelect) {
* encountered, which is the JDBC binding order of the generated {@code ?}
* positions.
*/
- private List resolveBindingParameters(
- PlainSelect plainSelect,
- Schema schema,
- Table table
- ) {
+ private List resolveBindingParameters(PlainSelect plainSelect, Schema schema, Table table) {
if (plainSelect.getWhere() == null) {
return List.of();
}
- dev.sqlcj.schema.Table schemaTable =
- findTable(schema, table.getName());
+ dev.sqlcj.schema.Table schemaTable = findTable(schema, table.getName());
List parameters = new ArrayList<>();
resolveParameters(
- plainSelect.getWhere(),
- schemaTable,
- parameters
+ plainSelect.getWhere(),
+ schemaTable,
+ parameters
);
return parameters;
}
private void resolveParameters(
- Expression expression,
- dev.sqlcj.schema.Table table,
- List parameters
+ Expression expression,
+ dev.sqlcj.schema.Table table,
+ List parameters
) {
if (expression instanceof AndExpression and) {
resolveParameters(and.getLeftExpression(), table, parameters);
@@ -147,9 +137,9 @@ private void resolveParameters(
if (expression instanceof ParenthesedExpressionList> parentheses) {
for (Expression nestedExpression : parentheses) {
resolveParameters(
- nestedExpression,
- table,
- parameters
+ nestedExpression,
+ table,
+ parameters
);
}
return;
@@ -162,26 +152,20 @@ private void resolveParameters(
if (expression instanceof ComparisonOperator comparison) {
resolveParameterComparison(
- comparison.getLeftExpression(),
- comparison.getRightExpression(),
- table,
- parameters
+ comparison.getLeftExpression(),
+ comparison.getRightExpression(),
+ table,
+ parameters
);
}
}
- private void resolveInExpression(
- InExpression in,
- dev.sqlcj.schema.Table table,
- List parameters
- ) {
- if (!(in.getLeftExpression()
- instanceof net.sf.jsqlparser.schema.Column column)) {
+ private void resolveInExpression(InExpression in, dev.sqlcj.schema.Table table, List parameters) {
+ if (!(in.getLeftExpression() instanceof net.sf.jsqlparser.schema.Column column)) {
return;
}
- dev.sqlcj.schema.Column schemaColumn =
- findColumn(table, column.getColumnName());
+ dev.sqlcj.schema.Column schemaColumn = findColumn(table, column.getColumnName());
Expression rightExpression = in.getRightExpression();
@@ -196,18 +180,18 @@ private void resolveInExpression(
}
resolveInExpression(
- rightExpression,
- schemaColumn,
- table,
- parameters
+ rightExpression,
+ schemaColumn,
+ table,
+ parameters
);
}
private void resolveInExpression(
- Expression expression,
- dev.sqlcj.schema.Column schemaColumn,
- dev.sqlcj.schema.Table table,
- List parameters
+ Expression expression,
+ dev.sqlcj.schema.Column schemaColumn,
+ dev.sqlcj.schema.Table table,
+ List parameters
) {
if (expression instanceof JdbcParameter parameter) {
addParameter(parameter, schemaColumn, parameters);
@@ -216,17 +200,17 @@ private void resolveInExpression(
if (expression instanceof AndExpression and) {
resolveInExpression(
- and.getLeftExpression(),
- schemaColumn,
- table,
- parameters
+ and.getLeftExpression(),
+ schemaColumn,
+ table,
+ parameters
);
resolveInExpression(
- and.getRightExpression(),
- schemaColumn,
- table,
- parameters
+ and.getRightExpression(),
+ schemaColumn,
+ table,
+ parameters
);
return;
@@ -234,17 +218,17 @@ private void resolveInExpression(
if (expression instanceof OrExpression or) {
resolveInExpression(
- or.getLeftExpression(),
- schemaColumn,
- table,
- parameters
+ or.getLeftExpression(),
+ schemaColumn,
+ table,
+ parameters
);
resolveInExpression(
- or.getRightExpression(),
- schemaColumn,
- table,
- parameters
+ or.getRightExpression(),
+ schemaColumn,
+ table,
+ parameters
);
return;
@@ -256,9 +240,9 @@ private void resolveInExpression(
addParameter(parameter, schemaColumn, parameters);
} else {
resolveParameters(
- nestedExpression,
- table,
- parameters
+ nestedExpression,
+ table,
+ parameters
);
}
}
@@ -266,74 +250,70 @@ private void resolveInExpression(
}
private void resolveParameterComparison(
- Expression left,
- Expression right,
- dev.sqlcj.schema.Table table,
- List parameters
+ Expression left,
+ Expression right,
+ dev.sqlcj.schema.Table table,
+ List parameters
) {
- if (left instanceof net.sf.jsqlparser.schema.Column column
- && right instanceof JdbcParameter parameter) {
-
+ if (
+ left instanceof net.sf.jsqlparser.schema.Column column
+ && right instanceof JdbcParameter parameter
+ ) {
addParameter(
- parameter,
- column.getColumnName(),
- table,
- parameters
+ parameter,
+ column.getColumnName(),
+ table,
+ parameters
);
return;
}
- if (left instanceof JdbcParameter parameter
- && right instanceof net.sf.jsqlparser.schema.Column column) {
-
+ if (
+ left instanceof JdbcParameter parameter
+ && right instanceof net.sf.jsqlparser.schema.Column column
+ ) {
addParameter(
- parameter,
- column.getColumnName(),
- table,
- parameters
+ parameter,
+ column.getColumnName(),
+ table,
+ parameters
);
}
}
private void addParameter(
- JdbcParameter parameter,
- String columnName,
- dev.sqlcj.schema.Table table,
- List parameters
+ JdbcParameter parameter,
+ String columnName,
+ dev.sqlcj.schema.Table table,
+ List parameters
) {
- dev.sqlcj.schema.Column column =
- findColumn(table, columnName);
+ dev.sqlcj.schema.Column column = findColumn(table, columnName);
parameters.add(
- new QueryParameter(
- parameter.getIndex(),
- column.name(),
- column.type()
- )
+ new QueryParameter(
+ parameter.getIndex(),
+ column.name(),
+ column.type()
+ )
);
}
private void addParameter(
- JdbcParameter parameter,
- dev.sqlcj.schema.Column column,
- List parameters
+ JdbcParameter parameter,
+ dev.sqlcj.schema.Column column,
+ List parameters
) {
parameters.add(
- new QueryParameter(
- parameter.getIndex(),
- column.name(),
- column.type()
- )
+ new QueryParameter(
+ parameter.getIndex(),
+ column.name(),
+ column.type()
+ )
);
}
- private List resolveColumns(
- PlainSelect plainSelect,
- Schema schema,
- Table table
- ) {
- dev.sqlcj.schema.Table schemaTable =
- findTable(schema, table.getName());
+ private List resolveColumns(PlainSelect plainSelect, Schema schema, Table table) {
+ dev.sqlcj.schema.Table schemaTable = findTable(schema, table.getName());
List columns = new ArrayList<>();
@@ -343,72 +323,63 @@ private List resolveColumns(
continue;
}
- if (selectItem.getExpression()
- instanceof net.sf.jsqlparser.schema.Column column) {
-
- dev.sqlcj.schema.Column schemaColumn =
- findColumn(schemaTable, column.getColumnName());
+ if (selectItem.getExpression() instanceof net.sf.jsqlparser.schema.Column column) {
+ dev.sqlcj.schema.Column schemaColumn = findColumn(schemaTable, column.getColumnName());
columns.add(
- new QueryColumn(
- schemaColumn.name(),
- schemaColumn.type(),
- schemaColumn.nullable()
- )
+ new QueryColumn(
+ schemaColumn.name(),
+ schemaColumn.type(),
+ schemaColumn.nullable()
+ )
);
continue;
}
throw new UnsupportedOperationException(
- "Unsupported SELECT expression: "
- + selectItem.getExpression().getClass().getSimpleName()
+ "Unsupported SELECT expression: "
+ + selectItem.getExpression().getClass().getSimpleName()
);
}
return columns;
}
- private dev.sqlcj.schema.Table findTable(
- Schema schema,
- String tableName
- ) {
+ private dev.sqlcj.schema.Table findTable(Schema schema, String tableName) {
return schema.tables().stream()
- .filter(table -> table.name().equalsIgnoreCase(tableName))
- .findFirst()
- .orElseThrow(() ->
- new IllegalArgumentException(
- "Table not found in schema: " + tableName
- )
- );
+ .filter(table -> table.name().equalsIgnoreCase(tableName))
+ .findFirst()
+ .orElseThrow(
+ () -> new IllegalArgumentException(
+ "Table not found in schema: " + tableName
+ )
+ );
}
- private List resolveAllColumns(
- dev.sqlcj.schema.Table table
- ) {
+ private List resolveAllColumns(dev.sqlcj.schema.Table table) {
return table.columns().stream()
- .map(column -> new QueryColumn(
- column.name(),
- column.type(),
- column.nullable()
- ))
- .toList();
+ .map(
+ column -> new QueryColumn(
+ column.name(),
+ column.type(),
+ column.nullable()
+ )
+ )
+ .toList();
}
- private dev.sqlcj.schema.Column findColumn(
- dev.sqlcj.schema.Table table,
- String columnName
- ) {
+ private dev.sqlcj.schema.Column findColumn(dev.sqlcj.schema.Table table, String columnName) {
return table.columns().stream()
- .filter(column -> column.name().equalsIgnoreCase(columnName))
- .findFirst()
- .orElseThrow(() ->
- new IllegalArgumentException(
- "Column not found in table "
- + table.name()
- + ": "
- + columnName
- )
- );
+ .filter(column -> column.name().equalsIgnoreCase(columnName))
+ .findFirst()
+ .orElseThrow(
+ () -> new IllegalArgumentException(
+ "Column not found in table "
+ + table.name()
+ + ": "
+ + columnName
+ )
+ );
}
}
diff --git a/src/main/java/dev/sqlcj/analysis/QueryColumn.java b/src/main/java/dev/sqlcj/analysis/QueryColumn.java
index ecbbc16..c4279fe 100644
--- a/src/main/java/dev/sqlcj/analysis/QueryColumn.java
+++ b/src/main/java/dev/sqlcj/analysis/QueryColumn.java
@@ -3,8 +3,8 @@
import dev.sqlcj.schema.ColumnType;
public record QueryColumn(
- String name,
- ColumnType type,
- boolean nullable
+ String name,
+ ColumnType type,
+ boolean nullable
) {
}
diff --git a/src/main/java/dev/sqlcj/analysis/QueryModel.java b/src/main/java/dev/sqlcj/analysis/QueryModel.java
index 3133bf4..1ba9fbc 100644
--- a/src/main/java/dev/sqlcj/analysis/QueryModel.java
+++ b/src/main/java/dev/sqlcj/analysis/QueryModel.java
@@ -14,12 +14,12 @@
* @param parameters query parameters in logical placeholder-index order
*/
public record QueryModel(
- String name,
- QueryType type,
- String table,
- String executableSql,
- List bindingParameterIndexes,
- List columns,
- List parameters
+ String name,
+ QueryType type,
+ String table,
+ String executableSql,
+ List bindingParameterIndexes,
+ List columns,
+ List parameters
) {
}
diff --git a/src/main/java/dev/sqlcj/analysis/QueryParameter.java b/src/main/java/dev/sqlcj/analysis/QueryParameter.java
index f4a3183..6db0090 100644
--- a/src/main/java/dev/sqlcj/analysis/QueryParameter.java
+++ b/src/main/java/dev/sqlcj/analysis/QueryParameter.java
@@ -3,8 +3,8 @@
import dev.sqlcj.schema.ColumnType;
public record QueryParameter(
- int index,
- String name,
- ColumnType type
+ int index,
+ String name,
+ ColumnType type
) {
}
diff --git a/src/main/java/dev/sqlcj/cli/SqlcjCommand.java b/src/main/java/dev/sqlcj/cli/SqlcjCommand.java
index 4104e4d..9d734db 100644
--- a/src/main/java/dev/sqlcj/cli/SqlcjCommand.java
+++ b/src/main/java/dev/sqlcj/cli/SqlcjCommand.java
@@ -2,16 +2,16 @@
import dev.sqlcj.cli.command.GenerateCommand;
import dev.sqlcj.cli.command.VersionCommand;
-import picocli.CommandLine;
+import picocli.CommandLine.Command;
-@CommandLine.Command(
- name = "sqlcj",
- mixinStandardHelpOptions = true,
- description = "SQL compiler and type-safe code generator for Java",
- subcommands = {
- VersionCommand.class,
- GenerateCommand.class
- }
+@Command(
+ name = "sqlcj",
+ mixinStandardHelpOptions = true,
+ description = "SQL compiler and type-safe code generator for Java",
+ subcommands = {
+ VersionCommand.class,
+ GenerateCommand.class
+ }
)
public class SqlcjCommand implements Runnable {
diff --git a/src/main/java/dev/sqlcj/cli/command/GenerateCommand.java b/src/main/java/dev/sqlcj/cli/command/GenerateCommand.java
index 1f580a0..7a2af0f 100644
--- a/src/main/java/dev/sqlcj/cli/command/GenerateCommand.java
+++ b/src/main/java/dev/sqlcj/cli/command/GenerateCommand.java
@@ -7,13 +7,16 @@
import dev.sqlcj.config.ConfigurationException;
import dev.sqlcj.config.YamlConfigLoader;
import picocli.CommandLine;
+import picocli.CommandLine.Command;
+import picocli.CommandLine.Model.CommandSpec;
+import picocli.CommandLine.Spec;
import java.nio.file.Path;
import java.util.concurrent.Callable;
-@CommandLine.Command(
- name = "generate",
- description = "Generate Java sources from SQL queries"
+@Command(
+ name = "generate",
+ description = "Generate Java sources from SQL queries"
)
public class GenerateCommand implements Callable {
@@ -21,8 +24,8 @@ public class GenerateCommand implements Callable {
private final ConfigLoader configLoader = new YamlConfigLoader();
- @CommandLine.Spec
- CommandLine.Model.CommandSpec spec;
+ @Spec
+ CommandSpec spec;
@Override
public Integer call() {
@@ -33,8 +36,8 @@ public Integer call() {
return CommandLine.ExitCode.OK;
} catch (ConfigurationException | CompilationException e) {
spec.commandLine()
- .getErr()
- .println("sqlcj: " + e.getMessage());
+ .getErr()
+ .println("sqlcj: " + e.getMessage());
return CommandLine.ExitCode.SOFTWARE;
}
diff --git a/src/main/java/dev/sqlcj/cli/command/VersionCommand.java b/src/main/java/dev/sqlcj/cli/command/VersionCommand.java
index 8574f5f..24b6179 100644
--- a/src/main/java/dev/sqlcj/cli/command/VersionCommand.java
+++ b/src/main/java/dev/sqlcj/cli/command/VersionCommand.java
@@ -1,11 +1,11 @@
package dev.sqlcj.cli.command;
import dev.sqlcj.Main;
-import picocli.CommandLine;
+import picocli.CommandLine.Command;
-@CommandLine.Command(
- name = "version",
- description = "Print SQLCJ version"
+@Command(
+ name = "version",
+ description = "Print SQLCJ version"
)
public class VersionCommand implements Runnable {
diff --git a/src/main/java/dev/sqlcj/compiler/CompilationException.java b/src/main/java/dev/sqlcj/compiler/CompilationException.java
index dc6b733..9b318ab 100644
--- a/src/main/java/dev/sqlcj/compiler/CompilationException.java
+++ b/src/main/java/dev/sqlcj/compiler/CompilationException.java
@@ -9,10 +9,7 @@ public CompilationException(String message) {
super(message);
}
- public CompilationException(
- String message,
- Throwable cause
- ) {
+ public CompilationException(String message, Throwable cause) {
super(message, cause);
}
}
diff --git a/src/main/java/dev/sqlcj/compiler/DefaultSourceLoader.java b/src/main/java/dev/sqlcj/compiler/DefaultSourceLoader.java
index 9c226d9..e85dfff 100644
--- a/src/main/java/dev/sqlcj/compiler/DefaultSourceLoader.java
+++ b/src/main/java/dev/sqlcj/compiler/DefaultSourceLoader.java
@@ -35,8 +35,8 @@ public List load(Config config) {
for (Query query : queries) {
if (!queryNames.add(query.name())) {
throw new CompilationException(
- "Duplicate query name '%s' in query source: %s"
- .formatted(query.name(), queriesPath)
+ "Duplicate query name '%s' in query source: %s"
+ .formatted(query.name(), queriesPath)
);
}
}
@@ -47,30 +47,24 @@ public List load(Config config) {
return sources;
}
- private String read(
- Path path,
- String kind
- ) {
+ private String read(Path path, String kind) {
try {
return fileLoader.read(path);
} catch (IOException e) {
throw new CompilationException(
- "Cannot read %s source: %s".formatted(kind, path),
- e
+ "Cannot read %s source: %s".formatted(kind, path),
+ e
);
}
}
- private List parse(
- String querySource,
- Path queriesPath
- ) {
+ private List parse(String querySource, Path queriesPath) {
try {
return queryParser.parse(querySource);
} catch (IllegalArgumentException e) {
throw new CompilationException(
- "Invalid query source %s: %s".formatted(queriesPath, e.getMessage()),
- e
+ "Invalid query source %s: %s".formatted(queriesPath, e.getMessage()),
+ e
);
}
}
diff --git a/src/main/java/dev/sqlcj/compiler/Source.java b/src/main/java/dev/sqlcj/compiler/Source.java
index 796fd79..5883fe0 100644
--- a/src/main/java/dev/sqlcj/compiler/Source.java
+++ b/src/main/java/dev/sqlcj/compiler/Source.java
@@ -5,7 +5,7 @@
import java.util.List;
public record Source(
- String schema,
- List queries
+ String schema,
+ List queries
) {
}
diff --git a/src/main/java/dev/sqlcj/compiler/SqlcjCompiler.java b/src/main/java/dev/sqlcj/compiler/SqlcjCompiler.java
index 950871c..ddc95bb 100644
--- a/src/main/java/dev/sqlcj/compiler/SqlcjCompiler.java
+++ b/src/main/java/dev/sqlcj/compiler/SqlcjCompiler.java
@@ -32,8 +32,7 @@ public final class SqlcjCompiler {
public void compile(Config config) {
List sources = sourceLoader.load(config);
- CodeGenerator codeGenerator =
- new JavaCodeGenerator(config.java().packageName());
+ CodeGenerator codeGenerator = new JavaCodeGenerator(config.java().packageName());
Path outputDirectory = Path.of(config.java().out());
@@ -44,22 +43,22 @@ public void compile(Config config) {
for (Query query : source.queries()) {
compileQuery(
- query,
- schema,
- codeGenerator,
- outputDirectory,
- generatedPaths
+ query,
+ schema,
+ codeGenerator,
+ outputDirectory,
+ generatedPaths
);
}
}
}
private void compileQuery(
- Query query,
- Schema schema,
- CodeGenerator codeGenerator,
- Path outputDirectory,
- Set generatedPaths
+ Query query,
+ Schema schema,
+ CodeGenerator codeGenerator,
+ Path outputDirectory,
+ Set generatedPaths
) {
Statement statement = sqlParser.parse(query.sql());
QueryModel model = queryAnalyzer.analyze(query, statement, schema);
@@ -67,17 +66,14 @@ private void compileQuery(
if (!generatedPaths.add(file.path())) {
throw new CompilationException(
- "Duplicate generated file: " + file.path()
+ "Duplicate generated file: " + file.path()
);
}
write(file, outputDirectory);
}
- private void write(
- GeneratedFile file,
- Path outputDirectory
- ) {
+ private void write(GeneratedFile file, Path outputDirectory) {
try {
generatedFileWriter.write(file, outputDirectory);
} catch (IOException e) {
diff --git a/src/main/java/dev/sqlcj/config/Config.java b/src/main/java/dev/sqlcj/config/Config.java
index 76d28bb..6003907 100644
--- a/src/main/java/dev/sqlcj/config/Config.java
+++ b/src/main/java/dev/sqlcj/config/Config.java
@@ -3,17 +3,21 @@
import java.util.List;
public record Config(
- String version,
- List sql,
- JavaConfig java
+ String version,
+ List sql,
+ JavaConfig java
) {
public static final String VERSION_1 = "1";
public Config(
- List sql,
- JavaConfig java
+ List sql,
+ JavaConfig java
) {
- this(VERSION_1, sql, java);
+ this(
+ VERSION_1,
+ sql,
+ java
+ );
}
}
diff --git a/src/main/java/dev/sqlcj/config/ConfigValidator.java b/src/main/java/dev/sqlcj/config/ConfigValidator.java
index 0522c82..cd66fee 100644
--- a/src/main/java/dev/sqlcj/config/ConfigValidator.java
+++ b/src/main/java/dev/sqlcj/config/ConfigValidator.java
@@ -10,34 +10,25 @@
*/
final class ConfigValidator {
- void validate(
- Config config,
- Path configFile
- ) {
+ void validate(Config config, Path configFile) {
validateVersion(config.version(), configFile);
validateSql(config.sql(), configFile);
validateJava(config.java(), configFile);
}
- private void validateVersion(
- String version,
- Path configFile
- ) {
+ private void validateVersion(String version, Path configFile) {
requireValue(version, "version", configFile);
if (!Config.VERSION_1.equals(version)) {
throw invalid(
- configFile,
- "unsupported 'version' value '%s', expected '%s'"
- .formatted(version, Config.VERSION_1)
+ configFile,
+ "unsupported 'version' value '%s', expected '%s'"
+ .formatted(version, Config.VERSION_1)
);
}
}
- private void validateSql(
- List sql,
- Path configFile
- ) {
+ private void validateSql(List sql, Path configFile) {
if (sql == null) {
throw invalid(configFile, "'sql' is required");
}
@@ -58,10 +49,7 @@ private void validateSql(
}
}
- private void validateJava(
- JavaConfig java,
- Path configFile
- ) {
+ private void validateJava(JavaConfig java, Path configFile) {
if (java == null) {
throw invalid(configFile, "'java' is required");
}
@@ -71,18 +59,14 @@ private void validateJava(
if (!SourceVersion.isName(java.packageName())) {
throw invalid(
- configFile,
- "'java.package' value '%s' is not a valid Java package name"
- .formatted(java.packageName())
+ configFile,
+ "'java.package' value '%s' is not a valid Java package name"
+ .formatted(java.packageName())
);
}
}
- private void requireValue(
- String value,
- String field,
- Path configFile
- ) {
+ private void requireValue(String value, String field, Path configFile) {
if (value == null) {
throw invalid(configFile, "'%s' is required".formatted(field));
}
@@ -92,12 +76,9 @@ private void requireValue(
}
}
- private ConfigurationException invalid(
- Path configFile,
- String detail
- ) {
+ private ConfigurationException invalid(Path configFile, String detail) {
return new ConfigurationException(
- "Invalid configuration in %s: %s".formatted(configFile, detail)
+ "Invalid configuration in %s: %s".formatted(configFile, detail)
);
}
}
diff --git a/src/main/java/dev/sqlcj/config/ConfigurationException.java b/src/main/java/dev/sqlcj/config/ConfigurationException.java
index 0f81153..5dff6b0 100644
--- a/src/main/java/dev/sqlcj/config/ConfigurationException.java
+++ b/src/main/java/dev/sqlcj/config/ConfigurationException.java
@@ -10,10 +10,7 @@ public ConfigurationException(String message) {
super(message);
}
- public ConfigurationException(
- String message,
- Throwable cause
- ) {
+ public ConfigurationException(String message, Throwable cause) {
super(message, cause);
}
}
diff --git a/src/main/java/dev/sqlcj/config/JavaConfig.java b/src/main/java/dev/sqlcj/config/JavaConfig.java
index 8950823..9607e46 100644
--- a/src/main/java/dev/sqlcj/config/JavaConfig.java
+++ b/src/main/java/dev/sqlcj/config/JavaConfig.java
@@ -3,8 +3,8 @@
import com.fasterxml.jackson.annotation.JsonProperty;
public record JavaConfig(
- String out,
- @JsonProperty("package")
- String packageName
+ String out,
+ @JsonProperty("package")
+ String packageName
) {
}
diff --git a/src/main/java/dev/sqlcj/config/SqlConfig.java b/src/main/java/dev/sqlcj/config/SqlConfig.java
index e57e47c..e9c0a68 100644
--- a/src/main/java/dev/sqlcj/config/SqlConfig.java
+++ b/src/main/java/dev/sqlcj/config/SqlConfig.java
@@ -1,7 +1,7 @@
package dev.sqlcj.config;
public record SqlConfig(
- String schema,
- String queries
+ String schema,
+ String queries
) {
}
diff --git a/src/main/java/dev/sqlcj/config/YamlConfigLoader.java b/src/main/java/dev/sqlcj/config/YamlConfigLoader.java
index cedf0b6..96fadbf 100644
--- a/src/main/java/dev/sqlcj/config/YamlConfigLoader.java
+++ b/src/main/java/dev/sqlcj/config/YamlConfigLoader.java
@@ -21,25 +21,25 @@
public class YamlConfigLoader implements ConfigLoader {
private static final ObjectMapper OBJECT_MAPPER = YAMLMapper.builder()
- .enable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
- .withCoercionConfig(
- LogicalType.Textual,
- coercion -> {
- coercion.setCoercion(
- CoercionInputShape.Integer,
- CoercionAction.Fail
- );
- coercion.setCoercion(
- CoercionInputShape.Float,
- CoercionAction.Fail
- );
- coercion.setCoercion(
- CoercionInputShape.Boolean,
- CoercionAction.Fail
- );
- }
- )
- .build();
+ .enable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
+ .withCoercionConfig(
+ LogicalType.Textual,
+ coercion -> {
+ coercion.setCoercion(
+ CoercionInputShape.Integer,
+ CoercionAction.Fail
+ );
+ coercion.setCoercion(
+ CoercionInputShape.Float,
+ CoercionAction.Fail
+ );
+ coercion.setCoercion(
+ CoercionInputShape.Boolean,
+ CoercionAction.Fail
+ );
+ }
+ )
+ .build();
private final ConfigValidator validator = new ConfigValidator();
@@ -57,7 +57,7 @@ public Config load(Path path) {
private Config read(Path configFile) {
if (!Files.isReadable(configFile)) {
throw new ConfigurationException(
- "Cannot read configuration file: " + configFile
+ "Cannot read configuration file: " + configFile
);
}
@@ -67,22 +67,22 @@ private Config read(Path configFile) {
config = OBJECT_MAPPER.readValue(configFile.toFile(), Config.class);
} catch (UnrecognizedPropertyException e) {
throw new ConfigurationException(
- "Invalid configuration in %s: unknown field '%s'"
- .formatted(configFile, e.getPropertyName()),
- e
+ "Invalid configuration in %s: unknown field '%s'"
+ .formatted(configFile, e.getPropertyName()),
+ e
);
} catch (MismatchedInputException e) {
throw invalidValue(configFile, e);
} catch (JacksonException e) {
throw new ConfigurationException(
- "Malformed configuration file: " + configFile,
- e
+ "Malformed configuration file: " + configFile,
+ e
);
}
if (config == null) {
throw new ConfigurationException(
- "Configuration file is empty: " + configFile
+ "Configuration file is empty: " + configFile
);
}
@@ -94,10 +94,7 @@ private Config read(Path configFile) {
* naming the configuration file, the offending property path, and the
* offending value or type as far as Jackson reports them.
*/
- private ConfigurationException invalidValue(
- Path configFile,
- MismatchedInputException e
- ) {
+ private ConfigurationException invalidValue(Path configFile, MismatchedInputException e) {
StringBuilder detail = new StringBuilder("invalid ");
String property = propertyPath(e);
@@ -108,8 +105,7 @@ private ConfigurationException invalidValue(
detail.append("value");
- if (e instanceof InvalidFormatException format
- && format.getValue() != null) {
+ if (e instanceof InvalidFormatException format && format.getValue() != null) {
detail.append(" '").append(format.getValue()).append("'");
}
@@ -126,8 +122,8 @@ private ConfigurationException invalidValue(
}
return new ConfigurationException(
- "Invalid configuration in %s: %s".formatted(configFile, detail),
- e
+ "Invalid configuration in %s: %s".formatted(configFile, detail),
+ e
);
}
@@ -185,29 +181,25 @@ private String describeExpectedType(Class> targetType) {
return "a value of type " + targetType.getSimpleName();
}
- private Config resolvePaths(
- Config config,
- Path baseDirectory
- ) {
+ private Config resolvePaths(Config config, Path baseDirectory) {
List sql = config.sql().stream()
- .map(entry -> new SqlConfig(
- resolvePath(entry.schema(), baseDirectory),
- resolvePath(entry.queries(), baseDirectory)
- ))
- .toList();
+ .map(
+ entry -> new SqlConfig(
+ resolvePath(entry.schema(), baseDirectory),
+ resolvePath(entry.queries(), baseDirectory)
+ )
+ )
+ .toList();
JavaConfig java = new JavaConfig(
- resolvePath(config.java().out(), baseDirectory),
- config.java().packageName()
+ resolvePath(config.java().out(), baseDirectory),
+ config.java().packageName()
);
return new Config(config.version(), sql, java);
}
- private String resolvePath(
- String value,
- Path baseDirectory
- ) {
+ private String resolvePath(String value, Path baseDirectory) {
Path path = Path.of(value);
if (path.isAbsolute()) {
diff --git a/src/main/java/dev/sqlcj/generator/GeneratedFile.java b/src/main/java/dev/sqlcj/generator/GeneratedFile.java
index 6baf9af..1b0eec8 100644
--- a/src/main/java/dev/sqlcj/generator/GeneratedFile.java
+++ b/src/main/java/dev/sqlcj/generator/GeneratedFile.java
@@ -3,7 +3,7 @@
import java.nio.file.Path;
public record GeneratedFile(
- Path path,
- String content
+ Path path,
+ String content
) {
}
diff --git a/src/main/java/dev/sqlcj/generator/JavaCodeGenerator.java b/src/main/java/dev/sqlcj/generator/JavaCodeGenerator.java
index 0ccd971..c61bfe5 100644
--- a/src/main/java/dev/sqlcj/generator/JavaCodeGenerator.java
+++ b/src/main/java/dev/sqlcj/generator/JavaCodeGenerator.java
@@ -38,8 +38,8 @@ public JavaCodeGenerator(String packageName) {
@Override
public GeneratedFile generate(QueryModel query) {
return new GeneratedFile(
- buildPath(query),
- generateSource(query)
+ buildPath(query),
+ generateSource(query)
);
}
@@ -51,26 +51,27 @@ private Path packageDirectory() {
String[] segments = packageName.split("\\.");
return Path.of(
- segments[0],
- Arrays.copyOfRange(segments, 1, segments.length)
+ segments[0],
+ Arrays.copyOfRange(segments, 1, segments.length)
);
}
private String generateSource(QueryModel query) {
return """
- %s
+ %s
+
+ %s
- %s
+ %s
- %s
-
- %s
- """.formatted(
+ %s
+ """
+ .formatted(
generatePackage(),
generateImports(query),
generateJavaDoc(query),
generateClass(query)
- );
+ );
}
private String generatePackage() {
@@ -88,25 +89,25 @@ private String generateImports(QueryModel query) {
}
query.columns().stream()
- .map(QueryColumn::type)
- .map(this::resolveImport)
- .filter(Objects::nonNull)
- .forEach(imports::add);
+ .map(QueryColumn::type)
+ .map(this::resolveImport)
+ .filter(Objects::nonNull)
+ .forEach(imports::add);
query.parameters().stream()
- .map(QueryParameter::type)
- .map(this::resolveImport)
- .filter(Objects::nonNull)
- .forEach(imports::add);
+ .map(QueryParameter::type)
+ .map(this::resolveImport)
+ .filter(Objects::nonNull)
+ .forEach(imports::add);
return imports.stream()
- .map(type -> "import " + type + ";")
- .collect(Collectors.joining("\n"));
+ .map(type -> "import " + type + ";")
+ .collect(Collectors.joining("\n"));
}
private boolean hasResult(QueryModel query) {
return query.type() == QueryType.ONE
- || query.type() == QueryType.MANY;
+ || query.type() == QueryType.MANY;
}
private String resolveImport(ColumnType type) {
@@ -120,24 +121,25 @@ private String resolveImport(ColumnType type) {
private String generateJavaDoc(QueryModel query) {
return """
- /**
- * Generated by sqlcj.
- *
- * Query: %s
- * Table: %s
- * Type: %s
- */
- """.formatted(
+ /**
+ * Generated by sqlcj.
+ *
+ * Query: %s
+ * Table: %s
+ * Type: %s
+ */
+ """
+ .formatted(
query.name(),
query.table(),
query.type()
- );
+ );
}
private String generateClass(QueryModel query) {
String rowMapper = hasResult(query)
- ? indent(generateRowMapper(query))
- : "";
+ ? indent(generateRowMapper(query))
+ : "";
return """
public final class %s {
@@ -152,14 +154,15 @@ public final class %s {
%s
}
- """.formatted(
+ """
+ .formatted(
query.name(),
indent(generateExecutorField()),
indent(generateConstructor(query)),
indent(generateResultType(query)),
rowMapper,
indent(generateMethod(query))
- );
+ );
}
private String indent(String text) {
@@ -168,69 +171,75 @@ private String indent(String text) {
private String generateResultType(QueryModel query) {
return """
- public record %s(
- %s
- ) {
- }
- """.formatted(
+ public record %s(
+ %s
+ ) {
+ }
+ """
+ .formatted(
generateResultTypeName(query),
generateResultComponents(query)
- );
+ );
}
private String generateResultComponents(QueryModel query) {
return query.columns().stream()
- .map(this::generateResultComponent)
- .collect(Collectors.joining(",\n"));
+ .map(this::generateResultComponent)
+ .collect(Collectors.joining(",\n"));
}
private String generateResultComponent(QueryColumn column) {
- return "%s %s".formatted(
+ return "%s %s"
+ .formatted(
typeResolver.resolve(column.type()),
column.name()
- ).indent(4).stripTrailing();
+ )
+ .indent(4)
+ .stripTrailing();
}
private String generateMethodParameters(QueryModel query) {
List names = generateParameterNames(query);
return IntStream.range(0, query.parameters().size())
- .mapToObj(i -> {
- QueryParameter parameter = query.parameters().get(i);
+ .mapToObj(i -> {
+ QueryParameter parameter = query.parameters().get(i);
- return typeResolver.resolve(parameter.type())
- + " "
- + names.get(i);
- })
- .collect(Collectors.joining(", "));
+ return typeResolver.resolve(parameter.type())
+ + " "
+ + names.get(i);
+ })
+ .collect(Collectors.joining(", "));
}
private List generateParameterNames(QueryModel query) {
Map occurrences = query.parameters().stream()
- .collect(Collectors.groupingBy(
- QueryParameter::name,
- Collectors.counting()
- ));
+ .collect(
+ Collectors.groupingBy(
+ QueryParameter::name,
+ Collectors.counting()
+ )
+ );
Map indexes = new HashMap<>();
return query.parameters().stream()
- .map(parameter -> {
- String name = parameter.name();
+ .map(parameter -> {
+ String name = parameter.name();
- if (occurrences.get(name) > 1) {
- int occurrence = indexes.merge(
- name,
- 1,
- Integer::sum
- );
+ if (occurrences.get(name) > 1) {
+ int occurrence = indexes.merge(
+ name,
+ 1,
+ Integer::sum
+ );
- name += occurrence;
- }
+ name += occurrence;
+ }
- return name;
- })
- .toList();
+ return name;
+ })
+ .toList();
}
private String generateMethod(QueryModel query) {
@@ -242,33 +251,35 @@ private String generateMethod(QueryModel query) {
private String generateQueryMethod(QueryModel query) {
return """
- public %s %s(%s) {
- return executor.%s(
- %s,
- %s,
- ROW_MAPPER
- );
- }
- """.formatted(
+ public %s %s(%s) {
+ return executor.%s(
+ %s,
+ %s,
+ ROW_MAPPER
+ );
+ }
+ """
+ .formatted(
generateReturnType(query),
generateMethodName(query),
generateMethodParameters(query),
generateExecutorMethod(query),
generateSql(query),
generateParameterList(query)
- );
+ );
}
private String generateUnsupportedMethod(QueryModel query) {
return """
- public %s %s(%s) {
- throw new UnsupportedOperationException("Not implemented");
- }
- """.formatted(
+ public %s %s(%s) {
+ throw new UnsupportedOperationException("Not implemented");
+ }
+ """
+ .formatted(
generateReturnType(query),
generateMethodName(query),
generateMethodParameters(query)
- );
+ );
}
private String generateExecutorMethod(QueryModel query) {
@@ -276,15 +287,15 @@ private String generateExecutorMethod(QueryModel query) {
case ONE -> "query";
case MANY -> "queryMany";
default -> throw new IllegalStateException(
- "Query type does not produce a result: " + query.type()
+ "Query type does not produce a result: " + query.type()
);
};
}
private String generateSql(QueryModel query) {
return "\"\"\"\n"
- + query.executableSql()
- + "\"\"\"";
+ + query.executableSql()
+ + "\"\"\"";
}
/**
@@ -295,8 +306,8 @@ private String generateParameterList(QueryModel query) {
Map namesByIndex = generateParameterNamesByIndex(query);
return query.bindingParameterIndexes().stream()
- .map(namesByIndex::get)
- .collect(Collectors.joining(", ", "List.of(", ")"));
+ .map(namesByIndex::get)
+ .collect(Collectors.joining(", ", "List.of(", ")"));
}
private Map generateParameterNamesByIndex(QueryModel query) {
@@ -306,8 +317,8 @@ private Map generateParameterNamesByIndex(QueryModel query) {
for (int i = 0; i < query.parameters().size(); i++) {
namesByIndex.put(
- query.parameters().get(i).index(),
- names.get(i)
+ query.parameters().get(i).index(),
+ names.get(i)
);
}
@@ -340,29 +351,30 @@ private String generateRowMapper(QueryModel query) {
resultSet -> new %s(
%s
);
- """.formatted(
+ """
+ .formatted(
generateResultTypeName(query),
generateResultTypeName(query),
generateResultMappings(query)
- );
+ );
}
private String generateResultMappings(QueryModel query) {
return query.columns().stream()
- .map(this::generateResultMapping)
- .collect(Collectors.joining(",\n"));
+ .map(this::generateResultMapping)
+ .collect(Collectors.joining(",\n"));
}
private String generateResultMapping(QueryColumn column) {
String javaType = typeResolver.resolve(column.type());
return "resultSet.getObject(\"%s\", %s.class)"
- .formatted(
- column.name(),
- javaType
- )
- .indent(8)
- .stripTrailing();
+ .formatted(
+ column.name(),
+ javaType
+ )
+ .indent(8)
+ .stripTrailing();
}
private String generateExecutorField() {
@@ -376,6 +388,7 @@ private String generateConstructor(QueryModel query) {
public %s(QueryExecutor executor) {
this.executor = executor;
}
- """.formatted(query.name());
+ """
+ .formatted(query.name());
}
}
diff --git a/src/main/java/dev/sqlcj/io/GeneratedFileWriter.java b/src/main/java/dev/sqlcj/io/GeneratedFileWriter.java
index 7f096b2..10e0afb 100644
--- a/src/main/java/dev/sqlcj/io/GeneratedFileWriter.java
+++ b/src/main/java/dev/sqlcj/io/GeneratedFileWriter.java
@@ -9,10 +9,7 @@
public final class GeneratedFileWriter {
- public void write(
- GeneratedFile file,
- Path outputDirectory
- ) throws IOException {
+ public void write(GeneratedFile file, Path outputDirectory) throws IOException {
Path outputFile = outputDirectory.resolve(file.path());
Path parent = outputFile.getParent();
@@ -22,10 +19,10 @@ public void write(
}
Files.writeString(
- outputFile,
- file.content(),
- StandardOpenOption.CREATE,
- StandardOpenOption.TRUNCATE_EXISTING
+ outputFile,
+ file.content(),
+ StandardOpenOption.CREATE,
+ StandardOpenOption.TRUNCATE_EXISTING
);
}
}
diff --git a/src/main/java/dev/sqlcj/parser/DefaultQueryParser.java b/src/main/java/dev/sqlcj/parser/DefaultQueryParser.java
index 5cf7b88..535d976 100644
--- a/src/main/java/dev/sqlcj/parser/DefaultQueryParser.java
+++ b/src/main/java/dev/sqlcj/parser/DefaultQueryParser.java
@@ -18,15 +18,12 @@ public List parse(String source) {
StringBuilder builder = new StringBuilder();
for (String line : source.lines().toList()) {
-
if (line.startsWith(HEADER_PREFIX)) {
-
if (currentName != null) {
queries.add(buildQuery(builder, currentName, currentType));
}
QueryHeader header = parseHeader(line);
-
currentName = header.name();
currentType = header.type();
@@ -35,8 +32,9 @@ public List parse(String source) {
}
if (currentName != null) {
- builder.append(line)
- .append(System.lineSeparator());
+ builder
+ .append(line)
+ .append(System.lineSeparator());
}
}
@@ -48,7 +46,7 @@ public List parse(String source) {
for (Query query : queries) {
if (!names.add(query.name())) {
throw new IllegalArgumentException(
- "Duplicate query: " + query.name()
+ "Duplicate query: " + query.name()
);
}
}
@@ -61,14 +59,14 @@ private Query buildQuery(StringBuilder builder, String currentName, QueryType cu
if (sql.isBlank()) {
throw new IllegalArgumentException(
- "Query '" + currentName + "' has no SQL"
+ "Query '" + currentName + "' has no SQL"
);
}
return new Query(
- currentName,
- currentType,
- sql
+ currentName,
+ currentType,
+ sql
);
}
@@ -78,7 +76,7 @@ private QueryHeader parseHeader(String line) {
if (parts.length != 2) {
throw new IllegalArgumentException(
- "Invalid query header: " + line
+ "Invalid query header: " + line
);
}
diff --git a/src/main/java/dev/sqlcj/parser/Query.java b/src/main/java/dev/sqlcj/parser/Query.java
index 081c46a..a6d754a 100644
--- a/src/main/java/dev/sqlcj/parser/Query.java
+++ b/src/main/java/dev/sqlcj/parser/Query.java
@@ -1,8 +1,8 @@
package dev.sqlcj.parser;
public record Query(
- String name,
- QueryType type,
- String sql
+ String name,
+ QueryType type,
+ String sql
) {
}
diff --git a/src/main/java/dev/sqlcj/parser/QueryHeader.java b/src/main/java/dev/sqlcj/parser/QueryHeader.java
index 85297e9..bc34dee 100644
--- a/src/main/java/dev/sqlcj/parser/QueryHeader.java
+++ b/src/main/java/dev/sqlcj/parser/QueryHeader.java
@@ -1,7 +1,7 @@
package dev.sqlcj.parser;
public record QueryHeader(
- String name,
- QueryType type
+ String name,
+ QueryType type
) {
}
diff --git a/src/main/java/dev/sqlcj/runtime/JdbcQueryExecutor.java b/src/main/java/dev/sqlcj/runtime/JdbcQueryExecutor.java
index 23bdcac..95eb55a 100644
--- a/src/main/java/dev/sqlcj/runtime/JdbcQueryExecutor.java
+++ b/src/main/java/dev/sqlcj/runtime/JdbcQueryExecutor.java
@@ -17,15 +17,10 @@ public JdbcQueryExecutor(DataSource dataSource) {
}
@Override
- public T query(
- String sql,
- List> parameters,
- RowMapper mapper
- ) {
+ public T query(String sql, List> parameters, RowMapper mapper) {
try (
- Connection connection = dataSource.getConnection();
- PreparedStatement statement =
- connection.prepareStatement(sql)
+ Connection connection = dataSource.getConnection();
+ PreparedStatement statement = connection.prepareStatement(sql)
) {
bindParameters(statement, parameters);
@@ -38,22 +33,17 @@ public T query(
}
} catch (SQLException e) {
throw new QueryExecutionException(
- "Failed to execute query",
- e
+ "Failed to execute query",
+ e
);
}
}
@Override
- public List queryMany(
- String sql,
- List> parameters,
- RowMapper mapper
- ) {
+ public List queryMany(String sql, List> parameters, RowMapper mapper) {
try (
- Connection connection = dataSource.getConnection();
- PreparedStatement statement =
- connection.prepareStatement(sql)
+ Connection connection = dataSource.getConnection();
+ PreparedStatement statement = connection.prepareStatement(sql)
) {
bindParameters(statement, parameters);
@@ -68,16 +58,13 @@ public List queryMany(
}
} catch (SQLException e) {
throw new QueryExecutionException(
- "Failed to execute query",
- e
+ "Failed to execute query",
+ e
);
}
}
- private void bindParameters(
- PreparedStatement statement,
- List> parameters
- ) throws SQLException {
+ private void bindParameters(PreparedStatement statement, List> parameters) throws SQLException {
for (int i = 0; i < parameters.size(); i++) {
statement.setObject(i + 1, parameters.get(i));
}
diff --git a/src/main/java/dev/sqlcj/runtime/QueryExecutor.java b/src/main/java/dev/sqlcj/runtime/QueryExecutor.java
index a89c615..7448615 100644
--- a/src/main/java/dev/sqlcj/runtime/QueryExecutor.java
+++ b/src/main/java/dev/sqlcj/runtime/QueryExecutor.java
@@ -4,15 +4,7 @@
public interface QueryExecutor {
- T query(
- String sql,
- List> parameters,
- RowMapper mapper
- );
+ T query(String sql, List> parameters, RowMapper mapper);
- List queryMany(
- String sql,
- List> parameters,
- RowMapper mapper
- );
+ List queryMany(String sql, List> parameters, RowMapper mapper);
}
diff --git a/src/main/java/dev/sqlcj/schema/Column.java b/src/main/java/dev/sqlcj/schema/Column.java
index f3dc5f7..5e672cf 100644
--- a/src/main/java/dev/sqlcj/schema/Column.java
+++ b/src/main/java/dev/sqlcj/schema/Column.java
@@ -1,8 +1,8 @@
package dev.sqlcj.schema;
public record Column(
- String name,
- ColumnType type,
- boolean nullable
+ String name,
+ ColumnType type,
+ boolean nullable
) {
}
diff --git a/src/main/java/dev/sqlcj/schema/Constraint.java b/src/main/java/dev/sqlcj/schema/Constraint.java
index 0413394..862ebfc 100644
--- a/src/main/java/dev/sqlcj/schema/Constraint.java
+++ b/src/main/java/dev/sqlcj/schema/Constraint.java
@@ -3,8 +3,8 @@
import java.util.List;
public record Constraint(
- ConstraintType type,
- List columns
+ ConstraintType type,
+ List columns
) {
public Constraint {
diff --git a/src/main/java/dev/sqlcj/schema/Schema.java b/src/main/java/dev/sqlcj/schema/Schema.java
index 9656af2..57b9000 100644
--- a/src/main/java/dev/sqlcj/schema/Schema.java
+++ b/src/main/java/dev/sqlcj/schema/Schema.java
@@ -3,7 +3,7 @@
import java.util.List;
public record Schema(
- List tables
+ List tables
) {
public Schema {
diff --git a/src/main/java/dev/sqlcj/schema/Table.java b/src/main/java/dev/sqlcj/schema/Table.java
index 2ac8534..8029c45 100644
--- a/src/main/java/dev/sqlcj/schema/Table.java
+++ b/src/main/java/dev/sqlcj/schema/Table.java
@@ -3,9 +3,9 @@
import java.util.List;
public record Table(
- String name,
- List columns,
- List constraints
+ String name,
+ List columns,
+ List constraints
) {
public Table {
diff --git a/src/main/java/dev/sqlcj/schema/parser/DefaultSchemaParser.java b/src/main/java/dev/sqlcj/schema/parser/DefaultSchemaParser.java
index a4d91e1..00ccbfa 100644
--- a/src/main/java/dev/sqlcj/schema/parser/DefaultSchemaParser.java
+++ b/src/main/java/dev/sqlcj/schema/parser/DefaultSchemaParser.java
@@ -30,8 +30,8 @@ public Schema parse(String sql) {
for (Statement statement : statements) {
if (!(statement instanceof CreateTable createTable)) {
throw new UnsupportedOperationException(
- "Unsupported schema statement: "
- + statement.getClass().getSimpleName()
+ "Unsupported schema statement: "
+ + statement.getClass().getSimpleName()
);
}
@@ -58,9 +58,9 @@ private Table parseTable(CreateTable createTable) {
constraints.addAll(parseTableConstraints(createTable));
return new Table(
- tableName,
- columns,
- constraints
+ tableName,
+ columns,
+ constraints
);
}
@@ -70,16 +70,16 @@ private Column parseColumn(ColumnDefinition definition) {
boolean nullable = isNullable(definition);
return new Column(
- name,
- type,
- nullable
+ name,
+ type,
+ nullable
);
}
private ColumnType parseColumnType(ColumnDefinition definition) {
String typeName = definition.getColDataType()
- .getDataType()
- .toUpperCase(Locale.ROOT);
+ .getDataType()
+ .toUpperCase(Locale.ROOT);
int parenthesisIndex = typeName.indexOf('(');
@@ -98,7 +98,7 @@ private ColumnType parseColumnType(ColumnDefinition definition) {
case "TIMESTAMP" -> ColumnType.TIMESTAMP;
case "DECIMAL", "NUMERIC" -> ColumnType.DECIMAL;
default -> throw new UnsupportedOperationException(
- "Unsupported SQL column type: " + typeName
+ "Unsupported SQL column type: " + typeName
);
};
}
@@ -111,8 +111,7 @@ private boolean isNullable(ColumnDefinition definition) {
}
for (int i = 0; i < specs.size() - 1; i++) {
- if ("NOT".equalsIgnoreCase(specs.get(i))
- && "NULL".equalsIgnoreCase(specs.get(i + 1))) {
+ if ("NOT".equalsIgnoreCase(specs.get(i)) && "NULL".equalsIgnoreCase(specs.get(i + 1))) {
return false;
}
}
@@ -132,24 +131,22 @@ private List parseColumnConstraints(ColumnDefinition definition) {
for (int i = 0; i < specs.size(); i++) {
String spec = specs.get(i);
- if ("PRIMARY".equalsIgnoreCase(spec)
- && i + 1 < specs.size()
- && "KEY".equalsIgnoreCase(specs.get(i + 1))) {
+ if ("PRIMARY".equalsIgnoreCase(spec) && i + 1 < specs.size() && "KEY".equalsIgnoreCase(specs.get(i + 1))) {
constraints.add(
- new Constraint(
- ConstraintType.PRIMARY_KEY,
- List.of(definition.getColumnName())
- )
+ new Constraint(
+ ConstraintType.PRIMARY_KEY,
+ List.of(definition.getColumnName())
+ )
);
}
if ("UNIQUE".equalsIgnoreCase(spec)) {
constraints.add(
- new Constraint(
- ConstraintType.UNIQUE,
- List.of(definition.getColumnName())
- )
+ new Constraint(
+ ConstraintType.UNIQUE,
+ List.of(definition.getColumnName())
+ )
);
}
}
@@ -173,15 +170,15 @@ private List parseTableConstraints(CreateTable createTable) {
case "PRIMARY KEY" -> ConstraintType.PRIMARY_KEY;
case "UNIQUE" -> ConstraintType.UNIQUE;
default -> throw new UnsupportedOperationException(
- "Unsupported table constraint: " + indexType
+ "Unsupported table constraint: " + indexType
);
};
constraints.add(
- new Constraint(
- type,
- index.getColumnsNames()
- )
+ new Constraint(
+ type,
+ index.getColumnsNames()
+ )
);
}
diff --git a/src/test/java/dev/sqlcj/analysis/QueryAnalyzerTest.java b/src/test/java/dev/sqlcj/analysis/QueryAnalyzerTest.java
index 4b01951..ccbf1db 100644
--- a/src/test/java/dev/sqlcj/analysis/QueryAnalyzerTest.java
+++ b/src/test/java/dev/sqlcj/analysis/QueryAnalyzerTest.java
@@ -21,17 +21,17 @@
class QueryAnalyzerTest {
private static final Schema schema = new Schema(
- List.of(
- new Table(
- "users",
- List.of(
- new Column("id", ColumnType.BIGINT, false),
- new Column("name", ColumnType.VARCHAR, true),
- new Column("active", ColumnType.BOOLEAN, true)
- ),
- List.of()
- )
+ List.of(
+ new Table(
+ "users",
+ List.of(
+ new Column("id", ColumnType.BIGINT, false),
+ new Column("name", ColumnType.VARCHAR, true),
+ new Column("active", ColumnType.BOOLEAN, true)
+ ),
+ List.of()
)
+ )
);
private final SqlParser parser = new SqlParser();
@@ -40,9 +40,9 @@ class QueryAnalyzerTest {
@Test
void shouldAnalyzeSelectWithoutParameters() {
Query query = new Query(
- "ListUsers",
- QueryType.MANY,
- """
+ "ListUsers",
+ QueryType.MANY,
+ """
SELECT *
FROM users;
"""
@@ -60,9 +60,9 @@ void shouldAnalyzeSelectWithoutParameters() {
@Test
void shouldAnalyzeSelectWithSingleParameter() {
Query query = new Query(
- "GetUser",
- QueryType.ONE,
- """
+ "GetUser",
+ QueryType.ONE,
+ """
SELECT *
FROM users
WHERE id = $1;
@@ -74,19 +74,19 @@ void shouldAnalyzeSelectWithSingleParameter() {
assertEquals("users", model.table());
assertEquals(
- List.of(
- new QueryParameter(1, "id", ColumnType.BIGINT)
- ),
- model.parameters()
+ List.of(
+ new QueryParameter(1, "id", ColumnType.BIGINT)
+ ),
+ model.parameters()
);
}
@Test
void shouldAnalyzeSelectWithMultipleParameters() {
Query query = new Query(
- "ListUsersByIdAndName",
- QueryType.MANY,
- """
+ "ListUsersByIdAndName",
+ QueryType.MANY,
+ """
SELECT *
FROM users
WHERE id = $1
@@ -99,20 +99,20 @@ void shouldAnalyzeSelectWithMultipleParameters() {
assertEquals("users", model.table());
assertEquals(
- List.of(
- new QueryParameter(1, "id", ColumnType.BIGINT),
- new QueryParameter(2, "name", ColumnType.VARCHAR)
- ),
- model.parameters()
+ List.of(
+ new QueryParameter(1, "id", ColumnType.BIGINT),
+ new QueryParameter(2, "name", ColumnType.VARCHAR)
+ ),
+ model.parameters()
);
}
@Test
void shouldRejectInsertStatements() {
Query query = new Query(
- "InsertUser",
- QueryType.EXEC,
- """
+ "InsertUser",
+ QueryType.EXEC,
+ """
INSERT INTO users(id)
VALUES ($1);
"""
@@ -120,24 +120,23 @@ INSERT INTO users(id)
Statement statement = parser.parse(query.sql());
- UnsupportedOperationException exception =
- assertThrows(
- UnsupportedOperationException.class,
- () -> analyzer.analyze(query, statement, schema)
- );
+ UnsupportedOperationException exception = assertThrows(
+ UnsupportedOperationException.class,
+ () -> analyzer.analyze(query, statement, schema)
+ );
assertEquals(
- "INSERT is not supported yet",
- exception.getMessage()
+ "INSERT is not supported yet",
+ exception.getMessage()
);
}
@Test
void shouldRejectUpdateStatements() {
Query query = new Query(
- "UpdateUser",
- QueryType.EXEC,
- """
+ "UpdateUser",
+ QueryType.EXEC,
+ """
UPDATE users
SET username = $2
WHERE id = $1;
@@ -146,24 +145,23 @@ void shouldRejectUpdateStatements() {
Statement statement = parser.parse(query.sql());
- UnsupportedOperationException exception =
- assertThrows(
- UnsupportedOperationException.class,
- () -> analyzer.analyze(query, statement, schema)
- );
+ UnsupportedOperationException exception = assertThrows(
+ UnsupportedOperationException.class,
+ () -> analyzer.analyze(query, statement, schema)
+ );
assertEquals(
- "UPDATE is not supported yet",
- exception.getMessage()
+ "UPDATE is not supported yet",
+ exception.getMessage()
);
}
@Test
void shouldRejectDeleteStatements() {
Query query = new Query(
- "DeleteUser",
- QueryType.EXEC,
- """
+ "DeleteUser",
+ QueryType.EXEC,
+ """
DELETE users
WHERE id = $1;
"""
@@ -171,32 +169,31 @@ void shouldRejectDeleteStatements() {
Statement statement = parser.parse(query.sql());
- UnsupportedOperationException exception =
- assertThrows(
- UnsupportedOperationException.class,
- () -> analyzer.analyze(query, statement, schema)
- );
+ UnsupportedOperationException exception = assertThrows(
+ UnsupportedOperationException.class,
+ () -> analyzer.analyze(query, statement, schema)
+ );
assertEquals(
- "DELETE is not supported yet",
- exception.getMessage()
+ "DELETE is not supported yet",
+ exception.getMessage()
);
}
@Test
void shouldAnalyzeSelectWithExplicitColumns() {
Query query = new Query(
- "GetUser",
- QueryType.ONE,
- "SELECT id, name FROM users WHERE id = $1"
+ "GetUser",
+ QueryType.ONE,
+ "SELECT id, name FROM users WHERE id = $1"
);
Statement statement = parser.parse(query.sql());
QueryModel model = analyzer.analyze(
- query,
- statement,
- schema
+ query,
+ statement,
+ schema
);
assertEquals("GetUser", model.name());
@@ -204,37 +201,37 @@ void shouldAnalyzeSelectWithExplicitColumns() {
assertEquals("users", model.table());
assertEquals(
- List.of(
- new QueryColumn("id", ColumnType.BIGINT, false),
- new QueryColumn("name", ColumnType.VARCHAR, true)
- ),
- model.columns()
+ List.of(
+ new QueryColumn("id", ColumnType.BIGINT, false),
+ new QueryColumn("name", ColumnType.VARCHAR, true)
+ ),
+ model.columns()
);
}
@Test
void shouldResolveAllColumns() {
Query query = new Query(
- "ListUsers",
- QueryType.MANY,
- "SELECT * FROM users"
+ "ListUsers",
+ QueryType.MANY,
+ "SELECT * FROM users"
);
Statement statement = parser.parse(query.sql());
QueryModel model = analyzer.analyze(
- query,
- statement,
- schema
+ query,
+ statement,
+ schema
);
assertEquals(
- List.of(
- new QueryColumn("id", ColumnType.BIGINT, false),
- new QueryColumn("name", ColumnType.VARCHAR, true),
- new QueryColumn("active", ColumnType.BOOLEAN, true)
- ),
- model.columns()
+ List.of(
+ new QueryColumn("id", ColumnType.BIGINT, false),
+ new QueryColumn("name", ColumnType.VARCHAR, true),
+ new QueryColumn("active", ColumnType.BOOLEAN, true)
+ ),
+ model.columns()
);
assertTrue(model.parameters().isEmpty());
@@ -243,71 +240,71 @@ void shouldResolveAllColumns() {
@Test
void shouldResolveParameterTypeFromColumn() {
Query query = new Query(
- "GetUser",
- QueryType.ONE,
- "SELECT * FROM users WHERE id = $1"
+ "GetUser",
+ QueryType.ONE,
+ "SELECT * FROM users WHERE id = $1"
);
Statement statement = parser.parse(query.sql());
QueryModel model = analyzer.analyze(
- query,
- statement,
- schema
+ query,
+ statement,
+ schema
);
assertEquals(
- List.of(
- new QueryParameter(1, "id", ColumnType.BIGINT)
- ),
- model.parameters()
+ List.of(
+ new QueryParameter(1, "id", ColumnType.BIGINT)
+ ),
+ model.parameters()
);
}
@Test
void shouldResolveMultipleParameters() {
Query query = new Query(
- "ListUsersByIdAndName",
- QueryType.MANY,
+ "ListUsersByIdAndName",
+ QueryType.MANY,
+ """
+ SELECT *
+ FROM users
+ WHERE id = $1
+ AND name = $2
"""
- SELECT *
- FROM users
- WHERE id = $1
- AND name = $2
- """
);
Statement statement = parser.parse(query.sql());
QueryModel model = analyzer.analyze(
- query,
- statement,
- schema
+ query,
+ statement,
+ schema
);
assertEquals(
- List.of(
- new QueryParameter(1, "id", ColumnType.BIGINT),
- new QueryParameter(2, "name", ColumnType.VARCHAR)
- ),
- model.parameters()
+ List.of(
+ new QueryParameter(1, "id", ColumnType.BIGINT),
+ new QueryParameter(2, "name", ColumnType.VARCHAR)
+ ),
+ model.parameters()
);
}
@Test
void shouldNotCreateParametersForLiteralExpressions() {
Query query = new Query(
- "ListUsers",
- QueryType.MANY,
- "SELECT * FROM users WHERE 1 = 1"
+ "ListUsers",
+ QueryType.MANY,
+ "SELECT * FROM users WHERE 1 = 1"
);
Statement statement = parser.parse(query.sql());
QueryModel model = analyzer.analyze(
- query,
- statement,
- schema
+ query,
+ statement,
+ schema
);
assertTrue(model.parameters().isEmpty());
@@ -316,49 +313,49 @@ void shouldNotCreateParametersForLiteralExpressions() {
@Test
void shouldThrowWhenTableDoesNotExist() {
Query query = new Query(
- "GetOrder",
- QueryType.ONE,
- "SELECT * FROM orders"
+ "GetOrder",
+ QueryType.ONE,
+ "SELECT * FROM orders"
);
Statement statement = parser.parse(query.sql());
assertThrows(
- IllegalArgumentException.class,
- () -> analyzer.analyze(query, statement, schema)
+ IllegalArgumentException.class,
+ () -> analyzer.analyze(query, statement, schema)
);
}
@Test
void shouldThrowWhenColumnDoesNotExist() {
Query query = new Query(
- "GetUser",
- QueryType.ONE,
- "SELECT username FROM users"
+ "GetUser",
+ QueryType.ONE,
+ "SELECT username FROM users"
);
Statement statement = parser.parse(query.sql());
assertThrows(
- IllegalArgumentException.class,
- () -> analyzer.analyze(query, statement, schema)
+ IllegalArgumentException.class,
+ () -> analyzer.analyze(query, statement, schema)
);
}
@Test
void shouldResolveQueryParameterFromReferencedColumn() {
Query query = new Query(
- "GetUser",
- QueryType.ONE,
- "SELECT * FROM users WHERE id = $1"
+ "GetUser",
+ QueryType.ONE,
+ "SELECT * FROM users WHERE id = $1"
);
Statement statement = parser.parse(query.sql());
QueryModel model = analyzer.analyze(
- query,
- statement,
- schema
+ query,
+ statement,
+ schema
);
assertEquals(1, model.parameters().size());
@@ -373,17 +370,17 @@ void shouldResolveQueryParameterFromReferencedColumn() {
@Test
void shouldResolveMultipleQueryParameters() {
Query query = new Query(
- "FindUsers",
- QueryType.MANY,
- "SELECT * FROM users WHERE id = $1 AND active = $2"
+ "FindUsers",
+ QueryType.MANY,
+ "SELECT * FROM users WHERE id = $1 AND active = $2"
);
Statement statement = parser.parse(query.sql());
QueryModel model = analyzer.analyze(
- query,
- statement,
- schema
+ query,
+ statement,
+ schema
);
assertEquals(2, model.parameters().size());
@@ -402,17 +399,17 @@ void shouldResolveMultipleQueryParameters() {
@Test
void shouldResolveMultipleParametersForSameColumn() {
Query query = new Query(
- "FindUsers",
- QueryType.MANY,
- "SELECT * FROM users WHERE id = $1 AND id = $2"
+ "FindUsers",
+ QueryType.MANY,
+ "SELECT * FROM users WHERE id = $1 AND id = $2"
);
Statement statement = parser.parse(query.sql());
QueryModel model = analyzer.analyze(
- query,
- statement,
- schema
+ query,
+ statement,
+ schema
);
assertEquals(2, model.parameters().size());
@@ -431,17 +428,17 @@ void shouldResolveMultipleParametersForSameColumn() {
@Test
void shouldResolveQueryParametersInIndexOrder() {
Query query = new Query(
- "FindUser",
- QueryType.ONE,
- "SELECT * FROM users WHERE active = $2 AND id = $1"
+ "FindUser",
+ QueryType.ONE,
+ "SELECT * FROM users WHERE active = $2 AND id = $1"
);
Statement statement = parser.parse(query.sql());
QueryModel model = analyzer.analyze(
- query,
- statement,
- schema
+ query,
+ statement,
+ schema
);
assertEquals(2, model.parameters().size());
@@ -460,17 +457,17 @@ void shouldResolveQueryParametersInIndexOrder() {
@Test
void shouldResolveQueryParametersInsideOrExpression() {
Query query = new Query(
- "FindUsers",
- QueryType.MANY,
- "SELECT * FROM users WHERE id = $1 OR active = $2"
+ "FindUsers",
+ QueryType.MANY,
+ "SELECT * FROM users WHERE id = $1 OR active = $2"
);
Statement statement = parser.parse(query.sql());
QueryModel model = analyzer.analyze(
- query,
- statement,
- schema
+ query,
+ statement,
+ schema
);
assertEquals(2, model.parameters().size());
@@ -489,9 +486,9 @@ void shouldResolveQueryParametersInsideOrExpression() {
@Test
void shouldResolveQueryParametersInsideNestedAndOrExpressions() {
Query query = new Query(
- "FindUsers",
- QueryType.MANY,
- """
+ "FindUsers",
+ QueryType.MANY,
+ """
SELECT *
FROM users
WHERE id = $1
@@ -502,9 +499,9 @@ void shouldResolveQueryParametersInsideNestedAndOrExpressions() {
Statement statement = parser.parse(query.sql());
QueryModel model = analyzer.analyze(
- query,
- statement,
- schema
+ query,
+ statement,
+ schema
);
assertEquals(3, model.parameters().size());
@@ -528,9 +525,9 @@ void shouldResolveQueryParametersInsideNestedAndOrExpressions() {
@Test
void shouldResolveQueryParametersForComparisonOperators() {
Query query = new Query(
- "FindUsers",
- QueryType.MANY,
- """
+ "FindUsers",
+ QueryType.MANY,
+ """
SELECT *
FROM users
WHERE id > $1
@@ -541,9 +538,9 @@ void shouldResolveQueryParametersForComparisonOperators() {
Statement statement = parser.parse(query.sql());
QueryModel model = analyzer.analyze(
- query,
- statement,
- schema
+ query,
+ statement,
+ schema
);
assertEquals(2, model.parameters().size());
@@ -560,33 +557,36 @@ void shouldResolveQueryParametersForComparisonOperators() {
}
@ParameterizedTest
- @ValueSource(strings = {
+ @ValueSource(
+ strings = {
"=",
"<>",
">",
">=",
"<",
"<="
- })
+ }
+ )
void shouldResolveQueryParameterForComparisonOperator(
- String operator
+ String operator
) {
Query query = new Query(
- "FindUser",
- QueryType.ONE,
- """
+ "FindUser",
+ QueryType.ONE,
+ """
SELECT *
FROM users
WHERE id %s $1
- """.formatted(operator)
+ """
+ .formatted(operator)
);
Statement statement = parser.parse(query.sql());
QueryModel model = analyzer.analyze(
- query,
- statement,
- schema
+ query,
+ statement,
+ schema
);
assertEquals(1, model.parameters().size());
@@ -601,17 +601,17 @@ void shouldResolveQueryParameterForComparisonOperator(
@Test
void shouldResolveQueryParameterWhenParameterIsOnLeftSide() {
Query query = new Query(
- "FindUser",
- QueryType.ONE,
- "SELECT * FROM users WHERE $1 = id"
+ "FindUser",
+ QueryType.ONE,
+ "SELECT * FROM users WHERE $1 = id"
);
Statement statement = parser.parse(query.sql());
QueryModel model = analyzer.analyze(
- query,
- statement,
- schema
+ query,
+ statement,
+ schema
);
assertEquals(1, model.parameters().size());
@@ -626,17 +626,17 @@ void shouldResolveQueryParameterWhenParameterIsOnLeftSide() {
@Test
void shouldResolveQueryParametersInsideInExpression() {
Query query = new Query(
- "FindUsers",
- QueryType.MANY,
- "SELECT * FROM users WHERE id IN ($1, $2, $3)"
+ "FindUsers",
+ QueryType.MANY,
+ "SELECT * FROM users WHERE id IN ($1, $2, $3)"
);
Statement statement = parser.parse(query.sql());
QueryModel model = analyzer.analyze(
- query,
- statement,
- schema
+ query,
+ statement,
+ schema
);
assertEquals(3, model.parameters().size());
@@ -660,17 +660,17 @@ void shouldResolveQueryParametersInsideInExpression() {
@Test
void shouldResolveQueryParametersInsideInExpressionInIndexOrder() {
Query query = new Query(
- "FindUsers",
- QueryType.MANY,
- "SELECT * FROM users WHERE id IN ($3, $1, $2)"
+ "FindUsers",
+ QueryType.MANY,
+ "SELECT * FROM users WHERE id IN ($3, $1, $2)"
);
Statement statement = parser.parse(query.sql());
QueryModel model = analyzer.analyze(
- query,
- statement,
- schema
+ query,
+ statement,
+ schema
);
assertEquals(3, model.parameters().size());
@@ -694,9 +694,9 @@ void shouldResolveQueryParametersInsideInExpressionInIndexOrder() {
@Test
void shouldResolveQueryParametersFromCombinedExpressions() {
Query query = new Query(
- "FindUsers",
- QueryType.MANY,
- """
+ "FindUsers",
+ QueryType.MANY,
+ """
SELECT *
FROM users
WHERE id IN ($1, $2)
@@ -707,9 +707,9 @@ WHERE id IN ($1, $2)
Statement statement = parser.parse(query.sql());
QueryModel model = analyzer.analyze(
- query,
- statement,
- schema
+ query,
+ statement,
+ schema
);
assertEquals(4, model.parameters().size());
@@ -744,29 +744,29 @@ void shouldProduceExecutableSql() {
""";
Query query = new Query(
- "GetUser",
- QueryType.ONE,
- sql
+ "GetUser",
+ QueryType.ONE,
+ sql
);
QueryModel model = analyzer.analyze(
- query,
- parser.parse(sql),
- schema
+ query,
+ parser.parse(sql),
+ schema
);
assertEquals(
- """
+ """
SELECT id, name
FROM users
WHERE id = ?
""",
- model.executableSql()
+ model.executableSql()
);
assertEquals(
- List.of(1),
- model.bindingParameterIndexes()
+ List.of(1),
+ model.bindingParameterIndexes()
);
}
@@ -780,38 +780,38 @@ void shouldResolveBindingIndexesInTextualOrder() {
""";
Query query = new Query(
- "FindUser",
- QueryType.ONE,
- sql
+ "FindUser",
+ QueryType.ONE,
+ sql
);
QueryModel model = analyzer.analyze(
- query,
- parser.parse(sql),
- schema
+ query,
+ parser.parse(sql),
+ schema
);
assertEquals(
- """
+ """
SELECT id, name
FROM users
WHERE active = ?
AND id = ?
""",
- model.executableSql()
+ model.executableSql()
);
assertEquals(
- List.of(
- new QueryParameter(1, "id", ColumnType.BIGINT),
- new QueryParameter(2, "active", ColumnType.BOOLEAN)
- ),
- model.parameters()
+ List.of(
+ new QueryParameter(1, "id", ColumnType.BIGINT),
+ new QueryParameter(2, "active", ColumnType.BOOLEAN)
+ ),
+ model.parameters()
);
assertEquals(
- List.of(2, 1),
- model.bindingParameterIndexes()
+ List.of(2, 1),
+ model.bindingParameterIndexes()
);
}
@@ -823,15 +823,15 @@ void shouldResolveEmptyBindingIndexesWithoutParameters() {
""";
Query query = new Query(
- "ListUsers",
- QueryType.MANY,
- sql
+ "ListUsers",
+ QueryType.MANY,
+ sql
);
QueryModel model = analyzer.analyze(
- query,
- parser.parse(sql),
- schema
+ query,
+ parser.parse(sql),
+ schema
);
assertTrue(model.bindingParameterIndexes().isEmpty());
diff --git a/src/test/java/dev/sqlcj/cli/command/GenerateCommandTest.java b/src/test/java/dev/sqlcj/cli/command/GenerateCommandTest.java
index a756eae..e106af8 100644
--- a/src/test/java/dev/sqlcj/cli/command/GenerateCommandTest.java
+++ b/src/test/java/dev/sqlcj/cli/command/GenerateCommandTest.java
@@ -19,19 +19,19 @@
class GenerateCommandTest {
private static final String SCHEMA = """
- CREATE TABLE users
- (
- id BIGINT NOT NULL,
- name VARCHAR(255)
- );
- """;
+ CREATE TABLE users
+ (
+ id BIGINT NOT NULL,
+ name VARCHAR(255)
+ );
+ """;
private static final String QUERIES = """
- -- name: GetUser :one
- SELECT id, name
- FROM users
- WHERE id = $1;
- """;
+ -- name: GetUser :one
+ SELECT id, name
+ FROM users
+ WHERE id = $1;
+ """;
@TempDir
Path workingDirectory;
@@ -41,8 +41,8 @@ void shouldGenerateFromConfigurationInWorkingDirectory() throws Exception {
Files.writeString(workingDirectory.resolve("schema.sql"), SCHEMA);
Files.writeString(workingDirectory.resolve("queries.sql"), QUERIES);
Files.writeString(
- workingDirectory.resolve("sqlcj.yaml"),
- """
+ workingDirectory.resolve("sqlcj.yaml"),
+ """
version: "1"
sql:
- schema: schema.sql
@@ -57,25 +57,21 @@ void shouldGenerateFromConfigurationInWorkingDirectory() throws Exception {
assertEquals(0, result.exitCode(), result.error());
- Path generated = workingDirectory.resolve(
- "generated/dev/example/generated/GetUser.java"
- );
+ Path generated = workingDirectory.resolve("generated/dev/example/generated/GetUser.java");
assertTrue(Files.exists(generated), result.error());
assertTrue(
- Files.readString(generated)
- .startsWith("package dev.example.generated;")
+ Files.readString(generated)
+ .startsWith("package dev.example.generated;")
);
}
@Test
- void shouldFailWithConciseDiagnosticForMalformedConfiguration()
- throws Exception {
-
+ void shouldFailWithConciseDiagnosticForMalformedConfiguration() throws Exception {
Files.writeString(
- workingDirectory.resolve("sqlcj.yaml"),
- """
+ workingDirectory.resolve("sqlcj.yaml"),
+ """
version: "1"
sql:
- schema: schema.sql
@@ -95,13 +91,11 @@ void shouldFailWithConciseDiagnosticForMalformedConfiguration()
}
@Test
- void shouldFailWithConciseDiagnosticForUnreadableSource()
- throws Exception {
-
+ void shouldFailWithConciseDiagnosticForUnreadableSource() throws Exception {
Files.writeString(workingDirectory.resolve("schema.sql"), SCHEMA);
Files.writeString(
- workingDirectory.resolve("sqlcj.yaml"),
- """
+ workingDirectory.resolve("sqlcj.yaml"),
+ """
version: "1"
sql:
- schema: schema.sql
@@ -117,9 +111,9 @@ void shouldFailWithConciseDiagnosticForUnreadableSource()
assertEquals(1, result.exitCode(), result.error());
assertTrue(result.error().contains("sqlcj: Cannot read queries source"));
assertTrue(
- result.error().contains(
- workingDirectory.resolve("missing.sql").toString()
- )
+ result.error().contains(
+ workingDirectory.resolve("missing.sql").toString()
+ )
);
assertFalse(result.error().contains("\tat "));
assertFalse(Files.exists(workingDirectory.resolve("generated")));
@@ -129,30 +123,30 @@ private Result runGenerate() throws IOException, InterruptedException {
Path java = Path.of(System.getProperty("java.home"), "bin", "java");
Process process = new ProcessBuilder(
- java.toString(),
- "-classpath",
- System.getProperty("java.class.path"),
- "dev.sqlcj.Main",
- "generate"
+ java.toString(),
+ "-classpath",
+ System.getProperty("java.class.path"),
+ "dev.sqlcj.Main",
+ "generate"
)
- .directory(workingDirectory.toFile())
- .start();
+ .directory(workingDirectory.toFile())
+ .start();
String output = new String(process.getInputStream().readAllBytes());
String error = new String(process.getErrorStream().readAllBytes());
assertTrue(
- process.waitFor(60, TimeUnit.SECONDS),
- "sqlcj generate did not terminate"
+ process.waitFor(60, TimeUnit.SECONDS),
+ "sqlcj generate did not terminate"
);
return new Result(process.exitValue(), output, error);
}
private record Result(
- int exitCode,
- String output,
- String error
+ int exitCode,
+ String output,
+ String error
) {
}
}
diff --git a/src/test/java/dev/sqlcj/compiler/DefaultSourceLoaderTest.java b/src/test/java/dev/sqlcj/compiler/DefaultSourceLoaderTest.java
index 431fd05..590ec92 100644
--- a/src/test/java/dev/sqlcj/compiler/DefaultSourceLoaderTest.java
+++ b/src/test/java/dev/sqlcj/compiler/DefaultSourceLoaderTest.java
@@ -26,42 +26,42 @@ class DefaultSourceLoaderTest {
@Test
void shouldLoadEntriesInDeclaredOrder() throws IOException {
Path userSchema = write("users-schema.sql", """
- CREATE TABLE users
- (
- id BIGINT NOT NULL
- );
- """);
+ CREATE TABLE users
+ (
+ id BIGINT NOT NULL
+ );
+ """);
Path userQueries = write("users-queries.sql", """
- -- name: GetUser :one
- SELECT id
- FROM users
- WHERE id = $1;
+ -- name: GetUser :one
+ SELECT id
+ FROM users
+ WHERE id = $1;
- -- name: ListUsers :many
- SELECT id
- FROM users;
- """);
+ -- name: ListUsers :many
+ SELECT id
+ FROM users;
+ """);
Path orderSchema = write("orders-schema.sql", """
- CREATE TABLE orders
- (
- id BIGINT NOT NULL
- );
- """);
+ CREATE TABLE orders
+ (
+ id BIGINT NOT NULL
+ );
+ """);
Path orderQueries = write("orders-queries.sql", """
- -- name: GetOrder :one
- SELECT id
- FROM orders
- WHERE id = $1;
- """);
+ -- name: GetOrder :one
+ SELECT id
+ FROM orders
+ WHERE id = $1;
+ """);
List sources = sourceLoader.load(
- config(
- new SqlConfig(userSchema.toString(), userQueries.toString()),
- new SqlConfig(orderSchema.toString(), orderQueries.toString())
- )
+ config(
+ new SqlConfig(userSchema.toString(), userQueries.toString()),
+ new SqlConfig(orderSchema.toString(), orderQueries.toString())
+ )
);
assertEquals(2, sources.size());
@@ -70,80 +70,80 @@ void shouldLoadEntriesInDeclaredOrder() throws IOException {
assertTrue(sources.get(1).schema().contains("CREATE TABLE orders"));
assertEquals(
- List.of("GetUser", "ListUsers"),
- names(sources.getFirst())
+ List.of("GetUser", "ListUsers"),
+ names(sources.getFirst())
);
assertEquals(
- List.of("GetOrder"),
- names(sources.get(1))
+ List.of("GetOrder"),
+ names(sources.get(1))
);
}
@Test
void shouldRejectDuplicateQueryNameAcrossEntries() throws IOException {
Path schema = write("schema.sql", """
- CREATE TABLE users
- (
- id BIGINT NOT NULL
- );
- """);
+ CREATE TABLE users
+ (
+ id BIGINT NOT NULL
+ );
+ """);
Path firstQueries = write("first.sql", """
- -- name: GetUser :one
- SELECT id
- FROM users
- WHERE id = $1;
- """);
+ -- name: GetUser :one
+ SELECT id
+ FROM users
+ WHERE id = $1;
+ """);
Path secondQueries = write("second.sql", """
- -- name: GetUser :many
- SELECT id
- FROM users;
- """);
+ -- name: GetUser :many
+ SELECT id
+ FROM users;
+ """);
CompilationException exception = assertThrows(
- CompilationException.class,
- () -> sourceLoader.load(
- config(
- new SqlConfig(schema.toString(), firstQueries.toString()),
- new SqlConfig(schema.toString(), secondQueries.toString())
- )
+ CompilationException.class,
+ () -> sourceLoader.load(
+ config(
+ new SqlConfig(schema.toString(), firstQueries.toString()),
+ new SqlConfig(schema.toString(), secondQueries.toString())
)
+ )
);
assertEquals(
- "Duplicate query name 'GetUser' in query source: " + secondQueries,
- exception.getMessage()
+ "Duplicate query name 'GetUser' in query source: " + secondQueries,
+ exception.getMessage()
);
}
@Test
void shouldRejectUnreadableQueriesSource() throws IOException {
Path schema = write("schema.sql", """
- CREATE TABLE users
- (
- id BIGINT NOT NULL
- );
- """);
+ CREATE TABLE users
+ (
+ id BIGINT NOT NULL
+ );
+ """);
Path missingQueries = tempDir.resolve("missing.sql");
CompilationException exception = assertThrows(
- CompilationException.class,
- () -> sourceLoader.load(
- config(
- new SqlConfig(
- schema.toString(),
- missingQueries.toString()
- )
- )
+ CompilationException.class,
+ () -> sourceLoader.load(
+ config(
+ new SqlConfig(
+ schema.toString(),
+ missingQueries.toString()
+ )
)
+ )
);
assertEquals(
- "Cannot read queries source: " + missingQueries,
- exception.getMessage()
+ "Cannot read queries source: " + missingQueries,
+ exception.getMessage()
);
}
@@ -152,67 +152,67 @@ void shouldRejectUnreadableSchemaSource() throws IOException {
Path missingSchema = tempDir.resolve("missing.sql");
Path queries = write("queries.sql", """
- -- name: GetUser :one
- SELECT id
- FROM users
- WHERE id = $1;
- """);
+ -- name: GetUser :one
+ SELECT id
+ FROM users
+ WHERE id = $1;
+ """);
CompilationException exception = assertThrows(
- CompilationException.class,
- () -> sourceLoader.load(
- config(
- new SqlConfig(
- missingSchema.toString(),
- queries.toString()
- )
- )
+ CompilationException.class,
+ () -> sourceLoader.load(
+ config(
+ new SqlConfig(
+ missingSchema.toString(),
+ queries.toString()
+ )
)
+ )
);
assertEquals(
- "Cannot read schema source: " + missingSchema,
- exception.getMessage()
+ "Cannot read schema source: " + missingSchema,
+ exception.getMessage()
);
}
@Test
void shouldReportInvalidQuerySourceWithItsPath() throws IOException {
Path schema = write("schema.sql", """
- CREATE TABLE users
- (
- id BIGINT NOT NULL
- );
- """);
+ CREATE TABLE users
+ (
+ id BIGINT NOT NULL
+ );
+ """);
Path queries = write("queries.sql", """
- -- name: GetUser :one
- SELECT id
- FROM users
- WHERE id = $1;
+ -- name: GetUser :one
+ SELECT id
+ FROM users
+ WHERE id = $1;
- -- name: GetUser :one
- SELECT id
- FROM users;
- """);
+ -- name: GetUser :one
+ SELECT id
+ FROM users;
+ """);
CompilationException exception = assertThrows(
- CompilationException.class,
- () -> sourceLoader.load(
- config(
- new SqlConfig(
- schema.toString(),
- queries.toString()
- )
- )
+ CompilationException.class,
+ () -> sourceLoader.load(
+ config(
+ new SqlConfig(
+ schema.toString(),
+ queries.toString()
+ )
)
+ )
);
assertTrue(
- exception.getMessage().startsWith(
- "Invalid query source " + queries + ":"
- ),
- exception.getMessage()
+ exception.getMessage().startsWith(
+ "Invalid query source " + queries + ":"
+ ),
+ exception.getMessage()
);
}
@@ -222,18 +222,15 @@ private List names(Source source) {
private Config config(SqlConfig... entries) {
return new Config(
- List.of(entries),
- new JavaConfig(
- tempDir.resolve("generated").toString(),
- "dev.example.generated"
- )
+ List.of(entries),
+ new JavaConfig(
+ tempDir.resolve("generated").toString(),
+ "dev.example.generated"
+ )
);
}
- private Path write(
- String name,
- String content
- ) throws IOException {
+ private Path write(String name, String content) throws IOException {
Path file = tempDir.resolve(name);
Files.writeString(file, content);
diff --git a/src/test/java/dev/sqlcj/compiler/SqlcjCompilerIntegrationTest.java b/src/test/java/dev/sqlcj/compiler/SqlcjCompilerIntegrationTest.java
index a4e026f..aa2601d 100644
--- a/src/test/java/dev/sqlcj/compiler/SqlcjCompilerIntegrationTest.java
+++ b/src/test/java/dev/sqlcj/compiler/SqlcjCompilerIntegrationTest.java
@@ -44,23 +44,23 @@ void shouldGenerateCompilableJavaFiles() throws IOException {
Path classesDirectory = tempDir.resolve("classes");
Files.writeString(
- schemaFile,
+ schemaFile,
+ """
+ CREATE TABLE users
+ (
+ id BIGINT NOT NULL,
+ name VARCHAR(255),
+ active BOOLEAN,
+ birth_date DATE,
+ created_at TIMESTAMP,
+ balance DECIMAL(10, 2)
+ );
"""
- CREATE TABLE users
- (
- id BIGINT NOT NULL,
- name VARCHAR(255),
- active BOOLEAN,
- birth_date DATE,
- created_at TIMESTAMP,
- balance DECIMAL(10, 2)
- );
- """
);
Files.writeString(
- queriesFile,
- """
+ queriesFile,
+ """
-- name: GetUser :one
SELECT *
FROM users
@@ -80,30 +80,27 @@ WHERE id IN ($1, $2)
);
Config config = new Config(
- List.of(
- new SqlConfig(
- schemaFile.toString(),
- queriesFile.toString()
- )
- ),
- new JavaConfig(
- generatedDirectory.toString(),
- "generated"
+ List.of(
+ new SqlConfig(
+ schemaFile.toString(),
+ queriesFile.toString()
)
+ ),
+ new JavaConfig(
+ generatedDirectory.toString(),
+ "generated"
+ )
);
SqlcjCompiler compiler = new SqlcjCompiler();
compiler.compile(config);
- Path getUserFile =
- generatedDirectory.resolve("generated/GetUser.java");
+ Path getUserFile = generatedDirectory.resolve("generated/GetUser.java");
- Path listUsersFile =
- generatedDirectory.resolve("generated/ListUsers.java");
+ Path listUsersFile = generatedDirectory.resolve("generated/ListUsers.java");
- Path findUsersFile =
- generatedDirectory.resolve("generated/FindUsers.java");
+ Path findUsersFile = generatedDirectory.resolve("generated/FindUsers.java");
assertTrue(Files.exists(getUserFile));
assertTrue(Files.exists(listUsersFile));
@@ -113,35 +110,19 @@ WHERE id IN ($1, $2)
assertTrue(getUser.contains("import java.time.LocalDate;"));
assertTrue(getUser.contains("import java.time.LocalDateTime;"));
assertTrue(getUser.contains("import java.math.BigDecimal;"));
- assertTrue(getUser.contains(
- "public GetUserResult getUser(LocalDateTime created_at)"
- ));
+ assertTrue(getUser.contains("public GetUserResult getUser(LocalDateTime created_at)"));
assertTrue(getUser.contains("Long id"));
assertTrue(getUser.contains("String name"));
assertTrue(getUser.contains("LocalDate birth_date"));
assertTrue(getUser.contains("LocalDateTime created_at"));
assertTrue(getUser.contains("BigDecimal balance"));
- assertTrue(getUser.contains(
- "private static final RowMapper ROW_MAPPER"
- ));
- assertTrue(getUser.contains(
- "resultSet.getObject(\"id\", Long.class)"
- ));
- assertTrue(getUser.contains(
- "resultSet.getObject(\"name\", String.class)"
- ));
- assertTrue(getUser.contains(
- "resultSet.getObject(\"active\", Boolean.class)"
- ));
- assertTrue(getUser.contains(
- "resultSet.getObject(\"birth_date\", LocalDate.class)"
- ));
- assertTrue(getUser.contains(
- "resultSet.getObject(\"created_at\", LocalDateTime.class)"
- ));
- assertTrue(getUser.contains(
- "resultSet.getObject(\"balance\", BigDecimal.class)"
- ));
+ assertTrue(getUser.contains("private static final RowMapper ROW_MAPPER"));
+ assertTrue(getUser.contains("resultSet.getObject(\"id\", Long.class)"));
+ assertTrue(getUser.contains("resultSet.getObject(\"name\", String.class)"));
+ assertTrue(getUser.contains("resultSet.getObject(\"active\", Boolean.class)"));
+ assertTrue(getUser.contains("resultSet.getObject(\"birth_date\", LocalDate.class)"));
+ assertTrue(getUser.contains("resultSet.getObject(\"created_at\", LocalDateTime.class)"));
+ assertTrue(getUser.contains("resultSet.getObject(\"balance\", BigDecimal.class)"));
String listUsers = Files.readString(listUsersFile);
assertTrue(listUsers.contains("public final class ListUsers"));
@@ -149,22 +130,16 @@ WHERE id IN ($1, $2)
assertTrue(listUsers.contains("import java.time.LocalDate;"));
assertTrue(listUsers.contains("import java.time.LocalDateTime;"));
assertTrue(listUsers.contains("import java.math.BigDecimal;"));
- assertTrue(listUsers.contains(
- "public List listUsers(LocalDateTime created_at)"
- ));
+ assertTrue(listUsers.contains("public List listUsers(LocalDateTime created_at)"));
String findUsers = Files.readString(findUsersFile);
assertTrue(findUsers.contains("public final class FindUsers"));
assertTrue(findUsers.contains("import java.util.List;"));
-
- assertTrue(findUsers.contains(
- "public List findUsers(Long id1, Long id2, Boolean active, String name)"
- ));
-
- assertTrue(findUsers.contains(
- "public record FindUsersResult("
- ));
-
+ assertTrue(
+ findUsers
+ .contains("public List findUsers(Long id1, Long id2, Boolean active, String name)")
+ );
+ assertTrue(findUsers.contains("public record FindUsersResult("));
assertTrue(findUsers.contains("Long id"));
assertTrue(findUsers.contains("String name"));
@@ -177,36 +152,36 @@ WHERE id IN ($1, $2)
String classpath = System.getProperty("java.class.path");
int result = compilerApi.run(
- null,
- null,
- null,
- "-classpath",
- classpath,
- "-d",
- classesDirectory.toString(),
- getUserFile.toString(),
- listUsersFile.toString(),
- findUsersFile.toString()
+ null,
+ null,
+ null,
+ "-classpath",
+ classpath,
+ "-d",
+ classesDirectory.toString(),
+ getUserFile.toString(),
+ listUsersFile.toString(),
+ findUsersFile.toString()
);
assertEquals(0, result);
assertTrue(
- Files.exists(
- classesDirectory.resolve("generated/GetUser.class")
- )
+ Files.exists(
+ classesDirectory.resolve("generated/GetUser.class")
+ )
);
assertTrue(
- Files.exists(
- classesDirectory.resolve("generated/ListUsers.class")
- )
+ Files.exists(
+ classesDirectory.resolve("generated/ListUsers.class")
+ )
);
assertTrue(
- Files.exists(
- classesDirectory.resolve("generated/FindUsers.class")
- )
+ Files.exists(
+ classesDirectory.resolve("generated/FindUsers.class")
+ )
);
}
@@ -218,23 +193,23 @@ void shouldExecuteGeneratedQuery() throws Exception {
Path classesDirectory = tempDir.resolve("classes");
Files.writeString(
- schemaFile,
+ schemaFile,
+ """
+ CREATE TABLE users
+ (
+ id BIGINT NOT NULL,
+ name VARCHAR(255),
+ active BOOLEAN,
+ birth_date DATE,
+ created_at TIMESTAMP,
+ balance DECIMAL(10, 2)
+ );
"""
- CREATE TABLE users
- (
- id BIGINT NOT NULL,
- name VARCHAR(255),
- active BOOLEAN,
- birth_date DATE,
- created_at TIMESTAMP,
- balance DECIMAL(10, 2)
- );
- """
);
Files.writeString(
- queriesFile,
- """
+ queriesFile,
+ """
-- name: GetUser :one
SELECT *
FROM users
@@ -243,16 +218,16 @@ balance DECIMAL(10, 2)
);
Config config = new Config(
- List.of(
- new SqlConfig(
- schemaFile.toString(),
- queriesFile.toString()
- )
- ),
- new JavaConfig(
- generatedDirectory.toString(),
- "generated"
+ List.of(
+ new SqlConfig(
+ schemaFile.toString(),
+ queriesFile.toString()
)
+ ),
+ new JavaConfig(
+ generatedDirectory.toString(),
+ "generated"
+ )
);
SqlcjCompiler compiler = new SqlcjCompiler();
@@ -272,14 +247,14 @@ balance DECIMAL(10, 2)
String classpath = System.getProperty("java.class.path");
int compilationResult = compilerApi.run(
- null,
- null,
- null,
- "-classpath",
- classpath,
- "-d",
- classesDirectory.toString(),
- getUserFile.toString()
+ null,
+ null,
+ null,
+ "-classpath",
+ classpath,
+ "-d",
+ classesDirectory.toString(),
+ getUserFile.toString()
);
assertEquals(0, compilationResult);
@@ -287,13 +262,13 @@ balance DECIMAL(10, 2)
JdbcDataSource dataSource = new JdbcDataSource();
dataSource.setURL(
- "jdbc:h2:mem:" + UUID.randomUUID()
- + ";DB_CLOSE_DELAY=-1"
+ "jdbc:h2:mem:" + UUID.randomUUID()
+ + ";DB_CLOSE_DELAY=-1"
);
try (
- Connection connection = dataSource.getConnection();
- Statement statement = connection.createStatement()
+ Connection connection = dataSource.getConnection();
+ Statement statement = connection.createStatement()
) {
statement.execute("""
CREATE TABLE users (
@@ -318,58 +293,53 @@ balance DECIMAL(10, 2)
QueryExecutor executor = new JdbcQueryExecutor(dataSource);
URL[] classpathUrls = {
- classesDirectory.toUri().toURL()
+ classesDirectory.toUri().toURL()
};
try (URLClassLoader classLoader = new URLClassLoader(classpathUrls, getClass().getClassLoader())) {
- Class> generatedClass =
- Class.forName(
- "generated.GetUser",
- true,
- classLoader
- );
-
- Constructor> constructor =
- generatedClass.getConstructor(
- QueryExecutor.class
- );
-
- Object generatedQuery =
- constructor.newInstance(executor);
-
- Method method =
- generatedClass.getMethod(
- "getUser",
- LocalDateTime.class
- );
-
- Object result =
- method.invoke(
- generatedQuery,
- LocalDateTime.of(
- 2026,
- 1,
- 1,
- 10,
- 0
- )
- );
+ Class> generatedClass = Class.forName(
+ "generated.GetUser",
+ true,
+ classLoader
+ );
+
+ Constructor> constructor = generatedClass.getConstructor(
+ QueryExecutor.class
+ );
+
+ Object generatedQuery = constructor.newInstance(executor);
+
+ Method method = generatedClass.getMethod(
+ "getUser",
+ LocalDateTime.class
+ );
+
+ Object result = method.invoke(
+ generatedQuery,
+ LocalDateTime.of(
+ 2026,
+ 1,
+ 1,
+ 10,
+ 0
+ )
+ );
assertNotNull(result);
assertEquals(
- 1L,
- getRecordComponent(result, "id")
+ 1L,
+ getRecordComponent(result, "id")
);
assertEquals(
- "Alice",
- getRecordComponent(result, "name")
+ "Alice",
+ getRecordComponent(result, "name")
);
assertEquals(
- true,
- getRecordComponent(result, "active")
+ true,
+ getRecordComponent(result, "active")
);
}
}
@@ -382,23 +352,23 @@ void shouldExecuteGeneratedManyQuery() throws Exception {
Path classesDirectory = tempDir.resolve("classes");
Files.writeString(
- schemaFile,
+ schemaFile,
+ """
+ CREATE TABLE users
+ (
+ id BIGINT NOT NULL,
+ name VARCHAR(255),
+ active BOOLEAN,
+ birth_date DATE,
+ created_at TIMESTAMP,
+ balance DECIMAL(10, 2)
+ );
"""
- CREATE TABLE users
- (
- id BIGINT NOT NULL,
- name VARCHAR(255),
- active BOOLEAN,
- birth_date DATE,
- created_at TIMESTAMP,
- balance DECIMAL(10, 2)
- );
- """
);
Files.writeString(
- queriesFile,
- """
+ queriesFile,
+ """
-- name: ListActiveUsers :many
SELECT id, name, active
FROM users
@@ -408,46 +378,43 @@ balance DECIMAL(10, 2)
);
Config config = new Config(
- List.of(
- new SqlConfig(
- schemaFile.toString(),
- queriesFile.toString()
- )
- ),
- new JavaConfig(
- generatedDirectory.toString(),
- "generated"
+ List.of(
+ new SqlConfig(
+ schemaFile.toString(),
+ queriesFile.toString()
)
+ ),
+ new JavaConfig(
+ generatedDirectory.toString(),
+ "generated"
+ )
);
SqlcjCompiler compiler = new SqlcjCompiler();
compiler.compile(config);
- Path listActiveUsersFile =
- generatedDirectory.resolve("generated/ListActiveUsers.java");
+ Path listActiveUsersFile = generatedDirectory.resolve("generated/ListActiveUsers.java");
assertTrue(Files.exists(listActiveUsersFile));
Files.createDirectories(classesDirectory);
- JavaCompiler compilerApi =
- ToolProvider.getSystemJavaCompiler();
+ JavaCompiler compilerApi = ToolProvider.getSystemJavaCompiler();
assertNotNull(compilerApi);
- String classpath =
- System.getProperty("java.class.path");
+ String classpath = System.getProperty("java.class.path");
int compilationResult = compilerApi.run(
- null,
- null,
- null,
- "-classpath",
- classpath,
- "-d",
- classesDirectory.toString(),
- listActiveUsersFile.toString()
+ null,
+ null,
+ null,
+ "-classpath",
+ classpath,
+ "-d",
+ classesDirectory.toString(),
+ listActiveUsersFile.toString()
);
assertEquals(0, compilationResult);
@@ -455,13 +422,13 @@ balance DECIMAL(10, 2)
JdbcDataSource dataSource = new JdbcDataSource();
dataSource.setURL(
- "jdbc:h2:mem:" + UUID.randomUUID()
- + ";DB_CLOSE_DELAY=-1"
+ "jdbc:h2:mem:" + UUID.randomUUID()
+ + ";DB_CLOSE_DELAY=-1"
);
try (
- Connection connection = dataSource.getConnection();
- Statement statement = connection.createStatement()
+ Connection connection = dataSource.getConnection();
+ Statement statement = connection.createStatement()
) {
statement.execute("""
CREATE TABLE users (
@@ -487,45 +454,39 @@ balance DECIMAL(10, 2)
""");
}
- QueryExecutor executor =
- new JdbcQueryExecutor(dataSource);
+ QueryExecutor executor = new JdbcQueryExecutor(dataSource);
URL[] classpathUrls = {
- classesDirectory.toUri().toURL()
+ classesDirectory.toUri().toURL()
};
- try (URLClassLoader classLoader =
- new URLClassLoader(
- classpathUrls,
- getClass().getClassLoader()
- )) {
-
- Class> generatedClass =
- Class.forName(
- "generated.ListActiveUsers",
- true,
- classLoader
- );
-
- Constructor> constructor =
- generatedClass.getConstructor(
- QueryExecutor.class
- );
-
- Object generatedQuery =
- constructor.newInstance(executor);
-
- Method method =
- generatedClass.getMethod(
- "listActiveUsers",
- Boolean.class
- );
-
- Object result =
- method.invoke(
- generatedQuery,
- true
- );
+ try (
+ URLClassLoader classLoader = new URLClassLoader(
+ classpathUrls,
+ getClass().getClassLoader()
+ )
+ ) {
+ Class> generatedClass = Class.forName(
+ "generated.ListActiveUsers",
+ true,
+ classLoader
+ );
+
+ Constructor> constructor = generatedClass.getConstructor(
+ QueryExecutor.class
+ );
+
+ Object generatedQuery = constructor.newInstance(executor);
+
+ Method method = generatedClass.getMethod(
+ "listActiveUsers",
+ Boolean.class
+ );
+
+ Object result = method.invoke(
+ generatedQuery,
+ true
+ );
assertNotNull(result);
assertInstanceOf(List.class, result);
@@ -538,59 +499,57 @@ balance DECIMAL(10, 2)
Object second = users.get(1);
assertEquals(
- 1L,
- getRecordComponent(first, "id")
+ 1L,
+ getRecordComponent(first, "id")
);
assertEquals(
- "Alice",
- getRecordComponent(first, "name")
+ "Alice",
+ getRecordComponent(first, "name")
);
assertEquals(
- true,
- getRecordComponent(first, "active")
+ true,
+ getRecordComponent(first, "active")
);
assertEquals(
- 3L,
- getRecordComponent(second, "id")
+ 3L,
+ getRecordComponent(second, "id")
);
assertEquals(
- "Charlie",
- getRecordComponent(second, "name")
+ "Charlie",
+ getRecordComponent(second, "name")
);
assertEquals(
- true,
- getRecordComponent(second, "active")
+ true,
+ getRecordComponent(second, "active")
);
}
}
@Test
- void shouldExecuteGeneratedQueryWithOutOfOrderPlaceholders()
- throws Exception {
-
+ void shouldExecuteGeneratedQueryWithOutOfOrderPlaceholders() throws Exception {
Path classesDirectory = generateAndCompile(
- """
+ """
-- name: FindUser :one
SELECT id, name, active
FROM users
WHERE active = $2
AND id = $1;
""",
- "FindUser"
+ "FindUser"
);
- String source = Files.readString(
- tempDir.resolve("generated/generated/FindUser.java")
- );
+ String source = Files.readString(tempDir.resolve("generated/generated/FindUser.java"));
- assertTrue(source.contains(
+ assertTrue(
+ source.contains(
"public FindUserResult findUser(Long id, Boolean active)"
- ));
+ )
+ );
assertTrue(source.contains("List.of(active, id)"));
@@ -598,19 +557,19 @@ void shouldExecuteGeneratedQueryWithOutOfOrderPlaceholders()
try (URLClassLoader classLoader = classLoader(classesDirectory)) {
Class> generatedClass = Class.forName(
- "generated.FindUser",
- true,
- classLoader
+ "generated.FindUser",
+ true,
+ classLoader
);
Object generatedQuery = generatedClass
- .getConstructor(QueryExecutor.class)
- .newInstance(executor);
+ .getConstructor(QueryExecutor.class)
+ .newInstance(executor);
Method method = generatedClass.getMethod(
- "findUser",
- Long.class,
- Boolean.class
+ "findUser",
+ Long.class,
+ Boolean.class
);
Object result = method.invoke(generatedQuery, 1L, true);
@@ -626,22 +585,22 @@ void shouldExecuteGeneratedQueryWithOutOfOrderPlaceholders()
@Test
void shouldExecuteGeneratedQueryWithoutParameters() throws Exception {
Path classesDirectory = generateAndCompile(
- """
+ """
-- name: GetFirstUser :one
SELECT id, name
FROM users
ORDER BY id;
""",
- "GetFirstUser"
+ "GetFirstUser"
);
- String source = Files.readString(
- tempDir.resolve("generated/generated/GetFirstUser.java")
- );
+ String source = Files.readString(tempDir.resolve("generated/generated/GetFirstUser.java"));
- assertTrue(source.contains(
+ assertTrue(
+ source.contains(
"public GetFirstUserResult getFirstUser()"
- ));
+ )
+ );
assertTrue(source.contains("List.of()"));
@@ -649,18 +608,18 @@ void shouldExecuteGeneratedQueryWithoutParameters() throws Exception {
try (URLClassLoader classLoader = classLoader(classesDirectory)) {
Class> generatedClass = Class.forName(
- "generated.GetFirstUser",
- true,
- classLoader
+ "generated.GetFirstUser",
+ true,
+ classLoader
);
Object generatedQuery = generatedClass
- .getConstructor(QueryExecutor.class)
- .newInstance(executor);
+ .getConstructor(QueryExecutor.class)
+ .newInstance(executor);
Object result = generatedClass
- .getMethod("getFirstUser")
- .invoke(generatedQuery);
+ .getMethod("getFirstUser")
+ .invoke(generatedQuery);
assertNotNull(result);
@@ -670,9 +629,7 @@ void shouldExecuteGeneratedQueryWithoutParameters() throws Exception {
}
@Test
- void shouldCompileConfiguredEntriesWithConfiguredPackage()
- throws IOException {
-
+ void shouldCompileConfiguredEntriesWithConfiguredPackage() throws IOException {
Path usersSchema = tempDir.resolve("users-schema.sql");
Path usersQueries = tempDir.resolve("users-queries.sql");
Path ordersSchema = tempDir.resolve("orders-schema.sql");
@@ -681,74 +638,70 @@ void shouldCompileConfiguredEntriesWithConfiguredPackage()
Path classesDirectory = tempDir.resolve("classes");
Files.writeString(
- usersSchema,
+ usersSchema,
+ """
+ CREATE TABLE users
+ (
+ id BIGINT NOT NULL,
+ name VARCHAR(255)
+ );
"""
- CREATE TABLE users
- (
- id BIGINT NOT NULL,
- name VARCHAR(255)
- );
- """
);
Files.writeString(
- usersQueries,
+ usersQueries,
+ """
+ -- name: GetUser :one
+ SELECT id, name
+ FROM users
+ WHERE id = $1;
"""
- -- name: GetUser :one
- SELECT id, name
- FROM users
- WHERE id = $1;
- """
);
Files.writeString(
- ordersSchema,
+ ordersSchema,
+ """
+ CREATE TABLE orders
+ (
+ id BIGINT NOT NULL,
+ total DECIMAL(10, 2),
+ created_at TIMESTAMP
+ );
"""
- CREATE TABLE orders
- (
- id BIGINT NOT NULL,
- total DECIMAL(10, 2),
- created_at TIMESTAMP
- );
- """
);
Files.writeString(
- ordersQueries,
+ ordersQueries,
+ """
+ -- name: ListOrders :many
+ SELECT id, total, created_at
+ FROM orders
+ WHERE created_at = $1;
"""
- -- name: ListOrders :many
- SELECT id, total, created_at
- FROM orders
- WHERE created_at = $1;
- """
);
Config config = new Config(
- List.of(
- new SqlConfig(
- usersSchema.toString(),
- usersQueries.toString()
- ),
- new SqlConfig(
- ordersSchema.toString(),
- ordersQueries.toString()
- )
+ List.of(
+ new SqlConfig(
+ usersSchema.toString(),
+ usersQueries.toString()
),
- new JavaConfig(
- generatedDirectory.toString(),
- "dev.example.generated"
+ new SqlConfig(
+ ordersSchema.toString(),
+ ordersQueries.toString()
)
+ ),
+ new JavaConfig(
+ generatedDirectory.toString(),
+ "dev.example.generated"
+ )
);
new SqlcjCompiler().compile(config);
- Path getUserFile = generatedDirectory.resolve(
- "dev/example/generated/GetUser.java"
- );
+ Path getUserFile = generatedDirectory.resolve("dev/example/generated/GetUser.java");
- Path listOrdersFile = generatedDirectory.resolve(
- "dev/example/generated/ListOrders.java"
- );
+ Path listOrdersFile = generatedDirectory.resolve("dev/example/generated/ListOrders.java");
assertTrue(Files.exists(getUserFile));
assertTrue(Files.exists(listOrdersFile));
@@ -756,16 +709,12 @@ total DECIMAL(10, 2),
String getUser = Files.readString(getUserFile);
assertTrue(getUser.startsWith("package dev.example.generated;"));
- assertTrue(getUser.contains(
- "public GetUserResult getUser(Long id)"
- ));
+ assertTrue(getUser.contains("public GetUserResult getUser(Long id)"));
String listOrders = Files.readString(listOrdersFile);
assertTrue(listOrders.startsWith("package dev.example.generated;"));
- assertTrue(listOrders.contains(
- "public List listOrders(LocalDateTime created_at)"
- ));
+ assertTrue(listOrders.contains("public List listOrders(LocalDateTime created_at)"));
assertTrue(listOrders.contains("BigDecimal total"));
Files.createDirectories(classesDirectory);
@@ -775,40 +724,38 @@ total DECIMAL(10, 2),
assertNotNull(compilerApi);
int compilationResult = compilerApi.run(
- null,
- null,
- null,
- "-classpath",
- System.getProperty("java.class.path"),
- "-d",
- classesDirectory.toString(),
- getUserFile.toString(),
- listOrdersFile.toString()
+ null,
+ null,
+ null,
+ "-classpath",
+ System.getProperty("java.class.path"),
+ "-d",
+ classesDirectory.toString(),
+ getUserFile.toString(),
+ listOrdersFile.toString()
);
assertEquals(0, compilationResult);
assertTrue(
- Files.exists(
- classesDirectory.resolve(
- "dev/example/generated/GetUser.class"
- )
+ Files.exists(
+ classesDirectory.resolve(
+ "dev/example/generated/GetUser.class"
)
+ )
);
assertTrue(
- Files.exists(
- classesDirectory.resolve(
- "dev/example/generated/ListOrders.class"
- )
+ Files.exists(
+ classesDirectory.resolve(
+ "dev/example/generated/ListOrders.class"
)
+ )
);
}
@Test
- void shouldRejectDuplicateQueryNameAcrossEntriesBeforeWriting()
- throws IOException {
-
+ void shouldRejectDuplicateQueryNameAcrossEntriesBeforeWriting() throws IOException {
Path usersSchema = tempDir.resolve("users-schema.sql");
Path usersQueries = tempDir.resolve("users-queries.sql");
Path ordersSchema = tempDir.resolve("orders-schema.sql");
@@ -816,118 +763,114 @@ void shouldRejectDuplicateQueryNameAcrossEntriesBeforeWriting()
Path generatedDirectory = tempDir.resolve("generated");
Files.writeString(
- usersSchema,
+ usersSchema,
+ """
+ CREATE TABLE users
+ (
+ id BIGINT NOT NULL
+ );
"""
- CREATE TABLE users
- (
- id BIGINT NOT NULL
- );
- """
);
Files.writeString(
- usersQueries,
+ usersQueries,
+ """
+ -- name: GetRecord :one
+ SELECT id
+ FROM users
+ WHERE id = $1;
"""
- -- name: GetRecord :one
- SELECT id
- FROM users
- WHERE id = $1;
- """
);
Files.writeString(
- ordersSchema,
+ ordersSchema,
+ """
+ CREATE TABLE orders
+ (
+ id BIGINT NOT NULL
+ );
"""
- CREATE TABLE orders
- (
- id BIGINT NOT NULL
- );
- """
);
Files.writeString(
- ordersQueries,
+ ordersQueries,
+ """
+ -- name: GetRecord :one
+ SELECT id
+ FROM orders
+ WHERE id = $1;
"""
- -- name: GetRecord :one
- SELECT id
- FROM orders
- WHERE id = $1;
- """
);
Config config = new Config(
- List.of(
- new SqlConfig(
- usersSchema.toString(),
- usersQueries.toString()
- ),
- new SqlConfig(
- ordersSchema.toString(),
- ordersQueries.toString()
- )
+ List.of(
+ new SqlConfig(
+ usersSchema.toString(),
+ usersQueries.toString()
),
- new JavaConfig(
- generatedDirectory.toString(),
- "dev.example.generated"
+ new SqlConfig(
+ ordersSchema.toString(),
+ ordersQueries.toString()
)
+ ),
+ new JavaConfig(
+ generatedDirectory.toString(),
+ "dev.example.generated"
+ )
);
SqlcjCompiler compiler = new SqlcjCompiler();
CompilationException exception = assertThrows(
- CompilationException.class,
- () -> compiler.compile(config)
+ CompilationException.class,
+ () -> compiler.compile(config)
);
assertEquals(
- "Duplicate query name 'GetRecord' in query source: "
- + ordersQueries,
- exception.getMessage()
+ "Duplicate query name 'GetRecord' in query source: "
+ + ordersQueries,
+ exception.getMessage()
);
assertFalse(Files.exists(generatedDirectory));
}
- private Path generateAndCompile(
- String queries,
- String queryName
- ) throws IOException {
+ private Path generateAndCompile(String queries, String queryName) throws IOException {
Path schemaFile = tempDir.resolve("schema.sql");
Path queriesFile = tempDir.resolve("queries.sql");
Path generatedDirectory = tempDir.resolve("generated");
Path classesDirectory = tempDir.resolve("classes");
Files.writeString(
- schemaFile,
+ schemaFile,
+ """
+ CREATE TABLE users
+ (
+ id BIGINT NOT NULL,
+ name VARCHAR(255),
+ active BOOLEAN
+ );
"""
- CREATE TABLE users
- (
- id BIGINT NOT NULL,
- name VARCHAR(255),
- active BOOLEAN
- );
- """
);
Files.writeString(queriesFile, queries);
Config config = new Config(
- List.of(
- new SqlConfig(
- schemaFile.toString(),
- queriesFile.toString()
- )
- ),
- new JavaConfig(
- generatedDirectory.toString(),
- "generated"
+ List.of(
+ new SqlConfig(
+ schemaFile.toString(),
+ queriesFile.toString()
)
+ ),
+ new JavaConfig(
+ generatedDirectory.toString(),
+ "generated"
+ )
);
new SqlcjCompiler().compile(config);
- Path generatedFile =
- generatedDirectory.resolve("generated").resolve(queryName + ".java");
+ Path generatedFile = generatedDirectory.resolve("generated").resolve(queryName + ".java");
assertTrue(Files.exists(generatedFile));
@@ -938,14 +881,14 @@ name VARCHAR(255),
assertNotNull(compilerApi);
int compilationResult = compilerApi.run(
- null,
- null,
- null,
- "-classpath",
- System.getProperty("java.class.path"),
- "-d",
- classesDirectory.toString(),
- generatedFile.toString()
+ null,
+ null,
+ null,
+ "-classpath",
+ System.getProperty("java.class.path"),
+ "-d",
+ classesDirectory.toString(),
+ generatedFile.toString()
);
assertEquals(0, compilationResult);
@@ -953,12 +896,10 @@ name VARCHAR(255),
return classesDirectory;
}
- private URLClassLoader classLoader(Path classesDirectory)
- throws IOException {
-
+ private URLClassLoader classLoader(Path classesDirectory) throws IOException {
return new URLClassLoader(
- new URL[]{classesDirectory.toUri().toURL()},
- getClass().getClassLoader()
+ new URL[] { classesDirectory.toUri().toURL() },
+ getClass().getClassLoader()
);
}
@@ -966,12 +907,12 @@ private JdbcDataSource usersDataSource() throws Exception {
JdbcDataSource dataSource = new JdbcDataSource();
dataSource.setURL(
- "jdbc:h2:mem:" + UUID.randomUUID() + ";DB_CLOSE_DELAY=-1"
+ "jdbc:h2:mem:" + UUID.randomUUID() + ";DB_CLOSE_DELAY=-1"
);
try (
- Connection connection = dataSource.getConnection();
- Statement statement = connection.createStatement()
+ Connection connection = dataSource.getConnection();
+ Statement statement = connection.createStatement()
) {
statement.execute("""
CREATE TABLE users (
@@ -992,13 +933,10 @@ INSERT INTO users (id, name, active)
return dataSource;
}
- private Object getRecordComponent(
- Object record,
- String componentName
- ) throws Exception {
+ private Object getRecordComponent(Object record, String componentName) throws Exception {
return record
- .getClass()
- .getMethod(componentName)
- .invoke(record);
+ .getClass()
+ .getMethod(componentName)
+ .invoke(record);
}
}
diff --git a/src/test/java/dev/sqlcj/config/YamlConfigLoaderTest.java b/src/test/java/dev/sqlcj/config/YamlConfigLoaderTest.java
index e366e09..1eeaf00 100644
--- a/src/test/java/dev/sqlcj/config/YamlConfigLoaderTest.java
+++ b/src/test/java/dev/sqlcj/config/YamlConfigLoaderTest.java
@@ -22,107 +22,105 @@ class YamlConfigLoaderTest {
@Test
void shouldMapVersionOneFields() throws IOException {
Path configFile = write("""
- version: "1"
- sql:
- - schema: schema.sql
- queries: queries.sql
- java:
- package: dev.example.generated
- out: generated
- """);
+ version: "1"
+ sql:
+ - schema: schema.sql
+ queries: queries.sql
+ java:
+ package: dev.example.generated
+ out: generated
+ """);
Config config = configLoader.load(configFile);
assertEquals("1", config.version());
assertEquals(1, config.sql().size());
assertEquals(
- tempDir.resolve("schema.sql").toString(),
- config.sql().getFirst().schema()
+ tempDir.resolve("schema.sql").toString(),
+ config.sql().getFirst().schema()
);
assertEquals(
- tempDir.resolve("queries.sql").toString(),
- config.sql().getFirst().queries()
+ tempDir.resolve("queries.sql").toString(),
+ config.sql().getFirst().queries()
);
assertEquals(
- "dev.example.generated",
- config.java().packageName()
+ "dev.example.generated",
+ config.java().packageName()
);
assertEquals(
- tempDir.resolve("generated").toString(),
- config.java().out()
+ tempDir.resolve("generated").toString(),
+ config.java().out()
);
}
@Test
void shouldPreserveSqlEntryOrder() throws IOException {
Path configFile = write("""
- version: "1"
- sql:
- - schema: users.sql
- queries: user-queries.sql
- - schema: orders.sql
- queries: order-queries.sql
- java:
- package: dev.example.generated
- out: generated
- """);
+ version: "1"
+ sql:
+ - schema: users.sql
+ queries: user-queries.sql
+ - schema: orders.sql
+ queries: order-queries.sql
+ java:
+ package: dev.example.generated
+ out: generated
+ """);
Config config = configLoader.load(configFile);
assertEquals(
- List.of(
- tempDir.resolve("users.sql").toString(),
- tempDir.resolve("orders.sql").toString()
- ),
- config.sql().stream().map(SqlConfig::schema).toList()
+ List.of(
+ tempDir.resolve("users.sql").toString(),
+ tempDir.resolve("orders.sql").toString()
+ ),
+ config.sql().stream().map(SqlConfig::schema).toList()
);
assertEquals(
- List.of(
- tempDir.resolve("user-queries.sql").toString(),
- tempDir.resolve("order-queries.sql").toString()
- ),
- config.sql().stream().map(SqlConfig::queries).toList()
+ List.of(
+ tempDir.resolve("user-queries.sql").toString(),
+ tempDir.resolve("order-queries.sql").toString()
+ ),
+ config.sql().stream().map(SqlConfig::queries).toList()
);
}
@Test
- void shouldResolveRelativePathsAgainstConfigurationDirectory()
- throws IOException {
-
+ void shouldResolveRelativePathsAgainstConfigurationDirectory() throws IOException {
Path configDirectory = Files.createDirectories(
- tempDir.resolve("project").resolve("config")
+ tempDir.resolve("project").resolve("config")
);
Path configFile = configDirectory.resolve("sqlcj.yaml");
Files.writeString(configFile, """
- version: "1"
- sql:
- - schema: ../sql/schema.sql
- queries: ./queries.sql
- java:
- package: dev.example.generated
- out: ../target/generated
- """);
+ version: "1"
+ sql:
+ - schema: ../sql/schema.sql
+ queries: ./queries.sql
+ java:
+ package: dev.example.generated
+ out: ../target/generated
+ """);
Config config = configLoader.load(
- Path.of(configFile.toString())
+ Path.of(configFile.toString())
);
assertEquals(
- tempDir.resolve("project/sql/schema.sql").toString(),
- config.sql().getFirst().schema()
+ tempDir.resolve("project/sql/schema.sql").toString(),
+ config.sql().getFirst().schema()
);
assertEquals(
- configDirectory.resolve("queries.sql").toString(),
- config.sql().getFirst().queries()
+ configDirectory.resolve("queries.sql").toString(),
+ config.sql().getFirst().queries()
);
assertEquals(
- tempDir.resolve("project/target/generated").toString(),
- config.java().out()
+ tempDir.resolve("project/target/generated").toString(),
+ config.java().out()
);
}
@@ -132,7 +130,8 @@ void shouldKeepAbsolutePathsAbsolute() throws IOException {
Path queriesFile = tempDir.resolve("absolute").resolve("queries.sql");
Path outputDirectory = tempDir.resolve("absolute").resolve("out");
- Path configFile = write("""
+ Path configFile = write(
+ """
version: "1"
sql:
- schema: %s
@@ -140,23 +139,25 @@ void shouldKeepAbsolutePathsAbsolute() throws IOException {
java:
package: dev.example.generated
out: %s
- """.formatted(schemaFile, queriesFile, outputDirectory));
+ """
+ .formatted(schemaFile, queriesFile, outputDirectory)
+ );
Config config = configLoader.load(configFile);
assertEquals(
- schemaFile.toString(),
- config.sql().getFirst().schema()
+ schemaFile.toString(),
+ config.sql().getFirst().schema()
);
assertEquals(
- queriesFile.toString(),
- config.sql().getFirst().queries()
+ queriesFile.toString(),
+ config.sql().getFirst().queries()
);
assertEquals(
- outputDirectory.toString(),
- config.java().out()
+ outputDirectory.toString(),
+ config.java().out()
);
}
@@ -165,50 +166,50 @@ void shouldRejectMissingConfigurationFile() {
Path configFile = tempDir.resolve("sqlcj.yaml");
ConfigurationException exception = assertThrows(
- ConfigurationException.class,
- () -> configLoader.load(configFile)
+ ConfigurationException.class,
+ () -> configLoader.load(configFile)
);
assertTrue(
- exception.getMessage().contains(
- "Cannot read configuration file: " + configFile
- ),
- exception.getMessage()
+ exception.getMessage().contains(
+ "Cannot read configuration file: " + configFile
+ ),
+ exception.getMessage()
);
}
@Test
void shouldRejectMalformedYaml() throws IOException {
Path configFile = write("""
- version: "1"
- sql: [
- """);
+ version: "1"
+ sql: [
+ """);
ConfigurationException exception = assertThrows(
- ConfigurationException.class,
- () -> configLoader.load(configFile)
+ ConfigurationException.class,
+ () -> configLoader.load(configFile)
);
assertTrue(
- exception.getMessage().contains(
- "Malformed configuration file: " + configFile
- ),
- exception.getMessage()
+ exception.getMessage().contains(
+ "Malformed configuration file: " + configFile
+ ),
+ exception.getMessage()
);
}
@Test
void shouldRejectUnknownField() throws IOException {
Path configFile = write("""
- version: "1"
- sql:
- - schema: schema.sql
- queries: queries.sql
- java:
- package: dev.example.generated
- out: generated
- indent: 2
- """);
+ version: "1"
+ sql:
+ - schema: schema.sql
+ queries: queries.sql
+ java:
+ package: dev.example.generated
+ out: generated
+ indent: 2
+ """);
assertInvalid(configFile, "unknown field 'indent'");
}
@@ -216,86 +217,86 @@ void shouldRejectUnknownField() throws IOException {
@Test
void shouldRejectWrongTypedField() throws IOException {
Path configFile = write("""
- version: "1"
- sql: schema.sql
- java:
- package: dev.example.generated
- out: generated
- """);
+ version: "1"
+ sql: schema.sql
+ java:
+ package: dev.example.generated
+ out: generated
+ """);
assertInvalid(
- configFile,
- "invalid 'sql' value of type string, expected a list"
+ configFile,
+ "invalid 'sql' value of type string, expected a list"
);
}
@Test
void shouldRejectWrongTypedNestedField() throws IOException {
Path configFile = write("""
- version: "1"
- sql:
- - schema: 42
- queries: queries.sql
- java:
- package: dev.example.generated
- out: generated
- """);
+ version: "1"
+ sql:
+ - schema: 42
+ queries: queries.sql
+ java:
+ package: dev.example.generated
+ out: generated
+ """);
assertInvalid(
- configFile,
- "invalid 'sql[0].schema' value '42' of type number, "
- + "expected a string"
+ configFile,
+ "invalid 'sql[0].schema' value '42' of type number, "
+ + "expected a string"
);
}
@Test
void shouldRejectWrongTypedJavaOut() throws IOException {
Path configFile = write("""
- version: "1"
- sql:
- - schema: schema.sql
- queries: queries.sql
- java:
- package: dev.example.generated
- out:
- - generated
- """);
+ version: "1"
+ sql:
+ - schema: schema.sql
+ queries: queries.sql
+ java:
+ package: dev.example.generated
+ out:
+ - generated
+ """);
assertInvalid(
- configFile,
- "invalid 'java.out' value of type list, expected a string"
+ configFile,
+ "invalid 'java.out' value of type list, expected a string"
);
}
@Test
void shouldRejectNumericVersion() throws IOException {
Path configFile = write("""
- version: 1
- sql:
- - schema: schema.sql
- queries: queries.sql
- java:
- package: dev.example.generated
- out: generated
- """);
+ version: 1
+ sql:
+ - schema: schema.sql
+ queries: queries.sql
+ java:
+ package: dev.example.generated
+ out: generated
+ """);
assertInvalid(
- configFile,
- "invalid 'version' value '1' of type number, "
- + "expected a string"
+ configFile,
+ "invalid 'version' value '1' of type number, "
+ + "expected a string"
);
}
@Test
void shouldRejectMissingVersion() throws IOException {
Path configFile = write("""
- sql:
- - schema: schema.sql
- queries: queries.sql
- java:
- package: dev.example.generated
- out: generated
- """);
+ sql:
+ - schema: schema.sql
+ queries: queries.sql
+ java:
+ package: dev.example.generated
+ out: generated
+ """);
assertInvalid(configFile, "'version' is required");
}
@@ -303,29 +304,29 @@ void shouldRejectMissingVersion() throws IOException {
@Test
void shouldRejectUnsupportedVersion() throws IOException {
Path configFile = write("""
- version: "2"
- sql:
- - schema: schema.sql
- queries: queries.sql
- java:
- package: dev.example.generated
- out: generated
- """);
+ version: "2"
+ sql:
+ - schema: schema.sql
+ queries: queries.sql
+ java:
+ package: dev.example.generated
+ out: generated
+ """);
assertInvalid(
- configFile,
- "unsupported 'version' value '2', expected '1'"
+ configFile,
+ "unsupported 'version' value '2', expected '1'"
);
}
@Test
void shouldRejectMissingSqlSection() throws IOException {
Path configFile = write("""
- version: "1"
- java:
- package: dev.example.generated
- out: generated
- """);
+ version: "1"
+ java:
+ package: dev.example.generated
+ out: generated
+ """);
assertInvalid(configFile, "'sql' is required");
}
@@ -333,12 +334,12 @@ void shouldRejectMissingSqlSection() throws IOException {
@Test
void shouldRejectEmptySqlList() throws IOException {
Path configFile = write("""
- version: "1"
- sql: []
- java:
- package: dev.example.generated
- out: generated
- """);
+ version: "1"
+ sql: []
+ java:
+ package: dev.example.generated
+ out: generated
+ """);
assertInvalid(configFile, "'sql' must contain at least one entry");
}
@@ -346,15 +347,15 @@ void shouldRejectEmptySqlList() throws IOException {
@Test
void shouldRejectNullSqlEntry() throws IOException {
Path configFile = write("""
- version: "1"
- sql:
- - schema: schema.sql
- queries: queries.sql
- -
- java:
- package: dev.example.generated
- out: generated
- """);
+ version: "1"
+ sql:
+ - schema: schema.sql
+ queries: queries.sql
+ -
+ java:
+ package: dev.example.generated
+ out: generated
+ """);
assertInvalid(configFile, "'sql[1]' must not be null");
}
@@ -362,14 +363,14 @@ void shouldRejectNullSqlEntry() throws IOException {
@Test
void shouldRejectBlankQueriesValue() throws IOException {
Path configFile = write("""
- version: "1"
- sql:
- - schema: schema.sql
- queries: " "
- java:
- package: dev.example.generated
- out: generated
- """);
+ version: "1"
+ sql:
+ - schema: schema.sql
+ queries: " "
+ java:
+ package: dev.example.generated
+ out: generated
+ """);
assertInvalid(configFile, "'sql[0].queries' must not be blank");
}
@@ -377,11 +378,11 @@ void shouldRejectBlankQueriesValue() throws IOException {
@Test
void shouldRejectMissingJavaSection() throws IOException {
Path configFile = write("""
- version: "1"
- sql:
- - schema: schema.sql
- queries: queries.sql
- """);
+ version: "1"
+ sql:
+ - schema: schema.sql
+ queries: queries.sql
+ """);
assertInvalid(configFile, "'java' is required");
}
@@ -389,13 +390,13 @@ void shouldRejectMissingJavaSection() throws IOException {
@Test
void shouldRejectMissingJavaOut() throws IOException {
Path configFile = write("""
- version: "1"
- sql:
- - schema: schema.sql
- queries: queries.sql
- java:
- package: dev.example.generated
- """);
+ version: "1"
+ sql:
+ - schema: schema.sql
+ queries: queries.sql
+ java:
+ package: dev.example.generated
+ """);
assertInvalid(configFile, "'java.out' is required");
}
@@ -403,34 +404,31 @@ void shouldRejectMissingJavaOut() throws IOException {
@Test
void shouldRejectInvalidJavaPackage() throws IOException {
Path configFile = write("""
- version: "1"
- sql:
- - schema: schema.sql
- queries: queries.sql
- java:
- package: dev.class.generated
- out: generated
- """);
+ version: "1"
+ sql:
+ - schema: schema.sql
+ queries: queries.sql
+ java:
+ package: dev.class.generated
+ out: generated
+ """);
assertInvalid(
- configFile,
- "'java.package' value 'dev.class.generated' "
- + "is not a valid Java package name"
+ configFile,
+ "'java.package' value 'dev.class.generated' "
+ + "is not a valid Java package name"
);
}
- private void assertInvalid(
- Path configFile,
- String detail
- ) {
+ private void assertInvalid(Path configFile, String detail) {
ConfigurationException exception = assertThrows(
- ConfigurationException.class,
- () -> configLoader.load(configFile)
+ ConfigurationException.class,
+ () -> configLoader.load(configFile)
);
assertEquals(
- "Invalid configuration in %s: %s".formatted(configFile, detail),
- exception.getMessage()
+ "Invalid configuration in %s: %s".formatted(configFile, detail),
+ exception.getMessage()
);
}
diff --git a/src/test/java/dev/sqlcj/generator/JavaCodeGeneratorTest.java b/src/test/java/dev/sqlcj/generator/JavaCodeGeneratorTest.java
index bb8f406..939e1ea 100644
--- a/src/test/java/dev/sqlcj/generator/JavaCodeGeneratorTest.java
+++ b/src/test/java/dev/sqlcj/generator/JavaCodeGeneratorTest.java
@@ -34,35 +34,35 @@ class JavaCodeGeneratorTest {
@Test
void shouldGenerateFilePath() {
QueryModel query = new QueryModel(
- "GetUser",
- QueryType.ONE,
- "users",
- SQL,
- List.of(),
- List.of(
- new QueryColumn("id", ColumnType.BIGINT, false)
- ),
- List.of()
+ "GetUser",
+ QueryType.ONE,
+ "users",
+ SQL,
+ List.of(),
+ List.of(
+ new QueryColumn("id", ColumnType.BIGINT, false)
+ ),
+ List.of()
);
GeneratedFile file = codeGenerator.generate(query);
assertEquals(
- Path.of("generated", "GetUser.java"),
- file.path()
+ Path.of("generated", "GetUser.java"),
+ file.path()
);
}
@Test
void shouldGenerateClassName() {
QueryModel query = new QueryModel(
- "GetUser",
- QueryType.ONE,
- "users",
- SQL,
- List.of(),
- List.of(),
- List.of()
+ "GetUser",
+ QueryType.ONE,
+ "users",
+ SQL,
+ List.of(),
+ List.of(),
+ List.of()
);
GeneratedFile file = codeGenerator.generate(query);
@@ -70,17 +70,16 @@ void shouldGenerateClassName() {
assertTrue(file.content().contains("public final class GetUser"));
}
-
@Test
void shouldGenerateMethodName() {
QueryModel query = new QueryModel(
- "GetUser",
- QueryType.ONE,
- "users",
- SQL,
- List.of(),
- List.of(),
- List.of()
+ "GetUser",
+ QueryType.ONE,
+ "users",
+ SQL,
+ List.of(),
+ List.of(),
+ List.of()
);
GeneratedFile file = codeGenerator.generate(query);
@@ -91,67 +90,67 @@ void shouldGenerateMethodName() {
@Test
void shouldGenerateSingleParameter() {
GeneratedFile file = codeGenerator.generate(
- query(
- "GetUser",
- QueryType.ONE,
- List.of(
- new QueryParameter(1, "id", ColumnType.BIGINT)
- )
+ query(
+ "GetUser",
+ QueryType.ONE,
+ List.of(
+ new QueryParameter(1, "id", ColumnType.BIGINT)
)
+ )
);
assertTrue(
- file.content().contains("Long id")
+ file.content().contains("Long id")
);
}
@Test
void shouldGenerateMultipleParameters() {
GeneratedFile file = codeGenerator.generate(
- query(
- "ListUsersByIdAndName",
- QueryType.MANY,
- List.of(
- new QueryParameter(1, "id", ColumnType.BIGINT),
- new QueryParameter(2, "name", ColumnType.VARCHAR)
- )
+ query(
+ "ListUsersByIdAndName",
+ QueryType.MANY,
+ List.of(
+ new QueryParameter(1, "id", ColumnType.BIGINT),
+ new QueryParameter(2, "name", ColumnType.VARCHAR)
)
+ )
);
assertTrue(
- file.content().contains(
- "Long id, String name"
- )
+ file.content().contains(
+ "Long id, String name"
+ )
);
}
@Test
void shouldGenerateMethodWithoutParameters() {
GeneratedFile file = codeGenerator.generate(
- query(
- "ListUsers",
- QueryType.MANY,
- List.of()
- )
+ query(
+ "ListUsers",
+ QueryType.MANY,
+ List.of()
+ )
);
assertTrue(
- file.content().contains(
- "public List listUsers()"
- )
+ file.content().contains(
+ "public List listUsers()"
+ )
);
}
@Test
void shouldGenerateJavaDoc() {
GeneratedFile file = codeGenerator.generate(
- query(
- "GetUser",
- QueryType.ONE,
- List.of(
- new QueryParameter(1, "id", ColumnType.BIGINT)
- )
+ query(
+ "GetUser",
+ QueryType.ONE,
+ List.of(
+ new QueryParameter(1, "id", ColumnType.BIGINT)
)
+ )
);
String source = file.content();
@@ -164,50 +163,47 @@ void shouldGenerateJavaDoc() {
@Test
void shouldGeneratePackageDeclaration() {
GeneratedFile file = codeGenerator.generate(
- query(
- "GetUser",
- QueryType.ONE,
- List.of(
- new QueryParameter(1, "id", ColumnType.BIGINT)
- )
+ query(
+ "GetUser",
+ QueryType.ONE,
+ List.of(
+ new QueryParameter(1, "id", ColumnType.BIGINT)
)
+ )
);
assertTrue(
- file.content().startsWith("package generated;")
+ file.content().startsWith("package generated;")
);
}
@Test
- void shouldGenerateConfiguredPackageDeclarationAndPath()
- throws IOException {
-
- CodeGenerator generator =
- new JavaCodeGenerator("dev.example.generated");
+ void shouldGenerateConfiguredPackageDeclarationAndPath() throws IOException {
+ CodeGenerator generator = new JavaCodeGenerator("dev.example.generated");
QueryModel query = new QueryModel(
- "GetUser",
- QueryType.ONE,
- "users",
- SQL,
- List.of(1),
- List.of(
- new QueryColumn("id", ColumnType.BIGINT, false)
- ),
- List.of(
- new QueryParameter(1, "id", ColumnType.BIGINT)
- )
+ "GetUser",
+ QueryType.ONE,
+ "users",
+ SQL,
+ List.of(1),
+ List.of(
+ new QueryColumn("id", ColumnType.BIGINT, false)
+ ),
+ List.of(
+ new QueryParameter(1, "id", ColumnType.BIGINT)
+ )
);
GeneratedFile file = generator.generate(query);
assertEquals(
- Path.of("dev", "example", "generated", "GetUser.java"),
- file.path()
+ Path.of("dev", "example", "generated", "GetUser.java"),
+ file.path()
);
assertTrue(
- file.content().startsWith("package dev.example.generated;")
+ file.content().startsWith("package dev.example.generated;")
);
assertCompiles(file);
@@ -216,17 +212,17 @@ void shouldGenerateConfiguredPackageDeclarationAndPath()
@Test
void shouldGenerateResultRecord() {
QueryModel query = new QueryModel(
- "GetUser",
- QueryType.ONE,
- "users",
- SQL,
- List.of(),
- List.of(
- new QueryColumn("id", ColumnType.BIGINT, false),
- new QueryColumn("name", ColumnType.VARCHAR, true),
- new QueryColumn("active", ColumnType.BOOLEAN, true)
- ),
- List.of()
+ "GetUser",
+ QueryType.ONE,
+ "users",
+ SQL,
+ List.of(),
+ List.of(
+ new QueryColumn("id", ColumnType.BIGINT, false),
+ new QueryColumn("name", ColumnType.VARCHAR, true),
+ new QueryColumn("active", ColumnType.BOOLEAN, true)
+ ),
+ List.of()
);
GeneratedFile file = codeGenerator.generate(query);
@@ -243,39 +239,39 @@ void shouldGenerateResultRecord() {
@Test
void shouldGenerateSingleResultReturnType() {
QueryModel query = new QueryModel(
- "GetUser",
- QueryType.ONE,
- "users",
- SQL,
- List.of(),
- List.of(
- new QueryColumn("id", ColumnType.BIGINT, false)
- ),
- List.of()
+ "GetUser",
+ QueryType.ONE,
+ "users",
+ SQL,
+ List.of(),
+ List.of(
+ new QueryColumn("id", ColumnType.BIGINT, false)
+ ),
+ List.of()
);
GeneratedFile file = codeGenerator.generate(query);
assertTrue(
- file.content().contains(
- "public GetUserResult getUser()"
- )
+ file.content().contains(
+ "public GetUserResult getUser()"
+ )
);
}
@Test
void shouldGenerateListResultReturnType() {
QueryModel query = new QueryModel(
- "ListUsers",
- QueryType.MANY,
- "users",
- SQL,
- List.of(),
- List.of(
- new QueryColumn("id", ColumnType.BIGINT, false),
- new QueryColumn("name", ColumnType.VARCHAR, true)
- ),
- List.of()
+ "ListUsers",
+ QueryType.MANY,
+ "users",
+ SQL,
+ List.of(),
+ List.of(
+ new QueryColumn("id", ColumnType.BIGINT, false),
+ new QueryColumn("name", ColumnType.VARCHAR, true)
+ ),
+ List.of()
);
GeneratedFile file = codeGenerator.generate(query);
@@ -283,77 +279,77 @@ void shouldGenerateListResultReturnType() {
assertTrue(file.content().contains("import java.util.List;"));
assertTrue(
- file.content().contains(
- "public List listUsers()"
- )
+ file.content().contains(
+ "public List listUsers()"
+ )
);
}
@Test
void shouldGenerateTypedMethodParameters() {
QueryModel query = new QueryModel(
- "ListUsersByIdAndName",
- QueryType.MANY,
- "users",
- SQL,
- List.of(1, 2),
- List.of(
- new QueryColumn("id", ColumnType.BIGINT, false),
- new QueryColumn("name", ColumnType.VARCHAR, true)
- ),
- List.of(
- new QueryParameter(1, "id", ColumnType.BIGINT),
- new QueryParameter(2, "name", ColumnType.VARCHAR)
- )
+ "ListUsersByIdAndName",
+ QueryType.MANY,
+ "users",
+ SQL,
+ List.of(1, 2),
+ List.of(
+ new QueryColumn("id", ColumnType.BIGINT, false),
+ new QueryColumn("name", ColumnType.VARCHAR, true)
+ ),
+ List.of(
+ new QueryParameter(1, "id", ColumnType.BIGINT),
+ new QueryParameter(2, "name", ColumnType.VARCHAR)
+ )
);
GeneratedFile file = codeGenerator.generate(query);
assertTrue(
- file.content().contains(
- "public List listUsersByIdAndName(Long id, String name)"
- )
+ file.content().contains(
+ "public List listUsersByIdAndName(Long id, String name)"
+ )
);
}
@Test
void shouldGenerateSingleResultWithTypedParameter() {
QueryModel query = new QueryModel(
- "GetUser",
- QueryType.ONE,
- "users",
- SQL,
- List.of(1),
- List.of(
- new QueryColumn("id", ColumnType.BIGINT, false),
- new QueryColumn("name", ColumnType.VARCHAR, true)
- ),
- List.of(
- new QueryParameter(1, "id", ColumnType.BIGINT)
- )
+ "GetUser",
+ QueryType.ONE,
+ "users",
+ SQL,
+ List.of(1),
+ List.of(
+ new QueryColumn("id", ColumnType.BIGINT, false),
+ new QueryColumn("name", ColumnType.VARCHAR, true)
+ ),
+ List.of(
+ new QueryParameter(1, "id", ColumnType.BIGINT)
+ )
);
GeneratedFile file = codeGenerator.generate(query);
assertTrue(
- file.content().contains(
- "public GetUserResult getUser(Long id)"
- )
+ file.content().contains(
+ "public GetUserResult getUser(Long id)"
+ )
);
}
@Test
void shouldGenerateListImportForSingleResultWithoutParameters() {
QueryModel query = new QueryModel(
- "GetUser",
- QueryType.ONE,
- "users",
- SQL,
- List.of(),
- List.of(
- new QueryColumn("id", ColumnType.BIGINT, false)
- ),
- List.of()
+ "GetUser",
+ QueryType.ONE,
+ "users",
+ SQL,
+ List.of(),
+ List.of(
+ new QueryColumn("id", ColumnType.BIGINT, false)
+ ),
+ List.of()
);
GeneratedFile file = codeGenerator.generate(query);
@@ -367,25 +363,26 @@ void shouldGenerateListImportForSingleResultWithoutParameters() {
@Test
void shouldGenerateParameterNamesFromQueryParameters() {
QueryModel query = query(
- "GetUser",
- QueryType.ONE,
- List.of(
- new QueryParameter(1, "userId", ColumnType.BIGINT),
- new QueryParameter(2, "enabled", ColumnType.BOOLEAN)
- )
+ "GetUser",
+ QueryType.ONE,
+ List.of(
+ new QueryParameter(1, "userId", ColumnType.BIGINT),
+ new QueryParameter(2, "enabled", ColumnType.BOOLEAN)
+ )
);
GeneratedFile file = codeGenerator.generate(query);
assertTrue(
- file.content().contains(
- "Long userId, Boolean enabled"
- )
+ file.content().contains(
+ "Long userId, Boolean enabled"
+ )
);
}
@ParameterizedTest
- @CsvSource({
+ @CsvSource(
+ {
"INTEGER, Integer",
"BIGINT, Long",
"SMALLINT, Short",
@@ -395,160 +392,161 @@ void shouldGenerateParameterNamesFromQueryParameters() {
"DATE, LocalDate",
"TIMESTAMP, LocalDateTime",
"DECIMAL, BigDecimal"
- })
+ }
+ )
void shouldGenerateJavaTypeForQueryParameter(
- ColumnType columnType,
- String expectedJavaType
+ ColumnType columnType,
+ String expectedJavaType
) {
GeneratedFile file = codeGenerator.generate(
- query(
- "GetUser",
- QueryType.ONE,
- List.of(
- new QueryParameter(1, "value", columnType)
- )
+ query(
+ "GetUser",
+ QueryType.ONE,
+ List.of(
+ new QueryParameter(1, "value", columnType)
)
+ )
);
assertTrue(
- file.content().contains(
- expectedJavaType + " value"
- )
+ file.content().contains(
+ expectedJavaType + " value"
+ )
);
}
@Test
void shouldGenerateQuerySpecificResultRecord() {
QueryModel query = new QueryModel(
- "ListUsers",
- QueryType.MANY,
- "users",
- SQL,
- List.of(),
- List.of(
- new QueryColumn("id", ColumnType.BIGINT, false)
- ),
- List.of()
+ "ListUsers",
+ QueryType.MANY,
+ "users",
+ SQL,
+ List.of(),
+ List.of(
+ new QueryColumn("id", ColumnType.BIGINT, false)
+ ),
+ List.of()
);
GeneratedFile file = codeGenerator.generate(query);
assertTrue(
- file.content().contains(
- "public record ListUsersResult("
- )
+ file.content().contains(
+ "public record ListUsersResult("
+ )
);
}
@Test
void shouldGenerateImportForLocalDate() {
QueryModel query = new QueryModel(
- "GetUser",
- QueryType.ONE,
- "users",
- SQL,
- List.of(),
- List.of(
- new QueryColumn(
- "birthDate",
- ColumnType.DATE,
- true
- )
- ),
- List.of()
+ "GetUser",
+ QueryType.ONE,
+ "users",
+ SQL,
+ List.of(),
+ List.of(
+ new QueryColumn(
+ "birthDate",
+ ColumnType.DATE,
+ true
+ )
+ ),
+ List.of()
);
GeneratedFile file = codeGenerator.generate(query);
assertTrue(
- file.content().contains(
- "import java.time.LocalDate;"
- )
+ file.content().contains(
+ "import java.time.LocalDate;"
+ )
);
}
@Test
void shouldGenerateImportForBigDecimal() {
QueryModel query = new QueryModel(
- "GetAccount",
- QueryType.ONE,
- "accounts",
- SQL,
- List.of(),
- List.of(
- new QueryColumn(
- "balance",
- ColumnType.DECIMAL,
- false
- )
- ),
- List.of()
+ "GetAccount",
+ QueryType.ONE,
+ "accounts",
+ SQL,
+ List.of(),
+ List.of(
+ new QueryColumn(
+ "balance",
+ ColumnType.DECIMAL,
+ false
+ )
+ ),
+ List.of()
);
GeneratedFile file = codeGenerator.generate(query);
assertTrue(
- file.content().contains(
- "import java.math.BigDecimal;"
- )
+ file.content().contains(
+ "import java.math.BigDecimal;"
+ )
);
}
@Test
void shouldGenerateImportForQueryParameterType() {
QueryModel query = new QueryModel(
- "FindUser",
- QueryType.ONE,
- "users",
- SQL,
- List.of(1),
- List.of(
- new QueryColumn(
- "id",
- ColumnType.BIGINT,
- false
- )
- ),
- List.of(
- new QueryParameter(
- 1,
- "createdAt",
- ColumnType.TIMESTAMP
- )
+ "FindUser",
+ QueryType.ONE,
+ "users",
+ SQL,
+ List.of(1),
+ List.of(
+ new QueryColumn(
+ "id",
+ ColumnType.BIGINT,
+ false
)
+ ),
+ List.of(
+ new QueryParameter(
+ 1,
+ "createdAt",
+ ColumnType.TIMESTAMP
+ )
+ )
);
GeneratedFile file = codeGenerator.generate(query);
assertTrue(
- file.content().contains(
- "import java.time.LocalDateTime;"
- )
+ file.content().contains(
+ "import java.time.LocalDateTime;"
+ )
);
}
@Test
void shouldGenerateEachImportOnlyOnce() {
QueryModel query = new QueryModel(
- "FindUsers",
- QueryType.MANY,
- "users",
- SQL,
- List.of(1),
- List.of(
- new QueryColumn(
- "createdAt",
- ColumnType.TIMESTAMP,
- true
- )
- ),
- List.of(
- new QueryParameter(
- 1,
- "updatedAt",
- ColumnType.TIMESTAMP
- )
+ "FindUsers",
+ QueryType.MANY,
+ "users",
+ SQL,
+ List.of(1),
+ List.of(
+ new QueryColumn(
+ "createdAt",
+ ColumnType.TIMESTAMP,
+ true
)
+ ),
+ List.of(
+ new QueryParameter(
+ 1,
+ "updatedAt",
+ ColumnType.TIMESTAMP
+ )
+ )
);
GeneratedFile file = codeGenerator.generate(query);
@@ -556,34 +554,34 @@ void shouldGenerateEachImportOnlyOnce() {
String source = file.content();
assertEquals(
- 1,
- source.lines()
- .filter(line -> line.equals("import java.time.LocalDateTime;"))
- .count()
+ 1,
+ source.lines()
+ .filter(line -> line.equals("import java.time.LocalDateTime;"))
+ .count()
);
}
@Test
void shouldGenerateMultipleRequiredImports() {
QueryModel query = new QueryModel(
- "ListAccounts",
- QueryType.MANY,
- "accounts",
- SQL,
- List.of(),
- List.of(
- new QueryColumn(
- "createdAt",
- ColumnType.TIMESTAMP,
- false
- ),
- new QueryColumn(
- "balance",
- ColumnType.DECIMAL,
- false
- )
+ "ListAccounts",
+ QueryType.MANY,
+ "accounts",
+ SQL,
+ List.of(),
+ List.of(
+ new QueryColumn(
+ "createdAt",
+ ColumnType.TIMESTAMP,
+ false
),
- List.of()
+ new QueryColumn(
+ "balance",
+ ColumnType.DECIMAL,
+ false
+ )
+ ),
+ List.of()
);
GeneratedFile file = codeGenerator.generate(query);
@@ -598,25 +596,25 @@ void shouldGenerateMultipleRequiredImports() {
@Test
void shouldGenerateQueryExecutionMethodBody() {
QueryModel query = new QueryModel(
- "GetUser",
- QueryType.ONE,
- "users",
- SQL,
- List.of(1),
- List.of(
- new QueryColumn(
- "id",
- ColumnType.BIGINT,
- false
- )
- ),
- List.of(
- new QueryParameter(
- 1,
- "id",
- ColumnType.BIGINT
- )
+ "GetUser",
+ QueryType.ONE,
+ "users",
+ SQL,
+ List.of(1),
+ List.of(
+ new QueryColumn(
+ "id",
+ ColumnType.BIGINT,
+ false
)
+ ),
+ List.of(
+ new QueryParameter(
+ 1,
+ "id",
+ ColumnType.BIGINT
+ )
+ )
);
String source = codeGenerator.generate(query).content();
@@ -630,40 +628,40 @@ void shouldGenerateQueryExecutionMethodBody() {
@Test
void shouldGenerateCompilableJavaSource() throws IOException {
QueryModel query = new QueryModel(
- "ListUsers",
- QueryType.MANY,
- "users",
- SQL,
- List.of(1),
- List.of(
- new QueryColumn(
- "id",
- ColumnType.BIGINT,
- false
- ),
- new QueryColumn(
- "birth_date",
- ColumnType.DATE,
- true
- ),
- new QueryColumn(
- "created_at",
- ColumnType.TIMESTAMP,
- true
- ),
- new QueryColumn(
- "balance",
- ColumnType.DECIMAL,
- true
- )
+ "ListUsers",
+ QueryType.MANY,
+ "users",
+ SQL,
+ List.of(1),
+ List.of(
+ new QueryColumn(
+ "id",
+ ColumnType.BIGINT,
+ false
),
- List.of(
- new QueryParameter(
- 1,
- "created_at",
- ColumnType.TIMESTAMP
- )
+ new QueryColumn(
+ "birth_date",
+ ColumnType.DATE,
+ true
+ ),
+ new QueryColumn(
+ "created_at",
+ ColumnType.TIMESTAMP,
+ true
+ ),
+ new QueryColumn(
+ "balance",
+ ColumnType.DECIMAL,
+ true
+ )
+ ),
+ List.of(
+ new QueryParameter(
+ 1,
+ "created_at",
+ ColumnType.TIMESTAMP
)
+ )
);
GeneratedFile file = codeGenerator.generate(query);
@@ -684,21 +682,22 @@ void shouldGenerateCompilableJavaSource() throws IOException {
String classpath = System.getProperty("java.class.path");
int result = compiler.run(
- null,
- null,
- null,
- "-classpath",
- classpath,
- "-d",
- outputDirectory.toString(),
- sourceFile.toString()
+ null,
+ null,
+ null,
+ "-classpath",
+ classpath,
+ "-d",
+ outputDirectory.toString(),
+ sourceFile.toString()
);
assertEquals(0, result);
}
@ParameterizedTest
- @CsvSource({
+ @CsvSource(
+ {
"INTEGER, Integer",
"BIGINT, Long",
"SMALLINT, Short",
@@ -708,187 +707,195 @@ void shouldGenerateCompilableJavaSource() throws IOException {
"DATE, LocalDate",
"TIMESTAMP, LocalDateTime",
"DECIMAL, BigDecimal"
- })
- void shouldGenerateJavaTypeForResultColumn(
- ColumnType columnType,
- String expectedJavaType
- ) {
+ }
+ )
+ void shouldGenerateJavaTypeForResultColumn(ColumnType columnType, String expectedJavaType) {
QueryModel query = new QueryModel(
- "GetValue",
- QueryType.ONE,
- "users",
- SQL,
- List.of(),
- List.of(
- new QueryColumn(
- "value",
- columnType,
- true
- )
- ),
- List.of()
+ "GetValue",
+ QueryType.ONE,
+ "users",
+ SQL,
+ List.of(),
+ List.of(
+ new QueryColumn(
+ "value",
+ columnType,
+ true
+ )
+ ),
+ List.of()
);
GeneratedFile file = codeGenerator.generate(query);
assertTrue(
- file.content().contains(
- expectedJavaType + " value"
- )
+ file.content().contains(
+ expectedJavaType + " value"
+ )
);
}
@Test
void shouldGenerateWrapperTypeForNullableColumn() {
QueryModel query = new QueryModel(
- "GetUser",
- QueryType.ONE,
- "users",
- SQL,
- List.of(),
- List.of(
- new QueryColumn(
- "id",
- ColumnType.BIGINT,
- true
- )
- ),
- List.of()
+ "GetUser",
+ QueryType.ONE,
+ "users",
+ SQL,
+ List.of(),
+ List.of(
+ new QueryColumn(
+ "id",
+ ColumnType.BIGINT,
+ true
+ )
+ ),
+ List.of()
);
GeneratedFile file = codeGenerator.generate(query);
assertTrue(
- file.content().contains("Long id")
+ file.content().contains("Long id")
);
}
@Test
void shouldGenerateWrapperTypeForNonNullableColumn() {
QueryModel query = new QueryModel(
- "GetUser",
- QueryType.ONE,
- "users",
- SQL,
- List.of(),
- List.of(
- new QueryColumn(
- "id",
- ColumnType.BIGINT,
- false
- )
- ),
- List.of()
+ "GetUser",
+ QueryType.ONE,
+ "users",
+ SQL,
+ List.of(),
+ List.of(
+ new QueryColumn(
+ "id",
+ ColumnType.BIGINT,
+ false
+ )
+ ),
+ List.of()
);
GeneratedFile file = codeGenerator.generate(query);
assertTrue(
- file.content().contains("Long id")
+ file.content().contains("Long id")
);
}
@Test
void shouldGenerateUniqueParameterNamesForDuplicateColumns() {
QueryModel query = new QueryModel(
- "FindUsers",
- QueryType.MANY,
- "users",
- SQL,
- List.of(1, 2),
- List.of(
- new QueryColumn("id", ColumnType.BIGINT, false)
- ),
- List.of(
- new QueryParameter(1, "id", ColumnType.BIGINT),
- new QueryParameter(2, "id", ColumnType.BIGINT)
- )
+ "FindUsers",
+ QueryType.MANY,
+ "users",
+ SQL,
+ List.of(1, 2),
+ List.of(
+ new QueryColumn("id", ColumnType.BIGINT, false)
+ ),
+ List.of(
+ new QueryParameter(1, "id", ColumnType.BIGINT),
+ new QueryParameter(2, "id", ColumnType.BIGINT)
+ )
);
GeneratedFile file = codeGenerator.generate(query);
assertTrue(
- file.content().contains(
- "public List findUsers(Long id1, Long id2)"
- )
+ file.content().contains(
+ "public List findUsers(Long id1, Long id2)"
+ )
);
}
@Test
void shouldGenerateRowMapperForOneQuery() {
QueryModel query = new QueryModel(
- "GetUser",
- QueryType.ONE,
- "users",
- SQL,
- List.of(),
- List.of(
- new QueryColumn("id", ColumnType.BIGINT, false),
- new QueryColumn("name", ColumnType.VARCHAR, true),
- new QueryColumn("birth_date", ColumnType.DATE, true),
- new QueryColumn("created_at", ColumnType.TIMESTAMP, true),
- new QueryColumn("balance", ColumnType.DECIMAL, true)
- ),
- List.of()
+ "GetUser",
+ QueryType.ONE,
+ "users",
+ SQL,
+ List.of(),
+ List.of(
+ new QueryColumn("id", ColumnType.BIGINT, false),
+ new QueryColumn("name", ColumnType.VARCHAR, true),
+ new QueryColumn("birth_date", ColumnType.DATE, true),
+ new QueryColumn("created_at", ColumnType.TIMESTAMP, true),
+ new QueryColumn("balance", ColumnType.DECIMAL, true)
+ ),
+ List.of()
);
GeneratedFile file = codeGenerator.generate(query);
String source = file.content();
- assertTrue(source.contains(
+ assertTrue(
+ source.contains(
"import dev.sqlcj.runtime.RowMapper;"
- ));
+ )
+ );
- assertTrue(source.contains(
+ assertTrue(
+ source.contains(
"private static final RowMapper ROW_MAPPER"
- ));
+ )
+ );
- assertTrue(source.contains(
+ assertTrue(
+ source.contains(
"resultSet.getObject(\"id\", Long.class)"
- ));
+ )
+ );
- assertTrue(source.contains(
+ assertTrue(
+ source.contains(
"resultSet.getObject(\"name\", String.class)"
- ));
+ )
+ );
- assertTrue(source.contains(
+ assertTrue(
+ source.contains(
"resultSet.getObject(\"birth_date\", LocalDate.class)"
- ));
+ )
+ );
- assertTrue(source.contains(
+ assertTrue(
+ source.contains(
"resultSet.getObject(\"created_at\", LocalDateTime.class)"
- ));
+ )
+ );
- assertTrue(source.contains(
+ assertTrue(
+ source.contains(
"resultSet.getObject(\"balance\", BigDecimal.class)"
- ));
+ )
+ );
}
@Test
void shouldPreserveResultColumnOrder() {
QueryModel query = new QueryModel(
- "GetUser",
- QueryType.ONE,
- "users",
- SQL,
- List.of(),
- List.of(
- new QueryColumn("name", ColumnType.VARCHAR, true),
- new QueryColumn("id", ColumnType.BIGINT, false)
- ),
- List.of()
+ "GetUser",
+ QueryType.ONE,
+ "users",
+ SQL,
+ List.of(),
+ List.of(
+ new QueryColumn("name", ColumnType.VARCHAR, true),
+ new QueryColumn("id", ColumnType.BIGINT, false)
+ ),
+ List.of()
);
String source = codeGenerator.generate(query).content();
- int nameIndex = source.indexOf(
- "resultSet.getObject(\"name\", String.class)"
- );
+ int nameIndex = source.indexOf("resultSet.getObject(\"name\", String.class)");
- int idIndex = source.indexOf(
- "resultSet.getObject(\"id\", Long.class)"
- );
+ int idIndex = source.indexOf("resultSet.getObject(\"id\", Long.class)");
assertTrue(nameIndex < idIndex);
}
@@ -896,284 +903,312 @@ void shouldPreserveResultColumnOrder() {
@Test
void shouldGenerateRowMapperForManyQuery() {
QueryModel query = new QueryModel(
- "ListUsers",
- QueryType.MANY,
- "users",
- SQL,
- List.of(),
- List.of(
- new QueryColumn("id", ColumnType.BIGINT, false),
- new QueryColumn("name", ColumnType.VARCHAR, true)
- ),
- List.of()
+ "ListUsers",
+ QueryType.MANY,
+ "users",
+ SQL,
+ List.of(),
+ List.of(
+ new QueryColumn("id", ColumnType.BIGINT, false),
+ new QueryColumn("name", ColumnType.VARCHAR, true)
+ ),
+ List.of()
);
String source = codeGenerator.generate(query).content();
- assertTrue(source.contains(
+ assertTrue(
+ source.contains(
"import dev.sqlcj.runtime.RowMapper;"
- ));
+ )
+ );
- assertTrue(source.contains(
+ assertTrue(
+ source.contains(
"private static final RowMapper ROW_MAPPER"
- ));
+ )
+ );
- assertTrue(source.contains(
+ assertTrue(
+ source.contains(
"resultSet.getObject(\"id\", Long.class)"
- ));
+ )
+ );
- assertTrue(source.contains(
+ assertTrue(
+ source.contains(
"resultSet.getObject(\"name\", String.class)"
- ));
+ )
+ );
}
@Test
void shouldGenerateQueryExecutorImport() {
QueryModel query = new QueryModel(
- "GetUser",
- QueryType.ONE,
- "users",
- SQL,
- List.of(),
- List.of(),
- List.of()
+ "GetUser",
+ QueryType.ONE,
+ "users",
+ SQL,
+ List.of(),
+ List.of(),
+ List.of()
);
String source = codeGenerator.generate(query).content();
assertTrue(
- source.contains(
- "import dev.sqlcj.runtime.QueryExecutor;"
- )
+ source.contains(
+ "import dev.sqlcj.runtime.QueryExecutor;"
+ )
);
}
@Test
void shouldGenerateQueryExecutorField() {
QueryModel query = new QueryModel(
- "GetUser",
- QueryType.ONE,
- "users",
- SQL,
- List.of(),
- List.of(),
- List.of()
+ "GetUser",
+ QueryType.ONE,
+ "users",
+ SQL,
+ List.of(),
+ List.of(),
+ List.of()
);
String source = codeGenerator.generate(query).content();
assertTrue(
- source.contains(
- "private final QueryExecutor executor;"
- )
+ source.contains(
+ "private final QueryExecutor executor;"
+ )
);
}
@Test
void shouldGenerateQueryExecutorConstructor() {
QueryModel query = new QueryModel(
- "GetUser",
- QueryType.ONE,
- "users",
- SQL,
- List.of(),
- List.of(),
- List.of()
+ "GetUser",
+ QueryType.ONE,
+ "users",
+ SQL,
+ List.of(),
+ List.of(),
+ List.of()
);
String source = codeGenerator.generate(query).content();
assertTrue(
- source.contains(
- "public GetUser(QueryExecutor executor)"
- )
+ source.contains(
+ "public GetUser(QueryExecutor executor)"
+ )
);
assertTrue(
- source.contains(
- "this.executor = executor;"
- )
+ source.contains(
+ "this.executor = executor;"
+ )
);
}
@Test
void shouldGenerateExecutionForOneQuery() {
QueryModel query = new QueryModel(
- "GetUser",
- QueryType.ONE,
- "users",
- """
- SELECT id, name
- FROM users
- WHERE id = ?
- """,
- List.of(1),
- List.of(
- new QueryColumn(
- "id",
- ColumnType.BIGINT,
- false
- ),
- new QueryColumn(
- "name",
- ColumnType.VARCHAR,
- true
- )
+ "GetUser",
+ QueryType.ONE,
+ "users",
+ """
+ SELECT id, name
+ FROM users
+ WHERE id = ?
+ """,
+ List.of(1),
+ List.of(
+ new QueryColumn(
+ "id",
+ ColumnType.BIGINT,
+ false
),
- List.of(
- new QueryParameter(
- 1,
- "id",
- ColumnType.BIGINT
- )
+ new QueryColumn(
+ "name",
+ ColumnType.VARCHAR,
+ true
)
+ ),
+ List.of(
+ new QueryParameter(
+ 1,
+ "id",
+ ColumnType.BIGINT
+ )
+ )
);
String source = codeGenerator.generate(query).content();
- assertTrue(source.contains("""
+ assertTrue(
+ source.contains("""
return executor.query(
- """));
+ """)
+ );
- assertTrue(source.contains("""
+ assertTrue(
+ source.contains("""
WHERE id = ?
- """));
+ """)
+ );
- assertTrue(source.contains(
+ assertTrue(
+ source.contains(
"List.of(id)"
- ));
+ )
+ );
- assertTrue(source.contains(
+ assertTrue(
+ source.contains(
"ROW_MAPPER"
- ));
+ )
+ );
assertFalse(
- source.contains("UnsupportedOperationException")
+ source.contains("UnsupportedOperationException")
);
- assertTrue(source.contains("""
+ assertTrue(
+ source.contains("""
return executor.query(
- """));
+ """)
+ );
- assertFalse(source.contains(
+ assertFalse(
+ source.contains(
"return executor.queryMany("
- ));
+ )
+ );
}
@Test
void shouldGenerateQueryManyExecutionForManyQuery() {
QueryModel query = new QueryModel(
- "ListUsers",
- QueryType.MANY,
- "users",
- SQL,
- List.of(1),
- List.of(
- new QueryColumn(
- "id",
- ColumnType.BIGINT,
- false
- ),
- new QueryColumn(
- "name",
- ColumnType.VARCHAR,
- true
- )
+ "ListUsers",
+ QueryType.MANY,
+ "users",
+ SQL,
+ List.of(1),
+ List.of(
+ new QueryColumn(
+ "id",
+ ColumnType.BIGINT,
+ false
),
- List.of(
- new QueryParameter(
- 1,
- "active",
- ColumnType.BOOLEAN
- )
+ new QueryColumn(
+ "name",
+ ColumnType.VARCHAR,
+ true
+ )
+ ),
+ List.of(
+ new QueryParameter(
+ 1,
+ "active",
+ ColumnType.BOOLEAN
)
+ )
);
String source = codeGenerator.generate(query).content();
- assertTrue(source.contains("""
+ assertTrue(
+ source.contains("""
return executor.queryMany(
- """));
+ """)
+ );
- assertTrue(source.contains(
+ assertTrue(
+ source.contains(
"List.of(active)"
- ));
+ )
+ );
- assertTrue(source.contains(
+ assertTrue(
+ source.contains(
"ROW_MAPPER"
- ));
+ )
+ );
- assertFalse(source.contains(
+ assertFalse(
+ source.contains(
"return executor.query("
- ));
+ )
+ );
}
@Test
void shouldPreserveParameterOrderWhenGeneratingExecution() {
QueryModel query = new QueryModel(
- "FindUser",
- QueryType.ONE,
- "users",
- """
- SELECT id, name
- FROM users
- WHERE active = ?
- AND id = ?
- AND name = ?
- """,
- List.of(1, 2, 3),
- List.of(
- new QueryColumn("id", ColumnType.BIGINT, false),
- new QueryColumn("name", ColumnType.VARCHAR, true)
- ),
- List.of(
- new QueryParameter(1, "active", ColumnType.BOOLEAN),
- new QueryParameter(2, "id", ColumnType.BIGINT),
- new QueryParameter(3, "name", ColumnType.VARCHAR)
- )
+ "FindUser",
+ QueryType.ONE,
+ "users",
+ """
+ SELECT id, name
+ FROM users
+ WHERE active = ?
+ AND id = ?
+ AND name = ?
+ """,
+ List.of(1, 2, 3),
+ List.of(
+ new QueryColumn("id", ColumnType.BIGINT, false),
+ new QueryColumn("name", ColumnType.VARCHAR, true)
+ ),
+ List.of(
+ new QueryParameter(1, "active", ColumnType.BOOLEAN),
+ new QueryParameter(2, "id", ColumnType.BIGINT),
+ new QueryParameter(3, "name", ColumnType.VARCHAR)
+ )
);
String source = codeGenerator.generate(query).content();
assertTrue(
- source.contains(
- "List.of(active, id, name)"
- )
+ source.contains(
+ "List.of(active, id, name)"
+ )
);
}
@Test
- void shouldGenerateLogicalParametersWithTextualBindingOrder()
- throws IOException {
-
+ void shouldGenerateLogicalParametersWithTextualBindingOrder() throws IOException {
QueryModel query = new QueryModel(
- "FindUser",
- QueryType.ONE,
- "users",
- """
- SELECT id, name
- FROM users
- WHERE active = ?
- AND id = ?
- """,
- List.of(2, 1),
- List.of(
- new QueryColumn("id", ColumnType.BIGINT, false),
- new QueryColumn("name", ColumnType.VARCHAR, true)
- ),
- List.of(
- new QueryParameter(1, "id", ColumnType.BIGINT),
- new QueryParameter(2, "active", ColumnType.BOOLEAN)
- )
+ "FindUser",
+ QueryType.ONE,
+ "users",
+ """
+ SELECT id, name
+ FROM users
+ WHERE active = ?
+ AND id = ?
+ """,
+ List.of(2, 1),
+ List.of(
+ new QueryColumn("id", ColumnType.BIGINT, false),
+ new QueryColumn("name", ColumnType.VARCHAR, true)
+ ),
+ List.of(
+ new QueryParameter(1, "id", ColumnType.BIGINT),
+ new QueryParameter(2, "active", ColumnType.BOOLEAN)
+ )
);
GeneratedFile file = codeGenerator.generate(query);
String source = file.content();
- assertTrue(source.contains(
+ assertTrue(
+ source.contains(
"public FindUserResult findUser(Long id, Boolean active)"
- ));
+ )
+ );
assertTrue(source.contains("WHERE active = ?"));
assertTrue(source.contains("AND id = ?"));
@@ -1183,32 +1218,32 @@ void shouldGenerateLogicalParametersWithTextualBindingOrder()
}
@Test
- void shouldGenerateEmptyArgumentListForQueryWithoutParameters()
- throws IOException {
-
+ void shouldGenerateEmptyArgumentListForQueryWithoutParameters() throws IOException {
QueryModel query = new QueryModel(
- "GetFirstUser",
- QueryType.ONE,
- "users",
- """
- SELECT id, name
- FROM users
- """,
- List.of(),
- List.of(
- new QueryColumn("id", ColumnType.BIGINT, false),
- new QueryColumn("name", ColumnType.VARCHAR, true)
- ),
- List.of()
+ "GetFirstUser",
+ QueryType.ONE,
+ "users",
+ """
+ SELECT id, name
+ FROM users
+ """,
+ List.of(),
+ List.of(
+ new QueryColumn("id", ColumnType.BIGINT, false),
+ new QueryColumn("name", ColumnType.VARCHAR, true)
+ ),
+ List.of()
);
GeneratedFile file = codeGenerator.generate(query);
String source = file.content();
- assertTrue(source.contains(
+ assertTrue(
+ source.contains(
"public GetFirstUserResult getFirstUser()"
- ));
+ )
+ );
assertTrue(source.contains("import java.util.List;"));
assertTrue(source.contains("List.of()"));
@@ -1234,34 +1269,30 @@ private void assertCompiles(GeneratedFile file) throws IOException {
assertNotNull(compiler);
int result = compiler.run(
- null,
- null,
- null,
- "-classpath",
- System.getProperty("java.class.path"),
- "-d",
- outputDirectory.toString(),
- sourceFile.toString()
+ null,
+ null,
+ null,
+ "-classpath",
+ System.getProperty("java.class.path"),
+ "-d",
+ outputDirectory.toString(),
+ sourceFile.toString()
);
assertEquals(0, result);
}
- private QueryModel query(
- String name,
- QueryType type,
- List parameters
- ) {
+ private QueryModel query(String name, QueryType type, List parameters) {
return new QueryModel(
- name,
- type,
- "users",
- SQL,
- parameters.stream()
- .map(QueryParameter::index)
- .toList(),
- List.of(),
- parameters
+ name,
+ type,
+ "users",
+ SQL,
+ parameters.stream()
+ .map(QueryParameter::index)
+ .toList(),
+ List.of(),
+ parameters
);
}
}
diff --git a/src/test/java/dev/sqlcj/io/GeneratedFileWriterTest.java b/src/test/java/dev/sqlcj/io/GeneratedFileWriterTest.java
index 8feeb6e..c67a804 100644
--- a/src/test/java/dev/sqlcj/io/GeneratedFileWriterTest.java
+++ b/src/test/java/dev/sqlcj/io/GeneratedFileWriterTest.java
@@ -23,19 +23,18 @@ void shouldWriteGeneratedFileToOutputDirectory() throws IOException {
Path outputDirectory = tempDir.resolve("generated");
GeneratedFile file = new GeneratedFile(
- Path.of("GetUser.java"),
- "public final class GetUser {}"
+ Path.of("GetUser.java"),
+ "public final class GetUser {}"
);
writer.write(file, outputDirectory);
- Path outputFile =
- outputDirectory.resolve("GetUser.java");
+ Path outputFile = outputDirectory.resolve("GetUser.java");
assertTrue(Files.exists(outputFile));
assertEquals(
- "public final class GetUser {}",
- Files.readString(outputFile)
+ "public final class GetUser {}",
+ Files.readString(outputFile)
);
}
@@ -44,19 +43,18 @@ void shouldCreateParentDirectories() throws IOException {
Path outputDirectory = tempDir.resolve("generated");
GeneratedFile file = new GeneratedFile(
- Path.of("nested", "GetUser.java"),
- "public final class GetUser {}"
+ Path.of("nested", "GetUser.java"),
+ "public final class GetUser {}"
);
writer.write(file, outputDirectory);
- Path outputFile =
- outputDirectory.resolve("nested").resolve("GetUser.java");
+ Path outputFile = outputDirectory.resolve("nested").resolve("GetUser.java");
assertTrue(Files.exists(outputFile));
assertEquals(
- "public final class GetUser {}",
- Files.readString(outputFile)
+ "public final class GetUser {}",
+ Files.readString(outputFile)
);
}
}
diff --git a/src/test/java/dev/sqlcj/parser/DefaultQueryParserTest.java b/src/test/java/dev/sqlcj/parser/DefaultQueryParserTest.java
index e5b4a5e..53e95c0 100644
--- a/src/test/java/dev/sqlcj/parser/DefaultQueryParserTest.java
+++ b/src/test/java/dev/sqlcj/parser/DefaultQueryParserTest.java
@@ -15,11 +15,11 @@ class DefaultQueryParserTest {
@Test
void parsesSingleQuery() {
String source = """
- -- name: GetUser :one
- SELECT *
- FROM users
- WHERE id = $1;
- """;
+ -- name: GetUser :one
+ SELECT *
+ FROM users
+ WHERE id = $1;
+ """;
List queries = parser.parse(source);
@@ -30,24 +30,24 @@ void parsesSingleQuery() {
assertEquals("GetUser", query.name());
assertEquals(QueryType.ONE, query.type());
assertEquals("""
- SELECT *
- FROM users
- WHERE id = $1;
- """.trim(), query.sql());
+ SELECT *
+ FROM users
+ WHERE id = $1;
+ """.trim(), query.sql());
}
@Test
void parsesMultipleQueries() {
String source = """
- -- name: GetUser :one
- SELECT *
- FROM users
- WHERE id = $1;
-
- -- name: ListUsers :many
- SELECT *
- FROM users;
- """;
+ -- name: GetUser :one
+ SELECT *
+ FROM users
+ WHERE id = $1;
+
+ -- name: ListUsers :many
+ SELECT *
+ FROM users;
+ """;
List queries = parser.parse(source);
@@ -65,10 +65,10 @@ void parsesMultipleQueries() {
@Test
void parsesExecQueryType() {
String source = """
- -- name: DeleteUser :exec
- DELETE FROM users
- WHERE id = $1;
- """;
+ -- name: DeleteUser :exec
+ DELETE FROM users
+ WHERE id = $1;
+ """;
List queries = parser.parse(source);
@@ -79,69 +79,69 @@ void parsesExecQueryType() {
@Test
void rejectsInvalidQueryType() {
String source = """
- -- name: GetUser :invalid
- SELECT *
- FROM users;
- """;
+ -- name: GetUser :invalid
+ SELECT *
+ FROM users;
+ """;
IllegalArgumentException exception = assertThrows(
- IllegalArgumentException.class,
- () -> parser.parse(source)
+ IllegalArgumentException.class,
+ () -> parser.parse(source)
);
assertEquals(
- "Unknown query type: :invalid",
- exception.getMessage()
+ "Unknown query type: :invalid",
+ exception.getMessage()
);
}
@Test
void rejectsDuplicateQueryNames() {
String source = """
- -- name: GetUser :one
- SELECT *
- FROM users
- WHERE id = $1;
-
- -- name: GetUser :many
- SELECT *
- FROM users;
- """;
+ -- name: GetUser :one
+ SELECT *
+ FROM users
+ WHERE id = $1;
+
+ -- name: GetUser :many
+ SELECT *
+ FROM users;
+ """;
IllegalArgumentException exception = assertThrows(
- IllegalArgumentException.class,
- () -> parser.parse(source)
+ IllegalArgumentException.class,
+ () -> parser.parse(source)
);
assertEquals(
- "Duplicate query: GetUser",
- exception.getMessage()
+ "Duplicate query: GetUser",
+ exception.getMessage()
);
}
@Test
void rejectsQueryWithoutSql() {
String source = """
- -- name: GetUser :one
- """;
+ -- name: GetUser :one
+ """;
IllegalArgumentException exception = assertThrows(
- IllegalArgumentException.class,
- () -> parser.parse(source)
+ IllegalArgumentException.class,
+ () -> parser.parse(source)
);
assertEquals(
- "Query 'GetUser' has no SQL",
- exception.getMessage()
+ "Query 'GetUser' has no SQL",
+ exception.getMessage()
);
}
@Test
void returnsEmptyListWhenNoQueriesExist() {
String source = """
- SELECT *
- FROM users;
- """;
+ SELECT *
+ FROM users;
+ """;
List queries = parser.parse(source);
@@ -151,19 +151,19 @@ void returnsEmptyListWhenNoQueriesExist() {
@Test
void rejectsInvalidHeader() {
String source = """
- -- name:
- SELECT *
- FROM users;
- """;
+ -- name:
+ SELECT *
+ FROM users;
+ """;
IllegalArgumentException exception = assertThrows(
- IllegalArgumentException.class,
- () -> parser.parse(source)
+ IllegalArgumentException.class,
+ () -> parser.parse(source)
);
assertEquals(
- "Invalid query header: -- name:",
- exception.getMessage()
+ "Invalid query header: -- name:",
+ exception.getMessage()
);
}
@@ -172,10 +172,10 @@ void preservesQueryOrder() {
String source = """
-- name: First :one
SELECT 1;
-
+
-- name: Second :one
SELECT 2;
-
+
-- name: Third :one
SELECT 3;
""";
diff --git a/src/test/java/dev/sqlcj/runtime/JdbcQueryExecutorTest.java b/src/test/java/dev/sqlcj/runtime/JdbcQueryExecutorTest.java
index ffa88e7..a6ff181 100644
--- a/src/test/java/dev/sqlcj/runtime/JdbcQueryExecutorTest.java
+++ b/src/test/java/dev/sqlcj/runtime/JdbcQueryExecutorTest.java
@@ -28,45 +28,47 @@ class JdbcQueryExecutorTest {
void setUp() throws SQLException {
dataSource = new JdbcDataSource();
dataSource.setURL(
- "jdbc:h2:mem:" + UUID.randomUUID() + ";DB_CLOSE_DELAY=-1"
+ "jdbc:h2:mem:" + UUID.randomUUID() + ";DB_CLOSE_DELAY=-1"
);
executor = new JdbcQueryExecutor(dataSource);
- try (Connection connection = dataSource.getConnection();
- Statement statement = connection.createStatement()) {
+ try (
+ Connection connection = dataSource.getConnection();
+ Statement statement = connection.createStatement()
+ ) {
statement.execute("""
- CREATE TABLE users (
- id BIGINT PRIMARY KEY,
- name VARCHAR(255),
- active BOOLEAN,
- birth_date DATE,
- created_at TIMESTAMP,
- balance DECIMAL(10, 2)
- )
- """);
+ CREATE TABLE users (
+ id BIGINT PRIMARY KEY,
+ name VARCHAR(255),
+ active BOOLEAN,
+ birth_date DATE,
+ created_at TIMESTAMP,
+ balance DECIMAL(10, 2)
+ )
+ """);
statement.execute("""
- INSERT INTO users
- (id, name, active, birth_date, created_at, balance)
- VALUES
- (1, 'Alice', TRUE, '1990-01-15',
- '2026-01-01 10:00:00', 100.50),
- (2, 'Bob', FALSE, '1985-05-20',
- '2026-02-01 11:30:00', 200.75),
- (3, 'Charlie', TRUE, '1995-10-10',
- '2026-03-01 12:45:00', 300.25)
- """);
+ INSERT INTO users
+ (id, name, active, birth_date, created_at, balance)
+ VALUES
+ (1, 'Alice', TRUE, '1990-01-15',
+ '2026-01-01 10:00:00', 100.50),
+ (2, 'Bob', FALSE, '1985-05-20',
+ '2026-02-01 11:30:00', 200.75),
+ (3, 'Charlie', TRUE, '1995-10-10',
+ '2026-03-01 12:45:00', 300.25)
+ """);
}
}
@Test
void shouldBindSingleParameter() {
Long result = executor.query(
- "SELECT id FROM users WHERE id = ?",
- List.of(1L),
- resultSet -> resultSet.getLong("id")
+ "SELECT id FROM users WHERE id = ?",
+ List.of(1L),
+ resultSet -> resultSet.getLong("id")
);
assertEquals(1L, result);
@@ -75,14 +77,14 @@ void shouldBindSingleParameter() {
@Test
void shouldBindParametersInOrder() {
String result = executor.query(
- """
+ """
SELECT name
FROM users
WHERE id = ?
AND active = ?
""",
- List.of(2L, false),
- resultSet -> resultSet.getString("name")
+ List.of(2L, false),
+ resultSet -> resultSet.getString("name")
);
assertEquals("Bob", result);
@@ -91,19 +93,19 @@ void shouldBindParametersInOrder() {
@Test
void shouldBindSupportedJavaTypes() {
String result = executor.query(
- """
+ """
SELECT name
FROM users
WHERE birth_date = ?
AND created_at = ?
AND balance = ?
""",
- List.of(
- LocalDate.of(1990, 1, 15),
- LocalDateTime.of(2026, 1, 1, 10, 0),
- new BigDecimal("100.50")
- ),
- resultSet -> resultSet.getString("name")
+ List.of(
+ LocalDate.of(1990, 1, 15),
+ LocalDateTime.of(2026, 1, 1, 10, 0),
+ new BigDecimal("100.50")
+ ),
+ resultSet -> resultSet.getString("name")
);
assertEquals("Alice", result);
@@ -112,41 +114,41 @@ void shouldBindSupportedJavaTypes() {
@Test
void shouldReturnAllRowsForQueryMany() {
List results = executor.queryMany(
- """
+ """
SELECT id, name
FROM users
WHERE active = ?
ORDER BY id
""",
- List.of(true),
- resultSet -> new User(
- resultSet.getLong("id"),
- resultSet.getString("name")
- )
+ List.of(true),
+ resultSet -> new User(
+ resultSet.getLong("id"),
+ resultSet.getString("name")
+ )
);
assertEquals(
- List.of(
- new User(1L, "Alice"),
- new User(3L, "Charlie")
- ),
- results
+ List.of(
+ new User(1L, "Alice"),
+ new User(3L, "Charlie")
+ ),
+ results
);
}
@Test
void shouldReturnEmptyListWhenQueryManyFindsNoRows() {
List results = executor.queryMany(
- """
+ """
SELECT id, name
FROM users
WHERE id = ?
""",
- List.of(999L),
- resultSet -> new User(
- resultSet.getLong("id"),
- resultSet.getString("name")
- )
+ List.of(999L),
+ resultSet -> new User(
+ resultSet.getLong("id"),
+ resultSet.getString("name")
+ )
);
assertTrue(results.isEmpty());
@@ -155,16 +157,16 @@ void shouldReturnEmptyListWhenQueryManyFindsNoRows() {
@Test
void shouldReturnNullWhenQueryFindsNoRows() {
User result = executor.query(
- """
+ """
SELECT id, name
FROM users
WHERE id = ?
""",
- List.of(999L),
- resultSet -> new User(
- resultSet.getLong("id"),
- resultSet.getString("name")
- )
+ List.of(999L),
+ resultSet -> new User(
+ resultSet.getLong("id"),
+ resultSet.getString("name")
+ )
);
assertNull(result);
@@ -173,12 +175,12 @@ void shouldReturnNullWhenQueryFindsNoRows() {
@Test
void shouldWrapSqlException() {
QueryExecutionException exception = assertThrows(
- QueryExecutionException.class,
- () -> executor.query(
- "SELECT * FROM missing_table",
- List.of(),
- resultSet -> resultSet.getLong("id")
- )
+ QueryExecutionException.class,
+ () -> executor.query(
+ "SELECT * FROM missing_table",
+ List.of(),
+ resultSet -> resultSet.getLong("id")
+ )
);
assertEquals("Failed to execute query", exception.getMessage());
@@ -186,8 +188,8 @@ void shouldWrapSqlException() {
}
private record User(
- long id,
- String name
+ long id,
+ String name
) {
}
}
diff --git a/src/test/java/dev/sqlcj/schema/parser/DefaultSchemaParserTest.java b/src/test/java/dev/sqlcj/schema/parser/DefaultSchemaParserTest.java
index 8ec5d0d..3155439 100644
--- a/src/test/java/dev/sqlcj/schema/parser/DefaultSchemaParserTest.java
+++ b/src/test/java/dev/sqlcj/schema/parser/DefaultSchemaParserTest.java
@@ -21,12 +21,12 @@ class DefaultSchemaParserTest {
@Test
void shouldParseTable() {
String sql = """
- CREATE TABLE users (
- id BIGINT NOT NULL,
- name VARCHAR(255),
- active BOOLEAN
- );
- """;
+ CREATE TABLE users (
+ id BIGINT NOT NULL,
+ name VARCHAR(255),
+ active BOOLEAN
+ );
+ """;
Schema schema = parser.parse(sql);
@@ -53,18 +53,18 @@ name VARCHAR(255),
Table table = schema.tables().getFirst();
assertEquals(
- new Column("id", ColumnType.BIGINT, false),
- table.columns().get(0)
+ new Column("id", ColumnType.BIGINT, false),
+ table.columns().get(0)
);
assertEquals(
- new Column("name", ColumnType.VARCHAR, true),
- table.columns().get(1)
+ new Column("name", ColumnType.VARCHAR, true),
+ table.columns().get(1)
);
assertEquals(
- new Column("active", ColumnType.BOOLEAN, true),
- table.columns().get(2)
+ new Column("active", ColumnType.BOOLEAN, true),
+ table.columns().get(2)
);
}
@@ -84,17 +84,17 @@ PRIMARY KEY (id),
Table table = schema.tables().getFirst();
assertEquals(
- List.of(
- new Constraint(
- ConstraintType.PRIMARY_KEY,
- List.of("id")
- ),
- new Constraint(
- ConstraintType.UNIQUE,
- List.of("email")
- )
+ List.of(
+ new Constraint(
+ ConstraintType.PRIMARY_KEY,
+ List.of("id")
),
- table.constraints()
+ new Constraint(
+ ConstraintType.UNIQUE,
+ List.of("email")
+ )
+ ),
+ table.constraints()
);
}
@@ -122,8 +122,8 @@ CREATE TABLE users (
""";
assertThrows(
- SchemaParseException.class,
- () -> parser.parse(sql)
+ SchemaParseException.class,
+ () -> parser.parse(sql)
);
}
}