diff --git a/README.md b/README.md index 4374918..5b9689c 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ A WASM plugin for SQLC allowing the generation of Java code. | `package` | string | yes | The name of the package where the generated files will be located. | | `emit_exact_table_names` | boolean | no | Whether table names will not be forced to singular form when generating the models. Defaults to `false`. | | `inflection_exclude_table_names` | []string | no | Table names to be excluded from being forced into singular form when generating the models. | -| `query_parameter_limit` | integer | no | not yet implemented | +| `query_parameter_limit` | integer | no | The max number of query parameters allowed before automatically generating a data model for method input. | | `indent_char` | string | no | The character to use to indent the code. Defaults to space `" "`. | | `chars_per_indent_level` | integer | no | The number of characters per indent level. Defaults to `4`. | | `nullable_annotation` | string | no | The full import path for the nullable annotation to use. Defaults to `org.jspecify.annotations.Nullable`. Set to empty string to disable. | diff --git a/internal/codegen/queries.go b/internal/codegen/queries.go index f0d0205..3080742 100644 --- a/internal/codegen/queries.go +++ b/internal/codegen/queries.go @@ -14,6 +14,10 @@ func resultRecordName(q core.Query) string { return strcase.ToCamel(q.MethodName) + "Row" } +func queryInputName(q core.Query) string { + return strcase.ToCamel(q.MethodName) + "QueryInput" +} + func createEmbeddedModel(sb *IndentStringBuilder, prefix, suffix string, identLevel, paramIdx int, r core.QueryReturn, embeddedModels core.EmbeddedModels) int { modelName := *r.EmbeddedModel model := embeddedModels[modelName] @@ -247,12 +251,15 @@ func BuildQueriesFile(engine string, config core.Config, queryFilename string, q methodBody.WriteIndentedString(2, "var stmt = conn.prepareStatement("+q.MethodName+");\n") } - // write the method signature - body.WriteString("\n") - body.WriteIndentedString(1, fmt.Sprintf("public %s %s(", returnType, q.MethodName)) - if len(q.Args) > 0 { - body.WriteString("\n") + queryInput := "" + useInputRecord := config.QueryParameterLimit != 0 && len(q.Args) >= config.QueryParameterLimit + // input method for query params limit + if useInputRecord { + queryInput = queryInputName(q) + + body.WriteString("\n") + body.WriteIndentedString(1, "public record "+queryInput+"(\n") for i, arg := range q.Args { imps, err := body.writeParameter(arg.JavaType, arg.Name, nonNullAnnotation, nullableAnnotation) if err != nil { @@ -265,6 +272,38 @@ func BuildQueriesFile(engine string, config core.Config, queryFilename string, q if i != len(q.Args)-1 { body.WriteString(",\n") } + } + body.WriteString("\n") + body.WriteIndentedString(1, ") {}\n") + } + + // write the method signature + body.WriteString("\n") + body.WriteIndentedString(1, fmt.Sprintf("public %s %s(", returnType, q.MethodName)) + + if len(q.Args) > 0 { + body.WriteString("\n") + + if useInputRecord { + body.WriteIndentedString(2, fmt.Sprintf("%s input", queryInput)) + } + + for i, arg := range q.Args { + if useInputRecord { + arg.Name = "input." + arg.Name + } else { + imps, err := body.writeParameter(arg.JavaType, arg.Name, nonNullAnnotation, nullableAnnotation) + if err != nil { + return "", nil, err + } + if imps != nil { + imports = append(imports, imps...) + } + + if i != len(q.Args)-1 { + body.WriteString(",\n") + } + } methodBody.WriteIndentedString(2, arg.BindStmt(engine)+"\n") }