@@ -39,6 +39,16 @@ def _conflict_response(mocker: MockerFixture, error_code: str) -> t.Any:
3939 resp .json .return_value = {"errorCode" : error_code }
4040 resp .raise_for_status .side_effect = requests .HTTPError (response = resp )
4141 return resp
42+ def _record_catalogs_at_execute (adapter : FabricEngineAdapter ) -> t .List [t .Optional [str ]]:
43+ catalogs : t .List [t .Optional [str ]] = []
44+ real_execute = adapter .execute
45+
46+ def execute (* args : t .Any , ** kwargs : t .Any ) -> None :
47+ catalogs .append (adapter ._resolved_catalog ())
48+ return real_execute (* args , ** kwargs )
49+
50+ adapter .execute = execute # type: ignore[method-assign]
51+ return catalogs
4252
4353
4454def test_get_current_catalog_uses_only_explicit_target_catalog (
@@ -514,11 +524,129 @@ def test_get_data_objects_uses_default_catalog_when_current_is_none(
514524 return_value = pd .DataFrame ([{"name" : "test_table" , "schema_name" : "dbo" , "type" : "TABLE" }]),
515525 )
516526
517- assert adapter ._get_data_objects ( " dbo" ) == [
527+ assert adapter .get_data_objects ( "ci_abc. dbo" ) == [
518528 DataObject (
519529 catalog = "ci_abc" ,
520530 schema = "dbo" ,
521531 name = "test_table" ,
522532 type = DataObjectType .TABLE ,
523533 )
524534 ]
535+
536+
537+ def test_get_data_objects_cache_hits_for_default_catalog (
538+ make_mocked_engine_adapter : t .Callable ,
539+ mocker : MockerFixture ,
540+ ) -> None :
541+ """Listing fills catalog on the return value. Cache must still hit."""
542+ adapter = make_mocked_engine_adapter (
543+ FabricEngineAdapter ,
544+ default_catalog = "ci_abc" ,
545+ database = "ci_abc" ,
546+ patch_get_data_objects = False ,
547+ )
548+ fetchdf = mocker .patch .object (
549+ adapter ,
550+ "fetchdf" ,
551+ return_value = pd .DataFrame ([{"name" : "t" , "schema_name" : "dbo" , "type" : "TABLE" }]),
552+ )
553+
554+ first = adapter .get_data_objects ("ci_abc.dbo" , {"t" }, safe_to_cache = True )
555+ second = adapter .get_data_objects ("ci_abc.dbo" , {"t" }, safe_to_cache = True )
556+
557+ assert first [0 ].catalog == "ci_abc"
558+ assert second [0 ].catalog == "ci_abc"
559+ assert fetchdf .call_count == 1
560+
561+
562+ def test_get_data_objects_labels_connected_warehouse_after_lazy_restore (
563+ make_mocked_engine_adapter : t .Callable ,
564+ mocker : MockerFixture ,
565+ ) -> None :
566+ """Logical catalog is None; the connection is still on planning.
567+
568+ Unqualified list must be planning. ci_abc.dbo must still switch.
569+ """
570+ adapter = make_mocked_engine_adapter (
571+ FabricEngineAdapter ,
572+ default_catalog = "ci_abc" ,
573+ database = "ci_abc" ,
574+ patch_get_data_objects = False ,
575+ )
576+ adapter .set_current_catalog ("planning" )
577+ adapter .set_current_catalog (None )
578+ assert adapter .get_current_catalog () is None
579+
580+ fetchdf = mocker .patch .object (
581+ adapter ,
582+ "fetchdf" ,
583+ return_value = pd .DataFrame ([{"name" : "t" , "schema_name" : "dbo" , "type" : "TABLE" }]),
584+ )
585+
586+ objects = adapter .get_data_objects ("dbo" )
587+
588+ assert objects == [
589+ DataObject (
590+ catalog = "planning" ,
591+ schema = "dbo" ,
592+ name = "t" ,
593+ type = DataObjectType .TABLE ,
594+ )
595+ ]
596+
597+ assert adapter .get_data_objects ("ci_abc.dbo" ) == [
598+ DataObject (
599+ catalog = "ci_abc" ,
600+ schema = "dbo" ,
601+ name = "t" ,
602+ type = DataObjectType .TABLE ,
603+ )
604+ ]
605+ assert fetchdf .call_count == 2
606+
607+
608+ def test_drop_data_object_default_catalog_drops_without_requalifying (
609+ make_mocked_engine_adapter : t .Callable ,
610+ mocker : MockerFixture ,
611+ ) -> None :
612+ """DROP SQL has no warehouse. Prove it ran on ci_abc, without reconnecting."""
613+ adapter = make_mocked_engine_adapter (
614+ FabricEngineAdapter ,
615+ default_catalog = "ci_abc" ,
616+ database = "ci_abc" ,
617+ )
618+ close = mocker .spy (adapter ._connection_pool , "close" )
619+ catalogs_at_execute = _record_catalogs_at_execute (adapter )
620+
621+ adapter .drop_data_object (
622+ DataObject (catalog = "ci_abc" , schema = "dbo" , name = "v" , type = DataObjectType .VIEW )
623+ )
624+
625+ close .assert_not_called ()
626+ assert catalogs_at_execute == ["ci_abc" ]
627+ assert to_sql_calls (adapter ) == ["DROP VIEW IF EXISTS [dbo].[v];" ]
628+
629+
630+ def test_drop_data_object_default_catalog_reconnects_when_connected_elsewhere (
631+ make_mocked_engine_adapter : t .Callable ,
632+ mocker : MockerFixture ,
633+ ) -> None :
634+ """DROP SQL has no warehouse. Prove it ran on ci_abc, then restored planning."""
635+ adapter = make_mocked_engine_adapter (
636+ FabricEngineAdapter ,
637+ default_catalog = "ci_abc" ,
638+ database = "ci_abc" ,
639+ )
640+ adapter .set_current_catalog ("planning" )
641+ assert adapter .get_current_catalog () == "planning"
642+ close = mocker .spy (adapter ._connection_pool , "close" )
643+ catalogs_at_execute = _record_catalogs_at_execute (adapter )
644+
645+ adapter .drop_data_object (
646+ DataObject (catalog = "ci_abc" , schema = "dbo" , name = "v" , type = DataObjectType .VIEW )
647+ )
648+
649+ assert catalogs_at_execute == ["ci_abc" ]
650+ assert adapter .get_current_catalog () == "planning"
651+ assert close .call_count == 2
652+ assert "DROP VIEW IF EXISTS [dbo].[v];" in to_sql_calls (adapter )
0 commit comments