Skip to content

Commit e6b2bc2

Browse files
committed
Add per-query SQL syntax validation toggle (@Query(checkSyntax)), update README with usage examples, and refactor validation mechanism in RepositoryProcessor.
1 parent 427c97d commit e6b2bc2

File tree

3 files changed

+39
-10
lines changed

3 files changed

+39
-10
lines changed

README.md

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -368,7 +368,8 @@ For more details take a look at the [examples](./examples).
368368
- When it runs: at KSP processing time, before your code is compiled/run.
369369
- Dialect notes: validation is dialect-agnostic and aims for an ANSI/portable subset. Some vendor-specific features
370370
(e.g., certain MySQL or PostgreSQL extensions) may not be recognized. If you hit a false positive, you can disable
371-
validation per module with ksp arg validate-sql-syntax=false.
371+
validation per module with ksp arg validate-sql-syntax=false, or disable it per query with
372+
`@Query(checkSyntax = false)`.
372373
- Most reliable with: SELECT, INSERT, UPDATE, DELETE statements. DDL or very advanced constructs may not be fully
373374
supported.
374375

@@ -380,12 +381,24 @@ Invalid SQL in function findAllBy: Encountered "FROMM" at line 1, column 15
380381
```
381382

382383
Tip: keep it enabled to catch typos early; if you rely heavily on vendor-specific syntax not yet supported by the
383-
parser, turn it off with:
384+
parser, turn it off either globally or just for a specific method:
385+
386+
- Globally (module-wide):
384387

385388
```kotlin
386389
ksp { arg("validate-sql-syntax", "false") }
387390
```
388391

392+
- Per query:
393+
394+
```kotlin
395+
@Repository(mapper = UserMapper::class)
396+
interface UserRepository {
397+
@Query("select * from users where id = :id", checkSyntax = false)
398+
suspend fun findOneById(context: QueryExecutor, id: Int): Result<User?>
399+
}
400+
```
401+
389402
### Database Migrations
390403

391404
Run any pending migrations against the database; and validate previously applied migrations against the current

sqlx4k-codegen/src/jvmMain/kotlin/io/github/smyrgeorge/sqlx4k/processor/RepositoryProcessor.kt

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@ class RepositoryProcessor(
3232
?: error("Missing ${TableProcessor.PACKAGE_OPTION} option")
3333
logger.info("[RepositoryProcessor] Output package: $outputPackage")
3434

35-
val validateSqlSyntax = options[VALIDATE_SQL_SYNTAX_OPTION]?.toBoolean() ?: true
36-
logger.info("[RepositoryProcessor] Validate SQL syntax: $validateSqlSyntax")
35+
val globalCheckSqlSyntax = options[VALIDATE_SQL_SYNTAX_OPTION]?.toBoolean() ?: true
36+
logger.info("[RepositoryProcessor] Validate SQL syntax: $globalCheckSqlSyntax")
3737

3838
val outputFilename = "GeneratedRepositories"
3939

@@ -72,7 +72,14 @@ class RepositoryProcessor(
7272
// findAll/findAllBy/findOneBy/deleteBy/countBy/execute and also *All variants
7373
fnsAll
7474
.filter { fn -> fn.annotations.any { it.qualifiedName() == TypeNames.QUERY_ANNOTATION } }
75-
.forEach { fn -> emitQueryMethod(file, fn, validateSqlSyntax, mapperTypeName, domainDecl) }
75+
.forEach { fn ->
76+
val queryAnn = fn.annotations.first { it.qualifiedName() == TypeNames.QUERY_ANNOTATION }
77+
val localCheckSqlSyntax = queryAnn.arguments
78+
.firstOrNull { it.name?.asString() == "checkSyntax" }
79+
?.value as? Boolean ?: true
80+
val doCheckSyntax = globalCheckSqlSyntax && localCheckSqlSyntax
81+
emitQueryMethod(file, fn, doCheckSyntax, mapperTypeName, domainDecl)
82+
}
7683

7784
// Generate CRUD methods: insert/update/delete;
7885
// Interface must implement CrudRepository<Domain> which we already validated.
Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,21 @@
11
package io.github.smyrgeorge.sqlx4k.annotation
22

33
/**
4-
* Annotation used to specify a query string for a database operation.
5-
* This annotation is applied to functions to indicate the query
6-
* that should be executed when the function is called.
4+
* Annotates a repository function with an inline SQL query to execute.
75
*
8-
* @property value The query string to be executed.
6+
* This is consumed by the KSP code generator to produce the implementation
7+
* and (optionally) validate the SQL syntax at compile time.
8+
*
9+
* Properties:
10+
* - value: the SQL string to execute. Named parameters are supported using :name.
11+
* - checkSyntax: when true (default), the processor will validate the SQL syntax
12+
* at compile time using JSqlParser, subject to the module-wide setting
13+
* `ksp { arg("validate-sql-syntax", "true|false") }`. Set to false to skip
14+
* validation for this specific query while leaving global validation enabled.
915
*/
1016
@Target(AnnotationTarget.FUNCTION)
1117
@Retention(AnnotationRetention.SOURCE)
12-
annotation class Query(val value: String)
18+
annotation class Query(
19+
val value: String,
20+
val checkSyntax: Boolean = true,
21+
)

0 commit comments

Comments
 (0)