B
    CVvgL  ã               @   sh  d dl Z d dlmZ d dlmZmZ d dlmZmZm	Z	 d dl
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gZG dd„ deeƒZdHd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ƒZG dd„ deƒZG dd„ deƒZG dd„ dejƒZ e !e¡ e !e¡ e !e¡ e !e¡ e !e¡ e !e ¡ G dd„ deƒZ"G d d!„ d!e"ƒZ#G d"d#„ d#ƒZ$G d$d%„ d%ƒZ%G d&d'„ d'ej&ƒZ'G d(d)„ d)ej(ƒZ)G d*d+„ d+e ƒZ*G d,d-„ d-e%e$ej+ƒZ,G d.d/„ d/e%e$ej-ƒZ.G d0d1„ d1e$ej/ƒZ0G d2d3„ d3e%e$ej1ƒZ2G d4d5„ d5e$ej3ƒZ4G d6d7„ d7e%e$ej5ƒZ6G d8d9„ d9e$ej7ƒZ8G d:d;„ d;e%e$ej9ƒZ:G d<d=„ d=ƒZ;G d>d?„ d?e;ej<ƒZ=G d@dA„ dAe;ej>ƒZ?G dBdC„ dCe;ej@ƒZAG dDdE„ dEe;ejBƒZCe" !e)¡ e" !e*¡ e" !e,¡ e" !e'¡ e" !e.¡ e" !e0¡ e" !e2¡ e" !e4¡ e" !e6¡ e" !e8¡ e" !e:¡ e" !e=¡ e" !e?¡ e" !eA¡ e" !eC¡ G dFdG„ dGƒZDdS )Ié    N)Úforms)ÚchecksÚ
exceptions)ÚNotSupportedErrorÚconnectionsÚrouter)Úlookups)ÚPostgresOperatorLookupÚ	Transform)Úgettext_lazyé   )ÚField)ÚCheckFieldDefaultMixinÚ	JSONFieldc                   sž   e Zd ZdZedƒZdedƒiZdZd‡ fdd„	Z‡ fd	d
„Z	dd„ Z
‡ fdd„Zdd„ Zdd„ Zdd„ Z‡ fdd„Z‡ fdd„Zdd„ Z‡ fdd„Z‡  ZS )r   FzA JSON objectÚinvalidzValue must be valid JSON.)Údictz{}Nc                sJ   |rt |ƒstdƒ‚|r(t |ƒs(tdƒ‚|| _|| _tƒ j||f|Ž d S )Nz0The encoder parameter must be a callable object.z0The decoder parameter must be a callable object.)ÚcallableÚ
ValueErrorÚencoderÚdecoderÚsuperÚ__init__)ÚselfZverbose_nameÚnamer   r   Úkwargs)Ú	__class__© ú@/tmp/pip-install-o3oxmrkh/Django/django/db/models/fields/json.pyr      s    zJSONField.__init__c                s0   t ƒ jf |Ž}| d¡pg }| |  |¡¡ |S )NÚ	databases)r   ÚcheckÚgetÚextendÚ_check_supported)r   r   Úerrorsr   )r   r   r   r   $   s    zJSONField.checkc             C   s~   g }xt|D ]l}t  || j¡sq
t| }| jjjrB| jjj|jkrBq
d| jjjks
|jj	s
| 
tjd|j | jdd�¡ q
W |S )NÚsupports_json_fieldz%s does not support JSONFields.zfields.E180)ÚobjÚid)r   Zallow_migrate_modelÚmodelr   Z_metaZrequired_db_vendorÚvendorZrequired_db_featuresÚfeaturesr$   Úappendr   ÚErrorZdisplay_name)r   r   r#   ÚdbÚ
connectionr   r   r   r"   *   s"    

zJSONField._check_supportedc                sF   t ƒ  ¡ \}}}}| jd k	r&| j|d< | jd k	r:| j|d< ||||fS )Nr   r   )r   Údeconstructr   r   )r   r   ÚpathÚargsr   )r   r   r   r.   C   s    



