o
    ðT·j€•  ã                   @   sz  d Z ddlmZ ddlmZ ddlZddlZddlT 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 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 ddlmZ zddlmZ W n eyo   dZY nw G dd„ deƒZdd„ Zdd„ Zdd„ ZG dd„ deƒZG dd„ deƒZG dd„ deƒZG d d!„ d!ed"d#ƒƒZG d$d%„ d%eƒZG d&d'„ d'eƒZ d(d)„ Z!dS )*a  
Lightweight schema migrations.

Example Usage
-------------

Instantiate a migrator:

    # Postgres example:
    my_db = PostgresqlDatabase(...)
    migrator = PostgresqlMigrator(my_db)

    # SQLite example:
    my_db = SqliteDatabase('my_database.db')
    migrator = SqliteMigrator(my_db)

Then you will use the `migrate` function to run various `Operation`s which
are generated by the migrator:

    migrate(
        migrator.add_column('some_table', 'column_name', CharField(default=''))
    )

Migrations are not wrapped in a transaction by default. Use
`migrator.migration_context()` to run operations in a transaction where
DDL is transactional and, on SQLite, disable foreign-key enforcement for
the duration:

    with migrator.migration_context():
        migrator.migrate(...)

For versioned migration scripts with history and a CLI, see
`playhouse.migrations`, which builds on this module.

Supported Operations
--------------------

Add new field(s) to an existing model:

    # Create your field instances. For non-null fields you must specify a
    # default value.
    pubdate_field = DateTimeField(null=True)
    comment_field = TextField(default='')

    # Run the migration, specifying the database table, field name and field.
    migrate(
        migrator.add_column('comment_tbl', 'pub_date', pubdate_field),
        migrator.add_column('comment_tbl', 'comment', comment_field),
    )

Renaming a field:

    # Specify the table, original name of the column, and its new name.
    migrate(
        migrator.rename_column('story', 'pub_date', 'publish_date'),
        migrator.rename_column('story', 'mod_date', 'modified_date'),
    )

Dropping a field:

    migrate(
        migrator.drop_column('story', 'some_old_field'),
    )

Making a field nullable or not nullable:

    # Note that when making a field not null that field must not have any
    # NULL values present.
    migrate(
        # Make `pub_date` allow NULL values.
        migrator.drop_not_null('story', 'pub_date'),

        # Prevent `modified_date` from containing NULL values.
        migrator.add_not_null('story', 'modified_date'),
    )

Renaming a table:

    migrate(
        migrator.rename_table('story', 'stories_tbl'),
    )

Adding an index:

    # Specify the table, column names, and whether the index should be
    # UNIQUE or not.
    migrate(
        # Create an index on the `pub_date` column.
        migrator.add_index('story', ('pub_date',), False),

        # Create a multi-column index on the `pub_date` and `status` fields.
        migrator.add_index('story', ('pub_date', 'status'), False),

        # Create a unique index on the category and title fields.
        migrator.add_index('story', ('category_id', 'title'), True),
    )

Dropping an index:

    # Specify the index name.
    migrate(migrator.drop_index('story', 'story_pub_date_status'))

Adding or dropping table constraints:

    # Add a CHECK() constraint to enforce the price cannot be negative.
    migrate(migrator.add_constraint(
        'products',
        'price_check',
        Check('price >= 0')))

    # Remove the price check constraint.
    migrate(migrator.drop_constraint('products', 'price_check'))

    # Add a UNIQUE constraint on the first and last names.
    migrate(migrator.add_unique('person', 'first_name', 'last_name'))
é    )Ú
namedtuple)ÚcontextmanagerN)Ú*)ÚCommaNodeList)ÚEnclosedNodeList©ÚEntity)Ú
Expression)ÚNode)ÚNodeList)ÚOP)ÚValueLiterals)Ú	callable_)Úsqlite3)Ú_truncate_constraint_name)ÚCockroachDatabasec                   @   s0   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
S )Ú	Operationz/Encapsulate a single schema altering operation.c                 O   s   || _ || _|| _|| _d S ©N)ÚmigratorÚfnÚargsÚkwargs)Úselfr   r   r   r   © r   úT/home/dinkstrade/pdmp-scanner/venv/lib/python3.10/site-packages/playhouse/migrate.pyÚ__init__Ž   s   
zOperation.__init__c                 C   s   | j j |¡ d S r   )r   ÚdatabaseÚexecute)r   Únoder   r   r   r   ”   s   zOperation.executec                 C   s\   t |ttfƒr|  |¡ d S t |tƒr| ¡  d S t |ttfƒr*|D ]	}|  |¡ q"d S d S r   )	Ú
isinstancer
   ÚContextr   r   ÚrunÚlistÚtupleÚ_handle_result)r   ÚresultÚitemr   r   r   r$   —   s   
