o
    ðT·jè  ã                   @   sŽ   d Z ddlZddlmZ ddlT ddlmZ g d¢ZeddƒZG d	d
„ d
eƒZeddƒZ	G dd„ de	ƒZ
dd„ Zdd„ Zddd„Zdd„ ZdS )aw  
Diff database schema against model definitions.

Detects basic changes:

* tables to create
    Tables in the database that no model covers are ignored, and tables
    are never proposed for dropping.
* columns to add/drop
    Column diff does not introspect types/nullability/defaults/constraints.
    Renames are shown as an add + drop.
* indexes to add/drop
    Index diff looks at columns being indexed and unique flag. Partial and
    expression indexes are compared by name only.

Usage::

    diff = diff_models(db, [User, Tweet])
    if diff:
        print(diff)

Each attribute of the result maps directly onto a SchemaMigrator call:

* ``create_tables``: model classes (in dependency order)
* ``add_columns``: model fields to add
* ``drop_columns``: list of ``(table, column name)``
* ``add_indexes``: list of :class:`IndexDiff`
* ``drop_indexes``: list of :class:`IndexDiff`
é    N)Ú
namedtuple)Ú*)Úsort_models)Ú	IndexDiffÚ
SchemaDiffÚdiff_modelsÚ
_IndexDiff)ÚtableÚnameÚcolumnsÚuniquec                   @   s   e Zd ZdZdd„ ZdS )r   © c                 C   sV   | j d u rd|| j| jf S d|| j| jrd| j ndd | j ¡| jr'df S df S )Nz%s index %s.%sz%s index %s%s (%s)%sz.%sÚ z, z unique)r   r	   r
   Újoinr   )ÚselfÚopr   r   úX/home/dinkstrade/pdmp-scanner/venv/lib/python3.10/site-packages/playhouse/schema_diff.pyÚdisplay0   s   
þþzIndexDiff.displayN)Ú__name__Ú
__module__Ú__qualname__Ú	__slots__r   r   r   r   r   r   -   s    r   Ú_SchemaDiff)Úcreate_tablesÚadd_columnsÚdrop_columnsÚadd_indexesÚdrop_indexesc                   @   s    e Zd ZdZdd„ Zdd„ ZdS )r   r   c                 C   s   t | ƒS ©N)Úany)r   r   r   r   Ú__bool__B   s   zSchemaDiff.__bool__c                 C   sr   dd„ | j D ƒ}| dd„ | jD ƒ¡ | dd„ | jD ƒ¡ | dd„ | jD ƒ¡ | dd„ | jD ƒ¡ d |¡S )	Nc                 S   s   g | ]}d |j j ‘qS )zcreate table %s)Ú_metaÚ
table_name)Ú.0Úmr   r   r   Ú
<listcomp>F   s    ÿz&SchemaDiff.__str__.<locals>.<listcomp>c                 s   s$   � | ]}d |j jj|jf V  qdS )zadd column %s.%sN)Úmodelr!   r"   Úcolumn_name)r#   Úfr   r   r   Ú	<genexpr>H   s   € 
þÿz%SchemaDiff.__str__.<locals>.<genexpr>c                 s   s   � | ]}d | V  qdS )zdrop column %s.%sNr   )r#   Útcr   r   r   r)   K   s   € c                 s   ó   � | ]}|  d ¡V  qdS )ÚaddN©r   ©r#   Úidxr   r   r   r)   L   ó   € c                 s   r+   )ÚdropNr-   r.   r   r   r   r)   M   r0   Ú
)r   Úextendr   r   r   r   r   )r   Úaccumr   r   r   Ú__str__E   s   ÿ
þ
zSchemaDiff.__str__N)r   r   r   r   r    r5   r   r   r   r   r   ?   s    r   c                 C   sŠ   t ƒ t ƒ }}| j ¡ D ]4}t|tƒsq|j}|jd u r7tdd„ |D ƒƒr7| t	dd„ |D ƒƒt
|jƒf¡ q|jr@| |j¡ q||fS )Nc                 s   s   � | ]}t |tƒV  qd S r   )Ú
isinstanceÚField©r#   Úpr   r   r   r)   Y   r0   z!_model_indexes.<locals>.<genexpr>c                 s   ó   � | ]}|j V  qd S r   ©r'   r8   r   r   r   r)   Z   ó   € )Úsetr!   Úfields_to_indexr6   ÚIndexÚ_expressionsÚ_whereÚallr,   ÚtupleÚboolÚ_uniqueÚ_name)r&   ÚplainÚnamedÚindexÚpartsr   r   r   Ú_model_indexesQ   s   
ÿ€rK   c                 C   s   t | jot d| jtj¡ƒS )Nz\)\s*WHERE\s)rD   ÚsqlÚreÚsearchÚI)rI   r   r   r   Ú_is_partiala   s   rP   c                 C   sv   i }|   ||¡D ]0}|jdks|j d¡s|j d¡rqd |jv s%t|ƒr+d ||j< qt|jƒt|jƒf||j< q|S )NÚPRIMARYÚ_pkeyÚsqlite_autoindex_)	Úget_indexesr
   ÚendswithÚ
startswithr   rP   rC   rD   r   )Údatabaser	   ÚschemaÚindexesrI   r   r   r   Ú_database_indexese   s   
ÿrZ   c              	      sò  g }g g }}g g }}i }t ƒ }t|ƒD ]Û}	|	j}
t|
ddƒr!q|
j|
j‰}|ˆf|v r/q| |ˆf¡ ||vrCt |  |¡ƒ||< ˆ|| vrO| |	¡ qt dd„ |  	ˆ|¡D ƒƒ‰ dd„ |
j
D ƒ}| ‡ fdd„| ¡ D ƒ¡ | ‡fdd„tˆ t |ƒ ƒD ƒ¡ t|	ƒ\}}t| ˆ|ƒ}t| ¡ ƒD ]5\}}||v r¤| |¡ q–||v r®| |¡ q–|du r½| tˆ|ddƒ¡ q–|\}}| tˆ|||ƒ¡ q–t|ƒD ]}| tˆ|ddƒ¡ qÐt|ƒD ]\}}| tˆd||ƒ¡ qáqt|||||ƒS )	z}
    Compare the database schema against the given models.

    :return: a `SchemaDiff` (falsy when everything matches).
    Úextension_moduleNc                 s   r:   r   )r
   )r#   Úcr   r   r   r)   �   r<   zdiff_models.<locals>.<genexpr>c                 S   s   i | ]}|j |“qS r   r;   )r#   Úfieldr   r   r   Ú
<dictcomp>‘   s    zdiff_models.<locals>.<dictcomp>c                 3   s    � | ]\}}|ˆ vr|V  qd S r   r   )r#   r
   r]   )r   r   r   r)   ’   s   €
 ÿÿc                 3   s   � | ]}ˆ |fV  qd S r   r   )r#   r
   )r	   r   r   r)   ”   s   € ÿ)r=   r   r!   Úgetattrr"   rX   r,   Ú
get_tablesÚappendÚget_columnsÚsorted_fieldsr3   ÚitemsÚsortedrK   rZ   Úremover   r   )rW   Úmodelsr   r   r   r   r   ÚtablesÚseenr&   ÚmetarX   ÚfieldsrG   rH   Ú
db_indexesr
   Ú	signatureÚcolsr   r   )r   r	   r   r   t   sV   


ÿÿÿr   r   )Ú__doc__rM   Úcollectionsr   Úpeeweer   Ú__all__r   r   r   r   rK   rP   rZ   r   r   r   r   r   Ú<module>   s    


