o
    _J@h                  
   @   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)
    NZ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)Zprimary_keynext_run_time   )index	job_stateF)Znullable)Zschema)super__init__pickle_protocolr   r   enginer   
ValueErrorr   r	   r   r
   r   jobs_t)selfurlr   Z	tablenamemetadatar   ZtableschemaZengine_options	__class__ S/var/www/html/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!   Z	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 r+   )r   	_get_jobsr    r,   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    r,   r   r-   r   order_bylimitr   r.   r/   r0   r   )r!   r3   r4   r   r&   r&   r'   get_next_run_timea   s   $z$SQLAlchemyJobStore.get_next_run_timec                 C   s   |   }| | |S r+   )r6   Z_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   r.   r/   r   r   )r!   jobr@   r4   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    updaterA   r   r   rB   rC   rD   r   r-   r,   r   r   r.   r/   rowcountr   )r!   rE   rG   r4   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    deleter-   r,   r   r   r.   r/   rH   r   )r!   r2   rK   r4   rI   r&   r&   r'   
remove_job   s   

"zSQLAlchemyJobStore.remove_jobc                 C   sD   | j  }| j }|| W d    d S 1 sw   Y  d S r+   )r    rK   r   r.   r/   )r!   rK   r4   r&   r&   r'   remove_all_jobs   s   
"z"SQLAlchemyJobStore.remove_all_jobsc                 C   s   | j   d S r+   )r   Zdisposer!   r&   r&   r'   shutdown   s   zSQLAlchemyJobStore.shutdownc                 C   s:   t |}| |d< tt}|| | j|_| j|_|S )NZjobstore)rB   loadsr   __new____setstate__Z
_scheduler_aliasZ_jobstore_alias)r!   r   rE   r&   r&   r'   r1      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    r,   r   r   r;   r   r-   r   setr   r.   r/   appendr1   BaseExceptionZ_logger	exceptionaddrK   in_)r!   
conditionsr>   r3   Zfailed_job_idsr4   rowrK   r&   r&   r'   r6      s8   


zSQLAlchemyJobStore._get_jobsc                 C   s   d| j j d| jj dS )N<z (url=z)>)r%   __name__r   r"   rN   r&   r&   r'   __repr__   s   zSQLAlchemyJobStore.__repr__)r]   
__module____qualname____doc__rB   HIGHEST_PROTOCOLr   r(   r5   r9   r=   r?   rF   rJ   rL   rM   rO   r1   r6   r^   __classcell__r&   r&   r$   r'   r      s.     	r   )rB   Zapscheduler.jobr   Zapscheduler.jobstores.baser   r   r   Zapscheduler.utilr   r   r   Z
sqlalchemyr	   r
   r   r   r   r   r   r   r   Zsqlalchemy.excr   Zsqlalchemy.sql.expressionr   ImportErrorexcr   r&   r&   r&   r'   <module>   s    ,