þzOperation._handle_resultc                 C   s(   |   | j| jg| j¢R i | j¤Ž¡ d S r   )r$   r   r   r   r   ©r   r   r   r   r!       s   (zOperation.runN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r$   r!   r   r   r   r   r   Œ   s    	r   c                    s   t  ˆ ¡‡ fdd„ƒ}|S )Nc                    s   t | ˆ g|¢R i |¤ŽS r   )r   ©r   r   r   ©r   r   r   Úinner¥   s   zoperation.<locals>.inner)Ú	functoolsÚwraps)r   r.   r   r-   r   Ú	operation¤   s   r1   c                 C   s   d| v r
t d|  ƒ‚| S )NÚ.zPTable name "%s" is schema-qualified. Use the migrator schema= parameter instead.)Ú
ValueError)Únamer   r   r   Ú_check_table_name«   s
   ÿr5   c                 C   s   t d | ft|ƒ ¡ƒS )NÚ_)r   Újoinr#   )Ú
table_nameÚcolumnsr   r   r   Úmake_index_name²   s   r:   c                   @   s†  e Zd ZdZdZdZdZd@dd„Zd@dd„Zdd	„ Z	e
dAd
d„ƒZdd„ Zed@dd„ƒZedd„ ƒZdd„ Zdd„ Ze	dBdd„ƒZedd„ ƒZedd„ ƒZedd„ ƒZdd„ Ze		dCd d!„ƒZedBd"d#„ƒZd$d%„ Zed&d'„ ƒZedAd(d)„ƒZed*d+„ ƒZed,d-„ ƒZed.d/„ ƒZed0d1„ ƒZ ed2d3„ ƒZ!ed@d4d5„ƒZ"ed6d7„ ƒZ#edDd8d9„ƒZ$e		dEd:d;„ƒZ%ed<d=„ ƒZ&ed@d>d?„ƒZ'dS )FÚSchemaMigratorFTNc                 C   s0   |d ur| j stdt| ƒj ƒ‚|| _|| _d S )Nz%s does not support schema=.)Úsupports_schemar3   Útyper(   r   Úschema)r   r   r>   r   r   r   r   ¼   s   ÿ
zSchemaMigrator.__init__c                 C   s   t |p| jt|ƒƒS r   )r   r>   r5   )r   Útabler>   r   r   r   Ú_tableÃ   s   zSchemaMigrator._tablec                 G   s   |D ]}|  ¡  qd S r   ©r!   )r   Ú
operationsr1   r   r   r   ÚmigrateÆ   ó   
ÿzSchemaMigrator.migratec                 c   sL   � |r!| j r!| j ¡ � d V  W d   ƒ d S 1 sw   Y  d S d V  d S r   )Útransactional_ddlr   Úatomic)r   rF   r   r   r   Úmigration_contextÊ   s   €
"ÿ
z SchemaMigrator.migration_contextc                 C   s
   | j  ¡ S r   )r   Úget_sql_contextr'   r   r   r   Úmake_contextÒ   s   
zSchemaMigrator.make_contextc                 C   s~   t |tƒr|jd u rtdƒ‚|j}trt |tƒrt}nt |tƒr#t}nt |tƒr+t	}nt |t
ƒr3t}ntd| ƒ‚|||d�S )Nz Database proxy is uninitialized.zUnsupported database: %s©r>   )r   ÚProxyÚobjr3   r   ÚCockroachDBMigratorÚPostgresqlDatabaseÚPostgresqlMigratorÚMySQLDatabaseÚMySQLMigratorÚSqliteDatabaseÚSqliteMigrator)Úclsr   r>   r   r   r   r   Úfrom_databaseÕ   s   




zSchemaMigrator.from_databasec                 C   sR   |j }t|ƒr
|ƒ }|  ¡  d¡ |  |¡¡ d¡ tt|ƒtj	| 
|¡dd�¡S )NzUPDATE z SET T)Úflat)Údefaultr   rI   ÚliteralÚsqlr@   r	   r   r   ÚEQÚdb_value)r   r?   Úcolumn_nameÚfieldrW   r   r   r   Úapply_defaultè   s   üüzSchemaMigrator.apply_defaultc                 C   s   |  d¡ |  |¡¡S )NúALTER TABLE )rX   rY   r@   )r   Úctxr?   r   r   r   Ú_alter_tableø   s   zSchemaMigrator._alter_tablec                 C   ó   |   ||¡ d¡ t|ƒ¡S )Nú ALTER COLUMN ©ra   rX   rY   r   ©r   r`   r?   Úcolumnr   r   r   Ú_alter_columnû   ó
   
ýzSchemaMigrator._alter_columnc                 C   sl   |   ¡ }|j}|sd|_|j|kr| |_|_|  ||¡ d¡ | |¡¡ ||_t|t	ƒr4|  
||¡ |S )NTz ADD COLUMN )rI   Únullr\   r4   ra   rX   rY   Úddlr   ÚForeignKeyFieldÚadd_inline_fk_sql)r   r?   r\   r]   Úallow_not_nullr`   Ú
field_nullr   r   r   Úalter_add_column  s   

