Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions rules/S8318/groovy/metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"title": "Direct JDBC Connection references should be avoided in favor of Groovy's Sql abstraction",
"type": "CODE_SMELL",
"status": "ready",
"remediation": {
"func": "Constant/Issue",
"constantCost": "30 min"
},
"tags": [
"groovy",
"jdbc",
"database"
],
"defaultSeverity": "Blocker",
"ruleSpecification": "RSPEC-8318",
"sqKey": "S8318",
"scope": "Main",
"defaultQualityProfiles": [
"Sonar way"
],
"quickfix": "unknown",
"code": {
"impacts": {
"RELIABILITY": "BLOCKER",
"MAINTAINABILITY": "BLOCKER"
},
"attribute": "CONVENTIONAL"
}
}
68 changes: 68 additions & 0 deletions rules/S8318/groovy/rule.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
This rule raises an issue when code directly references or uses `java.sql.Connection` instead of using Groovy's `Sql` abstraction layer.

== Why is this an issue?

Direct use of `java.sql.Connection` in Groovy applications goes against idiomatic Groovy practices and creates unnecessary complexity.

Groovy provides the `Sql` class as a higher-level abstraction over JDBC that offers several advantages:

* **Automatic resource management**: The `Sql` class handles connection, statement, and result set cleanup automatically, reducing the risk of resource leaks.
* **Concise syntax**: Groovy's `Sql` provides methods like `eachRow()`, `rows()`, and `execute()` that eliminate boilerplate code.
* **Built-in error handling**: The abstraction layer includes better exception handling and resource cleanup in error scenarios.
* **Groovy-friendly result handling**: Results are returned as `GroovyRowResult` objects that can be accessed using property syntax.

Using raw JDBC connections requires manual resource management, verbose try-catch-finally blocks, and explicit handling of statements and result sets. This approach is more error-prone and harder to maintain.

=== What is the potential impact?

Using direct JDBC connections can lead to resource leaks if connections, statements, or result sets are not properly closed. This can cause database connection pool exhaustion and application performance degradation. Additionally, the code becomes more verbose and harder to maintain compared to using Groovy's idiomatic database access patterns.

== How to fix it

Replace direct Connection usage with Groovy's Sql class. Use the Sql constructor with a DataSource and leverage its convenient methods for database operations.

=== Code examples

==== Noncompliant code example

[source,groovy,diff-id=1,diff-type=noncompliant]
----
import java.sql.Connection
import java.sql.Statement
import java.sql.ResultSet

Connection conn = dataSource.getConnection() // Noncompliant
Statement stmt = conn.createStatement()
ResultSet rs = stmt.executeQuery('SELECT * FROM users')
while (rs.next()) {
println rs.getString('name')
}
rs.close()
stmt.close()
conn.close()
----

==== Compliant solution

[source,groovy,diff-id=1,diff-type=compliant]
----
import groovy.sql.Sql

Sql sql = new Sql(dataSource)
sql.eachRow('SELECT * FROM users') { row ->
println row.name
}
sql.close()
----

== Resources

=== Documentation

* Groovy Sql Documentation - https://docs.groovy-lang.org/latest/html/api/groovy/sql/Sql.html[Official Groovy documentation for the Sql class and its methods]

* Groovy Database Programming - https://groovy-lang.org/databases.html[Groovy guide on database programming using the Sql abstraction]

=== Related rules

* CodeNarc-JdbcConnectionReference - https://codenarc.org/codenarc-rules-jdbc.html#jdbcconnectionreference-rule[CodeNarc rule that checks for direct use of java.sql.Connection]
2 changes: 2 additions & 0 deletions rules/S8318/metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
{
}