Ë
    £2Úiì&  ã                   ó¨   — d dl mZ d dlmZmZ d dlmZmZmZ d dl	m
Z
 d dlmZmZ dZ G d„ de«      Z G d	„ d
«      Z G d„ dej"                  «      Zy)é    )Úsettings)Ú
connectionÚmodels)ÚOuterRefÚQuerySetÚSubquery)Útimezone)Úget_app_model_primary_key_nameÚget_change_reason_from_objectÚ_historyc                   óR   ‡ — e Zd ZdZˆ fd„Zd„ Zˆ fd„Zd„ Zˆ fd„Zˆ fd„Z	d„ Z
ˆ xZS )	ÚHistoricalQuerySetaS  
    Enables additional functionality when working with historical records.

    For additional history on this topic, see:
        - https://github.com/jazzband/django-simple-history/pull/229
        - https://github.com/jazzband/django-simple-history/issues/354
        - https://github.com/jazzband/django-simple-history/issues/397
    c                 ó²   •— t        ‰| �  |i |¤Ž d| _        d | _        | j                  j
                  j                  j                  j                  | _	        y )NF)
ÚsuperÚ__init__Ú_as_instancesÚ_as_ofÚmodelÚinstance_typeÚ_metaÚpkÚattnameÚ_pk_attr©ÚselfÚargsÚkwargsÚ	__class__s      €úM/var/www/html/acx/venv/lib/python3.12/site-packages/simple_history/manager.pyr   zHistoricalQuerySet.__init__   sG   ø€ Ü‰Ñ˜$Ð) &Ò)Ø"ˆÔØˆŒØŸ
™
×0Ñ0×6Ñ6×9Ñ9×AÑAˆ�ó    c                 ót   — | j                   s| j                  d¬«      }d|_         |S | j                  «       }|S )zô
        Return a queryset that generates instances instead of historical records.
        Queries against the resulting queryset will translate `pk` into the
        primary key field of the original type.

        Returns a queryset.
        ú-)Úhistory_typeT)r   ÚexcludeÚ_clone)r   Úresults     r   Úas_instanceszHistoricalQuerySet.as_instances    s>   € ð ×!Ò!Ø—\‘\¨s�\Ó3ˆFØ#'ˆFÔ ð ˆð —[‘[“]ˆFØˆr    c                 ó~   •— | j                   r"d|v r|j                  d«      || j                  <   t        ‰| �  |i |¤ŽS )a  
        If a `pk` filter arrives and the queryset is returning instances
        then the caller actually wants to filter based on the original
        type's primary key, and not the history_id (historical record's
        primary key); this happens frequently with DRF.
        r   )r   Úpopr   r   Úfilterr   s      €r   r*   zHistoricalQuerySet.filter/   s?   ø€ ð ×Ò $¨&¡.Ø$*§J¡J¨tÓ$4ˆF�4—=‘=Ñ!Ü‰w‰~˜tÐ. vÑ.Ð.r    c                 óº  — t         j                  }|dk(  rwi }| j                  dd«      D ]>  }t        || j                  «      |vsŒ|j
                  |t        || j                  «      <   Œ@ | j                  |j                  «       ¬«      }|S |dk(  r[| j                  | j                  dd«      j                  | j                  «      j                  dd¬«      }| j                  |¬«      }|S  | j                  di | j                  t        | j                  «      i¤Žj                  dd«      j                  d«      d	d
 }| j                  t        |«      ¬«      }|S )z©
        Ensures results in the queryset are the latest historical record for each
        primary key.  Deletions are not removed.

        Returns a queryset.
        Úmysqlz-history_datez-pk)Úhistory_id__inÚ
