Skip to content

Commit

Permalink
Treat non-constant UUID defaults as no default.
Browse files Browse the repository at this point in the history
If the database has a default which is not a constant value, Slick is not able
to represent the fact that the default for a column is a computed value. In
the case of UUIDs, this change will mean that if the UUID default is given as
an SQL function (for example, to generate a UUID), Slick will instead treat
the column as not having a default.
  • Loading branch information
A1kmm committed Apr 2, 2016
1 parent cd85d38 commit e8817bc
Show file tree
Hide file tree
Showing 6 changed files with 30 additions and 10 deletions.
@@ -1,3 +1,5 @@
create table "person" ("id" INTEGER NOT NULL PRIMARY KEY,
"uuid" UUID NOT NULL,
"uuid_def" UUID DEFAULT('2f3f866c-d8e6-11e2-bb56-50e549c9b654'));
"uuid_def" UUID DEFAULT('2f3f866c-d8e6-11e2-bb56-50e549c9b654'),
"uuid_func" UUID DEFAULT random_uuid()
);
5 changes: 5 additions & 0 deletions slick-testkit/src/codegen/resources/dbs/uuid-postgres.sql
@@ -0,0 +1,5 @@
create table "person" ("id" INTEGER NOT NULL PRIMARY KEY,
"uuid" UUID NOT NULL,
"uuid_def" UUID DEFAULT('2f3f866c-d8e6-11e2-bb56-50e549c9b654'),
"uuid_func" UUID DEFAULT uuid_generate_v4()
);
Expand Up @@ -79,7 +79,7 @@ val SimpleA = CustomTyping.SimpleA
}
})
},
new UUIDConfig("CG10", StandardTestDBs.H2Mem, "H2Mem", Seq("/dbs/uuid.sql")),
new UUIDConfig("CG10", StandardTestDBs.H2Mem, "H2Mem", Seq("/dbs/uuid-h2.sql")),
new Config("Postgres1", StandardTestDBs.Postgres, "Postgres", Nil) {
import tdb.profile.api._
class A(tag: Tag) extends Table[(Int, Array[Byte], Blob)](tag, "a") {
Expand All @@ -103,7 +103,7 @@ val SimpleA = CustomTyping.SimpleA
| ).transactionally
""".stripMargin
},
new UUIDConfig("Postgres2", StandardTestDBs.Postgres, "Postgres", Seq("/dbs/uuid.sql")),
new UUIDConfig("Postgres2", StandardTestDBs.Postgres, "Postgres", Seq("/dbs/uuid-postgres.sql")),
new Config("EmptyDB", StandardTestDBs.H2Mem, "H2Mem", Nil),
new Config("Oracle1", StandardTestDBs.Oracle, "Oracle", Seq("/dbs/oracle1.sql")) {
override def useSingleLineStatements = true
Expand Down Expand Up @@ -143,13 +143,16 @@ val SimpleA = CustomTyping.SimpleA
| import java.util.UUID
| val u1 = UUID.randomUUID()
| val u2 = UUID.randomUUID()
| val p1 = PersonRow(1, u1)
| val p2 = PersonRow(2, u2)
| val u3 = UUID.randomUUID()
| val u4 = UUID.randomUUID()
| val p1 = PersonRow(1, u1, uuidFunc = Some(u3))
| val p2 = PersonRow(2, u2, uuidFunc = Some(u4))
|
| def assertAll(all: Seq[PersonRow]) = {
| assertEquals( 2, all.size )
| assertEquals( Set(1,2), all.map(_.id).toSet )
| assertEquals( Set(u1, u2), all.map(_.uuid).toSet )
| assertEquals( Set(Some(u3), Some(u4)), all.map(_.uuidFunc).toSet )
| //it should contain sample UUID
| assert(all.forall(_.uuidDef == Some(defaultUUID)))
| }
Expand Down
5 changes: 4 additions & 1 deletion slick-testkit/src/main/resources/testkit-reference.conf
Expand Up @@ -92,7 +92,10 @@ postgres {
CREATE TABLESPACE slick_test LOCATION '${testkit.absTestDir}'
CREATE DATABASE ${testDB} "TEMPLATE = template0 TABLESPACE slick_test"
]
postCreate = "create extension lo"
postCreate = [
"create extension lo",
"create extension \"uuid-ossp\""
]
drop = [
DROP DATABASE IF EXISTS ${testDB}
DROP TABLESPACE IF EXISTS slick_test
Expand Down
6 changes: 5 additions & 1 deletion slick/src/main/scala/slick/jdbc/H2Profile.scala
Expand Up @@ -56,7 +56,11 @@ trait H2Profile extends JdbcProfile {
override def createColumnBuilder(tableBuilder: TableBuilder, meta: MColumn): ColumnBuilder = new ColumnBuilder(tableBuilder, meta) {
override def length = super.length.filter(_ != Int.MaxValue) // H2 sometimes show this value, but doesn't accept it back in the DBType
override def default = rawDefault.map((_,tpe)).collect{
case (v,"java.util.UUID") => Some(Some(java.util.UUID.fromString(v.replaceAll("[\'\"]", "")))) //strip quotes
case (v,"java.util.UUID") =>
if (v.matches("^['\"].*['\"]$"))
Some(Some(java.util.UUID.fromString(v.replaceAll("[\'\"]", "")))) //strip quotes
else
None // The UUID is generated through a function - treat it as if there was no default.
}.getOrElse{super.default}
override def tpe = dbType match {
case Some("UUID") => "java.util.UUID"
Expand Down
9 changes: 6 additions & 3 deletions slick/src/main/scala/slick/jdbc/PostgresProfile.scala
Expand Up @@ -73,9 +73,12 @@ trait PostgresProfile extends JdbcProfile {
case (IntPattern(v),"Long") => Some(Some(v.toLong))
case ("NULL::character varying","String") => Some(None)
case (v,"java.util.UUID") => {
val uuid = v.replaceAll("[\'\"]", "") //strip quotes
.stripSuffix("::uuid") //strip suffix
Some(Some(java.util.UUID.fromString(uuid)))
if (v.matches("^['\"].*['\"](::uuid)?$")) {
val uuid = v.replaceAll("[\'\"]", "") //strip quotes
.stripSuffix("::uuid") //strip suffix
Some(Some(java.util.UUID.fromString(uuid)))
} else
None // The UUID is generated through a function - treat it as if there was no default.
}
}.getOrElse{
val d = super.default
Expand Down

0 comments on commit e8817bc

Please sign in to comment.