o
    wvXj
  ã                   @   sþ   d Z ddlmZmZ ddlZddlmZ ddlmZ ddl	m
Z
 ddlmZ ddlmZ dd	lmZ dd
lmZ ddlmZmZmZ ddlmZ zddlmZmZ ddlmZ W n eyc   edƒ‚w e e ¡Z!dZ"edd„ ƒZ#dd„ Z$G dd„ deƒZ%dS )z SQLAlchemy result store backend.é    )Úabsolute_importÚunicode_literalsN)Úcontextmanager©Úwraps)Ústates)ÚBaseBackend)ÚImproperlyConfigured)Úrange)Úmaybe_timedeltaé   )ÚTaskÚTaskExtendedÚTaskSet)ÚSessionManager)ÚDatabaseErrorÚInvalidRequestError)ÚStaleDataErrorzhThe database result backend requires SQLAlchemy to be installed.See https://pypi.org/project/SQLAlchemy/)ÚDatabaseBackendc                 c   s@   � zzd V  W n t y   |  ¡  ‚ w W |  ¡  d S |  ¡  w )N)Ú	ExceptionÚrollbackÚclose)Úsession© r   ú^/var/www/html/myproject/venv/lib/python3.10/site-packages/celery/backends/database/__init__.pyÚsession_cleanup    s   €
þÿr   c                    s   t ˆ ƒ‡ fdd„ƒ}|S )Nc                     st   |  dd¡}t|ƒD ]-}z
ˆ | i |¤ŽW   S  tttfy7   tjdˆ j|| d dd� |d |kr5‚ Y q
w d S )NÚmax_retriesé   z-Failed operation %s.  Retrying %s more times.r   T)Úexc_info)Úpopr
   r   r   r   ÚloggerÚwarningÚ__name__)ÚargsÚkwargsr   Úretries©Úfunr   r   Ú_inner-   s   ýÿûýzretry.<locals>._innerr   )r'   r(   r   r&   r   Úretry+   s   r)   c                       sº   e Zd ZdZdZeZeZd‡ fdd„	Z	e
dd„ ƒZeƒ fdd	„Ze		dd
d„ƒZ		ddd„Zedd„ ƒZedd„ ƒZedd„ ƒZedd„ ƒZedd„ ƒZdd„ Zd‡ fdd„	Z‡  ZS ) r   zThe database result backend.g      à?Nc                    sÊ   t t| ƒjdt|dœ|¤Ž | jj}| jrt| _|p|p|j	| _
t|p$i fi |jp*i ¤Ž| _| d|j¡| _|jp:i }|jp?i }| jj| d¡| d¡d� | jj| d¡| d¡d� | j
sctdƒ‚d S )N)Úexpires_typeÚurlÚshort_lived_sessionsÚtask)ÚschemaÚnameÚgroupzTMissing connection string! Do you have the database_url setting set to a real value?r   )Úsuperr   Ú__init__r   ÚappÚconfÚextended_resultr   Útask_clsÚdatabase_urlr+   ÚdictÚdatabase_engine_optionsÚengine_optionsÚgetÚdatabase_short_lived_sessionsr,   Údatabase_table_schemasÚdatabase_table_namesÚ	configureÚtaskset_clsr	   )ÚselfÚdburir:   r+   r$   r4   ÚschemasÚ
tablenames©Ú	__class__r   r   r2   I   sB   ÿÿÿþþ

þþÿÿzDatabaseBackend.__init__c                 C   s   | j j dd¡S )NÚextendedÚresult)r3   r4   Úfind_value_for_key)rA   r   r   r   r5   i   s   zDatabaseBackend.extended_resultc                 C   s   |j d| j| jdœ| j¤ŽS )N)rB   r,   r   )Úsession_factoryr+   r,   r:   )rA   Úsession_managerr   r   r   ÚResultSessionm   s   þýzDatabaseBackend.ResultSessionc           	      K   s¢   |   ¡ }t|ƒ�? t| | j¡ | jj|k¡ƒ}|o|d }|s1|  |¡}||_| |¡ | ¡  | j	|||||d� | 
¡  W d  ƒ dS 1 sJw   Y  dS )z1Store return value and state of an executed task.r   )Ú	tracebackÚrequestN)rL   r   ÚlistÚqueryr6   ÚfilterÚtask_idÚaddÚflushÚ_update_resultÚcommit)	rA   rR   rH   ÚstaterM   rN   r$   r   r-   r   r   r   Ú_store_results   s   