zJSONField.deconstructc             C   sP   |d kr|S t |tƒr$t |tƒs$|S ytj|| jd�S  tjk
rJ   |S X d S )N)Úcls)Ú
isinstanceÚKeyTransformÚstrÚjsonÚloadsr   ÚJSONDecodeError)r   ÚvalueZ
expressionr-   r   r   r   Úfrom_db_valueK   s    zJSONField.from_db_valuec             C   s   dS )Nr   r   )r   r   r   r   Úget_internal_typeW   s    zJSONField.get_internal_typec             C   s   |d kr|S t j|| jd�S )N)r1   )r5   Údumpsr   )r   r8   r   r   r   Úget_prep_valueZ   s    zJSONField.get_prep_valuec                s   t ƒ  |¡}|r|S t|ƒS )N)r   Úget_transformÚKeyTransformFactory)r   r   Z	transform)r   r   r   r=   _   s    zJSONField.get_transformc                sV   t ƒ  ||¡ ytj|| jd� W n. tk
rP   tj| jd dd|id�‚Y nX d S )N)r1   r   r8   )ÚcodeÚparams)	r   Úvalidater5   r;   r   Ú	TypeErrorr   ZValidationErrorZerror_messages)r   r8   Zmodel_instance)r   r   r   rA   e   s    zJSONField.validatec             C   s
   |   |¡S )N)Zvalue_from_object)r   r%   r   r   r   Úvalue_to_stringp   s    zJSONField.value_to_stringc                s    t ƒ jf tj| j| jdœ|–ŽS )N)Z
form_classr   r   )r   Ú	formfieldr   r   r   r   )r   r   )r   r   r   rD   s   s
    zJSONField.formfield)NNNN)Ú__name__Ú
__module__Ú__qualname__Zempty_strings_allowedÚ_ÚdescriptionZdefault_error_messagesZ_default_hintr   r   r"   r.   r9   r:   r<   r=   rA   rC   rD   Ú__classcell__r   r   )r   r   r      s   Tc          	   C   sp   |r
dgng }xV| D ]N}yt |ƒ}W n. tk
rR   | d¡ | t |¡¡ Y qX | d| ¡ qW d |¡S )Nú$Ú.z[%s]Ú )Úintr   r*   r5   r;   Újoin)Úkey_transformsÚinclude_rootr/   Úkey_transformÚnumr   r   r   Úcompile_json_path|   s    

