a
    Db+                     @   s   d Z ddlZzddlZW n ey6   ddlmZ Y n0 ddlmZ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 G d
d de
ZdS )zA base class session manager.    N)dbapi2)genweb)LoggingConfigurable)unicode_type)Instance)maybe_future)InstanceFromClassesc                   @   s   e Zd ZedZeddgdZdZdZh dZ	e
dd Ze
d	d
 Zdd Zdd Zejdd Zdd Zejd&ddZejdd Zejd'ddZejdd Zejdd Zdd Zejd(d d!Zejd"d# Zejd$d% ZdS ))SessionManagerz<notebook.services.kernels.kernelmanager.MappingKernelManagerz2notebook.services.contents.manager.ContentsManagerz8jupyter_server.services.contents.manager.ContentsManager)ZklassesN>   
session_idpathtype	kernel_idnamec                 C   s(   | j du r"| j | _ | j d | j S )z5Start a cursor and create a database called 'session'NzNCREATE TABLE session
                (session_id, path, name, type, kernel_id))_cursor
connectioncursorexecuteself r   Hlib/python3.9/site-packages/notebook/services/sessions/sessionmanager.pyr   +   s    
zSessionManager.cursorc                 C   s&   | j du r td| _ tj| j _| j S )zStart a database connectionNz:memory:)_connectionsqlite3ZconnectZRowZrow_factoryr   r   r   r   r   4   s    

zSessionManager.connectionc                 C   s   | j dur| j   d| _ dS )zClose the sqlite connectionN)r   closer   r   r   r   r   <   s    

zSessionManager.closec                 C   s   |    dS )z+Close connection once SessionManager closesN)r   r   r   r   r   __del__B   s    zSessionManager.__del__c                 c   sT   d}| j d|f | j  }|durFt| j|ddV }|durFd}t|dS )z2Check to see if the session of a given name existsFz"SELECT * FROM session WHERE path=?NT)tolerate_culled)r   r   fetchoner   row_to_modelr   Return)r   r   existsrowmodelr   r   r   session_existsF   s    
zSessionManager.session_existsc                 C   s   t t S )zCreate a uuid for a new session)r   uuidZuuid4r   r   r   r   new_session_idW   s    zSessionManager.new_session_idc                 c   sX   |   }|dur|| jv rn| |||||V }t| j|||||dV }t|dS )z'Creates a session and returns its modelN)r   r   r   r   )r%   kernel_managerstart_kernel_for_sessionr   save_sessionr   r   )r   r   r   r   kernel_namer   r   resultr   r   r   create_session[   s    zSessionManager.create_sessionc                 c   s2   | j j|d}t| jj||dV }t|dS )z'Start a new kernel for a given session.)r   )r   r)   N)contents_managerZget_kernel_pathr   r&   Zstart_kernelr   r   )r   r   r   r   r   r)   Zkernel_pathr   r   r   r   r'   i   s
    z'SessionManager.start_kernel_for_sessionc                 c   s8   | j d|||||f t| j|dV }t|dS )a  Saves the items for the session with the given session_id

        Given a session_id (and any other of the arguments), this method
        creates a row in the sqlite session database that holds the information
        for a session.

        Parameters
        ----------
        session_id : str
            uuid for the session; this method must be given a session_id
        path : str
            the path for the given session
        name: str
            the name of the session
        type: string
            the type of the session
        kernel_id : str
            a uuid for the kernel associated with this session

        Returns
        -------
        model : dict
            a dictionary of the session model
        z&INSERT INTO session VALUES (?,?,?,?,?)r   N)r   r   r   get_sessionr   r   )r   r   r   r   r   r   r*   r   r   r   r(   t   s
    zSessionManager.save_sessionc              
   k   s.  |st dg }| D ]&}|| jvr0t d||d|  qdd| }| j|t|  z| j	 }W n t
y   d}Y n0 |du rg }| D ]\}}|d||f  qtdd	d
| zt| |V }	W n: t
y }
 z tdd	t|
 W Y d}