zSchemaMigrator.alter_add_columnc                 C   s,   |   |  ¡ |¡ d¡ t|ƒ¡ d¡ |¡S )Nú ADD CONSTRAINT ú ©ra   rI   rX   rY   r   ©r   r?   r4   Ú
constraintr   r   r   Úadd_constraint  s   
ûzSchemaMigrator.add_constraintc                 G   s:   dd  |¡ }ttdƒtdd„ |D ƒƒfƒ}|  |||¡S )Nzuniq_%sr6   ÚUNIQUEc                 S   ó   g | ]}t |ƒ‘qS r   r   ©Ú.0rf   r   r   r   Ú
<listcomp>)  ó    z-SchemaMigrator.add_unique.<locals>.<listcomp>)r7   r   ÚSQLr   ru   )r   r?   Úcolumn_namesÚconstraint_namert   r   r   r   Ú
add_unique$  s   þzSchemaMigrator.add_uniquec                 C   ó    |   |  ¡ |¡ d¡ t|ƒ¡S ©Nz DROP CONSTRAINT rr   ©r   r?   r4   r   r   r   Údrop_constraint,  s
   
ýzSchemaMigrator.drop_constraintc                 C   sv   |j j}| d¡ |  |j|j¡¡ d¡ tt|j	j
ƒfƒ¡}|jd ur,| d|j ¡}|jd ur9| d|j ¡}|S )Nú REFERENCES rq   ú ON DELETE %sú ON UPDATE %s)Ú	rel_modelÚ_metarX   rY   r@   r8   r>   r   r   Ú	rel_fieldr\   Ú	on_deleteÚ	on_update)r   r`   r]   Úmetar   r   r   rl   3  s   ü

z SchemaMigrator.add_inline_fk_sqlc	                 C   s°   |pd|||f }	|   ¡  d¡ |  |¡¡ d¡ tt|	ƒƒ¡ d¡ tt|ƒfƒ¡ d¡ |  ||¡¡ d¡ t|ƒ¡ d¡}
|d urK|
 d| ¡}
|d urV|
 d	| ¡}
|
S )
Nzfk_%s_%s_refs_%sr_   rp   z FOREIGN KEY r„   z (ú)r…   r†   )rI   rX   rY   r@   r   r   r   )r   r?   r\   ÚrelÚ
rel_columnrŠ   r‹   r~   Ú
rel_schemart   r`   r   r   r   Úadd_foreign_key_constraint@  s.   þ
ôz)SchemaMigrator.add_foreign_key_constraintc                 C   sò   |  ¡ }|js|jd u r|std| ƒ‚t|tƒ}|r"|js"tdƒ‚|  ||||¡g}|js@|s@| |  	|||¡|  
||¡g¡ |r^| jr^| | j|||jjj|jj|j|j|jjjd�¡ |jsd|jrwt|dd ƒ}| |  ||f|j|¡¡ |S )Nz!%s is not null but has no defaultz$Foreign keys must specify a `field`.)r�   Ú
index_type)Úcloneri   rW   r3   r   rk   r‰   ro   Úextendr^   Úadd_not_nullÚexplicit_create_foreign_keyÚappendr‘   r‡   rˆ   r8   r\   rŠ   r‹   r>   ÚindexÚuniqueÚgetattrÚ	add_index)r   r?   r\   r]   rm   Úis_foreign_keyrB   Úusingr   r   r   Ú
add_columnZ  s>   

ÿ

þ
ùÿ
ÿzSchemaMigrator.add_columnc                 C   s@   | j  || j¡D ]}|j|kr|jr|j  S qtd||f ƒ‚)Nz=Unable to find foreign key constraint for "%s" on table "%s".)r   Úget_foreign_keysr>   rf   r4   ÚAttributeError)r   r?   r\   Úfkr   r   r   Úget_foreign_key_constraint…  s   
€ÿÿz)SchemaMigrator.get_foreign_key_constraintc                 C   ó   t ‚r   ©ÚNotImplementedError)r   r?   r\   r   r   r   Údrop_foreign_key_constraint�  s   z*SchemaMigrator.drop_foreign_key_constraintc                 C   sn   |   ¡ }|  ||¡ d¡ t|ƒ¡ |r| d¡ dd„ | j || j¡D ƒ}||v r5| jr5|  	||¡|gS |S )Nú DROP COLUMN ú CASCADEc                 S   s   g | ]}|j ‘qS r   ©rf   ©ry   r¡   r   r   r   rz   ›  s    z.SchemaMigrator.drop_column.<locals>.<listcomp>)
rI   ra   rX   rY   r   r   rŸ   r>   Úexplicit_delete_foreign_keyr¦   )r   r?   r\   Úcascader`   Ú
fk_columnsr   r   r   Údrop_column‘  s   

ÿzSchemaMigrator.drop_columnc                 C   s0   |   |  ¡ |¡ d¡ t|ƒ¡ d¡ t|ƒ¡S )Nú RENAME COLUMN ú TO rr   )r   r?   Úold_nameÚnew_namer   r   r   Úrename_column¢  s   

ûzSchemaMigrator.rename_columnc                 C   ó   |   |  ¡ ||¡ d¡S )Nz SET NOT NULL©rg   rI   rX   ©r   r?   rf   r   r   r   r•   «  ó   þzSchemaMigrator.add_not_nullc                 C   r´   )Nz DROP NOT NULLrµ   r¶   r   r   r   Údrop_not_null±  r·   zSchemaMigrator.drop_not_nullc                 C   sf   |d u rt dƒ‚t|ƒr|ƒ }t|tƒr| d¡rt|ƒ}|  |  ¡ |¡ d¡ 	t
|ƒ¡ d¡ 	|¡S )Nú `default` must be not None/NULL.©r�   ú'rc   z SET DEFAULT )r3   r   r   ÚstrÚendswithr|   ra   rI   rX   rY   r   )r   r?   rf   rW   r   r   r   Úadd_column_default·  s   
ûz!SchemaMigrator.add_column_defaultc                 C   s&   |   |  ¡ |¡ d¡ t|ƒ¡ d¡S )Nrc   z DROP DEFAULTrr   r¶   r   r   r   Údrop_column_defaultÉ  s   
üz"SchemaMigrator.drop_column_defaultc                 C   sV   |   ¡ }|  |||¡ d¡ | |¡¡}|d ur)t|tƒs!t|ƒ}| d¡ |¡}|S )Nz TYPE z USING )rI   rg   rX   rY   Úddl_datatyper   r
   r|   ©r   r?   rf   r]   Úcastr`   r   r   r   Úalter_column_typeÑ  s   