rT   c               @   s   e Zd ZdZdZdd„ ZdS )ÚDataContainsÚcontainsz@>c             C   sP   |j jstdƒ‚|  ||¡\}}|  ||¡\}}t|ƒt|ƒ }d||f |fS )Nz:contains lookup is not supported on this database backend.zJSON_CONTAINS(%s, %s))r)   Úsupports_json_field_containsr   Úprocess_lhsÚprocess_rhsÚtuple)r   Úcompilerr-   ÚlhsÚ
lhs_paramsÚrhsÚ
rhs_paramsr@   r   r   r   Úas_sql�   s    zDataContains.as_sqlN)rE   rF   rG   Úlookup_nameÚpostgres_operatorr`   r   r   r   r   rU   ‰   s   rU   c               @   s   e Zd ZdZdZdd„ ZdS )ÚContainedByZcontained_byz<@c             C   sP   |j jstdƒ‚|  ||¡\}}|  ||¡\}}t|ƒt|ƒ }d||f |fS )Nz>contained_by lookup is not supported on this database backend.zJSON_CONTAINS(%s, %s))r)   rW   r   rX   rY   rZ   )r   r[   r-   r\   r]   r^   r_   r@   r   r   r   r`   œ   s    zContainedBy.as_sqlN)rE   rF   rG   ra   rb   r`   r   r   r   r   rc   ˜   s   rc   c                   sB   e Zd ZdZddd„Zdd„ Zdd„ Z‡ fdd	„Zd
d„ Z‡  Z	S )ÚHasKeyLookupNc          	   C   sä   t | jtƒr*| j ||¡\}}}t|ƒ}n|  ||¡\}}d}|| }| j}	g }
t |	ttfƒsd|	g}	xJ|	D ]B}t |tƒrŒ| ||¡�^ }}n|g}|
 	d|t|dd�f ¡ qjW | j
rÐd| j
 |gt|
ƒ ¡ }|t|ƒt|
ƒ fS )NrK   z%s%sF)rQ   z(%s))r2   r\   r3   Úpreprocess_lhsrT   rX   r^   ÚlistrZ   r*   Úlogical_operatorrO   Úlen)r   r[   r-   Útemplater\   r]   Zlhs_key_transformsZlhs_json_pathÚsqlr^   r_   ÚkeyrH   Úrhs_key_transformsr   r   r   r`   ª   s(    


zHasKeyLookup.as_sqlc             C   s   | j ||dd�S )Nz"JSON_CONTAINS_PATH(%s, 'one', %%s))ri   )r`   )r   r[   r-   r   r   r   Úas_mysqlÆ   s    zHasKeyLookup.as_mysqlc             C   s$   | j ||dd�\}}|t|ƒ g fS )NzJSON_EXISTS(%s, '%%s'))ri   )r`   rZ   )r   r[   r-   rj   r@   r   r   r   Ú	as_oracleÉ   s    zHasKeyLookup.as_oraclec                s\   t | jtƒrN| j ||¡�^ }}x"|d d… D ]}t|| jƒ| _q.W |d | _tƒ  ||¡S )Néÿÿÿÿ)r2   r^   r3   re   r\   r   Úas_postgresql)r   r[   r-   rH   rl   rk   )r   r   r   rp   Ï   s    
zHasKeyLookup.as_postgresqlc             C   s   | j ||dd�S )NzJSON_TYPE(%s, %%s) IS NOT NULL)ri   )r`   )r   r[   r-   r   r   r   Ú	as_sqlite×   s    zHasKeyLookup.as_sqlite)N)
rE   rF   rG   rg   r`   rm   rn   rp   rq   rJ   r   r   )r   r   rd   §   s   
rd   c               @   s   e Zd ZdZdZdZdS )ÚHasKeyZhas_keyú?FN)rE   rF   rG   ra   rb   Zprepare_rhsr   r   r   r   rr   Û   s   rr   c               @   s    e Zd ZdZdZdZdd„ ZdS )ÚHasKeysZhas_keysz?&z AND c             C   s   dd„ | j D ƒS )Nc             S   s   g | ]}t |ƒ‘qS r   )r4   )Ú.0Úitemr   r   r   ú
<listcomp>ç   s    z+HasKeys.get_prep_lookup.<locals>.<listcomp>)r^   )r   r   r   r   Úget_prep_lookupæ   s    zHasKeys.get_prep_lookupN)rE   rF   rG   ra   rb   rg   rx   r   r   r   r   rt   á   s   rt   c               @   s   e Zd ZdZdZdZdS )Ú
HasAnyKeysZhas_any_keysz?|z OR N)rE   rF   rG   ra   rb   rg   r   r   r   r   ry   ê   s   ry   c                   s,   e Zd ZdZ‡ fdd„Z‡ fdd„Z‡  ZS )Ú	JSONExactTc                sP   t ƒ  ||¡\}}|jdkrHt ƒ  ||¡\}}|dkrH|d gkrHd| }||fS )NÚsqlitez%szJSON_TYPE(%s, '$'))r   rX   r(   rY   )r   r[   r-   r\   r]   r^   r_   )r   r   r   rX   ó   s    
zJSONExact.process_lhsc                sV   t ƒ  ||¡\}}|dkr*|d gkr*dg}|jdkrNdgt|ƒ }|t|ƒ }||fS )Nz%sÚnullÚmysqlzJSON_EXTRACT(%s, '$'))r   rY   r(   rh   rZ   )r   r[   r-   r^   r_   Úfunc)r   r   r   rY   ü   s    
zJSONExact.process_rhs)rE   rF   rG   Zcan_use_none_as_rhsrX   rY   rJ   r   r   )r   r   rz   ð   s   	rz   c                   sL   e Zd ZdZdZ‡ fdd„Zdd„ Zdd„ Zd	d
„ Zdd„ Z	dd„ Z
‡  ZS )r3   z->z#>c                s   t ƒ j||Ž t|ƒ| _d S )N)r   r   r4   Úkey_name)r   r   r0   r   )r   r   r   r     s    zKeyTransform.__init__c             C   sb   | j g}| j}x"t|tƒr0| d|j ¡ |j}qW | |¡\}}|jdkrXdd„ |D ƒ}|||fS )Nr   Úoraclec             S   s   g | ]}|  d d¡‘qS )ú%z%%)Úreplace)ru   rk   r   r   r   rw      s    z/KeyTransform.preprocess_lhs.<locals>.<listcomp>)r   r\   r2   r3   ÚinsertÚcompiler(   )r   r[   r-   rP   Úpreviousr\   r@   r   r   r   re     s    