postgresqlr   T)ÚflatNé   © )r   ÚvendorÚorder_byÚgetattrr   r   r*   ÚvaluesÚdistinctÚvalues_listr   r   )r   ÚbackendÚhistory_idsÚitemÚlatest_historicsÚlatest_pk_attr_historic_idss         r   Úlatest_of_eachz!HistoricalQuerySet.latest_of_each:   sR  € ô ×#Ñ#ˆØ�gÒØˆKØŸ™ o°uÓ=ò H�Ü˜4 §¡Ó/°{ÒBØ@DÇÁ�K¤¨¨d¯m©mÓ <Ò=ðHð  $Ÿ{™{¸+×:LÑ:LÓ:N˜{ÓOÐð"  Ðð! ˜Ò$à—‘˜dŸm™m¨_¸eÓDß‘˜$Ÿ-™-Ó(ß‘˜T¨�Ó-ð (ð
  $Ÿ{™{Ð:U˜{ÓVÐð  Ðð �—‘ÑG˜tŸ}™}¬h°t·}±}Ó.EÐFÑGß‘˜/¨5Ó1ß‘˜“˜b˜qð"ð (ð
  $Ÿ{™{Ü'Ð(CÓDð  +ó  Ðð  Ðr    c                 óŠ   •— t         ‰| �  «       }| j                  |_        | j                  |_        | j                  |_        |S ©N)r   r%   r   r   r   )r   Úcr   s     €r   r%   zHistoricalQuerySet._clone^   s7   ø€ Ü‰G‰NÓˆØ×,Ñ,ˆŒØ—;‘;ˆŒØ—]‘]ˆŒ
Øˆr    c                 óB   •— t         ‰| �  «        | j                  «        y r?   )r   Ú
_fetch_allÚ_instanceize©r   r   s    €r   rB   zHistoricalQuerySet._fetch_alle   s   ø€ Ü‰ÑÔØ×ÑÕr    c                 óL  — | j                   r“| j                  r†t        | j                   d   | j                  «      rb| j                   D �cg c]  }|j                  ‘Œ c}| _         | j                   D ])  }t        |t        «      }t        |d| j                  «       Œ+ yyyyc c}w )zä
        Convert the result cache to instances if possible and it has not already been
        done.  If a query extracts `.values(...)` then the result cache will not contain
        historical objects to be converted.
        r   r   N)	Ú_result_cacher   Ú
isinstancer   Úinstancer4   Ú SIMPLE_HISTORY_REVERSE_ATTR_NAMEÚsetattrr   )r   r:   Úhistorics      r   rC   zHistoricalQuerySet._instanceizei   s“   € ð ×ÒØ×"Ò"Ü˜4×-Ñ-¨aÑ0°$·*±*Ô=à<@×<NÑ<NÖ!O°D $§-£-Ò!OˆDÔØ×*Ñ*ò 9�Ü" 4Ô)IÓJ�Ü˜ (¨D¯K©KÕ8ñ9ð >ð #ð ùò "Ps   Á
B!)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r'   r*   r=   r%   rB   rC   Ú__classcell__©r   s   @r   r   r      s-   ø„ ñôBòô	/ò" ôHôö9r    r   c                   ó   — e Zd Zd„ Zd„ Zy)ÚHistoryDescriptorc                 ó   — || _         y r?   )r   )r   r   s     r   r   zHistoryDescriptor.__init__{   s	   € Øˆ�
r    c                 óT   — t        j                  t        «      | j                  |«      S r?   )ÚHistoryManagerÚfrom_querysetr   r   )r   rH   Úowners      r   Ú__get__zHistoryDescriptor.__get__~   s   € Ü×+Ñ+Ô,>Ó?ÀÇ
Á
ÈHÓUÐUr    N)rL   rM   rN   r   rY   r1   r    r   rS   rS   z   s   „ òóVr    rS   c                   óN   ‡ — e Zd Zdˆ fd„	Zˆ fd„Zd„ Zd„ Zd„ Z	 	 	 	 	 dd„Zˆ xZ	S )	rV   c                 ó>   •— t         ‰| �  «        || _        || _        y r?   )r   r   r   rH   )r   r   rH   r   s      €r   r   zHistoryManager.__init__ƒ   s   ø€ Ü‰ÑÔØˆŒ
Ø ˆ�r    c                 ó    •— t         ‰| �  «       S r?   )r   Úget_querysetrD   s    €r   Úget_super_querysetz!HistoryManager.get_super_querysetˆ   s   ø€ Ü‰wÑ#Ó%Ð%r    c                 óÔ   — | j                  «       }| j                  €|S t        | j                  «      } | j                  «       j                  di || j                  j                  i¤ŽS )Nr1   )r^   rH   r
   r*   r   )r   ÚqsÚkey_names      r   r]   zHistoryManager.get_queryset‹   s[   € Ø×$Ñ$Ó&ˆØ�=‰=Ð ØˆIä1°$·-±-Ó@ˆØ/ˆt×&Ñ&Ó(×/Ñ/ÑO°8¸T¿]¹]×=MÑ=MÐ2NÑOÐOr    c                 óŽ  — | j                   s8t        dj                  | j                  j                  j
                  «      «      ‚g }| j                  j                  D ]V  }t        |t        j                  «      r|j                  |j                  dz   «       Œ<|j                  |j                  «       ŒX t        |«      }	  | j                  «       j                  |Ž d   } | j                   j"                  di |¤ŽS # t        $ r= | j                   j!                  d| j                   j                  j
                  z  «      ‚w xY w)zX
        Returns the most recent copy of the instance available in the history.
        z.Can't use most_recent() without a {} instance.Ú_idr   z%s has no historical record.r1   )rH   Ú	TypeErrorÚformatr   r   Úobject_nameÚtracked_fieldsrG   r   Ú