ý
z SchemaMigrator.alter_column_typec                 C   r€   )Nz RENAME TO rr   ©r   r±   r²   r   r   r   Úrename_tableß  s
   
ýzSchemaMigrator.rename_tablec                 C   s:   |   ¡  |rdnd¡}| |  ||¡¡}|r| d¡S |S )NzDROP TABLE IF EXISTS zDROP TABLE r¨   ©rI   rX   rY   r@   )r   r?   Úsafer¬   r>   r`   r   r   r   Ú
drop_tableç  s
   
ÿzSchemaMigrator.drop_tablec              	      sj   |   ¡ }|p
t||ƒ}	tt|ƒ| jd�‰ ‡ fdd„|D ƒ}
t|	ˆ |
||||d�}| jjr0t|ƒ}| 	|¡S )NrJ   c                    s   g | ]}t ˆ j|ƒ‘qS r   )rš   Úcrx   ©Ú	table_objr   r   rz   ô  s    z,SchemaMigrator.add_index.<locals>.<listcomp>)r™   r�   ÚwhereÚnulls_distinct)
rI   r:   ÚTabler5   r>   ÚIndexr   Úindex_value_literalsr   rY   )r   r?   r9   r™   r�   rÌ   rÍ   r4   r`   Ú
index_nameÚcolsr˜   r   rÊ   r   r›   î  s   ÿ
zSchemaMigrator.add_indexc                 C   s   |   ¡  d¡ |  |¡¡S )NúDROP INDEX rÆ   ©r   r?   rÑ   r   r   r   Ú
drop_indexü  s
   ýzSchemaMigrator.drop_indexc                 C   s
   t ||ƒS r   )r|   )r   rY   Úparamsr   r   r   rY     ó   
zSchemaMigrator.sqlr   ©T©F)NNNN©FFN)FNNNN)(r(   r)   r*   r–   r«   r<   rE   r   r@   rC   r   rG   rI   ÚclassmethodrU   r1   r^   ra   rg   ro   ru   r   rƒ   rl   r‘   rž   r¢   r¦   r®   r³   r•   r¸   r¾   r¿   rÃ   rÅ   rÈ   r›   rÕ   rY   r   r   r   r   r;   ¶   s|    


ÿ


þ*






ÿ
r;   c                       s@   e Zd Zdd„ Zedd„ ƒZe‡ fdd„ƒZedd„ ƒZ‡  ZS )	rO   c                 C   sB   d}|   ¡  |  |¡¡ ¡ \}}| j ||f¡}dd„ | ¡ D ƒS )Nag  
            SELECT pg_attribute.attname
            FROM pg_index, pg_class, pg_attribute
            WHERE
                pg_class.oid = %s::regclass AND
                indrelid = pg_class.oid AND
                pg_attribute.attrelid = pg_class.oid AND
                pg_attribute.attnum = any(pg_index.indkey) AND
                indisprimary;
        c                 S   s   g | ]}|d  ‘qS )r   r   )ry   Úrowr   r   r   rz     r{   z;PostgresqlMigrator._primary_key_columns.<locals>.<listcomp>)rI   rY   r@   Úqueryr   Úexecute_sqlÚfetchall)r   ÚtblrÝ   r4   r6   Úcursorr   r   r   Ú_primary_key_columns	  s   z'PostgresqlMigrator._primary_key_columnsc                 C   s   |   ¡  d¡ t|ƒ¡S )NzSET search_path TO )rI   rX   rY   r   )r   Úschema_namer   r   r   Úset_search_path  s
   
