o
    .&ßa1$  ã                   @   sÐ   d dl Z d dlZd dlZd dlZd dl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 e e¡ZG dd„ deƒZG dd	„ d	ejƒZG d
d„ deƒZG dd„ deƒZG dd„ deƒZG dd„ de	ƒZdS )é    N)Úcollections_abc)ÚBaseHistoryHandler)Úsqlite3)Úbinary_typec                   @   s^   e Zd ZdZdZdd„ Zdd„ Zdd„ Zd	d
„ Zdd„ Z	dd„ Z
edd„ ƒZejdd„ ƒZdS )ÚDatabaseConnectionzË
        CREATE TABLE IF NOT EXISTS records (
          id TEXT,
          request_id TEXT,
          source TEXT,
          event_type TEXT,
          timestamp INTEGER,
          payload TEXT
        )zPRAGMA journal_mode=WALc                 C   s   t j|dd d�| _|  ¡  d S )NF)Úcheck_same_threadÚisolation_level)r   ÚconnectÚ_connectionÚ_ensure_database_setup)ÚselfÚdb_filename© r   úB/usr/lib/python3/dist-packages/awscli/customizations/history/db.pyÚ__init__*   s   ÿzDatabaseConnection.__init__c                 C   ó   | j  ¡  d S ©N©r
   Úclose©r   r   r   r   r   /   ó   zDatabaseConnection.closec                 G   s   | j j|g|¢R Ž S r   )r
   Úexecute)r   ÚqueryÚ
parametersr   r   r   r   2   s   zDatabaseConnection.executec                 C   s   |   ¡  |  ¡  d S r   )Ú_create_record_tableÚ_try_to_enable_walr   r   r   r   r   5   s   z)DatabaseConnection._ensure_database_setupc                 C   s   |   | j¡ d S r   )r   Ú_CREATE_TABLEr   r   r   r   r   9   s   z'DatabaseConnection._create_record_tablec                 C   s4   z	|   | j¡ W d S  tjy   t d¡ Y d S w )NzFailed to enable sqlite WAL.)r   Ú_ENABLE_WALr   ÚErrorÚLOGÚdebugr   r   r   r   r   <   s
   ýz%DatabaseConnection._try_to_enable_walc                 C   s   | j jS r   ©r
   Úrow_factoryr   r   r   r   r"   D   s   zDatabaseConnection.row_factoryc                 C   s   || j _d S r   r!   )r   r"   r   r   r   r"   H   s   N)Ú__name__Ú
__module__Ú__qualname__r   r   r   r   r   r   r   r   Úpropertyr"   Úsetterr   r   r   r   r      s    	
r   c                       sD   e Zd Zdd„ Zdd„ Zdd„ Zdd„ Z‡ fd	d
„Zdd„ Z‡  Z	S )ÚPayloadSerializerc                 C   s   t |ƒS r   )Údict©r   Úobjr   r   r   Ú_encode_mutable_mappingN   ó   z)PayloadSerializer._encode_mutable_mappingc                 C   s   |  ¡ S r   )Ú	isoformatr*   r   r   r   Ú_encode_datetimeQ   r-   z"PayloadSerializer._encode_datetimec                 C   s*   z|  d¡}W |S  ty   d}Y |S w )Nzutf-8z<Byte sequence>)ÚdecodeÚUnicodeDecodeErrorr*   r   r   r   Ú_try_decode_bytesT   s   þþz#PayloadSerializer._try_decode_bytesc                    sd   t |tƒrˆ  |¡}|S t |tƒr t‡ fdd„| ¡ D ƒƒ}|S t |ttfƒr0‡ fdd„|D ƒ}|S )Nc                 3   s"   � | ]\}}|ˆ   |¡fV  qd S r   ©Ú_remove_non_unicode_stings)Ú.0ÚkÚvr   r   r   Ú	<genexpr>_   s   €  z?PayloadSerializer._remove_non_unicode_stings.<locals>.<genexpr>c                    s   g | ]}ˆ   |¡‘qS r   r3   )r5   Úor   r   r   Ú
<listcomp>b   s    z@PayloadSerializer._remove_non_unicode_stings.<locals>.<listcomp>)Ú
isinstanceÚstrr2   r)   ÚitemsÚlistÚtupler*   r   r   r   r4   [   s   


ûÿþz,PayloadSerializer._remove_non_unicode_stingsc                    s@   z	t t| ƒ |¡W S  ty   |  |¡}t t| ƒ |¡ Y S w r   )Úsuperr(   Úencoder1   r4   )r   r+   Úscrubbed_obj©Ú	__class__r   r   rA   e   s   
ózPayloadSerializer.encodec                 C   sH   t |tjƒr|  |¡S t |tjƒr|  |¡S t |tƒr |  |¡S t|ƒS r   )	r;   Údatetimer/   r   ÚMutableMappingr,   r   r2   Úreprr*   r   r   r   Údefaultw   s   



