Permalink
Browse files

Treat non-constant UUID defaults as no default.

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...
1 parent cd85d38 commit e8817bc3939ca2ce79b038001f02b7b155db341c Andrew Miller committed Apr 2, 2016
@@ -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()
+ );
@@ -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()
+ );
@@ -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") {
@@ -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
@@ -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)))
| }
@@ -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
@@ -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"
@@ -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

0 comments on commit e8817bc

Please sign in to comment.