ýz"PostgresqlMigrator.set_search_pathc           
         sˆ   |   |¡}tt| ƒ}| ||¡g}t|ƒdkrBd||d f }d}| j ||| jf¡}t| 	¡ ƒrBd||d f }	| 
| ||	¡¡ |S )Né   z	%s_%s_seqr   zØ
                SELECT 1
                FROM information_schema.sequences
                WHERE LOWER(sequence_name) = LOWER(%s)
                    AND sequence_schema = COALESCE(%s, current_schema())
            )râ   ÚsuperrO   rÅ   Úlenr   rÞ   r>   ÚboolÚfetchoner—   )
r   r±   r²   Úpk_namesÚParentClassrB   Úseq_namerÝ   rá   Únew_seq_name©Ú	__class__r   r   rÅ      s   


ÿÿzPostgresqlMigrator.rename_tablec                 C   ó,   |   ||¡}|  |  ¡ |¡ d¡ t|ƒ¡S r�   ©r¢   ra   rI   rX   rY   r   ©r   r?   r\   Úfk_constraintr   r   r   r¦   9  ó   
ýz.PostgresqlMigrator.drop_foreign_key_constraint)	r(   r)   r*   râ   r1   rä   rÅ   r¦   Ú__classcell__r   r   rî   r   rO     s    
rO   c                   @   s(   e Zd ZdZdZdd„ Zedd„ ƒZdS )rM   TFc                 C   ó   d S r   r   ©r   r`   r]   r   r   r   rl   F  ó   z%CockroachDBMigrator.add_inline_fk_sqlc                 C   s    |   ¡  d¡ |  |¡¡ d¡S )NrÓ   r¨   rÆ   rÔ   r   r   r   rÕ   I  s   üzCockroachDBMigrator.drop_indexN)r(   r)   r*   r–   rE   rl   r1   rÕ   r   r   r   r   rM   B  s    rM   c                   @   s:   e Zd Zedd„ ƒZedd„ ƒZedd„ ƒZd
dd	„ZdS )ÚMySQLColumnc                 C   ó
   | j dkS )NÚPRI©Úpkr'   r   r   r   Úis_pkT  r×   zMySQLColumn.is_pkc                 C   rú   )NÚUNIrü   r'   r   r   r   Ú	is_uniqueX  r×   zMySQLColumn.is_uniquec                 C   rú   )NÚYES)ri   r'   r   r   r   Úis_null\  r×   zMySQLColumn.is_nullNc                 C   s–   |d u r| j }|d u r| j}t|ƒt| jƒg}| jr!| tdƒ¡ |r+| tdƒ¡ n| tdƒ¡ | jr<| tdƒ¡ | jrG| t| jƒ¡ t	|ƒS )Nrv   ÚNULLúNOT NULLzPRIMARY KEY)
r  r4   r   r|   Ú
definitionr   r—   rþ   Úextrar   )r   r\   r  Úpartsr   r   r   rY   `  s"   þzMySQLColumn.sql©NN)r(   r)   r*   Úpropertyrþ   r   r  rY   r   r   r   r   rù   R  s    


rù   Ú_Column)r4   r  ri   rý   rW   r  c                   @   s†   e Zd ZdZdZdZdd„ Zedd„ ƒZdd„ Z	ed	d
„ ƒZ
dd„ Zedd„ ƒZedd„ ƒZedd„ ƒZeddd„ƒZedd„ ƒZdS )rQ   TFc                 C   rb   )Nú MODIFY rd   re   r   r   r   rg   z  rh   zMySQLMigrator._alter_columnc                 C   s,   |   ¡  d¡ |  |¡¡ d¡ |  |¡¡S )NzRENAME TABLE r°   rÆ   rÄ   r   r   r   rÅ   €  s   ûzMySQLMigrator.rename_tablec           	      C   s\   |   ¡  |  |¡¡ ¡ \}}| j d| ¡}| ¡ }|D ]}t|Ž }|j|kr+|  S qdS )NzDESCRIBE %s;F)	rI   rY   r@   rÝ   r   rÞ   rß   rù   r4   )	r   r?   r\   r4   r6   rá   ÚrowsrÜ   rf   r   r   r   Ú_get_column_definitionŠ  s   
ÿz$MySQLMigrator._get_column_definitionc                 C   rð   )Nz DROP FOREIGN KEY rñ   rò   r   r   r   r¦   ”  rô   z)MySQLMigrator.drop_foreign_key_constraintc                 C   rö   r   r   r÷   r   r   r   rl   œ  rø   zMySQLMigrator.add_inline_fk_sqlc              
   C   sŒ   |   ||¡}|  |  ¡ |¡ d¡ |jdd�¡}tdd„ | j || j¡D ƒƒ}||vr-|S || }|  	||¡||  
|||j|j|j|j¡fS )Nr  F©r  c                 s   ó   � | ]}|j |fV  qd S r   r©   rª   r   r   r   Ú	<genexpr>§  ó
   € ÿ
