-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from takezoe/sql_validation_macro
SQL validation macro
- Loading branch information
Showing
12 changed files
with
586 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
{ | ||
"tables":[ | ||
{ | ||
"name": "USER", | ||
"columns": [ | ||
{ | ||
"name": "USER_ID" | ||
}, | ||
{ | ||
"name": "USER_NAME" | ||
}, | ||
{ | ||
"name": "DEPT_ID" | ||
} | ||
] | ||
}, | ||
{ | ||
"name": "COMPANY", | ||
"columns": [ | ||
{ | ||
"name": "COMPANY_ID" | ||
}, | ||
{ | ||
"name": "COMPANY_NAME" | ||
} | ||
] | ||
}, | ||
{ | ||
"name": "DEPT", | ||
"columns": [ | ||
{ | ||
"name": "DEPT_ID" | ||
}, | ||
{ | ||
"name": "DEPT_NAME" | ||
} | ||
] | ||
}, | ||
{ | ||
"name": "DEPT_GROUP", | ||
"columns": [ | ||
{ | ||
"name": "DEPT_ID" | ||
} | ||
] | ||
} | ||
|
||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
45 changes: 45 additions & 0 deletions
45
src/main/scala/com/github/takezoe/scala/jdbc/validation/DeleteValidator.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
package com.github.takezoe.scala.jdbc.validation | ||
|
||
import net.sf.jsqlparser.expression.ExpressionVisitorAdapter | ||
import net.sf.jsqlparser.schema.Column | ||
import net.sf.jsqlparser.statement.delete.Delete | ||
import net.sf.jsqlparser.statement.select.SubSelect | ||
|
||
import scala.reflect.macros.blackbox | ||
|
||
class DeleteValidator(c: blackbox.Context, delete: Delete, schema: Map[String, TableDef]) { | ||
|
||
def validate(): Unit = { | ||
val tableName = delete.getTable.getName | ||
|
||
schema.get(tableName) match { | ||
case None => if(schema.nonEmpty){ | ||
c.error(c.enclosingPosition, "Table " + tableName + " does not exist.") | ||
} | ||
case Some(tableDef) => { | ||
val select = new SelectModel() | ||
val tableModel = new TableModel() | ||
tableModel.select = Left(tableName) | ||
select.from += tableModel | ||
|
||
delete.getWhere.accept(new ExpressionVisitorAdapter { | ||
override def visit(column: Column): Unit = { | ||
val c = new ColumnModel() | ||
c.name = column.getColumnName | ||
c.table = Option(tableName) | ||
select.where += c | ||
} | ||
|
||
override def visit(subSelect: SubSelect): Unit = { | ||
val visitor = new SelectVisitor(c) | ||
subSelect.getSelectBody.accept(visitor) | ||
select.others += visitor.select | ||
} | ||
}) | ||
|
||
select.validate(c, schema) | ||
} | ||
} | ||
} | ||
|
||
} |
31 changes: 31 additions & 0 deletions
31
src/main/scala/com/github/takezoe/scala/jdbc/validation/InsertValidator.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package com.github.takezoe.scala.jdbc.validation | ||
|
||
import net.sf.jsqlparser.statement.insert.Insert | ||
|
||
import scala.collection.JavaConverters._ | ||
import scala.reflect.macros.blackbox | ||
|
||
class InsertValidator(c: blackbox.Context, insert: Insert, schema: Map[String, TableDef]) { | ||
|
||
def validate(): Unit = { | ||
val tableName = insert.getTable.getName | ||
|
||
schema.get(tableName) match { | ||
case None => if(schema.nonEmpty){ | ||
c.error(c.enclosingPosition, "Table " + tableName + " does not exist.") | ||
} | ||
case Some(tableDef) => insert.getColumns.asScala.foreach { column => | ||
if(!tableDef.columns.exists(_.name == column.getColumnName)){ | ||
c.error(c.enclosingPosition, "Column " + column.getColumnName + " does not exist in " + tableDef.name + ".") | ||
} | ||
} | ||
} | ||
|
||
if(insert.getSelect != null){ | ||
val visitor = new SelectVisitor(c) | ||
insert.getSelect.getSelectBody.accept(visitor) | ||
visitor.select.validate(c, schema) | ||
} | ||
} | ||
|
||
} |
32 changes: 32 additions & 0 deletions
32
src/main/scala/com/github/takezoe/scala/jdbc/validation/SchemaDef.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package com.github.takezoe.scala.jdbc.validation | ||
|
||
import better.files.File | ||
import com.fasterxml.jackson.databind.{DeserializationFeature, ObjectMapper} | ||
import com.fasterxml.jackson.module.scala.DefaultScalaModule | ||
|
||
case class SchemaDef(tables: Seq[TableDef]) | ||
|
||
case class TableDef(name:String, columns: Seq[ColumnDef]) | ||
|
||
case class ColumnDef(name: String) | ||
|
||
object SchemaDef { | ||
|
||
private val mapper = new ObjectMapper() | ||
mapper.enable(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS) | ||
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) | ||
mapper.registerModule(DefaultScalaModule) | ||
|
||
def load(): Map[String, TableDef] = { | ||
val file = File("schema.json") | ||
val schema: Map[String, TableDef] = if(file.exists){ | ||
val json = file.contentAsString | ||
val schema = mapper.readValue(json, classOf[SchemaDef]) | ||
schema.tables.map { t => t.name -> t }.toMap | ||
} else { | ||
Map.empty | ||
} | ||
schema | ||
} | ||
|
||
} |
16 changes: 16 additions & 0 deletions
16
src/main/scala/com/github/takezoe/scala/jdbc/validation/SelectValidator.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package com.github.takezoe.scala.jdbc.validation | ||
|
||
import net.sf.jsqlparser.statement.select.Select | ||
|
||
import scala.reflect.macros.blackbox | ||
|
||
class SelectValidator(c: blackbox.Context, select: Select, schema: Map[String, TableDef]) { | ||
|
||
def validate(): Unit = { | ||
val visitor = new SelectVisitor(c) | ||
select.getSelectBody.accept(visitor) | ||
|
||
visitor.select.validate(c, schema) | ||
} | ||
|
||
} |
Oops, something went wrong.