o
    óT·j�  ã                
   @   s¼   d dl Z d dlmZ d dlmZmZmZ d dlmZm	Z	m
Z
 z$d dlmZmZmZmZmZmZmZmZmZ d dlmZ d dlmZ W n eyS Z zedƒe‚dZ[ww G d	d
„ d
eƒZdS )é    N)ÚJob)ÚBaseJobStoreÚConflictingIdErrorÚJobLookupError)Údatetime_to_utc_timestampÚ	maybe_refÚutc_timestamp_to_datetime)	ÚColumnÚFloatÚLargeBinaryÚMetaDataÚTableÚUnicodeÚand_Úcreate_engineÚselect)ÚIntegrityError)Únullz0SQLAlchemyJobStore requires SQLAlchemy installedc                       sž   e Zd ZdZddddejddf‡ fdd„	Z‡ fdd„Zdd	„ Zd
d„ Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Z‡  ZS ) ÚSQLAlchemyJobStorea¸  
    Stores jobs in a database table using SQLAlchemy.
    The table will be created if it doesn't exist in the database.

    Plugin alias: ``sqlalchemy``

    :param str url: connection string (see
        :ref:`SQLAlchemy documentation <sqlalchemy:database_urls>` on this)
    :param engine: an SQLAlchemy :class:`~sqlalchemy.engine.Engine` to use instead of creating a
        new one based on ``url``
    :param str tablename: name of the table to store jobs in
    :param metadata: a :class:`~sqlalchemy.schema.MetaData` instance to use instead of creating a
        new one
    :param int pickle_protocol: pickle protocol level to use (for serialization), defaults to the
        highest available
    :param str tableschema: name of the (existing) schema in the target database where the table
        should be
    :param dict engine_options: keyword arguments to :func:`~sqlalchemy.create_engine`
        (ignored if ``engine`` is given)
    NÚapscheduler_jobsc              
      s’   t ƒ  ¡  || _t|ƒptƒ }|rt|ƒ| _n|r%t|fi |p i ¤Ž| _ntdƒ‚t||t	dt
dƒdd�t	dtdƒdd�t	d	td
d�|d�| _d S )Nz%Need either "engine" or "url" definedÚidé¿   T)Úprimary_keyÚnext_run_timeé   )ÚindexÚ	job_stateF)Únullable)Úschema)ÚsuperÚ__init__Úpickle_protocolr   r   Úenginer   Ú
ValueErrorr   r	   r   r
   r   Újobs_t)ÚselfÚurlr"   Ú	tablenameÚmetadatar!   ÚtableschemaÚengine_options©Ú	__class__© úc/home/dinkstrade/pdmp-scanner/venv/lib/python3.10/site-packages/apscheduler/jobstores/sqlalchemy.pyr    3   s    

úzSQLAlchemyJobStore.__init__c                    s"   t ƒ  ||¡ | j | jd¡ d S )NT)r   Ústartr$   Úcreater"   )r%   Ú	schedulerÚaliasr+   r-   r.   r/   S   s   zSQLAlchemyJobStore.startc                 C   sl   t | jjjƒ | jjj|k¡}| j ¡ �}| |¡ 	¡ }|r#|  
|¡nd W  d   ƒ S 1 s/w   Y  d S ©N)r   r$   Úcr   Úwherer   r"   ÚbeginÚexecuteÚscalarÚ_reconstitute_job)r%   Újob_idÚ
selectableÚ
connectionr   r-   r-   r.   Ú
lookup_jobW   s
   $þzSQLAlchemyJobStore.lookup_jobc                 C   s   t |ƒ}|  | jjj|k¡S r3   )r   Ú	_get_jobsr$   r4   r   )r%   ÚnowÚ	timestampr-   r-   r.   Úget_due_jobs]   s   zSQLAlchemyJobStore.get_due_jobsc                 C   sv   t | jjjƒ | jjjtƒ k¡ | jjj¡ d¡}| j 	¡ �}| 