zKeyTransform.preprocess_lhsc             C   s0   |   ||¡\}}}t|ƒ}d| t|ƒ|f fS )NzJSON_EXTRACT(%s, %%s))re   rT   rZ   )r   r[   r-   r\   r@   rP   Ú	json_pathr   r   r   rm   #  s    zKeyTransform.as_mysqlc             C   s6   |   ||¡\}}}t|ƒ}d||fd  t|ƒd fS )Nz4COALESCE(JSON_QUERY(%s, '%s'), JSON_VALUE(%s, '%s'))é   )re   rT   rZ   )r   r[   r-   r\   r@   rP   r†   r   r   r   rn   (  s
    zKeyTransform.as_oraclec             C   s„   |   ||¡\}}}t|ƒdkr>d|| jf }|t|ƒ|f fS yt| jƒ}W n tk
rf   | j}Y nX d|| jf t|ƒ|f fS )Nr   z(%s %s %%s))re   rh   Úpostgres_nested_operatorrZ   rN   r   r   rb   )r   r[   r-   r\   r@   rP   rj   Úlookupr   r   r   rp   0  s    zKeyTransform.as_postgresqlc             C   s0   |   ||¡\}}}t|ƒ}d| t|ƒ|f fS )NzJSON_EXTRACT(%s, %%s))re   rT   rZ   )r   r[   r-   r\   r@   rP   r†   r   r   r   rq   ;  s    zKeyTransform.as_sqlite)rE   rF   rG   rb   rˆ   r   re   rm   rn   rp   rq   rJ   r   r   )r   r   r3     s   r3   c               @   s   e Zd ZdZdZdS )ÚKeyTextTransformz->>z#>>N)rE   rF   rG   rb   rˆ   r   r   r   r   rŠ   A  s   rŠ   c                   s    e Zd ZdZ‡ fdd„Z‡  ZS )ÚKeyTransformTextLookupMixinzö
    Mixin for combining with a lookup expecting a text lhs from a JSONField
    key lookup. On PostgreSQL, make use of the ->> operator instead of casting
    key values to text and performing the lookup on the resulting
    representation.
    c                s@   t |tƒstdƒ‚t|jf|jž|jŽ}tƒ j|f|ž|Ž d S )NzLTransform should be an instance of KeyTransform in order to use this lookup.)	r2   r3   rB   rŠ   r   Zsource_expressionsÚextrar   r   )r   rR   r0   r   Zkey_text_transform)r   r   r   r   M  s    
z$KeyTransformTextLookupMixin.__init__)rE   rF   rG   Ú__doc__r   rJ   r   r   )r   r   r‹   F  s   r‹   c                   s,   e Zd ZdZ‡ fdd„Z‡ fdd„Z‡  ZS )ÚCaseInsensitiveMixinzý
    Mixin to allow case-insensitive comparison of JSON values on MySQL.
    MySQL handles strings used in JSON context using the utf8mb4_bin collation.
    Because utf8mb4_bin is a binary collation, comparison of JSON values is
    case-sensitive.
    c                s0   t ƒ  ||¡\}}|jdkr(d| |fS ||fS )Nr}   z	LOWER(%s))r   rX   r(   )r   r[   r-   r\   r]   )r   r   r   rX   a  s    
