3
v^G                 @   s   d dl Z d dlmZ d dlZd dlmZmZmZ d dl	m
Z
 edejd Ze jdZdd	 ZG d
d dZG dd deZdS )    N)
namedtuple)BaseDatabaseIntrospection	FieldInfo	TableInfo)Indexr   pkz&^\s*(?:var)?char\s*\(\s*(\d+)\s*\)\s*$c             C   s    t j| }|rt|jdS dS )z8 Extract the size number from a "varchar(11)" type name    N)field_size_researchintgroup)namem r   L/usr/lib/python3.6/site-packages/django/db/backends/sqlite3/introspection.pyget_field_size   s    
r   c               @   s>   e Zd Zdddddddddddd	d
d
dddddZdd ZdS )FlexibleFieldLookupDictBooleanFieldSmallIntegerFieldPositiveSmallIntegerFieldIntegerFieldBigIntegerFieldPositiveIntegerFieldDecimalField
FloatField	TextField	CharFieldBinaryField	DateFieldDateTimeField	TimeField)boolbooleansmallintzsmallint unsignedZsmallintegerr   integerbigintzinteger unsigneddecimalrealtextcharZvarcharZblobdatedatetimetimec             C   s"   |j  jddd j }| j| S )N(r   r   )lowersplitstripbase_data_types_reverse)selfkeyr   r   r   __getitem__2   s    z#FlexibleFieldLookupDict.__getitem__N)__name__
__module____qualname__r1   r4   r   r   r   r   r      s&   r   c                   sv   e Zd Ze Z fddZdd Zdd Zf fddZd	d
 Z	dd Z
dd Zdd Zdd Zdd Zdd Z  ZS )DatabaseIntrospectionc                s$   t  j||}|jr |dkr dS |S )Nr   r   r   	AutoField>   r   r   r   )superget_field_typer   )r2   	data_typedescription
field_type)	__class__r   r   r;   :   s    z$DatabaseIntrospection.get_field_typec             C   s   |j d dd |j D S )z>Return a list of table and view names in the current database.z
            SELECT name, type FROM sqlite_master
            WHERE type in ('table', 'view') AND NOT name='sqlite_sequence'
            ORDER BY namec             S   s"   g | ]}t |d  |d d  qS )r   r   )r   ).0rowr   r   r   
<listcomp>J   s    z8DatabaseIntrospection.get_table_list.<locals>.<listcomp>)executefetchall)r2   cursorr   r   r   get_table_listB   s    z$DatabaseIntrospection.get_table_listc             C   s*   |j d| jjj|  dd |j D S )zi
        Return a description of the table with the DB-API cursor.description
        interface.
        zPRAGMA table_info(%s)c             S   s:   g | ]2\}}}}}}t ||d t|d d | ||dk	qS )Nr   )r   r   )r@   cidr   r<   Znotnulldefaultr   r   r   r   rB   S   s   z?DatabaseIntrospection.get_table_description.<locals>.<listcomp>)rC   
connectionops
quote_namerD   )r2   rE   
table_namer   r   r   get_table_descriptionL   s    z+DatabaseIntrospection.get_table_descriptionc             C   s   | j ||}||dgS )N)tablecolumn)get_primary_key_column)r2   rE   rL   Ztable_fieldsZpk_colr   r   r   get_sequencesZ   s    z#DatabaseIntrospection.get_sequencesc             C   s  i }|j d|g |j \}}|dkr*|S ||jdd |jd }x<|jdD ],}|j }|jdrnqTtjd|tj	}|sqTd	d
 |j
 D \}	}
|jdrtjd|tj	}|j
 d jd}n|j d jd}|j d|	g |j d }|d j }|jd|jd }}||d | }xZ|jdD ]L}|j }|jdrNq2|jddd jd}||
