Skip to content

Commit 9d5a830

Browse files
committed
refactor: move private grants method to the end of EngineAdapter
1 parent d2b8f44 commit 9d5a830

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
@@ -2405,29 +2405,6 @@ def wap_publish(self, table_name: TableName, wap_id: str) -> None:
24052405
"""
24062406
raise NotImplementedError(f"Engine does not support WAP: {type(self)}")
24072407

2408-
def _get_current_grants_config(self, table: exp.Table) -> GrantsConfig:
2409-
"""Returns current grants for a table as a dictionary.
2410-
2411-
This method queries the database and returns the current grants/permissions
2412-
for the given table, parsed into a dictionary format. The it handles
2413-
case-insensitive comparison between these current grants and the desired
2414-
grants from model configuration.
2415-
2416-
Args:
2417-
table: The table/view to query grants for.
2418-
2419-
Returns:
2420-
Dictionary mapping permissions to lists of grantees. Permission names
2421-
should be returned as the database provides them (typically uppercase
2422-
for standard SQL permissions, but engine-specific roles may vary).
2423-
2424-
Raises:
2425-
NotImplementedError: If the engine does not support grants.
2426-
"""
2427-
if not self.SUPPORTS_GRANTS:
2428-
raise NotImplementedError(f"Engine does not support grants: {type(self)}")
2429-
raise NotImplementedError("Subclass must implement get_current_grants")
2430-
24312408
def sync_grants_config(
24322409
self,
24332410
table: exp.Table,
@@ -2455,104 +2432,6 @@ def sync_grants_config(
24552432
if dcl_exprs:
24562433
self.execute(dcl_exprs)
24572434

2458-
def _apply_grants_config_expr(
2459-
self,
2460-
table: exp.Table,
2461-
grant_config: GrantsConfig,
2462-
table_type: DataObjectType = DataObjectType.TABLE,
2463-
) -> t.List[exp.Expression]:
2464-
"""Returns SQLGlot Grant expressions to apply grants to a table.
2465-
2466-
Args:
2467-
table: The table/view to grant permissions on.
2468-
grant_config: Dictionary mapping permissions to lists of grantees.
2469-
table_type: The type of database object (TABLE, VIEW, MATERIALIZED_VIEW).
2470-
2471-
Returns:
2472-
List of SQLGlot expressions for grant operations.
2473-
2474-
Raises:
2475-
NotImplementedError: If the engine does not support grants.
2476-
"""
2477-
if not self.SUPPORTS_GRANTS:
2478-
raise NotImplementedError(f"Engine does not support grants: {type(self)}")
2479-
raise NotImplementedError("Subclass must implement _apply_grants_config_expr")
2480-
2481-
def _revoke_grants_config_expr(
2482-
self,
2483-
table: exp.Table,
2484-
grant_config: GrantsConfig,
2485-
table_type: DataObjectType = DataObjectType.TABLE,
2486-
) -> t.List[exp.Expression]:
2487-
"""Returns SQLGlot expressions to revoke grants from a table.
2488-
2489-
Note: SQLGlot doesn't yet have a Revoke expression type, so implementations
2490-
may return other expression types or handle revokes as strings.
2491-
2492-
Args:
2493-
table: The table/view to revoke permissions from.
2494-
grant_config: Dictionary mapping permissions to lists of grantees.
2495-
table_type: The type of database object (TABLE, VIEW, MATERIALIZED_VIEW).
2496-
2497-
Returns:
2498-
List of SQLGlot expressions for revoke operations.
2499-
2500-
Raises:
2501-
NotImplementedError: If the engine does not support grants.
2502-
"""
2503-
if not self.SUPPORTS_GRANTS:
2504-
raise NotImplementedError(f"Engine does not support grants: {type(self)}")
2505-
raise NotImplementedError("Subclass must implement _revoke_grants_config_expr")
2506-
2507-
@classmethod
2508-
def _diff_grants_configs(
2509-
cls, new_config: GrantsConfig, old_config: GrantsConfig
2510-
) -> t.Tuple[GrantsConfig, GrantsConfig]:
2511-
"""Compute additions and removals between two grants configurations.
2512-
2513-
This method compares new (desired) and old (current) GrantsConfigs case-insensitively
2514-
for both privilege keys and grantees, while preserving original casing
2515-
in the output GrantsConfigs.
2516-
2517-
Args:
2518-
new_config: Desired grants configuration (specified by the user).
2519-
old_config: Current grants configuration (returned by the database).
2520-
2521-
Returns:
2522-
A tuple of (additions, removals) GrantsConfig where:
2523-
- additions contains privileges/grantees present in new_config but not in old_config
2524-
- additions uses keys and grantee strings from new_config (user-specified casing)
2525-
- removals contains privileges/grantees present in old_config but not in new_config
2526-
- removals uses keys and grantee strings from old_config (database-returned casing)
2527-
2528-
Notes:
2529-
- Comparison is case-insensitive using casefold(); original casing is preserved in results.
2530-
- Overlapping grantees (case-insensitive) are excluded from the results.
2531-
"""
2532-
2533-
def _diffs(config1: GrantsConfig, config2: GrantsConfig) -> GrantsConfig:
2534-
diffs: GrantsConfig = {}
2535-
cf_config2 = {k.casefold(): {g.casefold() for g in v} for k, v in config2.items()}
2536-
for key, grantees in config1.items():
2537-
cf_key = key.casefold()
2538-
2539-
# Missing key (add all grantees)
2540-
if cf_key not in cf_config2:
2541-
diffs[key] = grantees.copy()
2542-
continue
2543-
2544-
# Include only grantees not in config2
2545-
cf_grantees2 = cf_config2[cf_key]
2546-
diff_grantees = []
2547-
for grantee in grantees:
2548-
if grantee.casefold() not in cf_grantees2:
2549-
diff_grantees.append(grantee)
2550-
if diff_grantees:
2551-
diffs[key] = diff_grantees
2552-
return diffs
2553-
2554-
return _diffs(new_config, old_config), _diffs(old_config, new_config)
2555-
25562435
@contextlib.contextmanager
25572436
def transaction(
25582437
self,
@@ -3084,6 +2963,127 @@ def _check_identifier_length(self, expression: exp.Expression) -> None:
30842963
def get_table_last_modified_ts(self, table_names: t.List[TableName]) -> t.List[int]:
30852964
raise NotImplementedError()
30862965

2966+
@classmethod
2967+
def _diff_grants_configs(
2968+
cls, new_config: GrantsConfig, old_config: GrantsConfig
2969+
) -> t.Tuple[GrantsConfig, GrantsConfig]:
2970+
"""Compute additions and removals between two grants configurations.
2971+
2972+
This method compares new (desired) and old (current) GrantsConfigs case-insensitively
2973+
for both privilege keys and grantees, while preserving original casing
2974+
in the output GrantsConfigs.
2975+
2976+
Args:
2977+
new_config: Desired grants configuration (specified by the user).
2978+
old_config: Current grants configuration (returned by the database).
2979+
2980+
Returns:
2981+
A tuple of (additions, removals) GrantsConfig where:
2982+
- additions contains privileges/grantees present in new_config but not in old_config
2983+
- additions uses keys and grantee strings from new_config (user-specified casing)
2984+
- removals contains privileges/grantees present in old_config but not in new_config
2985+
- removals uses keys and grantee strings from old_config (database-returned casing)
2986+
2987+
Notes:
2988+
- Comparison is case-insensitive using casefold(); original casing is preserved in results.
2989+
- Overlapping grantees (case-insensitive) are excluded from the results.
2990+
"""
2991+
2992+
def _diffs(config1: GrantsConfig, config2: GrantsConfig) -> GrantsConfig:
2993+
diffs: GrantsConfig = {}
2994+
cf_config2 = {k.casefold(): {g.casefold() for g in v} for k, v in config2.items()}
2995+
for key, grantees in config1.items():
2996+
cf_key = key.casefold()
2997+
2998+
# Missing key (add all grantees)
2999+
if cf_key not in cf_config2:
3000+
diffs[key] = grantees.copy()
3001+
continue
3002+
3003+
# Include only grantees not in config2
3004+
cf_grantees2 = cf_config2[cf_key]
3005+
diff_grantees = []
3006+
for grantee in grantees:
3007+
if grantee.casefold() not in cf_grantees2:
3008+
diff_grantees.append(grantee)
3009+
if diff_grantees:
3010+
diffs[key] = diff_grantees
3011+
return diffs
3012+
3013+
return _diffs(new_config, old_config), _diffs(old_config, new_config)
3014+
3015+
def _get_current_grants_config(self, table: exp.Table) -> GrantsConfig:
3016+
"""Returns current grants for a table as a dictionary.
3017+
3018+
This method queries the database and returns the current grants/permissions
3019+
for the given table, parsed into a dictionary format. The it handles
3020+
case-insensitive comparison between these current grants and the desired
3021+
grants from model configuration.
3022+
3023+
Args:
3024+
table: The table/view to query grants for.
3025+
3026+
Returns:
3027+
Dictionary mapping permissions to lists of grantees. Permission names
3028+
should be returned as the database provides them (typically uppercase
3029+
for standard SQL permissions, but engine-specific roles may vary).
3030+
3031+
Raises:
3032+
NotImplementedError: If the engine does not support grants.
3033+
"""
3034+
if not self.SUPPORTS_GRANTS:
3035+
raise NotImplementedError(f"Engine does not support grants: {type(self)}")
3036+
raise NotImplementedError("Subclass must implement get_current_grants")
3037+
3038+
def _apply_grants_config_expr(
3039+
self,
3040+
table: exp.Table,
3041+
grant_config: GrantsConfig,
3042+
table_type: DataObjectType = DataObjectType.TABLE,
3043+
) -> t.List[exp.Expression]:
3044+
"""Returns SQLGlot Grant expressions to apply grants to a table.
3045+
3046+
Args:
3047+
table: The table/view to grant permissions on.
3048+
grant_config: Dictionary mapping permissions to lists of grantees.
3049+
table_type: The type of database object (TABLE, VIEW, MATERIALIZED_VIEW).
3050+
3051+
Returns:
3052+
List of SQLGlot expressions for grant operations.
3053+
3054+
Raises:
3055+
NotImplementedError: If the engine does not support grants.
3056+
"""
3057+
if not self.SUPPORTS_GRANTS:
3058+
raise NotImplementedError(f"Engine does not support grants: {type(self)}")
3059+
raise NotImplementedError("Subclass must implement _apply_grants_config_expr")
3060+
3061+
def _revoke_grants_config_expr(
3062+
self,
3063+
table: exp.Table,
3064+
grant_config: GrantsConfig,
3065+
table_type: DataObjectType = DataObjectType.TABLE,
3066+
) -> t.List[exp.Expression]:
3067+
"""Returns SQLGlot expressions to revoke grants from a table.
3068+
3069+
Note: SQLGlot doesn't yet have a Revoke expression type, so implementations
3070+
may return other expression types or handle revokes as strings.
3071+
3072+
Args:
3073+
table: The table/view to revoke permissions from.
3074+
grant_config: Dictionary mapping permissions to lists of grantees.
3075+
table_type: The type of database object (TABLE, VIEW, MATERIALIZED_VIEW).
3076+
3077+
Returns:
3078+
List of SQLGlot expressions for revoke operations.
3079+
3080+
Raises:
3081+
NotImplementedError: If the engine does not support grants.
3082+
"""
3083+
if not self.SUPPORTS_GRANTS:
3084+
raise NotImplementedError(f"Engine does not support grants: {type(self)}")
3085+
raise NotImplementedError("Subclass must implement _revoke_grants_config_expr")
3086+
30873087

30883088
class EngineAdapterWithIndexSupport(EngineAdapter):
30893089
SUPPORTS_INDEXES = True

0 commit comments

Comments
 (0)