55import logging
66
77from .sql_content import SqlContent
8+ from .exceptions import PumException
89
910if TYPE_CHECKING :
1011 from .feedback import Feedback
@@ -43,12 +44,14 @@ def grant(
4344 role : str ,
4445 connection : psycopg .Connection ,
4546 commit : bool = False ,
47+ feedback : Optional ["Feedback" ] = None ,
4648 ) -> None :
4749 """Grant the permission to the specified role.
4850 Args:
4951 role: The name of the role to grant the permission to.
5052 connection: The database connection to execute the SQL statements.
5153 commit: Whether to commit the transaction. Defaults to False.
54+ feedback: Optional feedback object for progress reporting.
5255 """
5356 if not isinstance (role , str ):
5457 raise TypeError ("Role must be a string." )
@@ -57,6 +60,9 @@ def grant(
5760 raise ValueError ("Schemas must be defined for the permission." )
5861
5962 for schema in self .schemas :
63+ if feedback and feedback .is_cancelled ():
64+ raise PumException ("Permission grant cancelled by user" )
65+
6066 # Detect if schema exists; if not, warn and continue
6167 cursor = SqlContent ("SELECT 1 FROM pg_namespace WHERE nspname = {schema}" ).execute (
6268 connection = connection ,
@@ -121,6 +127,8 @@ def grant(
121127 raise ValueError (f"Unknown permission type: { self .type } " )
122128
123129 if commit :
130+ if feedback :
131+ feedback .lock_cancellation ()
124132 connection .commit ()
125133
126134 def _grant_existing_types (
@@ -223,14 +231,24 @@ def exists(self, connection: psycopg.Connection) -> bool:
223231 return bool (cursor ._pum_results )
224232
225233 def create (
226- self , connection : psycopg .Connection , grant : bool = False , commit : bool = False
234+ self ,
235+ connection : psycopg .Connection ,
236+ grant : bool = False ,
237+ commit : bool = False ,
238+ feedback : Optional ["Feedback" ] = None ,
227239 ) -> None :
228240 """Create the role in the database.
229241 Args:
230242 connection: The database connection to execute the SQL statements.
231243 grant: Whether to grant permissions to the role. Defaults to False.
232244 commit: Whether to commit the transaction. Defaults to False.
245+ feedback: Optional feedback object for progress reporting.
233246 """
247+ if feedback and feedback .is_cancelled ():
248+ from .exceptions import PumException
249+
250+ raise PumException ("Role creation cancelled by user" )
251+
234252 if self .exists (connection ):
235253 logger .debug (f"Role { self .name } already exists, skipping creation." )
236254 else :
@@ -262,9 +280,13 @@ def create(
262280 )
263281 if grant :
264282 for permission in self .permissions ():
265- permission .grant (role = self .name , connection = connection , commit = commit )
283+ permission .grant (
284+ role = self .name , connection = connection , commit = False , feedback = feedback
285+ )
266286
267287 if commit :
288+ if feedback :
289+ feedback .lock_cancellation ()
268290 connection .commit ()
269291
270292
@@ -320,11 +342,17 @@ def create_roles(
320342 """
321343 roles_list = list (self .roles .values ())
322344 for role in roles_list :
345+ if feedback and feedback .is_cancelled ():
346+ from .exceptions import PumException
347+
348+ raise PumException ("Role creation cancelled by user" )
323349 if feedback :
324350 feedback .increment_step ()
325351 feedback .report_progress (f"Creating role: { role .name } " )
326- role .create (connection = connection , commit = False , grant = grant )
352+ role .create (connection = connection , commit = False , grant = grant , feedback = feedback )
327353 if commit :
354+ if feedback :
355+ feedback .lock_cancellation ()
328356 connection .commit ()
329357
330358 def grant_permissions (
@@ -341,11 +369,19 @@ def grant_permissions(
341369 """
342370 roles_list = list (self .roles .values ())
343371 for role in roles_list :
372+ if feedback and feedback .is_cancelled ():
373+ from .exceptions import PumException
374+
375+ raise PumException ("Permission grant cancelled by user" )
344376 if feedback :
345377 feedback .increment_step ()
346378 feedback .report_progress (f"Granting permissions to role: { role .name } " )
347379 for permission in role .permissions ():
348- permission .grant (role = role .name , connection = connection , commit = False )
380+ permission .grant (
381+ role = role .name , connection = connection , commit = False , feedback = feedback
382+ )
349383 logger .info ("All permissions granted to roles." )
350384 if commit :
385+ if feedback :
386+ feedback .lock_cancellation ()
351387 connection .commit ()
0 commit comments