|¡ ¡ }t|ƒW  d   ƒ S 1 s4w   Y  d S )Né   )r   r$   r4   r   r5   r   Úorder_byÚlimitr"   r6   r7   r8   r   )r%   r;   r<   r   r-   r-   r.   Úget_next_run_timea   s   ü$þz$SQLAlchemyJobStore.get_next_run_timec                 C   s   |   ¡ }|  |¡ |S r3   )r>   Ú_fix_paused_jobs_sorting)r%   Újobsr-   r-   r.   Úget_all_jobsl   s   
zSQLAlchemyJobStore.get_all_jobsc              	   C   sŒ   | j  ¡ jdi |jt|jƒt | ¡ | j	¡dœ¤Ž}| j
 ¡ �}z| |¡ W n ty3   t|jƒ‚w W d   ƒ d S 1 s?w   Y  d S )N)r   r   r   r-   )r$   ÚinsertÚvaluesr   r   r   ÚpickleÚdumpsÚ__getstate__r!   r"   r6   r7   r   r   )r%   ÚjobrI   r<   r-   r-   r.   Úadd_jobq   s   ýÿ
ÿÿ"þzSQLAlchemyJobStore.add_jobc                 C   s�   | j  ¡ jdi t|jƒt | ¡ | j¡dœ¤Ž 	| j j
j|jk¡}| j ¡ �}| |¡}|jdkr6t|jƒ‚W d   ƒ d S 1 sAw   Y  d S )N)r   r   r   r-   )r$   ÚupdaterJ   r   r   rK   rL   rM   r!   r5   r4   r   r"   r6   r7   Úrowcountr   )r%   rN   rP   r<   Úresultr-   r-   r.   Ú
update_job   s   ÿþþø



ÿ"þzSQLAlchemyJobStore.update_jobc                 C   sf   | j  ¡  | j jj|k¡}| j ¡ �}| |¡}|jdkr!t	|ƒ‚W d   ƒ d S 1 s,w   Y  d S )Nr   )
r$   Údeleter5   r4   r   r"   r6   r7   rQ   r   )r%   r:   rT   r<   rR   r-   r-   r.   Ú
remove_job�   s   

ÿ"þzSQLAlchemyJobStore.remove_jobc                 C   sD   | j  ¡ }| j ¡ �}| |¡ W d   ƒ d S 1 sw   Y  d S r3   )r$   rT   r"   r6   r7   )r%   rT   r<   r-   r-   r.   Úremove_all_jobs–   s   
"ÿz"SQLAlchemyJobStore.remove_all_jobsc                 C   s   | j  ¡  d S r3   )r"   Údispose©r%   r-   r-   r.   Úshutdown›   s   zSQLAlchemyJobStore.shutdownc                 C   s:   t  |¡}| |d< t t¡}| |¡ | j|_| j|_|S )NÚjobstore)rK   Úloadsr   Ú__new__Ú__setstate__Ú
_schedulerÚ_aliasÚ_jobstore_alias)r%   r   rN   r-   r-   r.   r9   ž   s   


z$SQLAlchemyJobStore._reconstitute_jobc              
   G   s   g }t | jjj| jjjƒ | jjj¡}|r| t|Ž ¡n|}t	ƒ }| j
 ¡ �P}| |¡D ]$}z| |  |j¡¡ W q, tyP   | j d|j¡ | |j¡ Y q,w |rn| j ¡  | jjj |¡¡}| |¡ W d   ƒ |S W d   ƒ |S 1 syw   Y  |S )Nz)Unable to restore job "%s" -- removing it)r   r$   r4   r   r   rC   r   r5   r   Úsetr"   r6   r7   Úappendr9   ÚBaseExceptionÚ_loggerÚ	exceptionÚaddrT   Úin_)r%   Ú
conditionsrG   r;   Úfailed_job_idsr<   ÚrowrT   r-   r-   r.   r>   §   s8   ÿÿü
ÿ
ñú
õïzSQLAlchemyJobStore._get_jobsc                 C   s   d| j j› d| jj› d�S )Nú<z (url=z)>)r,   Ú__name__r"   r&   rX   r-   r-   r.   Ú__repr__Á   s   zSQLAlchemyJobStore.__repr__)rl   Ú
__module__Ú__qualname__Ú__doc__rK   ÚHIGHEST_PROTOCOLr    r/   r=   rA   rE   rH   rO   rS   rU   rV   rY   r9   r>   rm   Ú__classcell__r-   r-   r+   r.   r      s.    ø 	r   )rK   Úapscheduler.jobr   Úapscheduler.jobstores.baser   r   r   Úapscheduler.utilr   r   r   Ú
sqlalchemyr	   r
   r   r   r   r   r   r   r   Úsqlalchemy.excr   Úsqlalchemy.sql.expressionr   ÚImportErrorÚexcr   r-   r-   r-   r.   Ú<module>   s    ,
€ÿ