Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

added statically typed magics, also added support of Date for insertion

  • Loading branch information...
commit cbe162a0ecbf7996eba2ab028264a9cc332cb915 1 parent 5246807
authored August 17, 2011
8  samples-and-tests/just-test-cases/test/SqlTests.scala
@@ -132,7 +132,7 @@ class SqlTests extends UnitTestCase with ShouldMatchersForJUnit {
132 132
   import withDef._
133 133
 
134 134
   case class BBB(id:String,comment:String)
135  
-  object BBB extends MagicParser2[String,String,BBB](Some(Description2("Task")))
  135
+  object BBB extends AbstractMagicParser2[String,String,BBB](Some(Description2("Task")))
136 136
 
137 137
 
138 138
   @Test def useSomeMagicSqlCompileTime{
@@ -148,7 +148,7 @@ class SqlTests extends UnitTestCase with ShouldMatchersForJUnit {
148 148
 
149 149
     play.db.DB.execute("""insert into Task Values('1','some comment')""")
150 150
     play.db.DB.execute("""insert into Student Values('1','1')""")
151  
-    object TT2 extends MagicParser2[String,String,(String,String)](Some(Description2("Task"))) {
  151
+    object TT2 extends AbstractMagicParser2[String,String,(String,String)](Some(Description2("Task"))) {
152 152
 
153 153
       def apply(id:String,comment:String) = (id,comment)
154 154
 
@@ -158,9 +158,9 @@ class SqlTests extends UnitTestCase with ShouldMatchersForJUnit {
158 158
     SQL("select * from Task ").as(TT2) should be (("1","some comment")) 
159 159
   }
160 160
 
161  
- implicit def statementInOut[A](implicit c:ColumnTo[A], ts:ToStatement[A]):(ColumnTo[A],ToStatement[A]) = (c,ts)
162 161
 
163  
-  object AAA extends Magic2[Pk[Int],String,AAA]()
  162
+
  163
+  object AAA extends AbstractMagic2[Pk[Int],String,AAA]()
164 164
   case class AAA(id:Pk[Int],comment:String)
165 165
 
166 166
 
16  src/play/db/anorm/Anorm.scala
@@ -13,9 +13,13 @@ package object anorm {
13 13
     def SQL(stmt: String) = Sql.sql(stmt)
14 14
 
15 15
     val asIs :PartialFunction[AnalyserInfo,String] = {case ColumnC(t,f) => t+"."+f; case TableC(typeName) => typeName}
16  
-    val defaults = Convention(asIs)
17 16
 
18  
-//  implicit def statementInOut[A](implicit c:ColumnTo[A]):(ColumnTo[A],ToStatement[A]) = (c,null)
  17
+    val defaults = new Convention(asIs) with WithDefaults{
  18
+
  19
+        override lazy val defaultConvention = asIs
  20
+    }
  21
+
  22
+    implicit def statementInOut[A](implicit c:ColumnTo[A], ts:ToStatement[A]):(ColumnTo[A],ToStatement[A]) = (c,ts)
19 23
 
20 24
 }
21 25
 
@@ -786,6 +790,7 @@ package anorm {
786 790
                     case Some(o) => stmt.setObject(index, o)
787 791
                     case None => stmt.setObject(index, null)
788 792
                     case bd:java.math.BigDecimal => stmt.setBigDecimal(index,bd)
  793
+                    case date:java.util.Date => stmt.setDate(index,new java.sql.Date(date.getTime()))
789 794
                     case o => stmt.setObject(index,o)
790 795
                 }
791 796
                 stmt
@@ -794,6 +799,11 @@ package anorm {
794 799
             def set(s:java.sql.PreparedStatement,index:Int,aValue:T):Unit = setAny(index, aValue, s)
795 800
         }
796 801
 
  802
+        implicit val dateToStatement = new ToStatement[java.util.Date] {
  803
+            def set(s:java.sql.PreparedStatement, index:Int, aValue:java.util.Date):Unit = s.setDate(index,new java.sql.Date(aValue.getTime()))
  804
+
  805
+        }
  806
+
797 807
         implicit def optionToStatement[A](implicit ts:ToStatement[A]):ToStatement[Option[A]] = new ToStatement[Option[A]] {
798 808
             def set(s:java.sql.PreparedStatement,index:Int,aValue:Option[A]):Unit = {
799 809
                 aValue match {
@@ -973,4 +983,4 @@ package anorm {
973 983
     }
974 984
 
975 985
 
976  
-}
  986
+}
155  src/play/db/anorm/Magic10.scala
... ...
@@ -0,0 +1,155 @@
  1
+
  2
+
  3
+
  4
+
  5
+package play.db
  6
+
  7
+import play.utils.Scala.MayErr
  8
+import play.utils.Scala.MayErr._
  9
+
  10
+package anorm {
  11
+
  12
+    trait MParser10[ A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, R] extends ParserWithId[R] {
  13
+    
  14
+        val p1:ColumnTo[A1]
  15
+
  16
+        val p2:ColumnTo[A2]
  17
+
  18
+        val p3:ColumnTo[A3]
  19
+
  20
+        val p4:ColumnTo[A4]
  21
+
  22
+        val p5:ColumnTo[A5]
  23
+
  24
+        val p6:ColumnTo[A6]
  25
+
  26
+        val p7:ColumnTo[A7]
  27
+
  28
+        val p8:ColumnTo[A8]
  29
+
  30
+        val p9:ColumnTo[A9]
  31
+
  32
+        val p10:ColumnTo[A10]
  33
+
  34
+        def apply(a1:A1, a2:A2, a3:A3, a4:A4, a5:A5, a6:A6, a7:A7, a8:A8, a9:A9, a10:A10 ):R
  35
+
  36
+        val containerName:String
  37
+        val columnNames:(String, String, String, String, String, String, String, String, String, String)
  38
+
  39
+        lazy val (name1 ,name2 ,name3 ,name4 ,name5 ,name6 ,name7 ,name8 ,name9 ,name10) = columnNames
  40
+
  41
+        import SqlParser._
  42
+        override def apply(input:Input):SqlParser.ParseResult[R] = 
  43
+            (
  44
+             get[A1](name1)(p1) ~< 
  45
+             get[A2](name2)(p2) ~< 
  46
+             get[A3](name3)(p3) ~< 
  47
+             get[A4](name4)(p4) ~< 
  48
+             get[A5](name5)(p5) ~< 
  49
+             get[A6](name6)(p6) ~< 
  50
+             get[A7](name7)(p7) ~< 
  51
+             get[A8](name8)(p8) ~< 
  52
+             get[A9](name9)(p9) ~< 
  53
+             get[A10](name10)(p10) ^^ { case a1 ~ a2 ~ a3 ~ a4 ~ a5 ~ a6 ~ a7 ~ a8 ~ a9 ~ a10 => apply(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10)} )(input)
  54
+
  55
+        val uniqueId : (Row=> MayErr[SqlRequestError,Any]) = null
  56
+    }
  57
+
  58
+        trait M10[ A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, R] {
  59
+            self: MParser10[ A1, A2, A3, A4, A5, A6, A7, A8, A9, A10,R] =>
  60
+            
  61
+            val pt1:(ColumnTo[A1],ToStatement[A1])
  62
+            val pt2:(ColumnTo[A2],ToStatement[A2])
  63
+            val pt3:(ColumnTo[A3],ToStatement[A3])
  64
+            val pt4:(ColumnTo[A4],ToStatement[A4])
  65
+            val pt5:(ColumnTo[A5],ToStatement[A5])
  66
+            val pt6:(ColumnTo[A6],ToStatement[A6])
  67
+            val pt7:(ColumnTo[A7],ToStatement[A7])
  68
+            val pt8:(ColumnTo[A8],ToStatement[A8])
  69
+            val pt9:(ColumnTo[A9],ToStatement[A9])
  70
+            val pt10:(ColumnTo[A10],ToStatement[A10])
  71
+
  72
+            def unapply(r:R):Option[( A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)]
  73
+            def unqualify(columnName:String) = columnName.split('.').last
  74
+
  75
+            def update(v:R)(implicit hasId: (A1 <:< Pk[_])|:|(A2 <:< Pk[_])|:|(A3 <:< Pk[_])|:|(A4 <:< Pk[_])|:|(A5 <:< Pk[_])|:|(A6 <:< Pk[_])|:|(A7 <:< Pk[_])|:|(A8 <:< Pk[_])|:|(A9 <:< Pk[_])|:|(A10 <:< Pk[_]) ) = {
  76
+
  77
+                val all = ((v,hasId) match {
  78
+                        case (self( a1, a2, a3, a4, a5, a6, a7, a8, a9, a10), ( e1 |:| e2 |:| e3 |:| e4 |:| e5 |:| e6 |:| e7 |:| e8 |:| e9 |:| e10)) => 
  79
+                            List ( 
  80
+                                   (e1, unqualify(name1), toParameterValue(a1)(pt1._2)), 
  81
+                                   (e2, unqualify(name2), toParameterValue(a2)(pt2._2)), 
  82
+                                   (e3, unqualify(name3), toParameterValue(a3)(pt3._2)), 
  83
+                                   (e4, unqualify(name4), toParameterValue(a4)(pt4._2)), 
  84
+                                   (e5, unqualify(name5), toParameterValue(a5)(pt5._2)), 
  85
+                                   (e6, unqualify(name6), toParameterValue(a6)(pt6._2)), 
  86
+                                   (e7, unqualify(name7), toParameterValue(a7)(pt7._2)), 
  87
+                                   (e8, unqualify(name8), toParameterValue(a8)(pt8._2)), 
  88
+                                   (e9, unqualify(name9), toParameterValue(a9)(pt9._2)), 
  89
+                                   (e10, unqualify(name10), toParameterValue(a10)(pt10._2)))
  90
+                })
  91
+
  92
+                val (ids,toSet) = all.partition(_._1.isDefined)
  93
+                    if(ids == all) throw new Exception("everything is a Pk, nothing left to set!")
  94
+
  95
+                val toUpdate = toSet.map(_._2).map(n => n+" = "+"{"+n+"}").mkString(", ")
  96
+
  97
+                import Sql._
  98
+
  99
+                sql("update "+containerName +" set "+toUpdate+
  100
+                    " where "+ ids.map(_._2).map( n => n+" = "+"{"+n+"}").mkString(" and ") )
  101
+                        .on(all.map(v =>  (v._2,v._3)): _* )
  102
+                        .executeUpdate()
  103
+        
  104
+            }
  105
+
  106
+           def create(v:R)(implicit hasId: (A1 <:< Pk[_])|:|(A2 <:< Pk[_])|:|(A3 <:< Pk[_])|:|(A4 <:< Pk[_])|:|(A5 <:< Pk[_])|:|(A6 <:< Pk[_])|:|(A7 <:< Pk[_])|:|(A8 <:< Pk[_])|:|(A9 <:< Pk[_])|:|(A10 <:< Pk[_]) ) :R = {
  107
+
  108
+                val all = ((v,hasId) match {
  109
+                        case (self( a1, a2, a3, a4, a5, a6, a7, a8, a9, a10), ( e1 |:| e2 |:| e3 |:| e4 |:| e5 |:| e6 |:| e7 |:| e8 |:| e9 |:| e10)) => 
  110
+                            List ( 
  111
+                                   (e1, unqualify(name1), toParameterValue(a1)(pt1._2)), 
  112
+                                   (e2, unqualify(name2), toParameterValue(a2)(pt2._2)), 
  113
+                                   (e3, unqualify(name3), toParameterValue(a3)(pt3._2)), 
  114
+                                   (e4, unqualify(name4), toParameterValue(a4)(pt4._2)), 
  115
+                                   (e5, unqualify(name5), toParameterValue(a5)(pt5._2)), 
  116
+                                   (e6, unqualify(name6), toParameterValue(a6)(pt6._2)), 
  117
+                                   (e7, unqualify(name7), toParameterValue(a7)(pt7._2)), 
  118
+                                   (e8, unqualify(name8), toParameterValue(a8)(pt8._2)), 
  119
+                                   (e9, unqualify(name9), toParameterValue(a9)(pt9._2)), 
  120
+                                   (e10, unqualify(name10), toParameterValue(a10)(pt10._2)))
  121
+                })
  122
+
  123
+                val (notSetIds,toSet) = all.partition(i => i._1.isDefined && i._3.aValue==NotAssigned)
  124
+                if(notSetIds.length > 1) throw new Exception("multi ids not supported")
  125
+                val toInsert = toSet.map(_._2)
  126
+
  127
+                import Sql._
  128
+                import scala.util.control.Exception._
  129
+                import SqlParser._
  130
+
  131
+                val idParser:SqlParser.Parser[_] = {
  132
+                    SqlParser.RowParser(row =>
  133
+                        row.asList.headOption.flatMap(a =>
  134
+                            (if (a.isInstanceOf[Option[_]]) a else Option(a)).asInstanceOf[Option[_]]
  135
+                        ).toRight(NoColumnsInReturnedResult)
  136
+                    )
  137
+                }
  138
+
  139
+                val (statement, ok) = sql("insert into "+containerName+" ( "+toInsert.mkString(", ")+" ) values ( "+toInsert.map("{"+_+"}").mkString(", ")+")")
  140
+                    .on(all.map(v =>  (v._2,v._3)): _* )
  141
+                    .execute1(getGeneratedKeys=true)
  142
+
  143
+                val rs = statement.getGeneratedKeys();
  144
+                val id = idParser(StreamReader(Sql.resultSetToStream(rs))).get
  145
+
  146
+                val List( a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) = all.map(_._3.aValue).map({case NotAssigned => Id(id); case other => other})
  147
+                apply(a1.asInstanceOf[A1], a2.asInstanceOf[A2], a3.asInstanceOf[A3], a4.asInstanceOf[A4], a5.asInstanceOf[A5], a6.asInstanceOf[A6], a7.asInstanceOf[A7], a8.asInstanceOf[A8], a9.asInstanceOf[A9], a10.asInstanceOf[A10])
  148
+
  149
+        
  150
+        }
  151
+    }
  152
+
  153
+}
  154
+
  155
+
161  src/play/db/anorm/Magic11.scala
... ...
@@ -0,0 +1,161 @@
  1
+
  2
+
  3
+
  4
+
  5
+package play.db
  6
+
  7
+import play.utils.Scala.MayErr
  8
+import play.utils.Scala.MayErr._
  9
+
  10
+package anorm {
  11
+
  12
+    trait MParser11[ A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, R] extends ParserWithId[R] {
  13
+    
  14
+        val p1:ColumnTo[A1]
  15
+
  16
+        val p2:ColumnTo[A2]
  17
+
  18
+        val p3:ColumnTo[A3]
  19
+
  20
+        val p4:ColumnTo[A4]
  21
+
  22
+        val p5:ColumnTo[A5]
  23
+
  24
+        val p6:ColumnTo[A6]
  25
+
  26
+        val p7:ColumnTo[A7]
  27
+
  28
+        val p8:ColumnTo[A8]
  29
+
  30
+        val p9:ColumnTo[A9]
  31
+
  32
+        val p10:ColumnTo[A10]
  33
+
  34
+        val p11:ColumnTo[A11]
  35
+
  36
+        def apply(a1:A1, a2:A2, a3:A3, a4:A4, a5:A5, a6:A6, a7:A7, a8:A8, a9:A9, a10:A10, a11:A11 ):R
  37
+
  38
+        val containerName:String
  39
+        val columnNames:(String, String, String, String, String, String, String, String, String, String, String)
  40
+
  41
+        lazy val (name1 ,name2 ,name3 ,name4 ,name5 ,name6 ,name7 ,name8 ,name9 ,name10 ,name11) = columnNames
  42
+
  43
+        import SqlParser._
  44
+        override def apply(input:Input):SqlParser.ParseResult[R] = 
  45
+            (
  46
+             get[A1](name1)(p1) ~< 
  47
+             get[A2](name2)(p2) ~< 
  48
+             get[A3](name3)(p3) ~< 
  49
+             get[A4](name4)(p4) ~< 
  50
+             get[A5](name5)(p5) ~< 
  51
+             get[A6](name6)(p6) ~< 
  52
+             get[A7](name7)(p7) ~< 
  53
+             get[A8](name8)(p8) ~< 
  54
+             get[A9](name9)(p9) ~< 
  55
+             get[A10](name10)(p10) ~< 
  56
+             get[A11](name11)(p11) ^^ { case a1 ~ a2 ~ a3 ~ a4 ~ a5 ~ a6 ~ a7 ~ a8 ~ a9 ~ a10 ~ a11 => apply(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11)} )(input)
  57
+
  58
+        val uniqueId : (Row=> MayErr[SqlRequestError,Any]) = null
  59
+    }
  60
+
  61
+        trait M11[ A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, R] {
  62
+            self: MParser11[ A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11,R] =>
  63
+            
  64
+            val pt1:(ColumnTo[A1],ToStatement[A1])
  65
+            val pt2:(ColumnTo[A2],ToStatement[A2])
  66
+            val pt3:(ColumnTo[A3],ToStatement[A3])
  67
+            val pt4:(ColumnTo[A4],ToStatement[A4])
  68
+            val pt5:(ColumnTo[A5],ToStatement[A5])
  69
+            val pt6:(ColumnTo[A6],ToStatement[A6])
  70
+            val pt7:(ColumnTo[A7],ToStatement[A7])
  71
+            val pt8:(ColumnTo[A8],ToStatement[A8])
  72
+            val pt9:(ColumnTo[A9],ToStatement[A9])
  73
+            val pt10:(ColumnTo[A10],ToStatement[A10])
  74
+            val pt11:(ColumnTo[A11],ToStatement[A11])
  75
+
  76
+            def unapply(r:R):Option[( A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11)]
  77
+            def unqualify(columnName:String) = columnName.split('.').last
  78
+
  79
+            def update(v:R)(implicit hasId: (A1 <:< Pk[_])|:|(A2 <:< Pk[_])|:|(A3 <:< Pk[_])|:|(A4 <:< Pk[_])|:|(A5 <:< Pk[_])|:|(A6 <:< Pk[_])|:|(A7 <:< Pk[_])|:|(A8 <:< Pk[_])|:|(A9 <:< Pk[_])|:|(A10 <:< Pk[_])|:|(A11 <:< Pk[_]) ) = {
  80
+
  81
+                val all = ((v,hasId) match {
  82
+                        case (self( a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11), ( e1 |:| e2 |:| e3 |:| e4 |:| e5 |:| e6 |:| e7 |:| e8 |:| e9 |:| e10 |:| e11)) => 
  83
+                            List ( 
  84
+                                   (e1, unqualify(name1), toParameterValue(a1)(pt1._2)), 
  85
+                                   (e2, unqualify(name2), toParameterValue(a2)(pt2._2)), 
  86
+                                   (e3, unqualify(name3), toParameterValue(a3)(pt3._2)), 
  87
+                                   (e4, unqualify(name4), toParameterValue(a4)(pt4._2)), 
  88
+                                   (e5, unqualify(name5), toParameterValue(a5)(pt5._2)), 
  89
+                                   (e6, unqualify(name6), toParameterValue(a6)(pt6._2)), 
  90
+                                   (e7, unqualify(name7), toParameterValue(a7)(pt7._2)), 
  91
+                                   (e8, unqualify(name8), toParameterValue(a8)(pt8._2)), 
  92
+                                   (e9, unqualify(name9), toParameterValue(a9)(pt9._2)), 
  93
+                                   (e10, unqualify(name10), toParameterValue(a10)(pt10._2)), 
  94
+                                   (e11, unqualify(name11), toParameterValue(a11)(pt11._2)))
  95
+                })
  96
+
  97
+                val (ids,toSet) = all.partition(_._1.isDefined)
  98
+                    if(ids == all) throw new Exception("everything is a Pk, nothing left to set!")
  99
+
  100
+                val toUpdate = toSet.map(_._2).map(n => n+" = "+"{"+n+"}").mkString(", ")
  101
+
  102
+                import Sql._
  103
+
  104
+                sql("update "+containerName +" set "+toUpdate+
  105
+                    " where "+ ids.map(_._2).map( n => n+" = "+"{"+n+"}").mkString(" and ") )
  106
+                        .on(all.map(v =>  (v._2,v._3)): _* )
  107
+                        .executeUpdate()
  108
+        
  109
+            }
  110
+
  111
+           def create(v:R)(implicit hasId: (A1 <:< Pk[_])|:|(A2 <:< Pk[_])|:|(A3 <:< Pk[_])|:|(A4 <:< Pk[_])|:|(A5 <:< Pk[_])|:|(A6 <:< Pk[_])|:|(A7 <:< Pk[_])|:|(A8 <:< Pk[_])|:|(A9 <:< Pk[_])|:|(A10 <:< Pk[_])|:|(A11 <:< Pk[_]) ) :R = {
  112
+
  113
+                val all = ((v,hasId) match {
  114
+                        case (self( a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11), ( e1 |:| e2 |:| e3 |:| e4 |:| e5 |:| e6 |:| e7 |:| e8 |:| e9 |:| e10 |:| e11)) => 
  115
+                            List ( 
  116
+                                   (e1, unqualify(name1), toParameterValue(a1)(pt1._2)), 
  117
+                                   (e2, unqualify(name2), toParameterValue(a2)(pt2._2)), 
  118
+                                   (e3, unqualify(name3), toParameterValue(a3)(pt3._2)), 
  119
+                                   (e4, unqualify(name4), toParameterValue(a4)(pt4._2)), 
  120
+                                   (e5, unqualify(name5), toParameterValue(a5)(pt5._2)), 
  121
+                                   (e6, unqualify(name6), toParameterValue(a6)(pt6._2)), 
  122
+                                   (e7, unqualify(name7), toParameterValue(a7)(pt7._2)), 
  123
+                                   (e8, unqualify(name8), toParameterValue(a8)(pt8._2)), 
  124
+                                   (e9, unqualify(name9), toParameterValue(a9)(pt9._2)), 
  125
+                                   (e10, unqualify(name10), toParameterValue(a10)(pt10._2)), 
  126
+                                   (e11, unqualify(name11), toParameterValue(a11)(pt11._2)))
  127
+                })
  128
+
  129
+                val (notSetIds,toSet) = all.partition(i => i._1.isDefined && i._3.aValue==NotAssigned)
  130
+                if(notSetIds.length > 1) throw new Exception("multi ids not supported")
  131
+                val toInsert = toSet.map(_._2)
  132
+
  133
+                import Sql._
  134
+                import scala.util.control.Exception._
  135
+                import SqlParser._
  136
+
  137
+                val idParser:SqlParser.Parser[_] = {
  138
+                    SqlParser.RowParser(row =>
  139
+                        row.asList.headOption.flatMap(a =>
  140
+                            (if (a.isInstanceOf[Option[_]]) a else Option(a)).asInstanceOf[Option[_]]
  141
+                        ).toRight(NoColumnsInReturnedResult)
  142
+                    )
  143
+                }
  144
+
  145
+                val (statement, ok) = sql("insert into "+containerName+" ( "+toInsert.mkString(", ")+" ) values ( "+toInsert.map("{"+_+"}").mkString(", ")+")")
  146
+                    .on(all.map(v =>  (v._2,v._3)): _* )
  147
+                    .execute1(getGeneratedKeys=true)
  148
+
  149
+                val rs = statement.getGeneratedKeys();
  150
+                val id = idParser(StreamReader(Sql.resultSetToStream(rs))).get
  151
+
  152
+                val List( a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) = all.map(_._3.aValue).map({case NotAssigned => Id(id); case other => other})
  153
+                apply(a1.asInstanceOf[A1], a2.asInstanceOf[A2], a3.asInstanceOf[A3], a4.asInstanceOf[A4], a5.asInstanceOf[A5], a6.asInstanceOf[A6], a7.asInstanceOf[A7], a8.asInstanceOf[A8], a9.asInstanceOf[A9], a10.asInstanceOf[A10], a11.asInstanceOf[A11])
  154
+
  155
+        
  156
+        }
  157
+    }
  158
+
  159
+}
  160
+
  161
+
167  src/play/db/anorm/Magic12.scala
... ...
@@ -0,0 +1,167 @@
  1
+
  2
+
  3
+
  4
+
  5
+package play.db
  6
+
  7
+import play.utils.Scala.MayErr
  8
+import play.utils.Scala.MayErr._
  9
+
  10
+package anorm {
  11
+
  12
+    trait MParser12[ A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, R] extends ParserWithId[R] {
  13
+    
  14
+        val p1:ColumnTo[A1]
  15
+
  16
+        val p2:ColumnTo[A2]
  17
+
  18
+        val p3:ColumnTo[A3]
  19
+
  20
+        val p4:ColumnTo[A4]
  21
+
  22
+        val p5:ColumnTo[A5]
  23
+
  24
+        val p6:ColumnTo[A6]
  25
+
  26
+        val p7:ColumnTo[A7]
  27
+
  28
+        val p8:ColumnTo[A8]
  29
+
  30
+        val p9:ColumnTo[A9]
  31
+
  32
+        val p10:ColumnTo[A10]
  33
+
  34
+        val p11:ColumnTo[A11]
  35
+
  36
+        val p12:ColumnTo[A12]
  37
+
  38
+        def apply(a1:A1, a2:A2, a3:A3, a4:A4, a5:A5, a6:A6, a7:A7, a8:A8, a9:A9, a10:A10, a11:A11, a12:A12 ):R
  39
+
  40
+        val containerName:String
  41
+        val columnNames:(String, String, String, String, String, String, String, String, String, String, String, String)
  42
+
  43
+        lazy val (name1 ,name2 ,name3 ,name4 ,name5 ,name6 ,name7 ,name8 ,name9 ,name10 ,name11 ,name12) = columnNames
  44
+
  45
+        import SqlParser._
  46
+        override def apply(input:Input):SqlParser.ParseResult[R] = 
  47
+            (
  48
+             get[A1](name1)(p1) ~< 
  49
+             get[A2](name2)(p2) ~< 
  50
+             get[A3](name3)(p3) ~< 
  51
+             get[A4](name4)(p4) ~< 
  52
+             get[A5](name5)(p5) ~< 
  53
+             get[A6](name6)(p6) ~< 
  54
+             get[A7](name7)(p7) ~< 
  55
+             get[A8](name8)(p8) ~< 
  56
+             get[A9](name9)(p9) ~< 
  57
+             get[A10](name10)(p10) ~< 
  58
+             get[A11](name11)(p11) ~< 
  59
+             get[A12](name12)(p12) ^^ { case a1 ~ a2 ~ a3 ~ a4 ~ a5 ~ a6 ~ a7 ~ a8 ~ a9 ~ a10 ~ a11 ~ a12 => apply(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12)} )(input)
  60
+
  61
+        val uniqueId : (Row=> MayErr[SqlRequestError,Any]) = null
  62
+    }
  63
+
  64
+        trait M12[ A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, R] {
  65
+            self: MParser12[ A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12,R] =>
  66
+            
  67
+            val pt1:(ColumnTo[A1],ToStatement[A1])
  68
+            val pt2:(ColumnTo[A2],ToStatement[A2])
  69
+            val pt3:(ColumnTo[A3],ToStatement[A3])
  70
+            val pt4:(ColumnTo[A4],ToStatement[A4])
  71
+            val pt5:(ColumnTo[A5],ToStatement[A5])
  72
+            val pt6:(ColumnTo[A6],ToStatement[A6])
  73
+            val pt7:(ColumnTo[A7],ToStatement[A7])
  74
+            val pt8:(ColumnTo[A8],ToStatement[A8])
  75
+            val pt9:(ColumnTo[A9],ToStatement[A9])
  76
+            val pt10:(ColumnTo[A10],ToStatement[A10])
  77
+            val pt11:(ColumnTo[A11],ToStatement[A11])
  78
+            val pt12:(ColumnTo[A12],ToStatement[A12])
  79
+
  80
+            def unapply(r:R):Option[( A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12)]
  81
+            def unqualify(columnName:String) = columnName.split('.').last
  82
+
  83
+            def update(v:R)(implicit hasId: (A1 <:< Pk[_])|:|(A2 <:< Pk[_])|:|(A3 <:< Pk[_])|:|(A4 <:< Pk[_])|:|(A5 <:< Pk[_])|:|(A6 <:< Pk[_])|:|(A7 <:< Pk[_])|:|(A8 <:< Pk[_])|:|(A9 <:< Pk[_])|:|(A10 <:< Pk[_])|:|(A11 <:< Pk[_])|:|(A12 <:< Pk[_]) ) = {
  84
+
  85
+                val all = ((v,hasId) match {
  86
+                        case (self( a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12), ( e1 |:| e2 |:| e3 |:| e4 |:| e5 |:| e6 |:| e7 |:| e8 |:| e9 |:| e10 |:| e11 |:| e12)) => 
  87
+                            List ( 
  88
+                                   (e1, unqualify(name1), toParameterValue(a1)(pt1._2)), 
  89
+                                   (e2, unqualify(name2), toParameterValue(a2)(pt2._2)), 
  90
+                                   (e3, unqualify(name3), toParameterValue(a3)(pt3._2)), 
  91
+                                   (e4, unqualify(name4), toParameterValue(a4)(pt4._2)), 
  92
+                                   (e5, unqualify(name5), toParameterValue(a5)(pt5._2)), 
  93
+                                   (e6, unqualify(name6), toParameterValue(a6)(pt6._2)), 
  94
+                                   (e7, unqualify(name7), toParameterValue(a7)(pt7._2)), 
  95
+                                   (e8, unqualify(name8), toParameterValue(a8)(pt8._2)), 
  96
+                                   (e9, unqualify(name9), toParameterValue(a9)(pt9._2)), 
  97
+                                   (e10, unqualify(name10), toParameterValue(a10)(pt10._2)), 
  98
+                                   (e11, unqualify(name11), toParameterValue(a11)(pt11._2)), 
  99
+                                   (e12, unqualify(name12), toParameterValue(a12)(pt12._2)))
  100
+                })
  101
+
  102
+                val (ids,toSet) = all.partition(_._1.isDefined)
  103
+                    if(ids == all) throw new Exception("everything is a Pk, nothing left to set!")
  104
+
  105
+                val toUpdate = toSet.map(_._2).map(n => n+" = "+"{"+n+"}").mkString(", ")
  106
+
  107
+                import Sql._
  108
+
  109
+                sql("update "+containerName +" set "+toUpdate+
  110
+                    " where "+ ids.map(_._2).map( n => n+" = "+"{"+n+"}").mkString(" and ") )
  111
+                        .on(all.map(v =>  (v._2,v._3)): _* )
  112
+                        .executeUpdate()
  113
+        
  114
+            }
  115
+
  116
+           def create(v:R)(implicit hasId: (A1 <:< Pk[_])|:|(A2 <:< Pk[_])|:|(A3 <:< Pk[_])|:|(A4 <:< Pk[_])|:|(A5 <:< Pk[_])|:|(A6 <:< Pk[_])|:|(A7 <:< Pk[_])|:|(A8 <:< Pk[_])|:|(A9 <:< Pk[_])|:|(A10 <:< Pk[_])|:|(A11 <:< Pk[_])|:|(A12 <:< Pk[_]) ) :R = {
  117
+
  118
+                val all = ((v,hasId) match {
  119
+                        case (self( a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12), ( e1 |:| e2 |:| e3 |:| e4 |:| e5 |:| e6 |:| e7 |:| e8 |:| e9 |:| e10 |:| e11 |:| e12)) => 
  120
+                            List ( 
  121
+                                   (e1, unqualify(name1), toParameterValue(a1)(pt1._2)), 
  122
+                                   (e2, unqualify(name2), toParameterValue(a2)(pt2._2)), 
  123
+                                   (e3, unqualify(name3), toParameterValue(a3)(pt3._2)), 
  124
+                                   (e4, unqualify(name4), toParameterValue(a4)(pt4._2)), 
  125
+                                   (e5, unqualify(name5), toParameterValue(a5)(pt5._2)), 
  126
+                                   (e6, unqualify(name6), toParameterValue(a6)(pt6._2)), 
  127
+                                   (e7, unqualify(name7), toParameterValue(a7)(pt7._2)), 
  128
+                                   (e8, unqualify(name8), toParameterValue(a8)(pt8._2)), 
  129
+                                   (e9, unqualify(name9), toParameterValue(a9)(pt9._2)), 
  130
+                                   (e10, unqualify(name10), toParameterValue(a10)(pt10._2)), 
  131
+                                   (e11, unqualify(name11), toParameterValue(a11)(pt11._2)), 
  132
+                                   (e12, unqualify(name12), toParameterValue(a12)(pt12._2)))
  133
+                })
  134
+
  135
+                val (notSetIds,toSet) = all.partition(i => i._1.isDefined && i._3.aValue==NotAssigned)
  136
+                if(notSetIds.length > 1) throw new Exception("multi ids not supported")
  137
+                val toInsert = toSet.map(_._2)
  138
+
  139
+                import Sql._
  140
+                import scala.util.control.Exception._
  141
+                import SqlParser._
  142
+
  143
+                val idParser:SqlParser.Parser[_] = {
  144
+                    SqlParser.RowParser(row =>
  145
+                        row.asList.headOption.flatMap(a =>
  146
+                            (if (a.isInstanceOf[Option[_]]) a else Option(a)).asInstanceOf[Option[_]]
  147
+                        ).toRight(NoColumnsInReturnedResult)
  148
+                    )
  149
+                }
  150
+
  151
+                val (statement, ok) = sql("insert into "+containerName+" ( "+toInsert.mkString(", ")+" ) values ( "+toInsert.map("{"+_+"}").mkString(", ")+")")
  152
+                    .on(all.map(v =>  (v._2,v._3)): _* )
  153
+                    .execute1(getGeneratedKeys=true)
  154
+
  155
+                val rs = statement.getGeneratedKeys();
  156
+                val id = idParser(StreamReader(Sql.resultSetToStream(rs))).get
  157
+
  158
+                val List( a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) = all.map(_._3.aValue).map({case NotAssigned => Id(id); case other => other})
  159
+                apply(a1.asInstanceOf[A1], a2.asInstanceOf[A2], a3.asInstanceOf[A3], a4.asInstanceOf[A4], a5.asInstanceOf[A5], a6.asInstanceOf[A6], a7.asInstanceOf[A7], a8.asInstanceOf[A8], a9.asInstanceOf[A9], a10.asInstanceOf[A10], a11.asInstanceOf[A11], a12.asInstanceOf[A12])
  160
+
  161
+        
  162
+        }
  163
+    }
  164
+
  165
+}
  166
+
  167
+
173  src/play/db/anorm/Magic13.scala
... ...
@@ -0,0 +1,173 @@
  1
+
  2
+
  3
+
  4
+
  5
+package play.db
  6
+
  7
+import play.utils.Scala.MayErr
  8
+import play.utils.Scala.MayErr._
  9
+
  10
+package anorm {
  11
+
  12
+    trait MParser13[ A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, R] extends ParserWithId[R] {
  13
+    
  14
+        val p1:ColumnTo[A1]
  15
+
  16
+        val p2:ColumnTo[A2]
  17
+
  18
+        val p3:ColumnTo[A3]
  19
+
  20
+        val p4:ColumnTo[A4]
  21
+
  22
+        val p5:ColumnTo[A5]
  23
+
  24
+        val p6:ColumnTo[A6]
  25
+
  26
+        val p7:ColumnTo[A7]
  27
+
  28
+        val p8:ColumnTo[A8]
  29
+
  30
+        val p9:ColumnTo[A9]
  31
+
  32
+        val p10:ColumnTo[A10]
  33
+
  34
+        val p11:ColumnTo[A11]
  35
+
  36
+        val p12:ColumnTo[A12]
  37
+
  38
+        val p13:ColumnTo[A13]
  39
+
  40
+        def apply(a1:A1, a2:A2, a3:A3, a4:A4, a5:A5, a6:A6, a7:A7, a8:A8, a9:A9, a10:A10, a11:A11, a12:A12, a13:A13 ):R
  41
+
  42
+        val containerName:String
  43
+        val columnNames:(String, String, String, String, String, String, String, String, String, String, String, String, String)
  44
+
  45
+        lazy val (name1 ,name2 ,name3 ,name4 ,name5 ,name6 ,name7 ,name8 ,name9 ,name10 ,name11 ,name12 ,name13) = columnNames
  46
+
  47
+        import SqlParser._
  48
+        override def apply(input:Input):SqlParser.ParseResult[R] = 
  49
+            (
  50
+             get[A1](name1)(p1) ~< 
  51
+             get[A2](name2)(p2) ~< 
  52
+             get[A3](name3)(p3) ~< 
  53
+             get[A4](name4)(p4) ~< 
  54
+             get[A5](name5)(p5) ~< 
  55
+             get[A6](name6)(p6) ~< 
  56
+             get[A7](name7)(p7) ~< 
  57
+             get[A8](name8)(p8) ~< 
  58
+             get[A9](name9)(p9) ~< 
  59
+             get[A10](name10)(p10) ~< 
  60
+             get[A11](name11)(p11) ~< 
  61
+             get[A12](name12)(p12) ~< 
  62
+             get[A13](name13)(p13) ^^ { case a1 ~ a2 ~ a3 ~ a4 ~ a5 ~ a6 ~ a7 ~ a8 ~ a9 ~ a10 ~ a11 ~ a12 ~ a13 => apply(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13)} )(input)
  63
+
  64
+        val uniqueId : (Row=> MayErr[SqlRequestError,Any]) = null
  65
+    }
  66
+
  67
+        trait M13[ A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, R] {
  68
+            self: MParser13[ A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13,R] =>
  69
+            
  70
+            val pt1:(ColumnTo[A1],ToStatement[A1])
  71
+            val pt2:(ColumnTo[A2],ToStatement[A2])
  72
+            val pt3:(ColumnTo[A3],ToStatement[A3])
  73
+            val pt4:(ColumnTo[A4],ToStatement[A4])
  74
+            val pt5:(ColumnTo[A5],ToStatement[A5])
  75
+            val pt6:(ColumnTo[A6],ToStatement[A6])
  76
+            val pt7:(ColumnTo[A7],ToStatement[A7])
  77
+            val pt8:(ColumnTo[A8],ToStatement[A8])
  78
+            val pt9:(ColumnTo[A9],ToStatement[A9])
  79
+            val pt10:(ColumnTo[A10],ToStatement[A10])
  80
+            val pt11:(ColumnTo[A11],ToStatement[A11])
  81
+            val pt12:(ColumnTo[A12],ToStatement[A12])
  82
+            val pt13:(ColumnTo[A13],ToStatement[A13])
  83
+
  84
+            def unapply(r:R):Option[( A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13)]
  85
+            def unqualify(columnName:String) = columnName.split('.').last
  86
+
  87
+            def update(v:R)(implicit hasId: (A1 <:< Pk[_])|:|(A2 <:< Pk[_])|:|(A3 <:< Pk[_])|:|(A4 <:< Pk[_])|:|(A5 <:< Pk[_])|:|(A6 <:< Pk[_])|:|(A7 <:< Pk[_])|:|(A8 <:< Pk[_])|:|(A9 <:< Pk[_])|:|(A10 <:< Pk[_])|:|(A11 <:< Pk[_])|:|(A12 <:< Pk[_])|:|(A13 <:< Pk[_]) ) = {
  88
+
  89
+                val all = ((v,hasId) match {
  90
+                        case (self( a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13), ( e1 |:| e2 |:| e3 |:| e4 |:| e5 |:| e6 |:| e7 |:| e8 |:| e9 |:| e10 |:| e11 |:| e12 |:| e13)) => 
  91
+                            List ( 
  92
+                                   (e1, unqualify(name1), toParameterValue(a1)(pt1._2)), 
  93
+                                   (e2, unqualify(name2), toParameterValue(a2)(pt2._2)), 
  94
+                                   (e3, unqualify(name3), toParameterValue(a3)(pt3._2)), 
  95
+                                   (e4, unqualify(name4), toParameterValue(a4)(pt4._2)), 
  96
+                                   (e5, unqualify(name5), toParameterValue(a5)(pt5._2)), 
  97
+                                   (e6, unqualify(name6), toParameterValue(a6)(pt6._2)), 
  98
+                                   (e7, unqualify(name7), toParameterValue(a7)(pt7._2)), 
  99
+                                   (e8, unqualify(name8), toParameterValue(a8)(pt8._2)), 
  100
+                                   (e9, unqualify(name9), toParameterValue(a9)(pt9._2)), 
  101
+                                   (e10, unqualify(name10), toParameterValue(a10)(pt10._2)), 
  102
+                                   (e11, unqualify(name11), toParameterValue(a11)(pt11._2)), 
  103
+                                   (e12, unqualify(name12), toParameterValue(a12)(pt12._2)), 
  104
+                                   (e13, unqualify(name13), toParameterValue(a13)(pt13._2)))
  105
+                })
  106
+
  107
+                val (ids,toSet) = all.partition(_._1.isDefined)
  108
+                    if(ids == all) throw new Exception("everything is a Pk, nothing left to set!")
  109
+
  110
+                val toUpdate = toSet.map(_._2).map(n => n+" = "+"{"+n+"}").mkString(", ")
  111
+
  112
+                import Sql._
  113
+
  114
+                sql("update "+containerName +" set "+toUpdate+
  115
+                    " where "+ ids.map(_._2).map( n => n+" = "+"{"+n+"}").mkString(" and ") )
  116
+                        .on(all.map(v =>  (v._2,v._3)): _* )
  117
+                        .executeUpdate()
  118
+        
  119
+            }
  120
+
  121
+           def create(v:R)(implicit hasId: (A1 <:< Pk[_])|:|(A2 <:< Pk[_])|:|(A3 <:< Pk[_])|:|(A4 <:< Pk[_])|:|(A5 <:< Pk[_])|:|(A6 <:< Pk[_])|:|(A7 <:< Pk[_])|:|(A8 <:< Pk[_])|:|(A9 <:< Pk[_])|:|(A10 <:< Pk[_])|:|(A11 <:< Pk[_])|:|(A12 <:< Pk[_])|:|(A13 <:< Pk[_]) ) :R = {
  122
+
  123
+                val all = ((v,hasId) match {
  124
+                        case (self( a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13), ( e1 |:| e2 |:| e3 |:| e4 |:| e5 |:| e6 |:| e7 |:| e8 |:| e9 |:| e10 |:| e11 |:| e12 |:| e13)) => 
  125
+                            List ( 
  126
+                                   (e1, unqualify(name1), toParameterValue(a1)(pt1._2)), 
  127
+                                   (e2, unqualify(name2), toParameterValue(a2)(pt2._2)), 
  128
+                                   (e3, unqualify(name3), toParameterValue(a3)(pt3._2)), 
  129
+                                   (e4, unqualify(name4), toParameterValue(a4)(pt4._2)), 
  130
+                                   (e5, unqualify(name5), toParameterValue(a5)(pt5._2)), 
  131
+                                   (e6, unqualify(name6), toParameterValue(a6)(pt6._2)), 
  132
+                                   (e7, unqualify(name7), toParameterValue(a7)(pt7._2)), 
  133
+                                   (e8, unqualify(name8), toParameterValue(a8)(pt8._2)), 
  134
+                                   (e9, unqualify(name9), toParameterValue(a9)(pt9._2)), 
  135
+                                   (e10, unqualify(name10), toParameterValue(a10)(pt10._2)), 
  136
+                                   (e11, unqualify(name11), toParameterValue(a11)(pt11._2)), 
  137
+                                   (e12, unqualify(name12), toParameterValue(a12)(pt12._2)), 
  138
+                                   (e13, unqualify(name13), toParameterValue(a13)(pt13._2)))
  139
+                })
  140
+
  141
+                val (notSetIds,toSet) = all.partition(i => i._1.isDefined && i._3.aValue==NotAssigned)
  142
+                if(notSetIds.length > 1) throw new Exception("multi ids not supported")
  143
+                val toInsert = toSet.map(_._2)
  144
+
  145
+                import Sql._
  146
+                import scala.util.control.Exception._
  147
+                import SqlParser._
  148
+
  149
+                val idParser:SqlParser.Parser[_] = {
  150
+                    SqlParser.RowParser(row =>
  151
+                        row.asList.headOption.flatMap(a =>
  152
+                            (if (a.isInstanceOf[Option[_]]) a else Option(a)).asInstanceOf[Option[_]]
  153
+                        ).toRight(NoColumnsInReturnedResult)
  154
+                    )
  155
+                }
  156
+
  157
+                val (statement, ok) = sql("insert into "+containerName+" ( "+toInsert.mkString(", ")+" ) values ( "+toInsert.map("{"+_+"}").mkString(", ")+")")
  158
+                    .on(all.map(v =>  (v._2,v._3)): _* )
  159
+                    .execute1(getGeneratedKeys=true)
  160
+
  161
+                val rs = statement.getGeneratedKeys();
  162
+                val id = idParser(StreamReader(Sql.resultSetToStream(rs))).get
  163
+
  164
+                val List( a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) = all.map(_._3.aValue).map({case NotAssigned => Id(id); case other => other})
  165
+                apply(a1.asInstanceOf[A1], a2.asInstanceOf[A2], a3.asInstanceOf[A3], a4.asInstanceOf[A4], a5.asInstanceOf[A5], a6.asInstanceOf[A6], a7.asInstanceOf[A7], a8.asInstanceOf[A8], a9.asInstanceOf[A9], a10.asInstanceOf[A10], a11.asInstanceOf[A11], a12.asInstanceOf[A12], a13.asInstanceOf[A13])
  166
+
  167
+        
  168
+        }
  169
+    }
  170
+
  171
+}
  172
+
  173
+
179  src/play/db/anorm/Magic14.scala
... ...
@@ -0,0 +1,179 @@
  1
+
  2
+
  3
+
  4
+
  5
+package play.db
  6
+
  7
+import play.utils.Scala.MayErr
  8
+import play.utils.Scala.MayErr._
  9
+
  10
+package anorm {
  11
+
  12
+    trait MParser14[ A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, R] extends ParserWithId[R] {
  13
+    
  14
+        val p1:ColumnTo[A1]
  15
+
  16
+        val p2:ColumnTo[A2]
  17
+
  18
+        val p3:ColumnTo[A3]
  19
+
  20
+        val p4:ColumnTo[A4]
  21
+
  22
+        val p5:ColumnTo[A5]
  23
+
  24
+        val p6:ColumnTo[A6]
  25
+
  26
+        val p7:ColumnTo[A7]
  27
+
  28
+        val p8:ColumnTo[A8]
  29
+
  30
+        val p9:ColumnTo[A9]
  31
+
  32
+        val p10:ColumnTo[A10]
  33
+
  34
+        val p11:ColumnTo[A11]
  35
+
  36
+        val p12:ColumnTo[A12]
  37
+
  38
+        val p13:ColumnTo[A13]
  39
+
  40
+        val p14:ColumnTo[A14]
  41
+
  42
+        def apply(a1:A1, a2:A2, a3:A3, a4:A4, a5:A5, a6:A6, a7:A7, a8:A8, a9:A9, a10:A10, a11:A11, a12:A12, a13:A13, a14:A14 ):R
  43
+
  44
+        val containerName:String
  45
+        val columnNames:(String, String, String, String, String, String, String, String, String, String, String, String, String, String)
  46
+
  47
+        lazy val (name1 ,name2 ,name3 ,name4 ,name5 ,name6 ,name7 ,name8 ,name9 ,name10 ,name11 ,name12 ,name13 ,name14) = columnNames
  48
+
  49
+        import SqlParser._
  50
+        override def apply(input:Input):SqlParser.ParseResult[R] = 
  51
+            (
  52
+             get[A1](name1)(p1) ~< 
  53
+             get[A2](name2)(p2) ~< 
  54
+             get[A3](name3)(p3) ~< 
  55
+             get[A4](name4)(p4) ~< 
  56
+             get[A5](name5)(p5) ~< 
  57
+             get[A6](name6)(p6) ~< 
  58
+             get[A7](name7)(p7) ~< 
  59
+             get[A8](name8)(p8) ~< 
  60
+             get[A9](name9)(p9) ~< 
  61
+             get[A10](name10)(p10) ~< 
  62
+             get[A11](name11)(p11) ~< 
  63
+             get[A12](name12)(p12) ~< 
  64
+             get[A13](name13)(p13) ~< 
  65
+             get[A14](name14)(p14) ^^ { case a1 ~ a2 ~ a3 ~ a4 ~ a5 ~ a6 ~ a7 ~ a8 ~ a9 ~ a10 ~ a11 ~ a12 ~ a13 ~ a14 => apply(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14)} )(input)
  66
+
  67
+        val uniqueId : (Row=> MayErr[SqlRequestError,Any]) = null
  68
+    }
  69
+
  70
+        trait M14[ A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, R] {
  71
+            self: MParser14[ A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14,R] =>
  72
+            
  73
+            val pt1:(ColumnTo[A1],ToStatement[A1])
  74
+            val pt2:(ColumnTo[A2],ToStatement[A2])
  75
+            val pt3:(ColumnTo[A3],ToStatement[A3])
  76
+            val pt4:(ColumnTo[A4],ToStatement[A4])
  77
+            val pt5:(ColumnTo[A5],ToStatement[A5])
  78
+            val pt6:(ColumnTo[A6],ToStatement[A6])
  79
+            val pt7:(ColumnTo[A7],ToStatement[A7])
  80
+            val pt8:(ColumnTo[A8],ToStatement[A8])
  81
+            val pt9:(ColumnTo[A9],ToStatement[A9])
  82
+            val pt10:(ColumnTo[A10],ToStatement[A10])
  83
+            val pt11:(ColumnTo[A11],ToStatement[A11])
  84
+            val pt12:(ColumnTo[A12],ToStatement[A12])
  85
+            val pt13:(ColumnTo[A13],ToStatement[A13])
  86
+            val pt14:(ColumnTo[A14],ToStatement[A14])
  87
+
  88
+            def unapply(r:R):Option[( A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14)]
  89
+            def unqualify(columnName:String) = columnName.split('.').last
  90
+
  91
+            def update(v:R)(implicit hasId: (A1 <:< Pk[_])|:|(A2 <:< Pk[_])|:|(A3 <:< Pk[_])|:|(A4 <:< Pk[_])|:|(A5 <:< Pk[_])|:|(A6 <:< Pk[_])|:|(A7 <:< Pk[_])|:|(A8 <:< Pk[_])|:|(A9 <:< Pk[_])|:|(A10 <:< Pk[_])|:|(A11 <:< Pk[_])|:|(A12 <:< Pk[_])|:|(A13 <:< Pk[_])|:|(A14 <:< Pk[_]) ) = {
  92
+
  93
+                val all = ((v,hasId) match {
  94
+                        case (self( a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14), ( e1 |:| e2 |:| e3 |:| e4 |:| e5 |:| e6 |:| e7 |:| e8 |:| e9 |:| e10 |:| e11 |:| e12 |:| e13 |:| e14)) => 
  95
+                            List ( 
  96
+                                   (e1, unqualify(name1), toParameterValue(a1)(pt1._2)), 
  97
+                                   (e2, unqualify(name2), toParameterValue(a2)(pt2._2)), 
  98
+                                   (e3, unqualify(name3), toParameterValue(a3)(pt3._2)), 
  99
+                                   (e4, unqualify(name4), toParameterValue(a4)(pt4._2)), 
  100
+                                   (e5, unqualify(name5), toParameterValue(a5)(pt5._2)), 
  101
+                                   (e6, unqualify(name6), toParameterValue(a6)(pt6._2)), 
  102
+                                   (e7, unqualify(name7), toParameterValue(a7)(pt7._2)), 
  103
+                                   (e8, unqualify(name8), toParameterValue(a8)(pt8._2)), 
  104
+                                   (e9, unqualify(name9), toParameterValue(a9)(pt9._2)), 
  105
+                                   (e10, unqualify(name10), toParameterValue(a10)(pt10._2)), 
  106
+                                   (e11, unqualify(name11), toParameterValue(a11)(pt11._2)), 
  107
+                                   (e12, unqualify(name12), toParameterValue(a12)(pt12._2)), 
  108
+                                   (e13, unqualify(name13), toParameterValue(a13)(pt13._2)), 
  109
+                                   (e14, unqualify(name14), toParameterValue(a14)(pt14._2)))
  110
+                })
  111
+
  112
+                val (ids,toSet) = all.partition(_._1.isDefined)
  113
+                    if(ids == all) throw new Exception("everything is a Pk, nothing left to set!")
  114
+
  115
+                val toUpdate = toSet.map(_._2).map(n => n+" = "+"{"+n+"}").mkString(", ")
  116
+
  117
+                import Sql._
  118
+
  119
+                sql("update "+containerName +" set "+toUpdate+
  120
+                    " where "+ ids.map(_._2).map( n => n+" = "+"{"+n+"}").mkString(" and ") )
  121
+                        .on(all.map(v =>  (v._2,v._3)): _* )
  122
+                        .executeUpdate()
  123
+        
  124
+            }
  125
+
  126
+           def create(v:R)(implicit hasId: (A1 <:< Pk[_])|:|(A2 <:< Pk[_])|:|(A3 <:< Pk[_])|:|(A4 <:< Pk[_])|:|(A5 <:< Pk[_])|:|(A6 <:< Pk[_])|:|(A7 <:< Pk[_])|:|(A8 <:< Pk[_])|:|(A9 <:< Pk[_])|:|(A10 <:< Pk[_])|:|(A11 <:< Pk[_])|:|(A12 <:< Pk[_])|:|(A13 <:< Pk[_])|:|(A14 <:< Pk[_]) ) :R = {
  127
+
  128
+                val all = ((v,hasId) match {
  129
+                        case (self( a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14), ( e1 |:| e2 |:| e3 |:| e4 |:| e5 |:| e6 |:| e7 |:| e8 |:| e9 |:| e10 |:| e11 |:| e12 |:| e13 |:| e14)) => 
  130
+                            List ( 
  131
+                                   (e1, unqualify(name1), toParameterValue(a1)(pt1._2)), 
  132
+                                   (e2, unqualify(name2), toParameterValue(a2)(pt2._2)), 
  133
+                                   (e3, unqualify(name3), toParameterValue(a3)(pt3._2)), 
  134
+                                   (e4, unqualify(name4), toParameterValue(a4)(pt4._2)), 
  135
+                                   (e5, unqualify(name5), toParameterValue(a5)(pt5._2)), 
  136
+                                   (e6, unqualify(name6), toParameterValue(a6)(pt6._2)), 
  137
+                                   (e7, unqualify(name7), toParameterValue(a7)(pt7._2)), 
  138
+                                   (e8, unqualify(name8), toParameterValue(a8)(pt8._2)), 
  139
+                                   (e9, unqualify(name9), toParameterValue(a9)(pt9._2)), 
  140
+                                   (e10, unqualify(name10), toParameterValue(a10)(pt10._2)), 
  141
+                                   (e11, unqualify(name11), toParameterValue(a11)(pt11._2)), 
  142
+                                   (e12, unqualify(name12), toParameterValue(a12)(pt12._2)), 
  143
+                                   (e13, unqualify(name13), toParameterValue(a13)(pt13._2)), 
  144
+                                   (e14, unqualify(name14), toParameterValue(a14)(pt14._2)))
  145
+                })
  146
+
  147
+                val (notSetIds,toSet) = all.partition(i => i._1.isDefined && i._3.aValue==NotAssigned)
  148
+                if(notSetIds.length > 1) throw new Exception("multi ids not supported")
  149
+                val toInsert = toSet.map(_._2)
  150
+
  151
+                import Sql._
  152
+                import scala.util.control.Exception._
  153
+                import SqlParser._
  154
+
  155
+                val idParser:SqlParser.Parser[_] = {
  156
+                    SqlParser.RowParser(row =>
  157
+                        row.asList.headOption.flatMap(a =>
  158
+                            (if (a.isInstanceOf[Option[_]]) a else Option(a)).asInstanceOf[Option[_]]
  159
+                        ).toRight(NoColumnsInReturnedResult)
  160
+                    )
  161
+                }
  162
+
  163
+                val (statement, ok) = sql("insert into "+containerName+" ( "+toInsert.mkString(", ")+" ) values ( "+toInsert.map("{"+_+"}").mkString(", ")+")")
  164
+                    .on(all.map(v =>  (v._2,v._3)): _* )
  165
+                    .execute1(getGeneratedKeys=true)
  166
+
  167
+                val rs = statement.getGeneratedKeys();
  168
+                val id = idParser(StreamReader(Sql.resultSetToStream(rs))).get
  169
+
  170
+                val List( a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) = all.map(_._3.aValue).map({case NotAssigned => Id(id); case other => other})
  171
+                apply(a1.asInstanceOf[A1], a2.asInstanceOf[A2], a3.asInstanceOf[A3], a4.asInstanceOf[A4], a5.asInstanceOf[A5], a6.asInstanceOf[A6], a7.asInstanceOf[A7], a8.asInstanceOf[A8], a9.asInstanceOf[A9], a10.asInstanceOf[A10], a11.asInstanceOf[A11], a12.asInstanceOf[A12], a13.asInstanceOf[A13], a14.asInstanceOf[A14])
  172
+
  173
+        
  174
+        }
  175
+    }
  176
+
  177
+}
  178
+
  179
+
185  src/play/db/anorm/Magic15.scala
... ...
@@ -0,0 +1,185 @@
  1
+
  2
+
  3
+
  4
+
  5
+package play.db
  6
+
  7
+import play.utils.Scala.MayErr
  8
+import play.utils.Scala.MayErr._
  9
+
  10
+package anorm {
  11
+
  12
+    trait MParser15[ A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, R] extends ParserWithId[R] {
  13
+    
  14
+        val p1:ColumnTo[A1]
  15
+
  16
+        val p2:ColumnTo[A2]
  17
+
  18
+        val p3:ColumnTo[A3]
  19
+
  20
+        val p4:ColumnTo[A4]
  21
+
  22
+        val p5:ColumnTo[A5]
  23
+
  24
+        val p6:ColumnTo[A6]
  25
+
  26
+        val p7:ColumnTo[A7]
  27
+
  28
+        val p8:ColumnTo[A8]
  29
+
  30
+        val p9:ColumnTo[A9]
  31
+
  32
+        val p10:ColumnTo[A10]
  33
+
  34
+        val p11:ColumnTo[A11]
  35
+
  36
+        val p12:ColumnTo[A12]
  37
+
  38
+        val p13:ColumnTo[A13]
  39
+
  40
+        val p14:ColumnTo[A14]
  41
+
  42
+        val p15:ColumnTo[A15]
  43
+
  44
+        def apply(a1:A1, a2:A2, a3:A3, a4:A4, a5:A5, a6:A6, a7:A7, a8:A8, a9:A9, a10:A10, a11:A11, a12:A12, a13:A13, a14:A14, a15:A15 ):R
  45
+
  46
+        val containerName:String
  47
+        val columnNames:(String, String, String, String, String, String, String, String, String, String, String, String, String, String, String)
  48
+
  49
+        lazy val (name1 ,name2 ,name3 ,name4 ,name5 ,name6 ,name7 ,name8 ,name9 ,name10 ,name11 ,name12 ,name13 ,name14 ,name15) = columnNames
  50
+
  51
+        import SqlParser._
  52
+        override def apply(input:Input):SqlParser.ParseResult[R] = 
  53
+            (
  54
+             get[A1](name1)(p1) ~< 
  55
+             get[A2](name2)(p2) ~< 
  56
+             get[A3](name3)(p3) ~< 
  57
+             get[A4](name4)(p4) ~< 
  58
+             get[A5](name5)(p5) ~< 
  59
+             get[A6](name6)(p6) ~< 
  60
+             get[A7](name7)(p7) ~< 
  61
+             get[A8](name8)(p8) ~< 
  62
+             get[A9](name9)(p9) ~< 
  63
+             get[A10](name10)(p10) ~< 
  64
+             get[A11](name11)(p11) ~< 
  65
+             get[A12](name12)(p12) ~< 
  66
+             get[A13](name13)(p13) ~< 
  67
+             get[A14](name14)(p14) ~< 
  68
+             get[A15](name15)(p15) ^^ { case a1 ~ a2 ~ a3 ~ a4 ~ a5 ~ a6 ~ a7 ~ a8 ~ a9 ~ a10 ~ a11 ~ a12 ~ a13 ~ a14 ~ a15 => apply(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15)} )(input)
  69
+
  70
+        val uniqueId : (Row=> MayErr[SqlRequestError,Any]) = null
  71
+    }
  72
+
  73
+        trait M15[ A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, R] {
  74
+            self: MParser15[ A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15,R] =>
  75
+            
  76
+            val pt1:(ColumnTo[A1],ToStatement[A1])
  77
+            val pt2:(ColumnTo[A2],ToStatement[A2])
  78
+            val pt3:(ColumnTo[A3],ToStatement[A3])
  79
+            val pt4:(ColumnTo[A4],ToStatement[A4])
  80
+            val pt5:(ColumnTo[A5],ToStatement[A5])
  81
+            val pt6:(ColumnTo[A6],ToStatement[A6])
  82
+            val pt7:(ColumnTo[A7],ToStatement[A7])
  83
+            val pt8:(ColumnTo[A8],ToStatement[A8])
  84
+            val pt9:(ColumnTo[A9],ToStatement[A9])
  85
+            val pt10:(ColumnTo[A10],ToStatement[A10])
  86
+            val pt11:(ColumnTo[A11],ToStatement[A11])
  87
+            val pt12:(ColumnTo[A12],ToStatement[A12])
  88
+            val pt13:(ColumnTo[A13],ToStatement[A13])
  89
+            val pt14:(ColumnTo[A14],ToStatement[A14])
  90
+            val pt15:(ColumnTo[A15],ToStatement[A15])
  91
+
  92
+            def unapply(r:R):Option[( A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15)]
  93
+            def unqualify(columnName:String) = columnName.split('.').last
  94
+
  95
+            def update(v:R)(implicit hasId: (A1 <:< Pk[_])|:|(A2 <:< Pk[_])|:|(A3 <:< Pk[_])|:|(A4 <:< Pk[_])|:|(A5 <:< Pk[_])|:|(A6 <:< Pk[_])|:|(A7 <:< Pk[_])|:|(A8 <:< Pk[_])|:|(A9 <:< Pk[_])|:|(A10 <:< Pk[_])|:|(A11 <:< Pk[_])|:|(A12 <:< Pk[_])|:|(A13 <:< Pk[_])|:|(A14 <:< Pk[_])|:|(A15 <:< Pk[_]) ) = {
  96
+
  97
+                val all = ((v,hasId) match {
  98
+                        case (self( a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15), ( e1 |:| e2 |:| e3 |:| e4 |:| e5 |:| e6 |:| e7 |:| e8 |:| e9 |:| e10 |:| e11 |:| e12 |:| e13 |:| e14 |:| e15)) => 
  99
+                            List ( 
  100
+                                   (e1, unqualify(name1), toParameterValue(a1)(pt1._2)), 
  101
+                                   (e2, unqualify(name2), toParameterValue(a2)(pt2._2)), 
  102
+                                   (e3, unqualify(name3), toParameterValue(a3)(pt3._2)), 
  103
+                                   (e4, unqualify(name4), toParameterValue(a4)(pt4._2)), 
  104
+                                   (e5, unqualify(name5), toParameterValue(a5)(pt5._2)), 
  105
+                                   (e6, unqualify(name6), toParameterValue(a6)(pt6._2)), 
  106
+                                   (e7, unqualify(name7), toParameterValue(a7)(pt7._2)), 
  107
+                                   (e8, unqualify(name8), toParameterValue(a8)(pt8._2)), 
  108
+                                   (e9, unqualify(name9), toParameterValue(a9)(pt9._2)), 
  109
+                                   (e10, unqualify(name10), toParameterValue(a10)(pt10._2)), 
  110
+                                   (e11, unqualify(name11), toParameterValue(a11)(pt11._2)), 
  111
+                                   (e12, unqualify(name12), toParameterValue(a12)(pt12._2)), 
  112
+                                   (e13, unqualify(name13), toParameterValue(a13)(pt13._2)), 
  113
+                                   (e14, unqualify(name14), toParameterValue(a14)(pt14._2)), 
  114
+                                   (e15, unqualify(name15), toParameterValue(a15)(pt15._2)))
  115
+                })
  116
+
  117
+                val (ids,toSet) = all.partition(_._1.isDefined)
  118
+                    if(ids == all) throw new Exception("everything is a Pk, nothing left to set!")
  119
+
  120
+                val toUpdate = toSet.map(_._2).map(n => n+" = "+"{"+n+"}").mkString(", ")
  121
+
  122
+                import Sql._
  123
+
  124
+                sql("update "+containerName +" set "+toUpdate+
  125
+                    " where "+ ids.map(_._2).map( n => n+" = "+"{"+n+"}").mkString(" and ") )
  126
+                        .on(all.map(v =>  (v._2,v._3)): _* )
  127
+                        .executeUpdate()
  128
+        
  129
+            }
  130
+
  131
+           def create(v:R)(implicit hasId: (A1 <:< Pk[_])|:|(A2 <:< Pk[_])|:|(A3 <:< Pk[_])|:|(A4 <:< Pk[_])|:|(A5 <:< Pk[_])|:|(A6 <:< Pk[_])|:|(A7 <:< Pk[_])|:|(A8 <:< Pk[_])|:|(A9 <:< Pk[_])|:|(A10 <:< Pk[_])|:|(A11 <:< Pk[_])|:|(A12 <:< Pk[_])|:|(A13 <:< Pk[_])|:|(A14 <:< Pk[_])|:|(A15 <:< Pk[_]) ) :R = {
  132
+
  133
+                val all = ((v,hasId) match {
  134
+                        case (self( a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15), ( e1 |:| e2 |:| e3 |:| e4 |:| e5 |:| e6 |:| e7 |:| e8 |:| e9 |:| e10 |:| e11 |:| e12 |:| e13 |:| e14 |:| e15)) => 
  135
+                            List ( 
  136
+                                   (e1, unqualify(name1), toParameterValue(a1)(pt1._2)), 
  137
+                                   (e2, unqualify(name2), toParameterValue(a2)(pt2._2)), 
  138
+                                   (e3, unqualify(name3), toParameterValue(a3)(pt3._2)), 
  139
+                                   (e4, unqualify(name4), toParameterValue(a4)(pt4._2)), 
  140
+                                   (e5, unqualify(name5), toParameterValue(a5)(pt5._2)), 
  141
+                                   (e6, unqualify(name6), toParameterValue(a6)(pt6._2)), 
  142
+                                   (e7, unqualify(name7), toParameterValue(a7)(pt7._2)), 
  143
+                                   (e8, unqualify(name8), toParameterValue(a8)(pt8._2)), 
  144
+                                   (e9, unqualify(name9), toParameterValue(a9)(pt9._2)), 
  145
+                                   (e10, unqualify(name10), toParameterValue(a10)(pt10._2)), 
  146
+                                   (e11, unqualify(name11), toParameterValue(a11)(pt11._2)), 
  147
+                                   (e12, unqualify(name12), toParameterValue(a12)(pt12._2)), 
  148
+                                   (e13, unqualify(name13), toParameterValue(a13)(pt13._2)), 
  149
+                                   (e14, unqualify(name14), toParameterValue(a14)(pt14._2)), 
  150
+                                   (e15, unqualify(name15), toParameterValue(a15)(pt15._2)))
  151
+                })
  152
+
  153
+                val (notSetIds,toSet) = all.partition(i => i._1.isDefined && i._3.aValue==NotAssigned)
  154
+                if(notSetIds.length > 1) throw new Exception("multi ids not supported")
  155
+                val toInsert = toSet.map(_._2)
  156
+
  157
+                import Sql._
  158
+                import scala.util.control.Exception._
  159
+                import SqlParser._
  160
+
  161
+                val idParser:SqlParser.Parser[_] = {
  162
+                    SqlParser.RowParser(row =>
  163
+                        row.asList.headOption.flatMap(a =>
  164
+                            (if (a.isInstanceOf[Option[_]]) a else Option(a)).asInstanceOf[Option[_]]
  165
+                        ).toRight(NoColumnsInReturnedResult)
  166
+                    )
  167
+                }
  168
+
  169
+                val (statement, ok) = sql("insert into "+containerName+" ( "+toInsert.mkString(", ")+" ) values ( "+toInsert.map("{"+_+"}").mkString(", ")+")")
  170
+                    .on(all.map(v =>  (v._2,v._3)): _* )
  171
+                    .execute1(getGeneratedKeys=true)
  172
+
  173
+                val rs = statement.getGeneratedKeys();
  174
+                val id = idParser(StreamReader(Sql.resultSetToStream(rs))).get
  175
+
  176
+                val List( a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) = all.map(_._3.aValue).map({case NotAssigned => Id(id); case other => other})
  177
+                apply(a1.asInstanceOf[A1], a2.asInstanceOf[A2], a3.asInstanceOf[A3], a4.asInstanceOf[A4], a5.asInstanceOf[A5], a6.asInstanceOf[A6], a7.asInstanceOf[A7], a8.asInstanceOf[A8], a9.asInstanceOf[A9], a10.asInstanceOf[A10], a11.asInstanceOf[A11], a12.asInstanceOf[A12], a13.asInstanceOf[A13], a14.asInstanceOf[A14], a15.asInstanceOf[A15])
  178
+
  179
+        
  180
+        }
  181
+    }
  182
+
  183
+}
  184
+
  185
+
191  src/play/db/anorm/Magic16.scala
... ...
@@ -0,0 +1,191 @@
  1
+