@@ -19,6 +19,18 @@ def adapter(make_mocked_engine_adapter: t.Callable) -> FabricEngineAdapter:
1919 return make_mocked_engine_adapter (FabricEngineAdapter )
2020
2121
22+ def _record_catalogs_at_execute (adapter : FabricEngineAdapter ) -> t .List [t .Optional [str ]]:
23+ catalogs : t .List [t .Optional [str ]] = []
24+ real_execute = adapter .execute
25+
26+ def execute (* args : t .Any , ** kwargs : t .Any ) -> None :
27+ catalogs .append (adapter ._resolved_catalog ())
28+ return real_execute (* args , ** kwargs )
29+
30+ adapter .execute = execute # type: ignore[method-assign]
31+ return catalogs
32+
33+
2234def test_get_current_catalog_uses_only_explicit_target_catalog (
2335 make_mocked_engine_adapter : t .Callable ,
2436):
@@ -471,11 +483,129 @@ def test_get_data_objects_uses_default_catalog_when_current_is_none(
471483 return_value = pd .DataFrame ([{"name" : "test_table" , "schema_name" : "dbo" , "type" : "TABLE" }]),
472484 )
473485
474- assert adapter ._get_data_objects ( " dbo" ) == [
486+ assert adapter .get_data_objects ( "ci_abc. dbo" ) == [
475487 DataObject (
476488 catalog = "ci_abc" ,
477489 schema = "dbo" ,
478490 name = "test_table" ,
479491 type = DataObjectType .TABLE ,
480492 )
481493 ]
494+
495+
496+ def test_get_data_objects_cache_hits_for_default_catalog (
497+ make_mocked_engine_adapter : t .Callable ,
498+ mocker : MockerFixture ,
499+ ) -> None :
500+ """Listing fills catalog on the return value. Cache must still hit."""
501+ adapter = make_mocked_engine_adapter (
502+ FabricEngineAdapter ,
503+ default_catalog = "ci_abc" ,
504+ database = "ci_abc" ,
505+ patch_get_data_objects = False ,
506+ )
507+ fetchdf = mocker .patch .object (
508+ adapter ,
509+ "fetchdf" ,
510+ return_value = pd .DataFrame ([{"name" : "t" , "schema_name" : "dbo" , "type" : "TABLE" }]),
511+ )
512+
513+ first = adapter .get_data_objects ("ci_abc.dbo" , {"t" }, safe_to_cache = True )
514+ second = adapter .get_data_objects ("ci_abc.dbo" , {"t" }, safe_to_cache = True )
515+
516+ assert first [0 ].catalog == "ci_abc"
517+ assert second [0 ].catalog == "ci_abc"
518+ assert fetchdf .call_count == 1
519+
520+
521+ def test_get_data_objects_labels_connected_warehouse_after_lazy_restore (
522+ make_mocked_engine_adapter : t .Callable ,
523+ mocker : MockerFixture ,
524+ ) -> None :
525+ """Logical catalog is None; the connection is still on planning.
526+
527+ Unqualified list must be planning. ci_abc.dbo must still switch.
528+ """
529+ adapter = make_mocked_engine_adapter (
530+ FabricEngineAdapter ,
531+ default_catalog = "ci_abc" ,
532+ database = "ci_abc" ,
533+ patch_get_data_objects = False ,
534+ )
535+ adapter .set_current_catalog ("planning" )
536+ adapter .set_current_catalog (None )
537+ assert adapter .get_current_catalog () is None
538+
539+ fetchdf = mocker .patch .object (
540+ adapter ,
541+ "fetchdf" ,
542+ return_value = pd .DataFrame ([{"name" : "t" , "schema_name" : "dbo" , "type" : "TABLE" }]),
543+ )
544+
545+ objects = adapter .get_data_objects ("dbo" )
546+
547+ assert objects == [
548+ DataObject (
549+ catalog = "planning" ,
550+ schema = "dbo" ,
551+ name = "t" ,
552+ type = DataObjectType .TABLE ,
553+ )
554+ ]
555+
556+ assert adapter .get_data_objects ("ci_abc.dbo" ) == [
557+ DataObject (
558+ catalog = "ci_abc" ,
559+ schema = "dbo" ,
560+ name = "t" ,
561+ type = DataObjectType .TABLE ,
562+ )
563+ ]
564+ assert fetchdf .call_count == 2
565+
566+
567+ def test_drop_data_object_default_catalog_drops_without_requalifying (
568+ make_mocked_engine_adapter : t .Callable ,
569+ mocker : MockerFixture ,
570+ ) -> None :
571+ """DROP SQL has no warehouse. Prove it ran on ci_abc, without reconnecting."""
572+ adapter = make_mocked_engine_adapter (
573+ FabricEngineAdapter ,
574+ default_catalog = "ci_abc" ,
575+ database = "ci_abc" ,
576+ )
577+ close = mocker .spy (adapter ._connection_pool , "close" )
578+ catalogs_at_execute = _record_catalogs_at_execute (adapter )
579+
580+ adapter .drop_data_object (
581+ DataObject (catalog = "ci_abc" , schema = "dbo" , name = "v" , type = DataObjectType .VIEW )
582+ )
583+
584+ close .assert_not_called ()
585+ assert catalogs_at_execute == ["ci_abc" ]
586+ assert to_sql_calls (adapter ) == ["DROP VIEW IF EXISTS [dbo].[v];" ]
587+
588+
589+ def test_drop_data_object_default_catalog_reconnects_when_connected_elsewhere (
590+ make_mocked_engine_adapter : t .Callable ,
591+ mocker : MockerFixture ,
592+ ) -> None :
593+ """DROP SQL has no warehouse. Prove it ran on ci_abc, then restored planning."""
594+ adapter = make_mocked_engine_adapter (
595+ FabricEngineAdapter ,
596+ default_catalog = "ci_abc" ,
597+ database = "ci_abc" ,
598+ )
599+ adapter .set_current_catalog ("planning" )
600+ assert adapter .get_current_catalog () == "planning"
601+ close = mocker .spy (adapter ._connection_pool , "close" )
602+ catalogs_at_execute = _record_catalogs_at_execute (adapter )
603+
604+ adapter .drop_data_object (
605+ DataObject (catalog = "ci_abc" , schema = "dbo" , name = "v" , type = DataObjectType .VIEW )
606+ )
607+
608+ assert catalogs_at_execute == ["ci_abc" ]
609+ assert adapter .get_current_catalog () == "planning"
610+ assert close .call_count == 2
611+ assert "DROP VIEW IF EXISTS [dbo].[v];" in to_sql_calls (adapter )
0 commit comments