
    BChv                      |    d dl m Z  d dlmZmZmZmZ d dlmZ d dlm	Z	  G d de	      Z
 G d d      Zd	 Zd
 Zd Zy)    )datetime)ColumnBooleanDateTimeevent)declared_attr)Queryc                   n     e Zd ZdZ fdZ fdZ fdZd Zd Zd Z	d Z
 fd	Z fd
Zd fd	Z xZS )SoftDeleteQueryz@Query class that automatically filters out soft-deleted records.c                     t         t        |   |      }|y t        |d      r'|j                  rt        | d      r| j
                  r|S y |S )N
is_deleted_with_deleted)superr   gethasattrr   r   )selfidentobj	__class__s      &/var/www/html/app/utils/soft_delete.pyr   zSoftDeleteQuery.get
   sK    OT.u5;3%#..t_-$2D2D

    c                 \    t         t        |   |       }|j                  dd      |_        |S Nr   F)r   r   __new__popr   )clsargskwargsr   r   s       r   r   zSoftDeleteQuery.__new__   s,    OS1#6"JJ>
r   c                 Z    |j                  dd      | _        t        t        |   |i | y r   )r   r   r   r   __init__)r   r   r   r   s      r   r    zSoftDeleteQuery.__init__   s*    #ZZ?ot-t>v>r   c                 >   g }t        | d      s|S | j                  D ]}  }t        |d      r&|j                  |j                  j                         5t        |d      sBt        |j
                  d      sY|j                  |j
                  j                          |S )N	_entitiesentity_zeromapperclass_)r   r"   appendr#   r%   r$   )r   entitiesentitys      r   _get_entitieszSoftDeleteQuery._get_entities!   s     t[)Onn 	6Fv}- 2 2 9 9:*wv}}h/O 4 45		6
 r   c                    t        | d      r| j                  r| S | }t        | d      r| j                  r|S | j                         }|D ]-  }t        |d      s|j	                  |j
                  dk(        }/ d|_        |S )z-Add the is_deleted=False filter to the query.r   _filtered_deletedr   FT)r   r   r+   r)   filterr   )r   queryr'   r(   s       r   filter_deletedzSoftDeleteQuery.filter_deleted/   s     4)d.@.@K  4,-$2H2HL %%'  	AFv|,V%6%6%%?@	A
 #'r   c                     t        | d      r| j                  r| S | j                  | j                  d      | j                  d      }|S )*Include soft-deleted records in the query.r   with_deletedT)sessionr   )r   r   r   _only_full_mapper_zeror2   )r   r-   s     r   r1   zSoftDeleteQuery.with_deletedI   sL     4)d.@.@K t::>J$(LL  Fr   c                 V    t        | d      r| j                  r| S | j                         S )7Explicitly exclude soft-deleted records from the query.r+   )r   r+   r.   r   s    r   without_deletedzSoftDeleteQuery.without_deletedT   s-     4,-$2H2HK ""$$r   c                     t        | d      r| j                  rt        t        |          S | j                         }t        t        |j                    |      S )z*Apply soft delete filter before iterating.r   )r   r   r   r   __iter__r.   r   r   r-   r   s     r   r9   zSoftDeleteQuery.__iter__]   sM     4)d.@.@$8:: ##%_eoo?FFr   c                     t        | d      r| j                  rt        t        |          S | j                         }t        t        |j                    |      S )z)Apply soft delete filter before counting.r   )r   r   r   r   countr.   r   r:   s     r   r<   zSoftDeleteQuery.counth   sM     4)d.@.@$577 ##%_eoo<UCCr   c                    ddl m} t        | d      r=| j                  r1t        t	        t
        |       d      rt        t
        |   ||||      S | j                         }|d}|d}|t        ||      }|j                  |      j                  |dz
  |z        j                         }|j                  d      j                         } ||||||      S )	a  Apply soft delete filter before paginating.
        
        This method replicates Flask-SQLAlchemy's paginate functionality for our custom query class.
        
        Args:
            page: Page number (1-indexed)
            per_page: Number of items per page
            error_out: Abort with 404 if page/per_page are invalid
            max_per_page: Maximum items per page
            
        Returns:
            A Pagination object with the results
        r   )
Paginationr   paginate)pageper_page	error_outmax_per_pageN      )flask_sqlalchemyr>   r   r   r   r   r?   r.   minlimitoffsetallorder_byr<   )
r   r@   rA   rB   rC   r>   r-   itemstotalr   s
            r   r?   zSoftDeleteQuery.paginater   s     	0 4)d.@.@u_d3Z@_d<IT` =  
 ##% <DH#8\2H H%,,dQh(-BCGGI t$**, %x>>r   )NNTN)__name__
__module____qualname____doc__r   r   r    r)   r.   r1   r7   r9   r<   r?   __classcell__)r   s   @r   r   r      s?    J
?4	%	GD+? +?r   r   c                   @    e Zd ZdZeZed        Zed        Zd Z	d Z
y)SoftDeleteMixinzAMixin class to add soft deletion capability to SQLAlchemy models.c                 (    t        t        ddd      S )NFT)defaultnullableindex)r   r   r   s    r   r   zSoftDeleteMixin.is_deleted   s    guuDIIr   c                 $    t        t        d      S )NT)rW   )r   r   rY   s    r   
deleted_atzSoftDeleteMixin.deleted_at   s    h..r   c                 D    d| _         t        j                         | _        y)zMark the record as deleted.TN)r   r   utcnowr[   r6   s    r   soft_deletezSoftDeleteMixin.soft_delete   s    "//+r   c                      d| _         d| _        y)zRestore a soft-deleted record.FN)r   r[   r6   s    r   restorezSoftDeleteMixin.restore   s    r   N)rN   rO   rP   rQ   r   query_classr   r   r[   r^   r`    r   r   rT   rT      s@    K "K J J / /,
r   rT   c                 P   t        | j                  d      sy| j                  j                  j                         D ]B  }t        |d      st        |d      st	        |j
                  t              s8t        |_        D t        j                  | j                  d      d        }y)z4Initialize soft delete functionality for all models._decl_class_registryN__tablename__r   after_flushc                     | j                   D ]4  }t        |t              s| j                  |       |j	                          6 y)z+Update timestamps for soft-deleted records.N)deleted
isinstancerT   addr^   )r2   flush_contextr   s      r   rf   z+initialize_soft_delete.<locals>.after_flush   s7     ?? 	"C#/C !		"r   )r   Modelrd   values
issubclassr   rT   r   ra   r   listens_forr2   )dbmodelrf   s      r   initialize_soft_deleterr      s     28834..557 05/*wuk/JzZ_ZiZikzO{ /E0
 rzz=1" 2"r   c                 >    t        | d      r| j                         S | S )r0   r1   )r   r1   r-   s    r   r1   r1      s     un%!!##Lr   c                 >    t        | d      r| j                         S | S )r5   r7   )r   r7   rt   s    r   r7   r7      s!    u'($$&&Lr   N)r   
sqlalchemyr   r   r   r   sqlalchemy.ext.declarativer   sqlalchemy.ormr	   r   rT   rr   r1   r7   rb   r   r   <module>ry      s<     7 7 4  V?e V?p 4"(r   