zPayloadSerializer.default)
r#   r$   r%   r,   r/   r2   r4   rA   rH   Ú__classcell__r   r   rC   r   r(   M   s    
r(   c                   @   s0   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
S )ÚDatabaseRecordWriterz
        INSERT INTO records(
            id, request_id, source, event_type, timestamp, payload)
        VALUES (?,?,?,?,?,?) c                 C   s   || _ t ¡ | _d S r   )r
   Ú	threadingÚLockÚ_lock©r   Ú
connectionr   r   r   r   �   ó   zDatabaseRecordWriter.__init__c                 C   r   r   r   r   r   r   r   r   ‘   r   zDatabaseRecordWriter.closec                 C   sF   |   |¡}| j� | j | j|¡ W d   ƒ d S 1 sw   Y  d S r   )Ú_create_db_recordrM   r
   r   Ú_WRITE_RECORD)r   ÚrecordÚ	db_recordr   r   r   Úwrite_record”   s   
"ÿz!DatabaseRecordWriter.write_recordc                 C   s@   |d }t j|d td�}|d | d¡|d ||d |f}|S )NÚ
event_typeÚpayload)ÚclsÚ
command_idÚ
request_idÚsourceÚ	timestamp)ÚjsonÚdumpsr(   Úget)r   rS   rV   Újson_serialized_payloadrT   r   r   r   rQ   ™   s   
ÿúz&DatabaseRecordWriter._create_db_recordN)r#   r$   r%   rR   r   r   rU   rQ   r   r   r   r   rJ   ‡   s    rJ   c                   @   sX   e Zd ZdZde Zde Zde Zdd„ Zdd„ Zd	d
„ Z	dd„ Z
dd„ Zdd„ ZdS )ÚDatabaseRecordReaderzORDER BY timestampz•
        SELECT * FROM records
        WHERE id =
        (SELECT id FROM records WHERE timestamp =
        (SELECT max(timestamp) FROM records)) %s;z%SELECT * from records where id = ? %szìSELECT a.id AS id_a,     b.id AS id_b,     a.timestamp as timestamp,     a.payload AS args,     b.payload AS rc FROM records a, records b where a.event_type == "CLI_ARGUMENTS" AND     b.event_type = "CLI_RC" AND     id_a == id_b %s DESCc                 C   s   || _ | j| j _d S r   )r
   Ú_row_factoryr"   rN   r   r   r   r   ½   rP   zDatabaseRecordReader.__init__c                 C   r   r   r   r   r   r   r   r   Á   r   zDatabaseRecordReader.closec                 C   sF   i }t |jƒD ]\}}|| }|d dkrt |¡}|||d < q|S )Nr   rW   )Ú	enumerateÚdescriptionr]   Úloads)r   ÚcursorÚrowÚdÚidxÚcolÚvalr   r   r   rb   Ä   s   