ForeignKeyÚappendÚnameÚtupler]   r5   Ú
IndexErrorÚDoesNotExistr   )r   ÚtmpÚfieldÚfieldsr5   s        r   Úmost_recentzHistoryManager.most_recent“   s  € ð �}Š}ÜØ@×GÑGØ—J‘J×$Ñ$×0Ñ0óóð ð
 ˆà—Z‘Z×.Ñ.ò 	'ˆEÜ˜%¤×!2Ñ!2Ô3Ø—
‘
˜5Ÿ:™:¨Ñ-Õ.à—
‘
˜5Ÿ:™:Õ&ð		'ô
 �s“ˆð	Ø/�T×&Ñ&Ó(×/Ñ/°Ð8¸Ñ;ˆFð
 'ˆt�}‰}×&Ñ&Ñ0¨Ñ0Ð0øô	 ò 	Ø—-‘-×,Ñ,Ø.°·±×1DÑ1D×1PÑ1PÑPóð ð	ús   Ã C> Ã>AEc                 óR  — | j                  «       j                  |¬«      }| j                  s7t        |t        «      r||_        |j                  «       j                  «       }|S 	 |d   }|j                  dk(  r<| j                  j                  d| j                  j                  j                  z  «      ‚|j                  }t        |t        «      }t        |d|«       |S # t        $ r= | j                  j                  d| j                  j                  j                  z  «      ‚w xY w)a¥  
        Get a snapshot as of a specific date.

        When this is used on an instance, it will return the instance based
        on the specific date.  If the instance did not exist yet, or had been
        deleted, then a DoesNotExist error is railed.

        When this is used on a model's history manager, the resulting queryset
        will locate the most recent historical record before the specified date
        for each primary key, generating instances.  If the most recent historical
        record is a deletion, that instance is dropped from the result.

        A common usage pattern for querying is to accept an optional time
        point `date` and then use:

            `qs = <Model>.history.as_of(date) if date else <Model>.objects`

        after which point one can add filters, values - anything a normal
        queryset would support.

        To retrieve historical records, query the model's history directly;
        for example:
            `qs = <Model>.history.filter(history_date__lte=date, pk=...)`

        To retrieve the most recent historical record, including deletions,
        you could then use:
            `qs = qs.latest_of_each()`
        )Úhistory_date__lter   z%s had not yet been created.r"   z%s had already been deleted.r   )r]   r*   rH   rG   r   r   r=   r'   rl   rm   r   rf   r#   r4   rI   rJ   )r   ÚdateÚquerysetÚhistory_objr&   rK   s         r   Úas_ofzHistoryManager.as_of­   s  € ð: ×$Ñ$Ó&×-Ñ-ÀÐ-ÓEˆØ�}Š}Ü˜(Ô$6Ô7Ø"&�”Ø×.Ñ.Ó0×=Ñ=Ó?ˆHØˆOð	à" 1™+ˆKð
 ×#Ñ# sÒ*Ø—-‘-×,Ñ,Ø.°·±×1DÑ1D×1PÑ1PÑPóð ð ×%Ñ%ˆÜ˜6Ô#CÓDˆÜ�˜( DÔ)Øˆøô ò 	Ø—-‘-×,Ñ,Ø.°·±×1DÑ1D×1PÑ1PÑPóð ð	ús   Á%C  Ã AD&c                 ól  — t        t        dd«      syd}|rd}g }|D ]ê  }	t        |	d|xs | j                  j                  |	«      «      }
 | j                  dt        |	d|xs t	        j
                  «       «      |
