Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Drop validation macro #7

Merged
merged 2 commits into from
Sep 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
13 changes: 0 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,16 +74,3 @@ DB.autoClose(conn) { db =>
}
}
```

## SQL Validation (Experimental)

scala-jdbc provides `sqlc` macro that validates a given SQL. You can use it instead of sql string interpolation.

```scala
db.selectFirst(sqlc(s"SELECT * FROM USERS WHERE USER_ID = $userId")){ rs =>
(rs.getInt("USER_ID"), rs.getString("USER_NAME"))
}
```

This macro checks the sql syntax using [JsqlParser](https://github.com/JSQLParser/JSqlParser). When a given SQL is invalid, errors are reported in compile time.

2 changes: 0 additions & 2 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ scalaVersion := "2.13.8"
crossScalaVersions := Seq("2.11.12", "2.12.16", "2.13.8")

libraryDependencies ++= Seq(
"com.github.jsqlparser" % "jsqlparser" % "0.9.6",
"org.scalamacros" %% "resetallattrs" % "1.0.0",
"org.scala-lang" % "scala-reflect" % scalaVersion.value,
"org.scala-lang" % "scala-compiler" % scalaVersion.value % "provided",
"org.scalatest" %% "scalatest" % "3.0.8" % "test",
Expand Down
1 change: 0 additions & 1 deletion src/main/scala/com/github/takezoe/scala/jdbc/IOUtils.scala
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ object IOUtils {
}
}


def readStreamAsString(in: InputStream): String = {
val buf = new Array[Byte](1024 * 8)
var length = 0
Expand Down
51 changes: 2 additions & 49 deletions src/main/scala/com/github/takezoe/scala/jdbc/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import com.github.takezoe.scala.jdbc.SqlTemplate

import scala.language.experimental.macros
import scala.reflect.macros.blackbox.Context
import com.github.takezoe.scala.jdbc.validation._

import scala.language.implicitConversions

package object jdbc {

Expand All @@ -24,52 +25,4 @@ package object jdbc {
}

case class SqlTemplate(sql: String, params: Any*)

/**
* Macro version of sql string interpolation.
* This macro validates the given sql in compile time and returns SqlTemplate as same as string interpolation.
*/
def sqlc(sql: String): com.github.takezoe.scala.jdbc.SqlTemplate = macro Macros.validateSqlMacro

}

object Macros {

def validateSqlMacro(c: Context)(sql: c.Expr[String]): c.Expr[com.github.takezoe.scala.jdbc.SqlTemplate] = {
import c.universe._
sql.tree match {
case Literal(x) => x.value match {
case sql: String => SqlValidator.validateSql(sql, Nil, c)
val Apply(fun, _) = reify(new SqlTemplate("")).tree
c.Expr[com.github.takezoe.scala.jdbc.SqlTemplate](Apply.apply(fun, Literal(x) :: Nil))
}
case Apply(Select(Apply(Select(Select((_, _)), _), trees), _), args) => {
val sql = trees.collect { case Literal(x) => x.value.asInstanceOf[String] }.mkString("?")
SqlValidator.validateSql(sql, args.map(_.tpe.toString), c)
val Apply(fun, _) = reify(new SqlTemplate("")).tree

// args.foreach { arg =>
// println(arg.tpe.getClass)
// }

c.Expr[SqlTemplate](Apply.apply(fun, Literal(Constant(sql)) :: args))
}
case Select(Apply(Select(a, b), List(Literal(x))), TermName("stripMargin")) => {
x.value match {
case s: String =>
val sql = s.stripMargin
SqlValidator.validateSql(sql, Nil, c)
val Apply(fun, _) = reify(new SqlTemplate("")).tree
c.Expr[SqlTemplate](Apply.apply(fun, Literal(Constant(sql)) :: Nil))
}
}
case Select(Apply(_, List(Apply(Select(Apply(Select(Select((_, _)), _), trees), _), args))), TermName("stripMargin")) => {
val sql = trees.collect { case Literal(x) => x.value.asInstanceOf[String] }.mkString("?").stripMargin
SqlValidator.validateSql(sql, args.map(_.tpe.toString), c)
val Apply(fun, _) = reify(new SqlTemplate("")).tree
c.Expr[SqlTemplate](Apply.apply(fun, Literal(Constant(sql)) :: args))
}
}
}

}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,9 @@ class SqlTemplateSpec extends FunSuite {
)""")

db.update(sql"INSERT INTO articles (published,author,title) VALUES (${a.published},${a.author},${a.title})")
db.update(sqlc(s"INSERT INTO articles (published,author,title) VALUES (${a.published},${a.author},${a.title})"))

val aricles = db.select("SELECT * FROM articles", Article.apply _)
assert(aricles.size == 2)
assert(aricles.size == 1)
}
}

Expand Down

This file was deleted.