Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
gustavoamigo committed Jul 21, 2016
1 parent cbe4d05 commit 75f00e3
Show file tree
Hide file tree
Showing 6 changed files with 35 additions and 27 deletions.
9 changes: 4 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -202,18 +202,17 @@ object schema {
}
```

It is possible to define a column that is a key generated by the database. It will be ignored during insertions and returned as the result.

Note that it accepts only values that can be read as `Long`.
It is possible to make a column that is a generated by the database to be ignored during insertions and returned as
a returning value.

```scala
case class Product(id: Long, description: String, sku: Long)

val q = quote {
query[Product].schema(_.generated(_.id)).insert
query[Product].insert.returning(_.id)
}

ctx.run(q)
val returnedIds = ctx.run(q)(List(Product(0L, "My Product", 1011L)))
// INSERT INTO Product (description,sku) VALUES (?, ?)
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ class MysqlAsyncContext[N <: NamingStrategy](pool: PartitionedConnectionPool[MyS
(generated, result) match {
case (None, r) => r.rowsAffected.asInstanceOf[O]
case (Some(_), r: MySQLQueryResult) => r.lastInsertId.asInstanceOf[O]
case _ => throw new IllegalStateException("This is a bug. Cannot extract generated value.")
case _ => throw new IllegalStateException("This is a bug. Cannot extract returning value.")
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@ class PostgresAsyncContextSpec extends Spec {
val insert = quote { (i: Int) =>
qr1.insert(_.i -> i)
}
await(testContext.run(insert)(List(1))).head mustEqual (1)
await(testContext.run(insert)(List(1))) must contain(1)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,13 @@ class PostgresAsyncEncodingSpec extends EncodingSpec {
}

"returning UUID" in {
val uuid = Await.result(testContext.run(insertBarCode)(barCodeEntry), Duration.Inf).head
val barCode = Await.result(testContext.run(findBarCodeByUuid(uuid.get)), Duration.Inf).head
verifyBarcode(barCode)
val success = for {
uuidOpt <- Await.result(testContext.run(insertBarCode)(barCodeEntry), Duration.Inf).headOption
uuid <- uuidOpt
barCode <- Await.result(testContext.run(findBarCodeByUuid(uuid)), Duration.Inf).headOption
} yield {
verifyBarcode(barCode)
}
success must not be empty
}
}
24 changes: 10 additions & 14 deletions quill-core/src/main/scala/io/getquill/context/ActionMacro.scala
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ trait ActionMacro extends EncodingMacro {
functionParams match {
case Nil =>
val encodedParams = EncodeParams[S](c)(inPlaceParams, collection.Map())
expandedTreeSingle[R](quotedTree, action, inPlaceParams.map(_._1).toList, encodedParams, bodyType(t.tpe))
expandedTreeSingle[R](quotedTree, action, inPlaceParams.map(_._1).toList, encodedParams, returningType(t.tpe))

case List((param, tpe)) if (t.tpe.erasure <:< c.weakTypeOf[CoreDsl#UnassignedAction[Any, Any]].erasure) =>
val encodingValue = encoding(param, Encoding.inferEncoder[S](c))(c.WeakTypeTag(tpe))
Expand All @@ -40,11 +40,11 @@ trait ActionMacro extends EncodingMacro {
val assignedAction = AssignedAction(action, idents.map(k => Assignment(Ident("x"), k.name, k)))
val encodedParams = EncodeParams[S](c)(inPlaceParams, bindings.toMap)

expandedTreeBatch[R](quotedTree, assignedAction, idents.toList ++ inPlaceParams.map(_._1), List(tpe), encodedParams, bodyType(t.tpe))
expandedTreeBatch[R](quotedTree, assignedAction, idents.toList ++ inPlaceParams.map(_._1), List(tpe), encodedParams, returningType(t.tpe))

case functionParams =>
val encodedParams = EncodeParams[S](c)(bindingMap(functionParams) ++ inPlaceParams, collection.Map())
expandedTreeBatch[R](quotedTree, action, functionParams.map(_._1) ++ inPlaceParams.map(_._1), functionParams.map(_._2), encodedParams, bodyType(t.tpe))
expandedTreeBatch[R](quotedTree, action, functionParams.map(_._1) ++ inPlaceParams.map(_._1), functionParams.map(_._2), encodedParams, returningType(t.tpe))
}
}

Expand All @@ -54,45 +54,41 @@ trait ActionMacro extends EncodingMacro {
selectResultExtractor[R](selectValues)
}

private def expandedTreeSingle[R](quotedTree: Tree, action: Ast, idents: List[Ident], encodedParams: Tree, bodyTpe: Type)(implicit r: WeakTypeTag[R]) = {
private def expandedTreeSingle[R](quotedTree: Tree, action: Ast, idents: List[Ident], encodedParams: Tree, returningType: Type)(implicit r: WeakTypeTag[R]) = {
q"""
{
val quoted = $quotedTree
val (sql, bindings: List[io.getquill.ast.Ident], returning) =
${prepare(action, idents)}

${c.prefix}.executeAction[$bodyTpe](
${c.prefix}.executeAction[$returningType](
sql,
$encodedParams(bindings.map(_.name)),
returning,
${returningExtractor(bodyTpe)(r)}
${returningExtractor(returningType)(r)}
)
}
"""
}

private def expandedTreeBatch[R](quotedTree: Tree, action: Ast, idents: List[Ident], paramsTypes: List[Type], encodedParams: Tree, bodyTpe: Type)(implicit r: WeakTypeTag[R]) = {
private def expandedTreeBatch[R](quotedTree: Tree, action: Ast, idents: List[Ident], paramsTypes: List[Type], encodedParams: Tree, returningType: Type)(implicit r: WeakTypeTag[R]) = {
q"""
{
val quoted = $quotedTree
val (sql, bindings: List[io.getquill.ast.Ident], returning) =
${prepare(action, idents)}

${c.prefix}.executeActionBatch[(..$paramsTypes), $bodyTpe](
${c.prefix}.executeActionBatch[(..$paramsTypes), $returningType](
sql,
value => $encodedParams(bindings.map(_.name)),
returning,
${returningExtractor(bodyTpe)(r)}
${returningExtractor(returningType)(r)}
)
}
"""
}

private def bodyType(tpe: Type): Type =
if (tpe <:< c.typeOf[CoreDsl#Action[_, _]]) {
tpe.baseType(c.typeOf[CoreDsl#Action[_, _]].typeSymbol).typeArgs(1)
} else
fail("This is a bug, didnt work") // TODO: Better error message
private def returningType(tpe: Type): Type = tpe.baseType(c.typeOf[CoreDsl#Action[_, _]].typeSymbol).typeArgs(1)

private def bindingMap(value: Value, option: Boolean = false): List[(Ident, (Tree, Tree))] =
value match {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,15 @@ class JdbcEncodingSpec extends EncodingSpec {
row.setObject(idx, uuid, Types.OTHER)
}

val uuid = testContext.run(insertBarCode)(barCodeEntry).head
val barCode = testContext.run(findBarCodeByUuid(uuid.get)).head
verifyBarcode(barCode)
val success = for {
uuidOpt <- testContext.run(insertBarCode)(barCodeEntry).headOption
uuid <- uuidOpt
barCode <- testContext.run(findBarCodeByUuid(uuid)).headOption
} yield {
verifyBarcode(barCode)
}

success must not be empty

}
}

0 comments on commit 75f00e3

Please sign in to comment.