t        |	«      xs ||dœ| j                  j                  D �ci c]#  }|j                  t        |	|j                  «      “Œ% c}¤Ž}t        | j                  d	«      r|	j                  |_        |j                  |«       Œì | j                  j                  j                  ||¬
«      S c c}w )zÁ
        Bulk create the history for the objects specified by objs.
        If called by bulk_update_with_history, use the update boolean and
        save the history_type accordingly.
        ÚSIMPLE_HISTORY_ENABLEDTNú+ú~Ú_history_userÚ_history_date)Úhistory_dateÚhistory_userÚhistory_change_reasonr#   Úhistory_relation)Ú
batch_sizer1   )r4   r   r   Úget_default_history_userr	   Únowr   rg   r   Úhasattrr   Úhistory_relation_idri   ÚobjectsÚbulk_create)r   Úobjsr‚   ÚupdateÚdefault_userÚdefault_change_reasonÚdefault_dater#   Úhistorical_instancesrH   r   ro   Úrows                r   Úbulk_history_createz"HistoryManager.bulk_history_createá   s:  € ô ”xÐ!9¸4Ô@ØàˆÙØˆLà!ÐØò 	-ˆHÜ"ØØØÒM §
¡
× CÑ CÀHÓ MóˆLð
 �$—*‘*ð Ü$Ø˜o¨|Ò/M¼x¿|¹|»~óð *Ü&CÀHÓ&Mò ')Ø(Ø)ñð "&§¡×!:Ñ!:öàð —M‘M¤7¨8°U·]±]Ó#CÑCòñˆCô �t—z‘zÐ#5Ô6Ø*2¯+©+�Ô'Ø ×'Ñ'¨Õ,ð+	-ð. �z‰z×!Ñ!×-Ñ-Ø ¨Zð .ó 
ð 	
ùòs   Â#(D1r?   )NFNÚ N)
rL   rM   rN   r   r^   r]   rq   rw   r�   rP   rQ   s   @r   rV   rV   ‚   s4   ø„ õ!ô
&òPò1ò42ðn ØØØ Ø÷/
r    rV   N)Údjango.confr   Ú	django.dbr   r   Údjango.db.modelsr   r   r   Údjango.utilsr	   Úsimple_history.utilsr
   r   rI   r   rS   ÚManagerrV   r1   r    r   ú<module>r˜      sN   ðÝ  ß (ß 9Ñ 9Ý !÷ð $.Ð  ôg9˜ô g9÷TVñ VôN
�V—^‘^õ N
r    