z CaseInsensitiveMixin.process_lhsc                s0   t ƒ  ||¡\}}|jdkr(d| |fS ||fS )Nr}   z	LOWER(%s))r   rY   r(   )r   r[   r-   r^   r_   )r   r   r   rY   g  s    
z CaseInsensitiveMixin.process_rhs)rE   rF   rG   r�   rX   rY   rJ   r   r   )r   r   rŽ   Z  s   rŽ   c               @   s   e Zd Zdd„ Zdd„ ZdS )ÚKeyTransformIsNullc             C   s\   t | jj| jjƒ ||¡\}}| js,||fS | j ||¡\}}}d||f t|ƒt|ƒ fS )Nz(NOT %s OR %s IS NULL))rr   r\   r   rn   r^   re   rZ   )r   r[   r-   rj   r@   r\   r]   rH   r   r   r   rn   p  s    
zKeyTransformIsNull.as_oraclec             C   s,   d}| j sd}t| jj| jjƒj|||d�S )NzJSON_TYPE(%s, %%s) IS NULLzJSON_TYPE(%s, %%s) IS NOT NULL)ri   )r^   rr   r\   r   r`   )r   r[   r-   ri   r   r   r   rq   {  s    zKeyTransformIsNull.as_sqliteN)rE   rF   rG   rn   rq   r   r   r   r   r�   n  s   r�   c                   s   e Zd Z‡ fdd„Z‡  ZS )ÚKeyTransformInc                s�   t ƒ  ||||¡\}}t|dƒsp|jjsp|jdkrbt |¡}d}t|t	t
fƒrX|d }qp|d }n|jdkrpd}|jdkrˆ|jrˆd	| }||fS )
Nr`   r€   z9%s(JSON_OBJECT('value' VALUE %%s FORMAT JSON), '$.value')Ú
JSON_QUERYÚ
JSON_VALUE>   r}   r{   zJSON_EXTRACT(%s, '$')r}   zJSON_UNQUOTE(%s))r   Úresolve_expression_parameterÚhasattrr)   Úhas_native_json_fieldr(   r5   r6   r2   rf   r   Zmysql_is_mariadb)r   r[   r-   rj   Úparamr@   r8   )r   r   r   r“   ‡  s    





z+KeyTransformIn.resolve_expression_parameter)rE   rF   rG   r“   rJ   r   r   )r   r   r�   †  s   r�   c                   s4   e Zd Z‡ fdd„Z‡ fdd„Z‡ fdd„Z‡  ZS )ÚKeyTransformExactc                sb   t ƒ  ||¡\}}|jdkrZt ƒ  ||¡\}}|dkrZ|dgkrZ| j ||¡^}}d| }||fS )Nr{   z%sr|   zJSON_TYPE(%s, %%s))r   rX   r(   rY   r\   re   )r   r[   r-   r\   r]   r^   r_   rH   )r   r   r   rX   ž  s    
zKeyTransformExact.process_lhsc                sÂ   t | jtƒr ttj| ƒ ||¡S tƒ  ||¡\}}|jdkr–g }d}xB|D ]:}t 	|¡}t |t
tfƒrv| |d ¡ qJ| |d ¡ qJW |t|ƒ }n$|jdkrºdd„ |D ƒ}|t|ƒ }||fS )Nr€   z9%s(JSON_OBJECT('value' VALUE %%s FORMAT JSON), '$.value')r‘   r’   r{   c             S   s   g | ]}|d krdnd‘qS )r|   zJSON_EXTRACT(%s, '$')z%sr   )ru   r8   r   r   r   rw   ¶  s    z1KeyTransformExact.process_rhs.<locals>.<listcomp>)r2   r^   r3   r   r   ÚExactrY   r(   r5   r6   rf   r   r*   rZ   )r   r[   r-   r^   r_   r~   rj   r8   )r   r   r   rY   §  s     



