U
    ad[                     @   s   d dl Z d dlmZ d dlmZ d dlmZ d dlmZm	Z	 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ZdZG dd deZdS )    N)
itemgetter)Path)call_command)BaseCommandCommandError)DEFAULT_DB_ALIASconnections)MigrationLoader)MigrationRecorder)timezone)signalcommandzmanagestate.jsondefaultc                   @   s   e Zd ZU dZd ZZdZeed< eed< e	ed< e
ed< dd Zed	d
 Ze	dddZe	dddZedddZedddZe	e	edddZedddZedddZdS )Commandz,Manage database state in the convenient way.Nmigrate_argsmigrate_optionsfilename	verbosityc                 C   s   |j dddd |j ddtdt dd	 |j d
dtdt dd |j ddtdt dd |j dddddd |j dddd |j dddd |j dddd |j d dd!d |j d"dd#d$d d S )%Naction)dumploadztAn action to do. Dump action saves applied migrations to a file. Load action applies migrations specified in a file.)choiceshelpstate?z@A name of a state. Usually a name of a git branch. Defaults to "")nargsr   r   z-dz
--databasez6Nominates a database to synchronize. Defaults to the "z" database.)r   r   z-fz
--filenamez!A file to write to. Defaults to "z	--noinputz
--no-inputstore_falseinteractivez^The argument for "migrate" command. Tells Django to NOT prompt the user for input of any kind.)r   destr   z--fake
store_truezYThe argument for "migrate" command. Mark migrations as run without actually running them.)r   r   z--fake-initiala   The argument for "migrate" command. Detect if tables already exist and fake-apply initial migrations if so. Make sure that the current database schema matches your initial migration before using this flag. Django will only check for an existing table name.z--planzaThe argument for "migrate" command. Shows a list of the migration actions that will be performed.z--run-syncdbzOThe argument for "migrate" command. Creates tables for apps without migrations.z--checkZcheck_unappliedz_The argument for "migrate" command. Exits with a non-zero status if unapplied migrations exist.)add_argumentDEFAULT_STATEr   DEFAULT_FILENAME)selfparser r%   U/tmp/pip-unpacked-wheel-portabvm/django_extensions/management/commands/managestate.pyadd_arguments   sp       
  
  
         zCommand.add_argumentsc                 O   s>   || _ || _|d | _t| | _|| _|| _t| || d S )Nr   )r   r   r   r   conndatabaser   getattr)r#   r   r)   r   r   argsoptionsr%   r%   r&   handleR   s    

zCommand.handle)r   c              	   C   sL   |   }||   | ||i | j| jd| d| j d dS )z"Save applied migrations to a file.zMigrations for state "z"" have been successfully saved to .N)get_migrated_appsupdateget_applied_migrationswritestdoutstyleSUCCESSr   )r#   r   migrated_appsr%   r%   r&   r   \   s    zCommand.dumpc                 C   s   |   |}|dkr$td| | j| j| jdkr@| jd ndd}| D ]X\}}| ||rhqR| jdkr| j	| j
d| d ||f| j}td|| qR| j	| j
d	| d
 dS )zApply migrations from a file.NzNo such state saved:    r   )r)   r   zApplying migrations for "r   migrateMigrations for "z!" have been successfully applied.)r8   )readgetr   r   r)   r   items
is_appliedr3   r2   r4   WARNINGr   r   r5   )r#   r   
migrationskwargsapp	migrationr+   r%   r%   r&   r   e   s"    

zCommand.load)returnc                 C   s@   t | jj}t|d}| jdkr<| jddt	|  |S )z!Installed apps having migrations.Zzeror7   zApps having migrations: z, )
r	   r(   r6   dictfromkeysr   r3   r2   joinsorted)r#   Zappsr6   r%   r%   r&   r/   ~   s
    
zCommand.get_migrated_appsc                 C   s>   | j r| j S t| j }t| tdd}t|| _ | j S )z,Installed apps with last applied migrations.r7   )key)_applied_migrationsr
   r(   Zapplied_migrationsrG   keysr   rD   )r#   r?   Zlast_appliedr%   r%   r&   r1      s    
zCommand.get_applied_migrations)rA   rB   rC   c                 C   sD   |   |}||kr@| jdkr<| j| jd| d dS dS )z7Check whether a migration for an app is applied or not.r7   r9   z" are already applied.TF)r1   r;   r   r3   r2   r4   r>   )r#   rA   rB   Zappliedr%   r%   r&   r=      s    

zCommand.is_appliedc              
   C   sV   t | j}| r| s*td| j t| j}t|W  5 Q R  S Q R X dS )zGet saved state from the file.zNo such file: N)r   r   existsis_filer   openjsonr   )r#   pathfiler%   r%   r&   r:      s
    
zCommand.read)datac              	   C   sj   z|   }W n tk
r$   i }Y nX |j|tt d t| jd}tj	||ddd W 5 Q R X dS )z.Write new data to the file using existent one.)Z
updated_atw   T)indent	sort_keysN)
r:   r   r0   strr   nowrM   r   rN   r   )r#   rQ   ZsavedrP   r%   r%   r&   r2      s    
zCommand.write)__name__
__module____qualname__r   r(   r)   rI   rD   __annotations__rV   intr'   r   r-   r   r   r/   r1   boolr=   r:   r2   r%   r%   r%   r&   r      s"   
6
			r   )rN   operatorr   pathlibr   Zdjango.core.managementr   Zdjango.core.management.baser   r   Z	django.dbr   r   Zdjango.db.migrations.loaderr	   Zdjango.db.migrations.recorderr
   Zdjango.utilsr   Z"django_extensions.management.utilsr   r"   r!   r   r%   r%   r%   r&   <module>   s   