@@ -125,11 +125,11 @@ impl<'client> CardanoTransactionProvider<'client> {
125
125
126
126
pub ( crate ) fn get_transaction_up_to_beacon_condition (
127
127
& self ,
128
- beacon : & CardanoDbBeacon ,
128
+ beacon : ImmutableFileNumber ,
129
129
) -> WhereCondition {
130
130
WhereCondition :: new (
131
131
"immutable_file_number <= ?*" ,
132
- vec ! [ Value :: Integer ( beacon. immutable_file_number as i64 ) ] ,
132
+ vec ! [ Value :: Integer ( beacon as i64 ) ] ,
133
133
)
134
134
}
135
135
}
@@ -235,7 +235,7 @@ impl CardanoTransactionRepository {
235
235
/// chronological order.
236
236
pub async fn get_transactions_up_to (
237
237
& self ,
238
- beacon : & CardanoDbBeacon ,
238
+ beacon : ImmutableFileNumber ,
239
239
) -> StdResult < Vec < CardanoTransactionRecord > > {
240
240
let provider = CardanoTransactionProvider :: new ( & self . connection ) ;
241
241
let filters = provider. get_transaction_up_to_beacon_condition ( beacon) ;
@@ -279,12 +279,15 @@ impl CardanoTransactionRepository {
279
279
}
280
280
281
281
/// Create new [CardanoTransactionRecord]s in the database.
282
- pub async fn create_transactions (
282
+ pub async fn create_transactions < T : Into < CardanoTransactionRecord > > (
283
283
& self ,
284
- transactions : Vec < CardanoTransactionRecord > ,
284
+ transactions : Vec < T > ,
285
285
) -> StdResult < Vec < CardanoTransactionRecord > > {
286
+ let records: Vec < CardanoTransactionRecord > =
287
+ transactions. into_iter ( ) . map ( |tx| tx. into ( ) ) . collect ( ) ;
288
+
286
289
let provider = InsertCardanoTransactionProvider :: new ( & self . connection ) ;
287
- let filters = provider. get_insert_many_condition ( transactions ) ?;
290
+ let filters = provider. get_insert_many_condition ( records ) ?;
288
291
let cursor = provider. find ( filters) ?;
289
292
290
293
Ok ( cursor. collect ( ) )
@@ -293,10 +296,43 @@ impl CardanoTransactionRepository {
293
296
294
297
#[ async_trait]
295
298
impl TransactionStore for CardanoTransactionRepository {
299
+ async fn get_highest_beacon ( & self ) -> StdResult < Option < ImmutableFileNumber > > {
300
+ let sql = "select max(immutable_file_number) as highest from cardano_tx;" ;
301
+ match self
302
+ . connection
303
+ . prepare ( sql)
304
+ . with_context ( || {
305
+ format ! (
306
+ "Prepare query error: SQL=`{}`" ,
307
+ & sql. replace( '\n' , " " ) . trim( )
308
+ )
309
+ } ) ?
310
+ . iter ( )
311
+ . next ( )
312
+ {
313
+ None => Ok ( None ) ,
314
+ Some ( row) => {
315
+ let highest = row?. read :: < Option < i64 > , _ > ( 0 ) ;
316
+ highest
317
+ . map ( u64:: try_from)
318
+ . transpose ( )
319
+ . with_context ( ||
320
+ format ! ( "Integer field max(immutable_file_number) (value={highest:?}) is incompatible with u64 representation." )
321
+ )
322
+ }
323
+ }
324
+ }
325
+
326
+ async fn get_up_to ( & self , beacon : ImmutableFileNumber ) -> StdResult < Vec < CardanoTransaction > > {
327
+ self . get_transactions_up_to ( beacon) . await . map ( |v| {
328
+ v. into_iter ( )
329
+ . map ( |record| record. into ( ) )
330
+ . collect :: < Vec < CardanoTransaction > > ( )
331
+ } )
332
+ }
333
+
296
334
async fn store_transactions ( & self , transactions : & [ CardanoTransaction ] ) -> StdResult < ( ) > {
297
- let records: Vec < CardanoTransactionRecord > =
298
- transactions. iter ( ) . map ( |tx| tx. to_owned ( ) . into ( ) ) . collect ( ) ;
299
- self . create_transactions ( records)
335
+ self . create_transactions ( transactions. to_vec ( ) )
300
336
. await
301
337
. with_context ( || "CardanoTransactionRepository can not store transactions" ) ?;
302
338
@@ -307,11 +343,13 @@ impl TransactionStore for CardanoTransactionRepository {
307
343
#[ async_trait]
308
344
impl TransactionsRetriever for CardanoTransactionRepository {
309
345
async fn get_up_to ( & self , beacon : & CardanoDbBeacon ) -> StdResult < Vec < CardanoTransaction > > {
310
- self . get_transactions_up_to ( beacon) . await . map ( |v| {
311
- v. into_iter ( )
312
- . map ( |record| record. into ( ) )
313
- . collect :: < Vec < CardanoTransaction > > ( )
314
- } )
346
+ self . get_transactions_up_to ( beacon. immutable_file_number )
347
+ . await
348
+ . map ( |v| {
349
+ v. into_iter ( )
350
+ . map ( |record| record. into ( ) )
351
+ . collect :: < Vec < CardanoTransaction > > ( )
352
+ } )
315
353
}
316
354
}
317
355
@@ -368,10 +406,7 @@ mod tests {
368
406
let connection = Connection :: open_thread_safe ( ":memory:" ) . unwrap ( ) ;
369
407
let provider = CardanoTransactionProvider :: new ( & connection) ;
370
408
let ( expr, params) = provider
371
- . get_transaction_up_to_beacon_condition ( & CardanoDbBeacon {
372
- immutable_file_number : 2309 ,
373
- ..CardanoDbBeacon :: default ( )
374
- } )
409
+ . get_transaction_up_to_beacon_condition ( 2309 )
375
410
. expand ( ) ;
376
411
377
412
assert_eq ! ( "immutable_file_number <= ?1" . to_string( ) , expr) ;
@@ -557,8 +592,8 @@ mod tests {
557
592
let connection = get_connection ( ) . await ;
558
593
let repository = CardanoTransactionRepository :: new ( connection. clone ( ) ) ;
559
594
560
- let cardano_transactions: Vec < CardanoTransaction > = ( 20 ..=40 )
561
- . map ( |i| CardanoTransaction {
595
+ let cardano_transactions: Vec < CardanoTransactionRecord > = ( 20 ..=40 )
596
+ . map ( |i| CardanoTransactionRecord {
562
597
transaction_hash : format ! ( "tx-hash-{i}" ) ,
563
598
block_number : i % 10 ,
564
599
slot_number : i * 100 ,
@@ -567,33 +602,18 @@ mod tests {
567
602
} )
568
603
. collect ( ) ;
569
604
repository
570
- . store_transactions ( & cardano_transactions)
571
- . await
572
- . unwrap ( ) ;
573
-
574
- let transaction_result = repository
575
- . get_up_to ( & CardanoDbBeacon :: new ( "" . to_string ( ) , 1 , 34 ) )
605
+ . create_transactions ( cardano_transactions. clone ( ) )
576
606
. await
577
607
. unwrap ( ) ;
578
608
609
+ let transaction_result = repository. get_transactions_up_to ( 34 ) . await . unwrap ( ) ;
579
610
assert_eq ! ( cardano_transactions[ 0 ..=14 ] . to_vec( ) , transaction_result) ;
580
611
581
- let transaction_result = repository
582
- . get_up_to ( & CardanoDbBeacon :: new ( "" . to_string ( ) , 1 , 300 ) )
583
- . await
584
- . unwrap ( ) ;
612
+ let transaction_result = repository. get_transactions_up_to ( 300 ) . await . unwrap ( ) ;
613
+ assert_eq ! ( cardano_transactions. clone( ) , transaction_result) ;
585
614
586
- assert_eq ! (
587
- cardano_transactions. into_iter( ) . collect:: <Vec <_>>( ) ,
588
- transaction_result
589
- ) ;
590
-
591
- let transaction_result = repository
592
- . get_up_to ( & CardanoDbBeacon :: new ( "" . to_string ( ) , 1 , 19 ) )
593
- . await
594
- . unwrap ( ) ;
595
-
596
- assert_eq ! ( Vec :: <CardanoTransaction >:: new( ) , transaction_result) ;
615
+ let transaction_result = repository. get_transactions_up_to ( 19 ) . await . unwrap ( ) ;
616
+ assert_eq ! ( Vec :: <CardanoTransactionRecord >:: new( ) , transaction_result) ;
597
617
}
598
618
599
619
#[ tokio:: test]
@@ -654,4 +674,31 @@ mod tests {
654
674
transaction_result
655
675
) ;
656
676
}
677
+
678
+ #[ tokio:: test]
679
+ async fn repository_get_highest_beacon_without_transactions_in_db ( ) {
680
+ let connection = get_connection ( ) . await ;
681
+ let repository = CardanoTransactionRepository :: new ( connection. clone ( ) ) ;
682
+
683
+ let highest_beacon = repository. get_highest_beacon ( ) . await . unwrap ( ) ;
684
+ assert_eq ! ( None , highest_beacon) ;
685
+ }
686
+
687
+ #[ tokio:: test]
688
+ async fn repository_get_highest_beacon_with_transactions_in_db ( ) {
689
+ let connection = get_connection ( ) . await ;
690
+ let repository = CardanoTransactionRepository :: new ( connection. clone ( ) ) ;
691
+
692
+ let cardano_transactions = vec ! [
693
+ CardanoTransaction :: new( "tx-hash-123" . to_string( ) , 10 , 50 , "block-hash-123" , 50 ) ,
694
+ CardanoTransaction :: new( "tx-hash-456" . to_string( ) , 11 , 51 , "block-hash-456" , 100 ) ,
695
+ ] ;
696
+ repository
697
+ . store_transactions ( & cardano_transactions)
698
+ . await
699
+ . unwrap ( ) ;
700
+
701
+ let highest_beacon = repository. get_highest_beacon ( ) . await . unwrap ( ) ;
702
+ assert_eq ! ( Some ( 100 ) , highest_beacon) ;
703
+ }
657
704
}
0 commit comments