"özDatabaseBackend._store_resultc           
      C   sN   | j ||||ddd�}dd„ | jjjD ƒ}|D ]}| |¡}	t|||	ƒ qd S )NFT)rH   rW   rM   rN   Úformat_dateÚencodec                 S   s   g | ]
}|j d vr|j ‘qS )>   ÚidrR   )r/   )Ú.0Úcolumnr   r   r   Ú
<listcomp>�   s    
ÿz2DatabaseBackend._update_result.<locals>.<listcomp>)Ú_get_result_metar6   Ú	__table__Úcolumnsr;   Úsetattr)
rA   r-   rH   rW   rM   rN   Úmetara   r]   Úvaluer   r   r   rU   „   s   þ
þzDatabaseBackend._update_resultc                 C   sÐ   |   ¡ }t|ƒ�V t| | j¡ | jj|k¡ƒ}|o|d }|s,|  |¡}tj|_	d|_
| ¡ }| dd¡durA|  |d ¡|d< | dd¡durR|  |d ¡|d< |  |¡W  d  ƒ S 1 saw   Y  dS )z$Get task meta-data for a task by id.r   Nr#   r$   )rL   r   rO   rP   r6   rQ   rR   r   ÚPENDINGÚstatusrH   Úto_dictr;   ÚdecodeÚmeta_from_decoded)rA   rR   r   r-   Údatar   r   r   Ú_get_task_meta_for—   s   

$ôz"DatabaseBackend._get_task_meta_forc                 C   s^   |   ¡ }t|ƒ� |  ||¡}| |¡ | ¡  | ¡  |W  d  ƒ S 1 s(w   Y  dS )z&Store the result of an executed group.N)rL   r   r@   rS   rT   rV   )rA   Úgroup_idrH   r   r0   r   r   r   Ú_save_group©   s   

$ûzDatabaseBackend._save_groupc                 C   sn   |   ¡ }t|ƒ�% | | j¡ | jj|k¡ ¡ }|r%| ¡ W  d  ƒ S W d  ƒ dS 1 s0w   Y  dS )zGet meta-data for group by id.N)rL   r   rP   r@   rQ   Ú
taskset_idÚfirstrg   )rA   rl   r   r0   r   r   r   Ú_restore_group´   s   

ÿÿü"ýzDatabaseBackend._restore_groupc                 C   sd   |   ¡ }t|ƒ�  | | j¡ | jj|k¡ ¡  | ¡  | ¡  W d  ƒ dS 1 s+w   Y  dS )z!Delete meta-data for group by id.N)	rL   r   rP   r@   rQ   rn   ÚdeleterT   rV   )rA   rl   r   r   r   r   Ú_delete_group¾   s   

ÿ
"üzDatabaseBackend._delete_groupc                 C   s\   |   ¡ }t|ƒ� | | j¡ | jj|k¡ ¡  | ¡  W d  ƒ dS 1 s'w   Y  dS )zForget about result.N)rL   r   rP   r6   rQ   rR   rq   rV   )rA   rR   r   r   r   r   Ú_forgetÈ   s
   

"þzDatabaseBackend._forgetc                 C   s’   |   ¡ }| j}| j ¡ }t|ƒ�/ | | j¡ | jj|| k ¡ 	¡  | | j
¡ | j
j|| k ¡ 	¡  | ¡  W d  ƒ dS 1 sBw   Y  dS )zDelete expired meta-data.N)rL   Úexpiresr3   Únowr   rP   r6   rQ   Ú	date_donerq   r@   rV   )rA   r   rt   ru   r   r   r   ÚcleanupÐ   s   

ÿÿ
"ûzDatabaseBackend.cleanupr   c                    s6   |si n|}|  | j| j| jdœ¡ tt| ƒ ||¡S )N)rB   rt   r:   )Úupdater+   rt   r:   r1   r   Ú
__reduce__)rA   r#   r$   rE   r   r   ry   Ü   s   þÿzDatabaseBackend.__reduce__)NNN)NN)r   N)r"   Ú
__module__Ú__qualname__Ú__doc__Úsubpolling_intervalr   r6   r   r@   r2   Úpropertyr5   r   rL   r)   rX   rU   rk   rm   rp   rr   rs   rw   ry   Ú__classcell__r   r   rE   r   r   ?   s8     
ÿ
ÿ



	
	
r   )&r|   Ú
__future__r   r   ÚloggingÚ
contextlibr   Ú
vine.utilsr   Úceleryr   Úcelery.backends.baser   Úcelery.exceptionsr	   Úcelery.fiver
   Úcelery.utils.timer   Úmodelsr   r   r   r   r   Úsqlalchemy.excr   r   Úsqlalchemy.orm.excr   ÚImportErrorÚ	getLoggerr"   r    Ú__all__r   r)   r   r   r   r   r   Ú<module>   s4   ÿÿ