ÿz-MySQLMigrator.add_not_null.<locals>.<genexpr>)r  ra   rI   rX   rY   Údictr   rŸ   r>   r¦   r‘   Ú
dest_tableÚdest_columnrŠ   r‹   )r   r?   rf   Ú
column_defr•   Ú
fk_objectsÚfk_metadatar   r   r   r•   Ÿ  s.   ýþ
úþzMySQLMigrator.add_not_nullc                 C   s>   |   ||¡}|jrtdƒ‚|  |  ¡ |¡ d¡ |jdd�¡S )NzPrimary keys can not be nullr  Tr  )r  rþ   r3   ra   rI   rX   rY   )r   r?   rf   r  r   r   r   r¸   ¸  s   ýzMySQLMigrator.drop_not_nullc           	   
   C   s    t dd„ | j || j¡D ƒƒ}||v }|  ||¡}|  |  ¡ |¡ d¡ t	|ƒ¡ d¡ |j|d�¡}|rN|| }|  
||¡||  |||j|j|j|j¡gS |S )Nc                 s   r  r   r©   rª   r   r   r   r  Ä  r  z.MySQLMigrator.rename_column.<locals>.<genexpr>z CHANGE rq   )r\   )r  r   rŸ   r>   r  ra   rI   rX   rY   r   r¦   r‘   r  r  rŠ   r‹   )	r   r?   r±   r²   r  rœ   rf   Ú
rename_ctxr  r   r   r   r³   Â  s4   þ
û
úýzMySQLMigrator.rename_columnNc                 C   sF   |d urt dƒ‚|  ¡ }|  ||¡ d¡ t|ƒ¡ d¡ | |¡¡S )Nz5alter_column_type() does not support cast with MySQL.r  rq   )r3   rI   ra   rX   rY   r   rj   rÁ   r   r   r   rÃ   à  s   
ûzMySQLMigrator.alter_column_typec                 C   s*   |   ¡  d¡ t|ƒ¡ d¡ |  |¡¡S )NrÓ   z ON )rI   rX   rY   r   r@   rÔ   r   r   r   rÕ   í  s   
ûzMySQLMigrator.drop_indexr   )r(   r)   r*   r–   r«   rE   rg   r1   rÅ   r  r¦   rl   r•   r¸   r³   rÃ   rÕ   r   r   r   r   rQ   u  s*    
	



	
rQ   c                       s2  e Zd ZdZdZe d¡Ze d¡Ze d¡Z	e dej
¡Z‡ fdd„Zed+‡ fd
d„	ƒZdd„ Zedd„ ƒZdd„ Zed,dd„ƒZed-dd„ƒZed-‡ fdd„	ƒZed-‡ fdd„	ƒZedd„ ƒZedd„ ƒZed.dd „ƒZe‡ fd!d"„ƒZe‡ fd#d$„ƒZed/‡ fd%d&„	ƒZed'd(„ ƒZe	d0d)d*„ƒZ‡  ZS )1rS   zˆ
    SQLite supports a subset of ALTER TABLE queries, view the docs for the
    full details http://sqlite.org/lang_altertable.html
    Fz(.+?)\((.+)\)z(?:[^,(]|\([^)]*\))+z["`']?([\w]+)z FOREIGN KEY\s+\("?([\w]+)"?\)\s+c                    s$   t t| ƒj|i |¤Ž | jj| _d S r   )ræ   rS   r   r   Úserver_versionÚsqlite_versionr,   rî   r   r   r     s   zSqliteMigrator.__init__Tc              
   #   sŽ   � t | j d¡ƒ}|r| j dd¡ z)tt| ƒ |¡� d V  W d   ƒ n1 s)w   Y  W |r:| j dd¡ d S d S |rF| j dd¡ w w )NÚforeign_keysr   rå   )rè   r   Úpragmaræ   rS   rG   )r   rF   Úfks_enabledrî   r   r   rG     s   €ÿ€ÿÿz SqliteMigrator.migration_contextc                 C   s   | j  dd| ¡ g¡}| ¡ S )NzBselect name, sql from sqlite_master where type=? and LOWER(name)=?r?   )r   rÞ   Úlowerré   )r   r?   Úresr   r   r   Ú_get_create_table  s
   
ýz SqliteMigrator._get_create_tablec              	      sò  t dd„ ˆj |¡D ƒƒ}| ¡ |vrtd||f ƒ‚ˆ |¡\}}ˆj |¡}t dd|¡}ˆj	 
|¡ ¡ \}}ˆj |¡}	dd„ |	D ƒ}
g }g }g }d}|
D ]E}ˆj |¡ ¡ \}||kr|||ƒ}|r~| |¡ | |¡ ˆj |¡ ¡ \}| |¡ qP| |¡ | ¡  |¡s•| |¡ | |¡ qPtt||ƒƒ}| |¡‰ d	d
„ }ˆ s­dd
„ }nˆ |kr¸‡ ‡fdd
„}g }|D ]}ˆj |¡}|d urÔ| ¡ d |krÔ||ƒ}|rÛ| |¡ q¼|d }t dt |¡ tj¡}| d| |¡}d |¡}ttdƒt|ƒgƒtd| ¡ |f ƒg}ttdƒt|ƒtdd„ |D ƒƒtdƒtdd„ |D ƒƒtdƒt|ƒfƒ}ttdƒt|ƒgƒ}|||ˆ  ||¡g7 }t!dd
„ |ƒD ]*}||j"v�r^| t|j#ƒ¡ �qLˆ �ruˆ $|j#|ˆ ¡}|d u�ru| t|ƒ¡ �qL|S )Nc                 s   s   � | ]}|j  ¡ V  qd S r   )r4   r  rx   r   r   r   r    s   € ÿz0SqliteMigrator._update_column.<locals>.<genexpr>z"Column "%s" does not exist on "%s"z\s+rq   c                 S   s   g | ]}|  ¡ ‘qS r   ©Ústrip©ry   Úcolr   r   r   rz   3  r{   z1SqliteMigrator._update_column.<locals>.<listcomp>)zforeign zprimary zconstraint zcheck zunique c                 S   s   | S r   r   ©r  r   r   r   Ú<lambda>R  ó    z/SqliteMigrator._update_column.<locals>.<lambda>c                 S   rö   r   r   r%  r   r   r   r&  U  r'  c                    s   ˆj  dˆ  | ¡S )NzFOREIGN KEY ("%s") )Úfk_reÚsubr%  ©Ú
new_columnr   r   r   r&  X  s    þr   Ú__tmp__z("?)%s("?)\s*$z\1%s\2ú, zDROP TABLE IF EXISTSz%s (%s)zINSERT INTOc                 S   rw   r   r   r#  r   r   r   rz   u  r{   ÚSELECTc                 S   rw   r   r   r#  r   r   r   rz   w  r{   ÚFROMz
DROP TABLEc                 S   s   | j S r   )rY   )Úidxr   r   r   r&  „  s    )%Úsetr   Úget_columnsr  r3   r   Úget_indexesÚrer)  Ú	column_reÚsearchÚgroupsÚcolumn_split_reÚfindallÚcolumn_name_reÚmatchr—   Ú
startswithr  ÚzipÚgetr(  ÚcompileÚescapeÚIr7   r   r|   r   r"  r   r   rÅ   Úfilterr9   rY   Ú
_fix_index)r   r?   Úcolumn_to_updater   r9   Úcreate_tableÚindexesÚ
raw_createÚraw_columnsÚsplit_columnsÚcolumn_defsÚnew_column_defsÚnew_column_namesÚoriginal_column_namesÚconstraint_termsr  r\   Únew_column_defÚoriginal_to_newÚfk_filter_fnÚcleaned_columnsr;  Ú
temp_tableÚrgxÚcreateÚqueriesÚpopulate_tableÚdrop_originalr˜   rY   r   r*  r   Ú_update_column  sª   
ÿÿ