zKeyTransformExact.process_rhsc                sŒ   t ƒ  ||¡\}}|dgkr~t| jj| jjƒ}| ||¡\}}| j d¡| jdƒ}| ||¡\}	}
d||	f t|ƒt|
ƒ fS t ƒ  ||¡S )Nr|   ZisnullTz	%s AND %s)	r   rY   rr   r\   r   rn   Z
get_lookupr`   rZ   )r   r[   r-   r^   r_   Zhas_key_exprZhas_key_sqlZhas_key_paramsZis_null_exprZis_null_sqlZis_null_params)r   r   r   rn   º  s    

zKeyTransformExact.as_oracle)rE   rF   rG   rX   rY   rn   rJ   r   r   )r   r   r—   �  s   	r—   c               @   s   e Zd ZdS )ÚKeyTransformIExactN)rE   rF   rG   r   r   r   r   r™   É  s   r™   c               @   s   e Zd ZdS )ÚKeyTransformIContainsN)rE   rF   rG   r   r   r   r   rš   Í  s   rš   c               @   s   e Zd ZdS )ÚKeyTransformStartsWithN)rE   rF   rG   r   r   r   r   r›   Ñ  s   r›   c               @   s   e Zd ZdS )ÚKeyTransformIStartsWithN)rE   rF   rG   r   r   r   r   rœ   Õ  s   rœ   c               @   s   e Zd ZdS )ÚKeyTransformEndsWithN)rE   rF   rG   r   r   r   r   r�   Ù  s   r�   c               @   s   e Zd ZdS )ÚKeyTransformIEndsWithN)rE   rF   rG   r   r   r   r   rž   Ý  s   rž   c               @   s   e Zd ZdS )ÚKeyTransformRegexN)rE   rF   rG   r   r   r   r   rŸ   á  s   rŸ   c               @   s   e Zd ZdS )ÚKeyTransformIRegexN)rE   rF   rG   r   r   r   r   r    å  s   r    c                   s   e Zd Z‡ fdd„Z‡  ZS )ÚKeyTransformNumericLookupMixinc                s0   t ƒ  ||¡\}}|jjs(dd„ |D ƒ}||fS )Nc             S   s   g | ]}t  |¡‘qS r   )r5   r6   )ru   r8   r   r   r   rw   í  s    z>KeyTransformNumericLookupMixin.process_rhs.<locals>.<listcomp>)r   rY   r)   r•   )r   r[   r-   r^   r_   )r   r   r   rY   ê  s    z*KeyTransformNumericLookupMixin.process_rhs)rE   rF   rG   rY   rJ   r   r   )r   r   r¡   é  s   r¡   c               @   s   e Zd ZdS )ÚKeyTransformLtN)rE   rF   rG   r   r   r   r   r¢   ñ  s   r¢   c               @   s   e Zd ZdS )ÚKeyTransformLteN)rE   rF   rG   r   r   r   r   r£   õ  s   r£   c               @   s   e Zd ZdS )ÚKeyTransformGtN)rE   rF   rG   r   r   r   r   r¤   ù  s   r¤   c               @   s   e Zd ZdS )ÚKeyTransformGteN)rE   rF   rG   r   r   r   r   r¥   ý  s   r¥   c               @   s   e Zd Zdd„ Zdd„ ZdS )r>   c             C   s
   || _ d S )N)r   )r   r   r   r   r   r     s    zKeyTransformFactory.__init__c             O   s   t | jf|ž|ŽS )N)r3   r   )r   r0   r   r   r   r   Ú__call__  s    zKeyTransformFactory.__call__N)rE   rF   rG   r   r¦   r   r   r   r   r>     s   r>   )T)Er5   Zdjangor   Zdjango.corer   r   Z	django.dbr   r   r   Zdjango.db.modelsr   Zdjango.db.models.lookupsr	   r
   Zdjango.utils.translationr   rH   rM   r   Zmixinsr   Ú__all__r   rT   rU   rc   rd   rr   rt   ry   r˜   rz   Zregister_lookupr3   rŠ   r‹   rŽ   ZIsNullr�   ZInr�   r—   ZIExactr™   Z	IContainsrš   Z
StartsWithr›   ZIStartsWithrœ   ZEndsWithr�   Z	IEndsWithrž   ÚRegexrŸ   ZIRegexr    r¡   ZLessThanr¢   ZLessThanOrEqualr£   ZGreaterThanr¤   ZGreaterThanOrEqualr¥   r>   r   r   r   r   Ú<module>   sx   l
4	





2,