kr2||	f||< P q2W qTW |S )z
        Return a dictionary of {field_name: (field_name_other_table, other_table)}
        representing all relationships to the given table.
        zUSELECT sql, type FROM sqlite_master WHERE tbl_name = %s AND type IN ('table', 'view')viewr-   r   ),UNIQUEz$references (\S*) ?\(["|]?(.*)["|]?\)c             S   s   g | ]}|j d qS )")r0   )r@   sr   r   r   rB   }   s    z7DatabaseIntrospection.get_relations.<locals>.<listcomp>zFOREIGN KEYzFOREIGN KEY\s*\(([^\)]*)\).*r   rV   z1SELECT sql FROM sqlite_master WHERE tbl_name = %s )rC   fetchoneindexrindexr/   r0   
startswithrer
   IgroupsmatchrD   )r2   rE   rL   Z	relations
create_sql
table_typeresults
field_descr   rN   rO   
field_nameresultZother_table_resultsZliZriZ
other_descZ
other_namer   r   r   get_relations^   sD    


z#DatabaseIntrospection.get_relationsc             C   s   g }|j d|dg |j d j }||jdd |jd }x`t|jdD ]N\}}|j }|jdrlqPtj	d	|tj
}|sqP|jtd
d |j D  qPW |S )z
        Return a list of (column_name, referenced_table_name, referenced_column_name)
        for all key columns in given table.
        z?SELECT sql FROM sqlite_master WHERE tbl_name = %s AND type = %srN   r   r-   r   rS   rT   rU   z("(.*)".*references (.*) \(["|](.*)["|]\)c             s   s   | ]}|j d V  qdS )rV   N)r0   )r@   rW   r   r   r   	<genexpr>   s    z8DatabaseIntrospection.get_key_columns.<locals>.<genexpr>)rC   rY   r0   rZ   r[   	enumerater/   r\   r]   r
   r^   appendtupler_   )r2   rE   rL   key_columnsrc   Zfield_indexrd   r   r   r   r   get_key_columns   s    
 z%DatabaseIntrospection.get_key_columnsc       	      C   s   |j d|g |j }|dkr*td| |\}}|dkr>dS ||jdd |jd }xH|jdD ]:}|j }tjd	|}|rf|j	dr|j	dS |j	d
S qfW dS )z>Return the column name of the primary key for the given table.zUSELECT sql, type FROM sqlite_master WHERE tbl_name = %s AND type IN ('table', 'view')NzTable %s does not existrR   r-   r   rS   rT   z1(?:(?:["`\[])(.*)(?:["`\]])|(\w+)).*PRIMARY KEY.*   )
rC   rY   
ValueErrorrZ   r[   r/   r0   r]   r`   r   )	r2   rE   rL   rA   ra   rb   Z
fields_sqlrd   r   r   r   r   rP      s     "z,DatabaseIntrospection.get_primary_key_columnc       
      C   sh   i }|j d| jjj|  xF|j D ]:}|d d \}}}}}	|gdd||	fddd|d| < q&W |S )NzPRAGMA foreign_key_list(%s)   F)columnsprimary_keyuniqueforeign_keycheckrZ   zfk_%d)rC   rI   rJ   rK   rD   )