ÿÿ
€


€


€þ
þù
ý
€zSqliteMigrator._update_columnc           
      C   sÚ   |  |¡}t|ƒdkr| ||¡S | dd¡\}}t|  |¡ƒdkr,d|| ||¡f S | dd¡d   d¡}dd	„ |D ƒ}g }|D ]}	t d
t |¡ |	¡rY||	t|ƒd …  }	| |	¡ qBd|d dd„ |D ƒ¡f S )Né   ú(rå   z%s(%sr�   r   ú,c                 S   s   g | ]}|  d ¡‘qS )z"`[]' r!  )ry   Úpartr   r   r   rz      s    z-SqliteMigrator._fix_index.<locals>.<listcomp>z%s(?:[\'"`\]]?\s|$)z%s(%s)r-  c                 s   s   � | ]}d | V  qdS )z"%s"Nr   )ry   rÉ   r   r   r   r  ¬  s   € z,SqliteMigrator._fix_index.<locals>.<genexpr>)	Úsplitrç   ÚreplaceÚrsplitr4  r;  r@  r—   r7   )
r   rY   rD  r+  r  ÚlhsÚrhsr9   Úcleanrf   r   r   r   rC  Ž  s    
ÿzSqliteMigrator._fix_indexc                 C   sH   | j dkr|s|  ¡ }|  ||¡ d¡ t|ƒ¡ |S |  ||dd„ ¡S )N)é   é#   r   r§   c                 S   rö   r   r   )ÚaÚbr   r   r   r&  ¶  r'  z,SqliteMigrator.drop_column.<locals>.<lambda>)r  rI   ra   rX   rY   r   rY  )r   r?   r\   r¬   Úlegacyr`   r   r   r   r®   ®  s   
zSqliteMigrator.drop_columnc                    sX   | j dkr|s|  |  ¡ |¡ d¡ t|ƒ¡ d¡ tˆ ƒ¡S ‡ fdd„}|  |||¡S )N)rd  é   r   r¯   r°   c                    s    t jdt  | ¡ dˆ  |dd�S )Nz(["\'`]?)%s\1z	\g<1>%s\1rå   )Úcount)r4  r)  r@  ©r\   r  ©r²   r   r   Ú_renameÁ  s   üz-SqliteMigrator.rename_column.<locals>._rename)r  ra   rI   rX   rY   r   rY  )r   r?   r±   r²   rh  rm  r   rl  r   r³   ¸  s   

û	zSqliteMigrator.rename_columnc                    ó6   | j dkr|stt| ƒ ||¡S dd„ }|  |||¡S )N©rd  é5   r   c                 S   s   |d S )Nz	 NOT NULLr   rk  r   r   r   Ú_add_not_nullÑ  s   z2SqliteMigrator.add_not_null.<locals>._add_not_null)r  ræ   rS   r•   rY  )r   r?   rf   rh  rq  rî   r   r   r•   Ì  ó   zSqliteMigrator.add_not_nullc                    rn  )Nro  c                 S   s   |  dd¡S )Nr  Ú )r_  rk  r   r   r   Ú_drop_not_nullÚ  s   z4SqliteMigrator.drop_not_null.<locals>._drop_not_null)r  ræ   rS   r¸   rY  )r   r?   rf   rh  rt  rî   r   r   r¸   Õ  rr  zSqliteMigrator.drop_not_nullc                    sd   ˆ d u rt dƒ‚tˆ ƒrˆ ƒ ‰ tˆ tƒr%ˆ  d¡s%ˆ  ¡ s%dˆ  dd¡ ‰ ‡ fdd„}|  |||¡S )Nr¹   rº   z'%s'r»   z''c                    s   |dˆ   S )Nz DEFAULT %sr   rk  ©rW   r   r   Ú_add_defaultç  s   z7SqliteMigrator.add_column_default.<locals>._add_default)r3   r   r   r¼   r½   Úisdigitr_  rY  )r   r?   rf   rW   rv  r   ru  r   r¾   Þ  s   ÿz!SqliteMigrator.add_column_defaultc                 C   s   dd„ }|   |||¡S )Nc                 S   s   t jdd|t jd�}| ¡ S )NzDEFAULT\s+[\w"\'\(\)]+(\s|$)rs  )Úflags)r4  r)  rA  r"  )r\   r  r$  r   r   r   Ú_drop_defaultî  s   
ÿz9SqliteMigrator.drop_column_default.<locals>._drop_default)rY  )r   r?   rf   ry  r   r   r   r¿   ì  s   z"SqliteMigrator.drop_column_defaultNc                    s6   |d urt dƒ‚|  ¡ ‰‡ ‡‡fdd„}|  |ˆ |¡S )Nz6alter_column_type() does not support cast with Sqlite.c                    s*   ˆ  ˆ¡}ˆ tˆ ƒ¡ |¡ ¡ \}}|S r   )rj   rY   r   rÝ   )r\   r  Ú	node_listrY   r6   ©rf   r`   r]   r   r   Ú_alter_column_typeú  s   
z<SqliteMigrator.alter_column_type.<locals>._alter_column_type)r3   rI   rY  )r   r?   rf   r]   rÂ   r|  r   r{  r   rÃ   ô  s
   z SqliteMigrator.alter_column_typec                    s"   | j dkrtt| ƒ |||¡S t‚©Nro  )r  ræ   rS   ru   r¥   rs   rî   r   r   ru      s
   

ÿzSqliteMigrator.add_constraintc                    s    | j dkrtt| ƒ ||¡S t‚r}  )r  ræ   rS   rƒ   r¥   r‚   rî   r   r   rƒ     s   
zSqliteMigrator.drop_constraintc                    s   |rt ‚tt| ƒj|||d�S )NrJ   )r¥   ræ   rS   rÈ   )r   r?   rÇ   r¬   r>   rî   r   r   rÈ     s
   ÿzSqliteMigrator.drop_tablec                 G   r£   r   r¤   )r   r?   r}   r   r   r   r     ó   zSqliteMigrator.add_uniquec                 C   r£   r   r¤   )r   r?   r\   r]   rŠ   r‹   r   r   r   r‘     r~  z)SqliteMigrator.add_foreign_key_constraintrØ   )TFrÙ   r   rÚ   r  ) r(   r)   r*   r+   r<   r4  r?  r5  r8  r:  rA  r(  r   r   rG   r   r1   rY  rC  r®   r³   r•   r¸   r¾   r¿   rÃ   ru   rƒ   rÈ   r   r‘   rõ   r   r   rî   r   rS   ÷  sN    



q 	


ÿrS   c                  O   s   | D ]}|  ¡  qd S r   rA   )rB   r   r1   r   r   r   rC      rD   rC   )"r+   Úcollectionsr   Ú
contextlibr   r/   r4  Úpeeweer   r   r   r	   r
   r   r   r   r   r   r   Úplayhouse.cockroachdbr   ÚImportErrorÚobjectr   r1   r5   r:   r;   rO   rM   rù   rQ   rS   rC   r   r   r   r   Ú<module>   sL    tÿ  T:#   +