Permalink
Browse files

Fixes #1699. Throws an exception if `insertOrUpdate()` is called on a…

… table without primary keys;
  • Loading branch information...
greenhat committed Jan 5, 2018
1 parent f0776fb commit 64653b84331ebce59dfc18f66e8e1677dfed9356
@@ -162,6 +162,26 @@ class InsertTest extends AsyncTest[JdbcTestDB] {
} yield ()
}
def testInsertOrUpdateNoPK = {
class T(tag: Tag) extends Table[(Int, String)](tag, "t_merge_no_pk") {
def id = column[Int]("id")
def name = column[String]("name")
def * = (id, name)
def ins = (id, name)
}
val ts = TableQuery[T]
val failed = try {
ts.insertOrUpdate((3, "c"))
false
}
catch {
case _: SlickException => true
}
if (!failed) throw new RuntimeException("Should fail since insertOrUpdate is not supported on a table without PK.")
DBIO.seq()
}
def testInsertOrUpdatePlainWithFuncDefinedPK: DBIOAction[Unit, _, _] = {
//FIXME remove this after fixed checkInsert issue
if (tdb.profile.isInstanceOf[DerbyProfile]) return DBIO.successful(())
@@ -10,6 +10,7 @@ import scala.collection.mutable.Builder
import scala.util.control.NonFatal
import slick.SlickException
import slick.ast.ColumnOption.PrimaryKey
import slick.dbio._
import slick.ast._
import slick.ast.Util._
@@ -537,6 +538,17 @@ trait JdbcActionComponent extends SqlActionComponent { self: JdbcProfile =>
class InsertOrUpdateAction(value: U) extends SimpleJdbcProfileAction[SingleInsertOrUpdateResult]("InsertOrUpdateAction",
if(useServerSideUpsert) Vector(compiled.upsert.sql) else Vector(compiled.checkInsert.sql, compiled.updateInsert.sql, compiled.standardInsert.sql)) {
private def tableHasPrimaryKey: Boolean =
List(compiled.upsert, compiled.checkInsert, compiled.updateInsert)
.filter(_ != null)
.exists(artifacts =>
artifacts.ibr.table.profileTable.asInstanceOf[Table[_]].primaryKeys.nonEmpty
|| artifacts.ibr.fields.exists(_.options.contains(PrimaryKey))
)
if (!tableHasPrimaryKey)
throw new SlickException("InsertOrUpdate is not supported on a table without PK.")
def run(ctx: Backend#Context, sql: Vector[String]) = {
def f: SingleInsertOrUpdateResult =
if(useServerSideUpsert) nativeUpsert(value, sql.head)(ctx.session) else emulate(value, sql(0), sql(1), sql(2))(ctx.session)

0 comments on commit 64653b8

Please sign in to comment.