r2   rE   rL   constraintsrA   id__rN   from_tor   r   r   _get_foreign_key_constraints   s    z2DatabaseIntrospection._get_foreign_key_constraintsc             C   s  d }d }d }d }d}g }d}	g }
d}xX|D ]N}|j tjjdrL|d7 }n>|j tjjdrp|d8 }|dk rP n|dkr|j tjjdrP |d kr|j tjjd}|rq,|rz|d kr|jtjjtjjfkr|j}n |jtjjj	j
kr|jdd }|j tjjdrd	}|}nh|r||kr*|r,d}q,|jtjjtjjfkrP|j|j n(|jtjjj	j
kr|j|jdd  nd|d kr|jtjjtjjfkr|j}n"|jtjjj	j
kr|jdd }|j tjjdr|g}|j tjjd
rd	}	|}q,|	r,||kr|
r,d}	q,|jtjjtjjfkrD|j|kr||
j|j q,|jtjjj	j
kr,|jdd |kr,|
j|jdd  q,W |rd	|dd dddnd }|
rd	|
ddd ddnd }||||fS )NFr   r-   r   rS   rT   Z
CONSTRAINTrU   TZCHECK)rs   rq   rr   rt   ru   rZ   )ru   rq   rr   rs   rt   rZ   r|   r|   r|   r|   )r`   sqlparsetokensPunctuationZKeywordZttypeNamevalueLiteralStringZSymbolrj   )r2   r~   rq   tokenZis_constraint_definitionre   constraint_namers   Zunique_columnsru   Zcheck_columnsZbraces_deepZunique_braces_deepZcheck_braces_deepZunique_constraintZcheck_constraintr   r   r   &_parse_column_or_constraint_definition   s    



z<DatabaseIntrospection._parse_column_or_constraint_definitionc             C   s   t j|d }i }d}dd |j D }x|D ]}|jt jjdr.P q.W xv| j||\}}	}
}|	r|rp|	||< n|d7 }|	|d| < |
r|r|
||< n|d7 }|
|d| < |jt jjdrJP qJW |S )Nr   c             s   s   | ]}|j s|V  qd S )N)Zis_whitespace)r@   r   r   r   r   rh   <  s    zADatabaseIntrospection._parse_table_constraints.<locals>.<genexpr>r-   r   z__unnamed_constraint_%s__rS   )r}   parseflattenr`   r~   r   r   )r2   sqlrq   	statementrv   Zunnamed_constrains_indexr~   r   r   rs   ru   Z	end_tokenr   r   r   _parse_table_constraints6  s,    


z.DatabaseIntrospection._parse_table_constraintsc             C   s  i }y&|j d| jjj|f j d }W n tk
r>   Y n*X dd | j||D }|j| j|| |j d| jjj|  x|j	 D ]}|dd \}}}	|j d| jjj|  |j pd\}
|
sq|j d	| jjj|  xL|j	 D ]@\}}}||kr g d
t
|	dd
dd||< || d j| qW || d r|| d  rtj|| d< |
jdd jdd jd}dd |D }||| d< qW | j||}|r|gdd
dd
d
d|d< |j| j|| |S )zu
        Retrieve any constraints or keys (unique, pk, fk, check, index) across
        one or more columns.
        z<SELECT sql FROM sqlite_master WHERE type='table' and name=%sr   c             S   s   h | ]
}|j qS r   )r   )r@   infor   r   r   	<setcomp>e  s    z8DatabaseIntrospection.get_constraints.<locals>.<setcomp>zPRAGMA index_list(%s)N   z<SELECT sql FROM sqlite_master WHERE type='index' AND name=%szPRAGMA index_info(%s)FT)rq   rr   rs   rt   ru   rZ   rq   rZ   rs   typer-   r   rS   rT   c             S   s   g | ]}|j d rd ndqS )DESCASC)endswith)r@   r   r   r   r   rB     s    z9DatabaseIntrospection.get_constraints.<locals>.<listcomp>ordersZ__primary__)Nr|   )rC   rI   rJ   rK   rY   	TypeErrorrM   updater   rD   r!   rj   r   suffixr/   rP   r{   )r2   rE   rL   rv   Ztable_schemarq   rA   numberrZ   rs   r   Z
index_rankZcolumn_rankrO   Z
order_infor   Z	pk_columnr   r   r   get_constraintsT  sX    

z%DatabaseIntrospection.get_constraints)r5   r6   r7   r   Zdata_types_reverser;   rF   rM   rQ   rg   rm   rP   r{   r   r   r   __classcell__r   r   )r?   r   r8   7   s   
:Zr8   )r   )r]   collectionsr   r}   Z%django.db.backends.base.introspectionr   r   ZBaseFieldInfor   django.db.models.indexesr   _fieldscompiler	   r   r   r8   r   r   r   r   <module>   s   
	