Skip to content

Commit 603cef1

Browse files
committed
refactor: move private grants method to the end of EngineAdapter
1 parent 5efad1a commit 603cef1

1 file changed

Lines changed: 121 additions & 121 deletions

File tree

sqlmesh/core/engine_adapter/base.py

Lines changed: 121 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -2483,29 +2483,6 @@ def wap_publish(self, table_name: TableName, wap_id: str) -> None:
24832483
"""
24842484
raise NotImplementedError(f"Engine does not support WAP: {type(self)}")
24852485

2486-
def _get_current_grants_config(self, table: exp.Table) -> GrantsConfig:
2487-
"""Returns current grants for a table as a dictionary.
2488-
2489-
This method queries the database and returns the current grants/permissions
2490-
for the given table, parsed into a dictionary format. The it handles
2491-
case-insensitive comparison between these current grants and the desired
2492-
grants from model configuration.
2493-
2494-
Args:
2495-
table: The table/view to query grants for.
2496-
2497-
Returns:
2498-
Dictionary mapping permissions to lists of grantees. Permission names
2499-
should be returned as the database provides them (typically uppercase
2500-
for standard SQL permissions, but engine-specific roles may vary).
2501-
2502-
Raises:
2503-
NotImplementedError: If the engine does not support grants.
2504-
"""
2505-
if not self.SUPPORTS_GRANTS:
2506-
raise NotImplementedError(f"Engine does not support grants: {type(self)}")
2507-
raise NotImplementedError("Subclass must implement get_current_grants")
2508-
25092486
def sync_grants_config(
25102487
self,
25112488
table: exp.Table,
@@ -2533,104 +2510,6 @@ def sync_grants_config(
25332510
if dcl_exprs:
25342511
self.execute(dcl_exprs)
25352512

2536-
def _apply_grants_config_expr(
2537-
self,
2538-
table: exp.Table,
2539-
grant_config: GrantsConfig,
2540-
table_type: DataObjectType = DataObjectType.TABLE,
2541-
) -> t.List[exp.Expression]:
2542-
"""Returns SQLGlot Grant expressions to apply grants to a table.
2543-
2544-
Args:
2545-
table: The table/view to grant permissions on.
2546-
grant_config: Dictionary mapping permissions to lists of grantees.
2547-
table_type: The type of database object (TABLE, VIEW, MATERIALIZED_VIEW).
2548-
2549-
Returns:
2550-
List of SQLGlot expressions for grant operations.
2551-
2552-
Raises:
2553-
NotImplementedError: If the engine does not support grants.
2554-
"""
2555-
if not self.SUPPORTS_GRANTS:
2556-
raise NotImplementedError(f"Engine does not support grants: {type(self)}")
2557-
raise NotImplementedError("Subclass must implement _apply_grants_config_expr")
2558-
2559-
def _revoke_grants_config_expr(
2560-
self,
2561-
table: exp.Table,
2562-
grant_config: GrantsConfig,
2563-
table_type: DataObjectType = DataObjectType.TABLE,
2564-
) -> t.List[exp.Expression]:
2565-
"""Returns SQLGlot expressions to revoke grants from a table.
2566-
2567-
Note: SQLGlot doesn't yet have a Revoke expression type, so implementations
2568-
may return other expression types or handle revokes as strings.
2569-
2570-
Args:
2571-
table: The table/view to revoke permissions from.
2572-
grant_config: Dictionary mapping permissions to lists of grantees.
2573-
table_type: The type of database object (TABLE, VIEW, MATERIALIZED_VIEW).
2574-
2575-
Returns:
2576-
List of SQLGlot expressions for revoke operations.
2577-
2578-
Raises:
2579-
NotImplementedError: If the engine does not support grants.
2580-
"""
2581-
if not self.SUPPORTS_GRANTS:
2582-
raise NotImplementedError(f"Engine does not support grants: {type(self)}")
2583-
raise NotImplementedError("Subclass must implement _revoke_grants_config_expr")
2584-
2585-
@classmethod
2586-
def _diff_grants_configs(
2587-
cls, new_config: GrantsConfig, old_config: GrantsConfig
2588-
) -> t.Tuple[GrantsConfig, GrantsConfig]:
2589-
"""Compute additions and removals between two grants configurations.
2590-
2591-
This method compares new (desired) and old (current) GrantsConfigs case-insensitively
2592-
for both privilege keys and grantees, while preserving original casing
2593-
in the output GrantsConfigs.
2594-
2595-
Args:
2596-
new_config: Desired grants configuration (specified by the user).
2597-
old_config: Current grants configuration (returned by the database).
2598-
2599-
Returns:
2600-
A tuple of (additions, removals) GrantsConfig where:
2601-
- additions contains privileges/grantees present in new_config but not in old_config
2602-
- additions uses keys and grantee strings from new_config (user-specified casing)
2603-
- removals contains privileges/grantees present in old_config but not in new_config
2604-
- removals uses keys and grantee strings from old_config (database-returned casing)
2605-
2606-
Notes:
2607-
- Comparison is case-insensitive using casefold(); original casing is preserved in results.
2608-
- Overlapping grantees (case-insensitive) are excluded from the results.
2609-
"""
2610-
2611-
def _diffs(config1: GrantsConfig, config2: GrantsConfig) -> GrantsConfig:
2612-
diffs: GrantsConfig = {}
2613-
cf_config2 = {k.casefold(): {g.casefold() for g in v} for k, v in config2.items()}
2614-
for key, grantees in config1.items():
2615-
cf_key = key.casefold()
2616-
2617-
# Missing key (add all grantees)
2618-
if cf_key not in cf_config2:
2619-
diffs[key] = grantees.copy()
2620-
continue
2621-
2622-
# Include only grantees not in config2
2623-
cf_grantees2 = cf_config2[cf_key]
2624-
diff_grantees = []
2625-
for grantee in grantees:
2626-
if grantee.casefold() not in cf_grantees2:
2627-
diff_grantees.append(grantee)
2628-
if diff_grantees:
2629-
diffs[key] = diff_grantees
2630-
return diffs
2631-
2632-
return _diffs(new_config, old_config), _diffs(old_config, new_config)
2633-
26342513
@contextlib.contextmanager
26352514
def transaction(
26362515
self,
@@ -3182,6 +3061,127 @@ def _check_identifier_length(self, expression: exp.Expression) -> None:
31823061
def get_table_last_modified_ts(self, table_names: t.List[TableName]) -> t.List[int]:
31833062
raise NotImplementedError()
31843063

3064+
@classmethod
3065+
def _diff_grants_configs(
3066+
cls, new_config: GrantsConfig, old_config: GrantsConfig
3067+
) -> t.Tuple[GrantsConfig, GrantsConfig]:
3068+
"""Compute additions and removals between two grants configurations.
3069+
3070+
This method compares new (desired) and old (current) GrantsConfigs case-insensitively
3071+
for both privilege keys and grantees, while preserving original casing
3072+
in the output GrantsConfigs.
3073+
3074+
Args:
3075+
new_config: Desired grants configuration (specified by the user).
3076+
old_config: Current grants configuration (returned by the database).
3077+
3078+
Returns:
3079+
A tuple of (additions, removals) GrantsConfig where:
3080+
- additions contains privileges/grantees present in new_config but not in old_config
3081+
- additions uses keys and grantee strings from new_config (user-specified casing)
3082+
- removals contains privileges/grantees present in old_config but not in new_config
3083+
- removals uses keys and grantee strings from old_config (database-returned casing)
3084+
3085+
Notes:
3086+
- Comparison is case-insensitive using casefold(); original casing is preserved in results.
3087+
- Overlapping grantees (case-insensitive) are excluded from the results.
3088+
"""
3089+
3090+
def _diffs(config1: GrantsConfig, config2: GrantsConfig) -> GrantsConfig:
3091+
diffs: GrantsConfig = {}
3092+
cf_config2 = {k.casefold(): {g.casefold() for g in v} for k, v in config2.items()}
3093+
for key, grantees in config1.items():
3094+
cf_key = key.casefold()
3095+
3096+
# Missing key (add all grantees)
3097+
if cf_key not in cf_config2:
3098+
diffs[key] = grantees.copy()
3099+
continue
3100+
3101+
# Include only grantees not in config2
3102+
cf_grantees2 = cf_config2[cf_key]
3103+
diff_grantees = []
3104+
for grantee in grantees:
3105+
if grantee.casefold() not in cf_grantees2:
3106+
diff_grantees.append(grantee)
3107+
if diff_grantees:
3108+
diffs[key] = diff_grantees
3109+
return diffs
3110+
3111+
return _diffs(new_config, old_config), _diffs(old_config, new_config)
3112+
3113+
def _get_current_grants_config(self, table: exp.Table) -> GrantsConfig:
3114+
"""Returns current grants for a table as a dictionary.
3115+
3116+
This method queries the database and returns the current grants/permissions
3117+
for the given table, parsed into a dictionary format. The it handles
3118+
case-insensitive comparison between these current grants and the desired
3119+
grants from model configuration.
3120+
3121+
Args:
3122+
table: The table/view to query grants for.
3123+
3124+
Returns:
3125+
Dictionary mapping permissions to lists of grantees. Permission names
3126+
should be returned as the database provides them (typically uppercase
3127+
for standard SQL permissions, but engine-specific roles may vary).
3128+
3129+
Raises:
3130+
NotImplementedError: If the engine does not support grants.
3131+
"""
3132+
if not self.SUPPORTS_GRANTS:
3133+
raise NotImplementedError(f"Engine does not support grants: {type(self)}")
3134+
raise NotImplementedError("Subclass must implement get_current_grants")
3135+
3136+
def _apply_grants_config_expr(
3137+
self,
3138+
table: exp.Table,
3139+
grant_config: GrantsConfig,
3140+
table_type: DataObjectType = DataObjectType.TABLE,
3141+
) -> t.List[exp.Expression]:
3142+
"""Returns SQLGlot Grant expressions to apply grants to a table.
3143+
3144+
Args:
3145+
table: The table/view to grant permissions on.
3146+
grant_config: Dictionary mapping permissions to lists of grantees.
3147+
table_type: The type of database object (TABLE, VIEW, MATERIALIZED_VIEW).
3148+
3149+
Returns:
3150+
List of SQLGlot expressions for grant operations.
3151+
3152+
Raises:
3153+
NotImplementedError: If the engine does not support grants.
3154+
"""
3155+
if not self.SUPPORTS_GRANTS:
3156+
raise NotImplementedError(f"Engine does not support grants: {type(self)}")
3157+
raise NotImplementedError("Subclass must implement _apply_grants_config_expr")
3158+
3159+
def _revoke_grants_config_expr(
3160+
self,
3161+
table: exp.Table,
3162+
grant_config: GrantsConfig,
3163+
table_type: DataObjectType = DataObjectType.TABLE,
3164+
) -> t.List[exp.Expression]:
3165+
"""Returns SQLGlot expressions to revoke grants from a table.
3166+
3167+
Note: SQLGlot doesn't yet have a Revoke expression type, so implementations
3168+
may return other expression types or handle revokes as strings.
3169+
3170+
Args:
3171+
table: The table/view to revoke permissions from.
3172+
grant_config: Dictionary mapping permissions to lists of grantees.
3173+
table_type: The type of database object (TABLE, VIEW, MATERIALIZED_VIEW).
3174+
3175+
Returns:
3176+
List of SQLGlot expressions for revoke operations.
3177+
3178+
Raises:
3179+
NotImplementedError: If the engine does not support grants.
3180+
"""
3181+
if not self.SUPPORTS_GRANTS:
3182+
raise NotImplementedError(f"Engine does not support grants: {type(self)}")
3183+
raise NotImplementedError("Subclass must implement _revoke_grants_config_expr")
3184+
31853185

31863186
class EngineAdapterWithIndexSupport(EngineAdapter):
31873187
SUPPORTS_INDEXES = True

0 commit comments

Comments
 (0)