z!DatabaseRecordReader._row_factoryc                 c   ó$   � | j  | j¡}|D ]}|V  q
d S r   )r
   r   Ú_GET_LAST_ID_RECORDS©r   rf   rg   r   r   r   Úiter_latest_recordsÍ   ó
   €ÿz(DatabaseRecordReader.iter_latest_recordsc                 c   s(   � | j  | j|g¡}|D ]}|V  qd S r   )r
   r   Ú_GET_RECORDS_BY_ID)r   Ú	record_idrf   rg   r   r   r   Úiter_recordsÒ   s
   €ÿz!DatabaseRecordReader.iter_recordsc                 c   rl   r   )r
   r   Ú_GET_ALL_RECORDSrn   r   r   r   Úiter_all_records×   rp   z%DatabaseRecordReader.iter_all_recordsN)r#   r$   r%   Ú	_ORDERINGrm   rq   rt   r   r   rb   ro   rs   ru   r   r   r   r   ra   ¨   s     ü	÷ÿ	ra   c                   @   sL   e Zd Zeg d¢ƒZdZdd„ Zdd„ Zdd„ Zd	d
„ Z	dd„ Z
dd„ ZdS )ÚRecordBuilder)ÚAPI_CALLÚHTTP_REQUESTÚHTTP_RESPONSEÚPARSED_RESPONSErx   c                 C   s   d | _ t ¡ | _d S r   )Ú_identifierrK   ÚlocalÚ_localsr   r   r   r   r   â   rP   zRecordBuilder.__init__c                 C   s   t | jdd ƒ}|S ©NrZ   )Úgetattrr~   )r   rZ   r   r   r   Ú_get_current_thread_request_idæ   s   z,RecordBuilder._get_current_thread_request_idc                 C   s   t | jdtt ¡ ƒƒ d S r   )Úsetattrr~   r<   ÚuuidÚuuid4r   r   r   r   Ú_start_http_lifecycleê   s   z#RecordBuilder._start_http_lifecyclec                 C   s,   || j kr	|  ¡  || jv r|  ¡ }|S d S r   )Ú!_START_OF_REQUEST_LIFECYCLE_EVENTr…   Ú_REQUEST_LIFECYCLE_EVENTSr�   )r   rV   rZ   r   r   r   Ú_get_request_idí   s   

zRecordBuilder._get_request_idc                 C   s   | j d u rtt ¡ ƒ| _ | j S r   )r|   r<   rƒ   r„   r   r   r   r   Ú_get_identifierõ   s   
zRecordBuilder._get_identifierc                 C   s>   |   ¡ }||||tt ¡ d ƒdœ}|  |¡}|r||d< |S )Niè  )rY   rV   rW   r[   r\   rZ   )r‰   ÚintÚtimerˆ   )r   rV   rW   r[   ÚuidrS   rZ   r   r   r   Úbuild_recordú   s   û
zRecordBuilder.build_recordN)r#   r$   r%   Úsetr‡   r†   r   r�   r…   rˆ   r‰   r�   r   r   r   r   rw   Ý   s    ÿrw   c                   @   s   e Zd Zdd„ Zdd„ ZdS )ÚDatabaseHistoryHandlerc                 C   s   || _ || _d S r   )Ú_writerÚ_record_builder)r   ÚwriterÚrecord_builderr   r   r   r   
  s   
zDatabaseHistoryHandler.__init__c                 C   s    | j  |||¡}| j |¡ d S r   )r‘   r�   r�   rU   )r   rV   rW   r[   rS   r   r   r   Úemit  s   zDatabaseHistoryHandler.emitN)r#   r$   r%   r   r”   r   r   r   r   r�   	  s    r�   )rƒ   r‹   r]   rE   rK   ÚloggingÚawscli.compatr   Úbotocore.historyr   r   r   Ú	getLoggerr#   r   Úobjectr   ÚJSONEncoderr(   rJ   ra   rw   r�   r   r   r   r   Ú<module>   s"   
/:!5,