1- use std:: ops:: Bound ;
1+ use std:: { collections :: HashMap , ops:: Bound } ;
22
33use diesel:: {
44 pg:: sql_types,
@@ -252,32 +252,11 @@ impl DataSourcesTable {
252252 . order_by ( & self . vid )
253253 . load :: < Tuple > ( conn) ?;
254254
255+ let manifest_map =
256+ ManifestIdxMap :: new ( src_manifest_idx_and_name, dst_manifest_idx_and_name) ;
255257 let mut count = 0 ;
256- for ( block_range, src_manifest_idx, param, context, causality_region, done_at) in src_tuples
257- {
258- let name = & src_manifest_idx_and_name
259- . iter ( )
260- . find ( |( idx, _) | idx == & src_manifest_idx)
261- . with_context ( || {
262- anyhow ! (
263- "the source {} does not have a template with index {}" ,
264- self . namespace,
265- src_manifest_idx
266- )
267- } ) ?
268- . 1 ;
269- let dst_manifest_idx = dst_manifest_idx_and_name
270- . iter ( )
271- . find ( |( _, n) | n == name)
272- . with_context ( || {
273- anyhow ! (
274- "the destination {} is missing a template with name {}. The source {} created one at block {:?}" ,
275- dst. namespace,
276- name, self . namespace, block_range. 0
277- )
278- } ) ?
279- . 0 ;
280-
258+ for ( block_range, src_idx, param, context, causality_region, done_at) in src_tuples {
259+ let dst_idx = manifest_map. dst_idx ( src_idx) ?;
281260 let query = format ! (
282261 "\
283262 insert into {dst}(block_range, manifest_idx, param, context, causality_region, done_at)
@@ -293,7 +272,7 @@ impl DataSourcesTable {
293272 count += sql_query ( query)
294273 . bind :: < Integer , _ > ( target_block)
295274 . bind :: < sql_types:: Range < Integer > , _ > ( block_range)
296- . bind :: < Integer , _ > ( dst_manifest_idx )
275+ . bind :: < Integer , _ > ( dst_idx )
297276 . bind :: < Nullable < Binary > , _ > ( param)
298277 . bind :: < Nullable < Jsonb > , _ > ( context)
299278 . bind :: < Integer , _ > ( causality_region)
@@ -361,3 +340,43 @@ impl DataSourcesTable {
361340 . optional ( ) ?)
362341 }
363342}
343+
344+ /// Map src manifest indexes to dst manifest indexes. If the
345+ /// destination is missing an entry, put `None` as the value for the
346+ /// source index
347+ struct ManifestIdxMap < ' a > {
348+ map : HashMap < i32 , ( Option < i32 > , & ' a String ) > ,
349+ }
350+
351+ impl < ' a > ManifestIdxMap < ' a > {
352+ fn new ( src : & ' a [ ( i32 , String ) ] , dst : & ' a [ ( i32 , String ) ] ) -> Self {
353+ let map = src
354+ . iter ( )
355+ . map ( |( src_idx, src_name) | {
356+ (
357+ * src_idx,
358+ (
359+ dst. iter ( )
360+ . find ( |( _, dst_name) | src_name == dst_name)
361+ . map ( |( dst_idx, _) | * dst_idx) ,
362+ src_name,
363+ ) ,
364+ )
365+ } )
366+ . collect ( ) ;
367+ ManifestIdxMap { map }
368+ }
369+
370+ fn dst_idx ( & self , src_idx : i32 ) -> Result < i32 , StoreError > {
371+ let ( dst_idx, name) = self . map . get ( & src_idx) . with_context ( || {
372+ anyhow ! ( "the source does not have a template with index {}" , src_idx)
373+ } ) ?;
374+ let dst_idx = dst_idx. with_context ( || {
375+ anyhow ! (
376+ "the destination does not have a template with name {}" ,
377+ name
378+ )
379+ } ) ?;
380+ Ok ( dst_idx)
381+ }
382+ }
0 commit comments