@@ -28,54 +28,63 @@ trait AsyncDBSession extends LogSupport {
2828
2929 val connection : AsyncConnection
3030
31- def execute (statement : String , parameters : Any * )(implicit cxt : EC = ECGlobal ): Future [Boolean ] =
32- withListeners(statement, parameters) {
33- queryLogging(statement, parameters)
34- connection.sendPreparedStatement(statement, parameters : _* ).map { result =>
31+ def execute (statement : String , parameters : Any * )(implicit cxt : EC = ECGlobal ): Future [Boolean ] = {
32+ val _parameters = ensureAndNormalizeParameters(parameters)
33+ withListeners(statement, _parameters) {
34+ queryLogging(statement, _parameters)
35+ connection.sendPreparedStatement(statement, _parameters : _* ).map { result =>
3536 result.rowsAffected.map(_ > 0 ).getOrElse(false )
3637 }
3738 }
39+ }
3840
39- def update (statement : String , parameters : Any * )(implicit cxt : EC = ECGlobal ): Future [Int ] =
40- withListeners(statement, parameters) {
41- queryLogging(statement, parameters)
41+ def update (statement : String , parameters : Any * )(implicit cxt : EC = ECGlobal ): Future [Int ] = {
42+ val _parameters = ensureAndNormalizeParameters(parameters)
43+ withListeners(statement, _parameters) {
44+ queryLogging(statement, _parameters)
4245 if (connection.isShared) {
4346 // create local transaction because postgresql-async 0.2.4 seems not to be stable with PostgreSQL without transaction
4447 connection.toNonSharedConnection().map(c => TxAsyncDBSession (c)).flatMap { tx : TxAsyncDBSession =>
45- tx.update(statement, parameters : _* )
48+ tx.update(statement, _parameters : _* )
4649 }
4750 } else {
48- connection.sendPreparedStatement(statement, parameters : _* ).map { result =>
51+ connection.sendPreparedStatement(statement, _parameters : _* ).map { result =>
4952 result.rowsAffected.map(_.toInt).getOrElse(0 )
5053 }
5154 }
5255 }
56+ }
5357
54- def updateAndReturnGeneratedKey (statement : String , parameters : Any * )(implicit cxt : EC = ECGlobal ): Future [Long ] =
55- withListeners(statement, parameters) {
56- queryLogging(statement, parameters)
58+ def updateAndReturnGeneratedKey (statement : String , parameters : Any * )(implicit cxt : EC = ECGlobal ): Future [Long ] = {
59+ val _parameters = ensureAndNormalizeParameters(parameters)
60+ withListeners(statement, _parameters) {
61+ queryLogging(statement, _parameters)
5762 connection.toNonSharedConnection().flatMap { conn =>
58- conn.sendPreparedStatement(statement, parameters : _* ).map { result =>
63+ conn.sendPreparedStatement(statement, _parameters : _* ).map { result =>
5964 result.generatedKey.getOrElse {
6065 throw new IllegalArgumentException (ErrorMessage .FAILED_TO_RETRIEVE_GENERATED_KEY + " SQL: '" + statement + " '" )
6166 }
6267 }
6368 }
6469 }
70+ }
6571
66- def traversable [A ](statement : String , parameters : Any * )(extractor : WrappedResultSet => A )(implicit cxt : EC = ECGlobal ): Future [Traversable [A ]] =
67- withListeners(statement, parameters) {
68- queryLogging(statement, parameters)
69- connection.sendPreparedStatement(statement, parameters : _* ).map { result =>
72+ def traversable [A ](statement : String , parameters : Any * )(extractor : WrappedResultSet => A )(implicit cxt : EC = ECGlobal ): Future [Traversable [A ]] = {
73+ val _parameters = ensureAndNormalizeParameters(parameters)
74+ withListeners(statement, _parameters) {
75+ queryLogging(statement, _parameters)
76+ connection.sendPreparedStatement(statement, _parameters : _* ).map { result =>
7077 result.rows.map { ars =>
7178 new AsyncResultSetTraversable (ars).map(rs => extractor(rs))
7279 }.getOrElse(Nil )
7380 }
7481 }
82+ }
7583
7684 def single [A ](statement : String , parameters : Any * )(extractor : WrappedResultSet => A )(
7785 implicit cxt : EC = ECGlobal ): Future [Option [A ]] = {
78- traversable(statement, parameters : _* )(extractor).map { results =>
86+ val _parameters = ensureAndNormalizeParameters(parameters)
87+ traversable(statement, _parameters : _* )(extractor).map { results =>
7988 results match {
8089 case Nil => None
8190 case one :: Nil => Option (one)
@@ -85,13 +94,15 @@ trait AsyncDBSession extends LogSupport {
8594 }
8695
8796 def list [A ](statement : String , parameters : Any * )(extractor : WrappedResultSet => A )(implicit cxt : EC = ECGlobal ): Future [List [A ]] = {
88- (traversable[A ](statement, parameters : _* )(extractor)).map(_.toList)
97+ val _parameters = ensureAndNormalizeParameters(parameters)
98+ (traversable[A ](statement, _parameters : _* )(extractor)).map(_.toList)
8999 }
90100
91101 def oneToOneTraversable [A , B , Z ](statement : String , parameters : Any * )(extractOne : (WrappedResultSet ) => A )(extractTo : (WrappedResultSet ) => Option [B ])(transform : (A , B ) => Z )(
92- implicit cxt : EC = ECGlobal ): Future [Traversable [Z ]] =
93- withListeners(statement, parameters) {
94- queryLogging(statement, parameters)
102+ implicit cxt : EC = ECGlobal ): Future [Traversable [Z ]] = {
103+ val _parameters = ensureAndNormalizeParameters(parameters)
104+ withListeners(statement, _parameters) {
105+ queryLogging(statement, _parameters)
95106
96107 def processResultSet (oneToOne : (LinkedHashMap [A , Option [B ]]), rs : WrappedResultSet ): LinkedHashMap [A , Option [B ]] = {
97108 val o = extractOne(rs)
@@ -101,7 +112,7 @@ trait AsyncDBSession extends LogSupport {
101112 oneToOne += (o -> extractTo(rs))
102113 }
103114 }
104- connection.sendPreparedStatement(statement, parameters : _* ).map { result =>
115+ connection.sendPreparedStatement(statement, _parameters : _* ).map { result =>
105116 result.rows.map { ars =>
106117 new AsyncResultSetTraversable (ars).foldLeft(LinkedHashMap [A , Option [B ]]())(processResultSet).map {
107118 case (one, Some (to)) => transform(one, to)
@@ -110,11 +121,16 @@ trait AsyncDBSession extends LogSupport {
110121 }.getOrElse(Nil )
111122 }
112123 }
124+ }
113125
114- def oneToManyTraversable [A , B , Z ](statement : String , parameters : Any * )(extractOne : (WrappedResultSet ) => A )(extractTo : (WrappedResultSet ) => Option [B ])(transform : (A , Seq [B ]) => Z )(
115- implicit cxt : EC = ECGlobal ): Future [Traversable [Z ]] =
116- withListeners(statement, parameters) {
117- queryLogging(statement, parameters)
126+ def oneToManyTraversable [A , B , Z ](statement : String , parameters : Any * )(
127+ extractOne : (WrappedResultSet ) => A )(
128+ extractTo : (WrappedResultSet ) => Option [B ])(
129+ transform : (A , Seq [B ]) => Z )(
130+ implicit cxt : EC = ECGlobal ): Future [Traversable [Z ]] = {
131+ val _parameters = ensureAndNormalizeParameters(parameters)
132+ withListeners(statement, _parameters) {
133+ queryLogging(statement, _parameters)
118134
119135 def processResultSet (oneToMany : (LinkedHashMap [A , Seq [B ]]), rs : WrappedResultSet ): LinkedHashMap [A , Seq [B ]] = {
120136 val o = extractOne(rs)
@@ -124,21 +140,25 @@ trait AsyncDBSession extends LogSupport {
124140 oneToMany += (o -> extractTo(rs).map(many => Vector (many)).getOrElse(Nil ))
125141 }
126142 }
127- connection.sendPreparedStatement(statement, parameters : _* ).map { result =>
143+ connection.sendPreparedStatement(statement, _parameters : _* ).map { result =>
128144 result.rows.map { ars =>
129145 new AsyncResultSetTraversable (ars).foldLeft(LinkedHashMap [A , Seq [B ]]())(processResultSet).map {
130146 case (one, to) => transform(one, to)
131147 }
132148 }.getOrElse(Nil )
133149 }
134150 }
151+ }
135152
136153 def oneToManies2Traversable [A , B1 , B2 , Z ](statement : String , parameters : Any * )(
137154 extractOne : (WrappedResultSet ) => A )(
138155 extractTo1 : (WrappedResultSet ) => Option [B1 ],
139- extractTo2 : (WrappedResultSet ) => Option [B2 ])(transform : (A , Seq [B1 ], Seq [B2 ]) => Z )(implicit cxt : EC = ECGlobal ): Future [Traversable [Z ]] =
140- withListeners(statement, parameters) {
141- queryLogging(statement, parameters)
156+ extractTo2 : (WrappedResultSet ) => Option [B2 ])(
157+ transform : (A , Seq [B1 ], Seq [B2 ]) => Z )(
158+ implicit cxt : EC = ECGlobal ): Future [Traversable [Z ]] = {
159+ val _parameters = ensureAndNormalizeParameters(parameters)
160+ withListeners(statement, _parameters) {
161+ queryLogging(statement, _parameters)
142162
143163 def processResultSet (result : (LinkedHashMap [A , (Seq [B1 ], Seq [B2 ])]), rs : WrappedResultSet ): LinkedHashMap [A , (Seq [B1 ], Seq [B2 ])] = {
144164 val o = extractOne(rs)
@@ -155,22 +175,26 @@ trait AsyncDBSession extends LogSupport {
155175 result += (o -> (to1.map(t => Vector (t)).getOrElse(Vector ()), to2.map(t => Vector (t)).getOrElse(Vector ())))
156176 }
157177 }
158- connection.sendPreparedStatement(statement, parameters : _* ).map { result =>
178+ connection.sendPreparedStatement(statement, _parameters : _* ).map { result =>
159179 result.rows.map { ars =>
160180 new AsyncResultSetTraversable (ars).foldLeft(LinkedHashMap [A , (Seq [B1 ], Seq [B2 ])]())(processResultSet).map {
161181 case (one, (t1, t2)) => transform(one, t1, t2)
162182 }
163183 }.getOrElse(Nil )
164184 }
165185 }
186+ }
166187
167188 def oneToManies3Traversable [A , B1 , B2 , B3 , Z ](statement : String , parameters : Any * )(
168189 extractOne : (WrappedResultSet ) => A )(
169190 extractTo1 : (WrappedResultSet ) => Option [B1 ],
170191 extractTo2 : (WrappedResultSet ) => Option [B2 ],
171- extractTo3 : (WrappedResultSet ) => Option [B3 ])(transform : (A , Seq [B1 ], Seq [B2 ], Seq [B3 ]) => Z )(implicit cxt : EC = ECGlobal ): Future [Traversable [Z ]] =
172- withListeners(statement, parameters) {
173- queryLogging(statement, parameters)
192+ extractTo3 : (WrappedResultSet ) => Option [B3 ])(
193+ transform : (A , Seq [B1 ], Seq [B2 ], Seq [B3 ]) => Z )(
194+ implicit cxt : EC = ECGlobal ): Future [Traversable [Z ]] = {
195+ val _parameters = ensureAndNormalizeParameters(parameters)
196+ withListeners(statement, _parameters) {
197+ queryLogging(statement, _parameters)
174198
175199 def processResultSet (result : (LinkedHashMap [A , (Seq [B1 ], Seq [B2 ], Seq [B3 ])]), rs : WrappedResultSet ): LinkedHashMap [A , (Seq [B1 ], Seq [B2 ], Seq [B3 ])] = {
176200 val o = extractOne(rs)
@@ -194,23 +218,27 @@ trait AsyncDBSession extends LogSupport {
194218 )
195219 }
196220 }
197- connection.sendPreparedStatement(statement, parameters : _* ).map { result =>
221+ connection.sendPreparedStatement(statement, _parameters : _* ).map { result =>
198222 result.rows.map { ars =>
199223 new AsyncResultSetTraversable (ars).foldLeft(LinkedHashMap [A , (Seq [B1 ], Seq [B2 ], Seq [B3 ])]())(processResultSet).map {
200224 case (one, (t1, t2, t3)) => transform(one, t1, t2, t3)
201225 }
202226 }.getOrElse(Nil )
203227 }
204228 }
229+ }
205230
206231 def oneToManies4Traversable [A , B1 , B2 , B3 , B4 , Z ](statement : String , parameters : Any * )(
207232 extractOne : (WrappedResultSet ) => A )(
208233 extractTo1 : (WrappedResultSet ) => Option [B1 ],
209234 extractTo2 : (WrappedResultSet ) => Option [B2 ],
210235 extractTo3 : (WrappedResultSet ) => Option [B3 ],
211- extractTo4 : (WrappedResultSet ) => Option [B4 ])(transform : (A , Seq [B1 ], Seq [B2 ], Seq [B3 ], Seq [B4 ]) => Z )(implicit cxt : EC = ECGlobal ): Future [Traversable [Z ]] =
212- withListeners(statement, parameters) {
213- queryLogging(statement, parameters)
236+ extractTo4 : (WrappedResultSet ) => Option [B4 ])(
237+ transform : (A , Seq [B1 ], Seq [B2 ], Seq [B3 ], Seq [B4 ]) => Z )(
238+ implicit cxt : EC = ECGlobal ): Future [Traversable [Z ]] = {
239+ val _parameters = ensureAndNormalizeParameters(parameters)
240+ withListeners(statement, _parameters) {
241+ queryLogging(statement, _parameters)
214242
215243 def processResultSet (result : (LinkedHashMap [A , (Seq [B1 ], Seq [B2 ], Seq [B3 ], Seq [B4 ])]), rs : WrappedResultSet ): LinkedHashMap [A , (Seq [B1 ], Seq [B2 ], Seq [B3 ], Seq [B4 ])] = {
216244 val o = extractOne(rs)
@@ -236,26 +264,35 @@ trait AsyncDBSession extends LogSupport {
236264 )
237265 }
238266 }
239- connection.sendPreparedStatement(statement, parameters : _* ).map { result =>
267+ connection.sendPreparedStatement(statement, _parameters : _* ).map { result =>
240268 result.rows.map { ars =>
241- new AsyncResultSetTraversable (ars).foldLeft(LinkedHashMap [A , (Seq [B1 ], Seq [B2 ], Seq [B3 ], Seq [B4 ])]())(processResultSet).map {
242- case (one, (t1, t2, t3, t4)) => transform(one, t1, t2, t3, t4)
243- }
269+ new AsyncResultSetTraversable (ars).foldLeft(
270+ LinkedHashMap [A , (Seq [B1 ], Seq [B2 ], Seq [B3 ], Seq [B4 ])]())(processResultSet).map {
271+ case (one, (t1, t2, t3, t4)) => transform(one, t1, t2, t3, t4)
272+ }
244273 }.getOrElse(Nil )
245274 }
246275 }
276+ }
247277
248- def oneToManies5Traversable [A , B1 , B2 , B3 , B4 , B5 , Z ](statement : String , parameters : Any * )(
249- extractOne : (WrappedResultSet ) => A )(
250- extractTo1 : (WrappedResultSet ) => Option [B1 ],
251- extractTo2 : (WrappedResultSet ) => Option [B2 ],
252- extractTo3 : (WrappedResultSet ) => Option [B3 ],
253- extractTo4 : (WrappedResultSet ) => Option [B4 ],
254- extractTo5 : (WrappedResultSet ) => Option [B5 ])(transform : (A , Seq [B1 ], Seq [B2 ], Seq [B3 ], Seq [B4 ], Seq [B5 ]) => Z )(implicit cxt : EC = ECGlobal ): Future [Traversable [Z ]] =
255- withListeners(statement, parameters) {
256- queryLogging(statement, parameters)
257-
258- def processResultSet (result : (LinkedHashMap [A , (Seq [B1 ], Seq [B2 ], Seq [B3 ], Seq [B4 ], Seq [B5 ])]), rs : WrappedResultSet ): LinkedHashMap [A , (Seq [B1 ], Seq [B2 ], Seq [B3 ], Seq [B4 ], Seq [B5 ])] = {
278+ def oneToManies5Traversable [A , B1 , B2 , B3 , B4 , B5 , Z ](
279+ statement : String ,
280+ parameters : Any * )(
281+ extractOne : (WrappedResultSet ) => A )(
282+ extractTo1 : (WrappedResultSet ) => Option [B1 ],
283+ extractTo2 : (WrappedResultSet ) => Option [B2 ],
284+ extractTo3 : (WrappedResultSet ) => Option [B3 ],
285+ extractTo4 : (WrappedResultSet ) => Option [B4 ],
286+ extractTo5 : (WrappedResultSet ) => Option [B5 ])(
287+ transform : (A , Seq [B1 ], Seq [B2 ], Seq [B3 ], Seq [B4 ], Seq [B5 ]) => Z )(
288+ implicit cxt : EC = ECGlobal ): Future [Traversable [Z ]] = {
289+ val _parameters = ensureAndNormalizeParameters(parameters)
290+ withListeners(statement, _parameters) {
291+ queryLogging(statement, _parameters)
292+
293+ def processResultSet (
294+ result : (LinkedHashMap [A , (Seq [B1 ], Seq [B2 ], Seq [B3 ], Seq [B4 ], Seq [B5 ])]),
295+ rs : WrappedResultSet ): LinkedHashMap [A , (Seq [B1 ], Seq [B2 ], Seq [B3 ], Seq [B4 ], Seq [B5 ])] = {
259296 val o = extractOne(rs)
260297 val (to1, to2, to3, to4, to5) = (extractTo1(rs), extractTo2(rs), extractTo3(rs), extractTo4(rs), extractTo5(rs))
261298 result.keys.find(_ == o).map { _ =>
@@ -281,21 +318,31 @@ trait AsyncDBSession extends LogSupport {
281318 )
282319 }
283320 }
284- connection.sendPreparedStatement(statement, parameters : _* ).map { result =>
321+ connection.sendPreparedStatement(statement, _parameters : _* ).map { result =>
285322 result.rows.map { ars =>
286- new AsyncResultSetTraversable (ars).foldLeft(LinkedHashMap [A , (Seq [B1 ], Seq [B2 ], Seq [B3 ], Seq [B4 ], Seq [B5 ])]())(processResultSet).map {
287- case (one, (t1, t2, t3, t4, t5)) => transform(one, t1, t2, t3, t4, t5)
288- }
323+ new AsyncResultSetTraversable (ars).foldLeft(
324+ LinkedHashMap [A , (Seq [B1 ], Seq [B2 ], Seq [B3 ], Seq [B4 ], Seq [B5 ])]())(processResultSet).map {
325+ case (one, (t1, t2, t3, t4, t5)) => transform(one, t1, t2, t3, t4, t5)
326+ }
289327 }.getOrElse(Nil )
290328 }
291329 }
330+ }
292331
293332 protected def queryLogging (statement : String , parameters : Seq [Any ]): Unit = {
294333 if (loggingSQLAndTime.enabled) {
295334 log.withLevel(loggingSQLAndTime.logLevel)(s " [SQL Execution] ' ${statement}' with ( ${parameters.mkString(" ," )}) " )
296335 }
297336 }
298337
338+ protected def ensureAndNormalizeParameters (parameters : Seq [Any ]): Seq [Any ] = {
339+ parameters.map {
340+ case withValue : ParameterBinderWithValue [_] => withValue.value
341+ case binder : ParameterBinder => throw new IllegalArgumentException (" ParameterBinder is unsupported" )
342+ case rawValue => rawValue
343+ }
344+ }
345+
299346 protected def withListeners [A ](statement : String , parameters : Seq [Any ], startMillis : Long = System .currentTimeMillis)(
300347 f : Future [A ])(implicit cxt : EC = EC .global): Future [A ] = {
301348 f.onSuccess {
0 commit comments