#NEWLINE# def MultiDelete( self , urns , token = None ) : #NEWLINE# #INDENT# 'Drop all the information about given objects.\n\n    DANGEROUS! This recursively deletes all objects contained within the\n    specified URN.\n\n    Args:\n      urns: Urns of objects to remove.\n      token: The Security Token to use for opening this item.\n    Raises:\n      RuntimeError: If one of the urns is too short. This is a safety check to\n      ensure the root is not removed.\n    ' #NEWLINE# urns = [ rdfvalue . RDFURN ( urn ) for urn in urns ] #NEWLINE# if ( token is None ) : #NEWLINE# #INDENT# token = data_store . default_token #NEWLINE# #UNINDENT# for urn in urns : #NEWLINE# #INDENT# if ( urn . Path ( ) == '/' ) : #NEWLINE# #INDENT# raise RuntimeError ( "Can't delete root URN. Please enter a valid URN" ) #NEWLINE# #UNINDENT# #UNINDENT# deletion_pool = DeletionPool ( token = root ) #NEWLINE# for urn in urns : #NEWLINE# #INDENT# deletion_pool . MarkForDeletion ( urn ) #NEWLINE# #UNINDENT# marked_root_urns = deletion_pool . root_urns_for_deletion #NEWLINE# marked_urns = deletion_pool . urns_for_deletion #NEWLINE# logging . debug ( 'Found %d objects to remove when removing %s' , len ( marked_urns ) , urns ) #NEWLINE# logging . debug ( 'Removing %d root objects when removing %s: %s' , len ( marked_root_urns ) , urns , marked_root_urns ) #NEWLINE# for root in marked_root_urns : #NEWLINE# #INDENT# self . _DeleteChildFromIndex ( root , token ) #NEWLINE# #UNINDENT# for urn_to_delete in marked_urns : #NEWLINE# #INDENT# try : #NEWLINE# #INDENT# self . intermediate_cache . ExpireObject ( urn_to_delete . Path ( ) ) #NEWLINE# #UNINDENT# except KeyError : #NEWLINE# #INDENT# pass #NEWLINE# #UNINDENT# data_store . DB . DeleteSubject ( urn_to_delete , token = token , sync = False ) #NEWLINE# logging . debug ( '%s deleted from data store' , urn_to_delete ) #NEWLINE# #UNINDENT# self . Flush ( ) #NEWLINE# logging . debug ( 'Removed %d objects' , len ( marked_urns ) )