@@ -186,6 +186,22 @@ private[projection] class R2dbcOffsetStore(
186
186
(projection_name, projection_key, slice, persistence_id, seq_nr, timestamp_offset, timestamp_consumed)
187
187
VALUES (?,?,?,?,?,?, transaction_timestamp()) """
188
188
189
+ private def insertTimestampOffsetBatchSql (pid : Pid , seqNr : SeqNr , offsetTimestamp : Instant ): String = {
190
+ def validateStringParam (name : String , value : String ): Unit = {
191
+ if (value.contains('\' ' ))
192
+ throw new IllegalArgumentException (s " Illegal $name parameter [ $value] " )
193
+ }
194
+ validateStringParam(" projectionId.name" , projectionId.name)
195
+ validateStringParam(" projectionId.key" , projectionId.key)
196
+ validateStringParam(" pid" , pid)
197
+
198
+ val slice = persistenceExt.sliceForPersistenceId(pid)
199
+ sql """
200
+ INSERT INTO $timestampOffsetTable
201
+ (projection_name, projection_key, slice, persistence_id, seq_nr, timestamp_offset, timestamp_consumed)
202
+ VALUES (' ${projectionId.name}',' ${projectionId.key}', $slice,' $pid', $seqNr,' $offsetTimestamp', transaction_timestamp()) """
203
+ }
204
+
189
205
// delete less than a timestamp
190
206
private val deleteOldTimestampOffsetSql : String =
191
207
sql " DELETE FROM $timestampOffsetTable WHERE slice BETWEEN ? AND ? AND projection_name = ? AND timestamp_offset < ? "
@@ -499,19 +515,15 @@ private[projection] class R2dbcOffsetStore(
499
515
// FIXME change to trace
500
516
logger.debug(" saving timestamp offset [{}], {}" , records.last.timestamp, records)
501
517
502
- val statement = conn.createStatement(insertTimestampOffsetSql)
503
-
504
518
if (records.size == 1 ) {
519
+ val statement = conn.createStatement(insertTimestampOffsetSql)
505
520
val boundStatement = bindRecord(statement, records.head)
506
521
R2dbcExecutor .updateOneInTx(boundStatement)
507
522
} else {
508
- // TODO Try Batch without bind parameters for better performance. Risk of sql injection for these parameters is low.
509
- val boundStatement =
510
- records.foldLeft(statement) { (stmt, rec) =>
511
- stmt.add()
512
- bindRecord(stmt, rec)
513
- }
514
- R2dbcExecutor .updateBatchInTx(boundStatement)
523
+ val statements = records.map { rec =>
524
+ insertTimestampOffsetBatchSql(rec.pid, rec.seqNr, rec.timestamp)
525
+ }
526
+ R2dbcExecutor .updateBatchInTx(conn, statements)
515
527
}
516
528
}
517
529
0 commit comments