22
33import pathlib
44import re
5+ import sys
56import time
67from concurrent .futures import ThreadPoolExecutor , as_completed
7- import sys
8+ from datetime import datetime
89from typing import Any , Dict , Iterable , List , Optional , Tuple
910from uuid import UUID
1011
@@ -541,6 +542,12 @@ def run(self, invoked_as: str, args: List[str]) -> None:
541542
542543 inspector = self .get_inspector ()
543544
545+ # On successful completion, will tell Gate to delete any now-orphaned
546+ # relations from prior introspections older than this timestamp.
547+ introspection_started_at = datetime .utcnow ()
548+
549+ # This and delta() just for development timing figures. Could become yet another
550+ # timer context manager implementation.
544551 start = time .monotonic ()
545552
546553 def delta () -> float :
@@ -600,12 +607,15 @@ def delta() -> float:
600607 session .headers .update (auth_header )
601608
602609 if message_queue :
603- # Clear out any prior known relations for this datasource.
604- self .inform_gate_start (session , ds_id )
605-
606610 for message in message_queue :
607611 self .inform_gate_relation (session , ds_id , message )
608612
613+ # Clear out any prior known relations which may not exist anymore in this datasource.
614+ #
615+ # We do this at the tail end of things, and not the beginning, so as to not eagerly delete
616+ # prior known data if we happen to croak due to some unforseen exception while introspecting.
617+ self .inform_gate_completed (session , ds_id , introspection_started_at )
618+
609619 print (f'Done storing discovered table and view structures in { delta ()} ' )
610620
611621 # run() contract: return what to bind to the SQL cell variable name, and if display() needs
@@ -821,14 +831,6 @@ def introspect_columns(
821831
822832 return retlist
823833
824- def inform_gate_start (self , session : requests .Session , datasource_id : UUID ):
825- """Tell gate to forget about any prior structures known for this datasource"""
826-
827- # No route implemented for this yet, but need one, otherwise Gate-side will
828- # never forget about dropped tables/views.
829-
830- pass
831-
832834 def inform_gate_relation (
833835 self ,
834836 session : requests .Session ,
@@ -851,6 +853,16 @@ def inform_gate_relation(
851853 f'Failed storing structure of { relation_description .schema_name } .{ relation_description .relation_name } : { resp .status_code } , { resp .text } '
852854 )
853855
856+ def inform_gate_completed (
857+ self , session : requests .Session , datasource_id : UUID , started_at : datetime
858+ ):
859+ """Tell gate to forget about any structures known for this datasource older than when we
860+ started this introspection run."""
861+
862+ session .delete (
863+ f"http://gate.default/api/v1/datasources/{ datasource_id } /schema/relations?older_than={ started_at .isoformat ()} "
864+ )
865+
854866 def get_datasource_id (self ) -> UUID :
855867 """Convert a noteable_magics.sql.connection.Connection's name to the original
856868 UUID Gate knew it as.
0 commit comments