package com.jacoby6000.smithplates.testkit

import com.jacoby6000.smithplates.sql.ddl.renderer.common.SqlSchemaDdlRenderer
import com.jacoby6000.smithplates.sql.model.DDLStatement
import com.jacoby6000.smithplates.sql.model.SqlSchema

import java.sql.Connection
import scala.util.Try

object SqlDdlSupport {
  def renderSchemaDdlStatements(renderer: SqlSchemaDdlRenderer, schema: SqlSchema): List[DDLStatement] =
    renderer.renderSchemaDdlStatements(schema)

  def applyDdl(connection: Connection, statements: Iterable[DDLStatement]): Unit = {
    val statement = connection.createStatement()
    try
      statements.foreach { ddl =>
        statement.execute(ddl.statement)
      }
    finally statement.close()
  }

  def applyDdl(connection: Connection, renderer: SqlSchemaDdlRenderer, schema: SqlSchema): Unit =
    applyDdl(connection, renderSchemaDdlStatements(renderer, schema))

  def assertInsertFails(connection: Connection, sql: String): Unit = {
    val failed = Try(executeUpdate(connection, sql)).isFailure
    if (!failed) {
      throw new AssertionError(s"expected statement to fail: $sql")
    }
  }

  def executeUpdate(connection: Connection, sql: String): Unit = {
    val statement = connection.createStatement()
    try {
      val _ = statement.executeUpdate(sql)
    } finally statement.close()
  }
}
