@@ -72,6 +72,16 @@ async fn create_source_state_table(pool: &PgPool, table_name: &str) -> Result<()
7272 Ok ( ( ) )
7373}
7474
75+ async fn delete_source_states_for_sources (
76+ pool : & PgPool ,
77+ table_name : & str ,
78+ source_ids : & Vec < i32 > ,
79+ ) -> Result < ( ) > {
80+ let query = format ! ( "DELETE FROM {} WHERE source_id = ANY($1)" , table_name, ) ;
81+ sqlx:: query ( & query) . bind ( source_ids) . execute ( pool) . await ?;
82+ Ok ( ( ) )
83+ }
84+
7585#[ derive( Debug , Clone , Serialize , Deserialize , PartialEq ) ]
7686pub struct TrackingTableSetupState {
7787 pub table_name : String ,
@@ -92,14 +102,14 @@ pub struct TrackingTableSetupChange {
92102 pub source_state_table_always_exists : bool ,
93103 pub legacy_source_state_table_names : BTreeSet < String > ,
94104
95- pub source_ids_to_delete : Vec < i32 > ,
105+ pub source_names_need_state_cleanup : BTreeMap < i32 , BTreeSet < String > > ,
96106}
97107
98108impl TrackingTableSetupChange {
99109 pub fn new (
100110 desired : Option < & TrackingTableSetupState > ,
101111 existing : & CombinedState < TrackingTableSetupState > ,
102- source_ids_to_delete : Vec < i32 > ,
112+ source_names_need_state_cleanup : BTreeMap < i32 , BTreeSet < String > > ,
103113 ) -> Option < Self > {
104114 let legacy_tracking_table_names = existing
105115 . legacy_values ( desired, |v| & v. table_name )
@@ -125,7 +135,7 @@ impl TrackingTableSetupChange {
125135 . all ( |v| v. source_state_table_name . is_some ( ) ) ,
126136 legacy_source_state_table_names,
127137 min_existing_version_id,
128- source_ids_to_delete ,
138+ source_names_need_state_cleanup ,
129139 } )
130140 } else {
131141 None
@@ -201,29 +211,28 @@ impl ResourceSetupChange for TrackingTableSetupChange {
201211 ) ) ) ;
202212 }
203213
204- if !self . source_ids_to_delete . is_empty ( ) {
214+ if !self . source_names_need_state_cleanup . is_empty ( ) {
205215 changes. push ( setup:: ChangeDescription :: Action ( format ! (
206- "Delete source IDs : {}. " ,
207- self . source_ids_to_delete
208- . iter ( )
209- . map ( |id| id . to_string ( ) )
210- . collect :: < Vec < String >> ( )
216+ "Clean up legacy source states : {}. " ,
217+ self . source_names_need_state_cleanup
218+ . values ( )
219+ . flatten ( )
220+ . dedup ( )
211221 . join( ", " )
212222 ) ) ) ;
213223 }
214224 changes
215225 }
216226
217227 fn change_type ( & self ) -> SetupChangeType {
218- let source_state_table_up_to_date = self . legacy_source_state_table_names . is_empty ( )
219- && ( self . source_state_table_always_exists
220- || self
221- . desired_state
222- . as_ref ( )
223- . map_or ( true , |v| v. source_state_table_name . is_none ( ) ) ) ;
224228 match ( self . min_existing_version_id , & self . desired_state ) {
225229 ( None , Some ( _) ) => SetupChangeType :: Create ,
226230 ( Some ( min_version_id) , Some ( desired) ) => {
231+ let source_state_table_up_to_date = self . legacy_source_state_table_names . is_empty ( )
232+ && self . source_names_need_state_cleanup . is_empty ( )
233+ && ( self . source_state_table_always_exists
234+ || desired. source_state_table_name . is_none ( ) ) ;
235+
227236 if min_version_id == desired. version_id
228237 && self . legacy_tracking_table_names . is_empty ( )
229238 && source_state_table_up_to_date
@@ -279,6 +288,18 @@ impl TrackingTableSetupChange {
279288 if !self . source_state_table_always_exists {
280289 create_source_state_table ( pool, source_state_table_name) . await ?;
281290 }
291+ if !self . source_names_need_state_cleanup . is_empty ( ) {
292+ delete_source_states_for_sources (
293+ pool,
294+ source_state_table_name,
295+ & self
296+ . source_names_need_state_cleanup
297+ . keys ( )
298+ . map ( |v| * v)
299+ . collect :: < Vec < _ > > ( ) ,
300+ )
301+ . await ?;
302+ }
282303 } else {
283304 for lagacy_name in self . legacy_source_state_table_names . iter ( ) {
284305 let query = format ! ( "DROP TABLE IF EXISTS {lagacy_name}" ) ;
0 commit comments