~
n
d}
~
0 0 t|	dS )aF  Returns the model for a particular session.

        Takes a keyword argument and searches for the value in the session
        database, then returns the rest of the session's info.

        Parameters
        ----------
        **kwargs : keyword argument
            must be given one of the keywords and values from the session database
            (i.e. session_id, path, name, type, kernel_id)

        Returns
        -------
        model : dict
            returns a dictionary that includes all the information from the
            session described by the kwarg.
        zmust specify a column to queryNo such column: %r%s=?zSELECT * FROM session WHERE %sz AND Nz%s=%ri  zSession not found: %s, )	TypeErrorkeys_columnsappendjoinr   r   listvaluesr   KeyErroritemsr   Z	HTTPErrorr   r   strr   r   )r   kwargsZ
conditionscolumnqueryr!   qkeyvaluer"   er   r   r   r.      s.    


*zSessionManager.get_sessionc                 k   s~   t | j|dV  |sdS g }| D ](}|| jvr@td| |d|  q&dd| }| j|t	|
 |g  dS )a  Updates the values in the session database.

        Changes the values of the session with the given session_id
        with the values from the keyword arguments.

        Parameters
        ----------
        session_id : str
            a uuid that identifies a session in the sqlite3 database
        **kwargs : str
            the key must correspond to a column title in session database,
            and the value replaces the current value in the session
            with session_id.
        r-   Nr/   r0   z(UPDATE session SET %s WHERE session_id=?r1   )r   r.   r3   r4   r2   r5   r6   r   r   r7   r8   )r   r   r<   Zsetsr=   r>   r   r   r   update_session   s    
zSessionManager.update_sessionc                 C   s
   || j vS )zRChecks if the kernel is still considered alive and returns true if its not found. )r&   )r   r   r   r   r   kernel_culled   s    zSessionManager.kernel_culledFc                 c   s   t | |d V }|rh| jd|d f dj|d |d d}|r`| j|d  tdt	|t | j
|d V }|d |d |d	 |d
 |d}|d
 dkr|d |d	 d|d< t|dS )z@Takes sqlite database session row and turns it into a dictionaryr   &DELETE FROM session WHERE session_id=?r   zKernel '{kernel_id}' appears to have been culled or died unexpectedly, invalidating session '{session_id}'. The session has been removed.)r   r   z  Continuing...Nr   r   r   )idr   r   r   kernelZnotebook)r   r   )r   rD   r   r   formatlogZwarningr   r   r9   r&   kernel_model)r   r!   r   rD   msgrJ   r"   r   r   r   r      s,    
zSessionManager.row_to_modelc              	   c   s^   | j d}g }| D ]6}zt| |V }|| W q tyL   Y q0 qt|dS )z_Returns a list of dictionaries containing all the information from
        the session databasezSELECT * FROM sessionN)	r   r   Zfetchallr   r   r5   r9   r   r   )r   cr*   r!   r"   r   r   r   list_sessions  s    zSessionManager.list_sessionsc                 c   s@   t | j|dV }t | j|d d V  | jd|f dS )z=Deletes the row in the session database with given session_idr-   rG   rF   rE   N)r   r.   r&   Zshutdown_kernelr   r   )r   r   Zsessionr   r   r   delete_session  s    zSessionManager.delete_session)NNNNN)NNNN)F)__name__
__module____qualname__r   r&   r	   r,   r   r   r4   propertyr   r   r   r   r   	coroutiner#   r%   r+   r'   r(   r.   rC   rD   r   rM   rN   r   r   r   r   r
      sF   





1
"
r
   )__doc__r$   r   ImportErrorZ	pysqlite2r   Ztornador   r   Ztraitlets.config.configurabler   Zipython_genutils.py3compatr   Z	traitletsr   Znotebook.utilsr   Znotebook.traittypesr	   r
   r   r   r   r   <module>   s   