o
    ˷eN                     @   s  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dLd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ZG dd dZ G d d! d!ej!Z"G d"d# d#e ej#Z$e%e 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+ej)Z*G d,d- d-ej+Z,G d.d/ d/e"Z-G d0d1 d1e e(ej.Z/G d2d3 d3e e(ej#Z0G d4d5 d5e(ej1Z2G d6d7 d7e e(ej3Z4G d8d9 d9e(ej5Z6G d:d; d;e e(ej7Z8G d<d= d=e(ej9Z:G d>d? d?e e(ej;Z<G d@dA dAZ=G dBdC dCe=ej>Z?G dDdE dEe=ej@ZAG dFdG dGe=ejBZCG dHdI dIe=ejDZEe&%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 e&%eE G dJdK dKZFdS )M    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                    sN   |r
t |s
td|rt |std|| _|| _t j||fi | d S )Nz0The encoder parameter must be a callable object.z0The decoder parameter must be a callable object.)callable
ValueErrorencoderdecodersuper__init__)selfverbose_namenamer   r   kwargs	__class__ S/var/www/ideatree/venv/lib/python3.10/site-packages/django/db/models/fields/json.pyr      s   zJSONField.__init__c                    s4   t  jdi |}|dpg }|| | |S )N	databasesr   )r   checkgetextend_check_supported)r   r   errorsr    r   r   r   r!   (   s   zJSONField.checkc                 C   sz   g }|D ]6}t || jsqt| }| jjjr | jjj|jkr qd| jjjv s:|jj	s:|
tjd|j | jdd q|S )Nsupports_json_fieldz%s does not support JSONFields.zfields.E180)objid)r   allow_migrate_modelmodelr   _metarequired_db_vendorvendorrequired_db_featuresfeaturesr&   appendr   Errordisplay_name)r   r    r%   db
connectionr   r   r   r$   .   s*   zJSONField._check_supportedc                    sF   t   \}}}}| jd ur| j|d< | jd ur| j|d< ||||fS )Nr   r   )r   deconstructr   r   )r   r   pathargsr   r   r   r   r5   F   s   



zJSONField.deconstructc                 C   sP   |d u r|S t |trt |ts|S z	tj|| jdW S  tjy'   | Y S w Ncls)
isinstanceKeyTransformstrjsonloadsr   JSONDecodeError)r   value
expressionr4   r   r   r   from_db_valueN   s   zJSONField.from_db_valuec                 C   s   dS )Nr   r   r   r   r   r   get_internal_typeZ   s   zJSONField.get_internal_typec                 C   s   |d u r|S t j|| jdS r8   )r>   dumpsr   )r   rA   r   r   r   get_prep_value]   s   zJSONField.get_prep_valuec                    s   t  |}|r
|S t|S N)r   get_transformKeyTransformFactory)r   r   	transformr   r   r   rI   b   s   zJSONField.get_transformc                    sN   t  || ztj|| jd W d S  ty&   tj| jd dd|idw )Nr9   r   rA   )codeparams)	r   validater>   rF   r   	TypeErrorr   ValidationErrorerror_messages)r   rA   model_instancer   r   r   rN   h   s   zJSONField.validatec                 C   s
   |  |S rH   )value_from_object)r   r'   r   r   r   value_to_strings      
zJSONField.value_to_stringc                    s$   t  jdi tj| j| jd|S )N)
form_classr   r   r   )r   	formfieldr   r   r   r   )r   r   r   r   r   rW   v   s   
zJSONField.formfield)NNNN)__name__
__module____qualname__empty_strings_allowed_descriptiondefault_error_messages_default_hintr   r!   r$   r5   rC   rE   rG   rI   rN   rT   rW   __classcell__r   r   r   r   r      s*    Tc              	   C   sj   |rdgng }| D ]&}zt |}W n ty'   |d |t| Y q	w |d|  q	d|S )N$.z[%s] )intr   r0   r>   rF   join)key_transformsinclude_rootr6   key_transformnumr   r   r   compile_json_path   s   

rj   c                   @      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.JSON_CONTAINS(%s, %s)r/   supports_json_field_containsr   process_lhsprocess_rhstupler   compilerr4   lhs
lhs_paramsrhs
rhs_paramsrM   r   r   r   as_sql      zDataContains.as_sqlNrX   rY   rZ   lookup_namepostgres_operatorrz   r   r   r   r   rl          rl   c                   @   rk   )ContainedBy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.rn   ro   rt   r   r   r   rz      r{   zContainedBy.as_sqlNr|   r   r   r   r   r      r   r   c                       sJ   e Zd ZdZdd ZdddZdd Zdd	 Z fd
dZdd Z	  Z
S )HasKeyLookupNc                 C   s   dt | S )Nz.%s)r>   rF   r   rh   r   r   r   compile_json_path_final_key   s   z(HasKeyLookup.compile_json_path_final_keyc                 C   s   t | jtr| j||\}}}t|}n
| ||\}}d}|| }| j}	g }
t |	ttfs2|	g}	|	D ]-}t |trE|||^ }}n|g}|^ }}t|dd}|| 	|7 }|

||  q4| jrrd| j|gt|
  }|t|t|
 fS )Nra   Frg   z(%s))r;   rv   r<   preprocess_lhsrj   rq   rx   listrs   r   r0   logical_operatorre   len)r   ru   r4   templaterv   rw   lhs_key_transformslhs_json_pathsqlrx   ry   keyr\   rhs_key_transforms	final_keyrhs_json_pathr   r   r   rz      s.   



zHasKeyLookup.as_sqlc                 C      | j ||ddS )Nz"JSON_CONTAINS_PATH(%s, 'one', %%s)r   rz   r   ru   r4   r   r   r   as_mysql      zHasKeyLookup.as_mysqlc                 C   s$   | j ||dd\}}|t| g fS )NzJSON_EXISTS(%s, '%%s')r   )rz   rs   )r   ru   r4   r   rM   r   r   r   	as_oracle   s   
zHasKeyLookup.as_oraclec                    sX   t | jtr%| j||^ }}|d d D ]	}t|| j| _q|d | _t ||S )N)r;   rx   r<   r   rv   r   as_postgresql)r   ru   r4   r\   r   r   r   r   r   r      s   
zHasKeyLookup.as_postgresqlc                 C   r   )NJSON_TYPE(%s, %%s) IS NOT NULLr   r   r   r   r   r   	as_sqlite   r   zHasKeyLookup.as_sqliterH   )rX   rY   rZ   r   r   rz   r   r   r   r   r`   r   r   r   r   r      s    
r   c                   @      e Zd ZdZdZdZdS )HasKeyhas_key?FN)rX   rY   rZ   r}   r~   prepare_rhsr   r   r   r   r          r   c                   @   s    e Zd ZdZdZdZdd ZdS )HasKeyshas_keysz?&z AND c                 C   s   dd | j D S )Nc                 S      g | ]}t |qS r   )r=   ).0itemr   r   r   
<listcomp>       z+HasKeys.get_prep_lookup.<locals>.<listcomp>)rx   rD   r   r   r   get_prep_lookup   s   zHasKeys.get_prep_lookupN)rX   rY   rZ   r}   r~   r   r   r   r   r   r   r      s
    r   c                   @   r   )
HasAnyKeyshas_any_keysz?|z OR N)rX   rY   rZ   r}   r~   r   r   r   r   r   r      r   r   c                   @   s   e Zd Zdd ZdS )HasKeyOrArrayIndexc                 C   s   t |gddS )NFr   )rj   r   r   r   r   r     s   z.HasKeyOrArrayIndex.compile_json_path_final_keyN)rX   rY   rZ   r   r   r   r   r   r     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                    0   t  ||\}}|jdkrd| |fS ||fS Nmysqlz	LOWER(%s))r   rq   r-   )r   ru   r4   rv   rw   r   r   r   rq        
z CaseInsensitiveMixin.process_lhsc                    r   r   )r   rr   r-   r   ru   r4   rx   ry   r   r   r   rr     r   z CaseInsensitiveMixin.process_rhs)rX   rY   rZ   __doc__rq   rr   r`   r   r   r   r   r     s    r   c                           e Zd ZdZ fddZ  ZS )	JSONExactTc                    sV   t  ||\}}|dkr|d gkrdg}|jdkr'dgt| }|t| }||fS )N%snullr   JSON_EXTRACT(%s, '$'))r   rr   r-   r   rs   )r   ru   r4   rx   ry   funcr   r   r   rr     s   
zJSONExact.process_rhs)rX   rY   rZ   can_use_none_as_rhsrr   r`   r   r   r   r   r     s    r   c                   @      e Zd ZdS )JSONIContainsNrX   rY   rZ   r   r   r   r   r   )      r   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 )r<   z->z#>c                    s    t  j|i | t|| _d S rH   )r   r   r=   key_name)r   r   r7   r   r   r   r   r   :  s   zKeyTransform.__init__c                 C   sf   | j g}| j}t|tr|d|j  |j}t|ts||\}}|jdkr.dd |D }|||fS )Nr   oraclec                 S   s   g | ]}| d dqS )%z%%)replace)r   r   r   r   r   r   G  s    z/KeyTransform.preprocess_lhs.<locals>.<listcomp>)r   rv   r;   r<   insertcompiler-   )r   ru   r4   rf   previousrv   rM   r   r   r   r   >  s   



zKeyTransform.preprocess_lhsc                 C   s0   |  ||\}}}t|}d| t||f fS )NzJSON_EXTRACT(%s, %%s)r   rj   rs   r   ru   r4   rv   rM   rf   	json_pathr   r   r   r   J  s   zKeyTransform.as_mysqlc                 C   s6   |  ||\}}}t|}d||fd  t|d fS )Nz4COALESCE(JSON_QUERY(%s, '%s'), JSON_VALUE(%s, '%s'))   r   r   r   r   r   r   O  s   

zKeyTransform.as_oraclec                 C   s   |  ||\}}}t|dkrd|| jf }|t||f fS zt| j}W n ty2   | j}Y nw d|| jf t||f fS )Nr   z(%s %s %%s))r   r   postgres_nested_operatorrs   rd   r   r   r~   )r   ru   r4   rv   rM   rf   r   lookupr   r   r   r   W  s   
zKeyTransform.as_postgresqlc                 C   sT   |  ||\}}}t|}ddd |jjD }d||||f t||f d fS )N,c                 S   r   r   )repr)r   datatyper   r   r   r   f  r   z*KeyTransform.as_sqlite.<locals>.<listcomp>z](CASE WHEN JSON_TYPE(%s, %%s) IN (%s) THEN JSON_TYPE(%s, %%s) ELSE JSON_EXTRACT(%s, %%s) END)   )r   rj   re   opsjsonfield_datatype_valuesrs   )r   ru   r4   rv   rM   rf   r   datatype_valuesr   r   r   r   b  s   
zKeyTransform.as_sqlite)rX   rY   rZ   r~   r   r   r   r   r   r   r   r`   r   r   r   r   r<   6  s    r<   c                   @   s   e Zd ZdZdZdS )KeyTextTransformz->>z#>>N)rX   rY   rZ   r~   r   r   r   r   r   r   n  s    r   c                       r   )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                    sL   t |ts	tdt|jg|jR i |j}t j|g|R i | d S )NzLTransform should be an instance of KeyTransform in order to use this lookup.)	r;   r<   rO   r   r   source_expressionsextrar   r   )r   rh   r7   r   key_text_transformr   r   r   r   {  s   
z$KeyTransformTextLookupMixin.__init__)rX   rY   rZ   r   r   r`   r   r   r   r   r   s  s    r   c                   @      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))r   rv   r   r   rx   r   rs   )r   ru   r4   r   rM   rv   rw   r\   r   r   r   r     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 NULLr   r   )rx   r   rv   r   rz   )r   ru   r4   r   r   r   r   r     s   zKeyTransformIsNull.as_sqliteN)rX   rY   rZ   r   r   r   r   r   r   r     s    r   c                          e Zd Z fddZ  ZS )KeyTransformInc                    s   t  ||||\}}t|dsE|jjsE|jdkr1t|}d}t|t	t
fr,|d }n|d }n|jdksC|jdkrE|d |jjvrEd	}|jdkrQ|jrQd
| }||fS )Nrz   r   9%s(JSON_OBJECT('value' VALUE %%s FORMAT JSON), '$.value')
JSON_QUERY
JSON_VALUEr   sqliter   r   zJSON_UNQUOTE(%s))r   resolve_expression_parameterhasattrr/   has_native_json_fieldr-   r>   r?   r;   r   r   r   r   mysql_is_mariadb)r   ru   r4   r   paramrM   rA   r   r   r   r     s.   





z+KeyTransformIn.resolve_expression_parameter)rX   rY   rZ   r   r`   r   r   r   r   r         r   c                       s(   e Zd Z fddZ fddZ  ZS )KeyTransformExactc                    s   t | jtrttj| ||S t ||\}}|jdkrLg }d}|D ]}t	|}t |t
tfr:||d  q$||d  q$|t| }||fS |jdkrog }|D ]}||jjv rc|d qU|d qU|t| }||fS )Nr   r   r   r   r   r   r   )r;   rx   r<   r   r   Exactrr   r-   r>   r?   r   r   r0   rs   r   r   )r   ru   r4   rx   ry   r   r   rA   r   r   r   rr     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   isnullTz	%s AND %s)	r   rr   r   rv   r   r   
get_lookuprz   rs   )r   ru   r4   rx   ry   has_key_exprhas_key_sqlhas_key_paramsis_null_expris_null_sqlis_null_paramsr   r   r   r     s   

zKeyTransformExact.as_oracle)rX   rY   rZ   rr   r   r`   r   r   r   r   r     s    r   c                   @   r   )KeyTransformIExactNr   r   r   r   r   r         r   c                   @   r   )KeyTransformIContainsNr   r   r   r   r   r     r   r   c                   @   r   )KeyTransformStartsWithNr   r   r   r   r   r     r   r   c                   @   r   )KeyTransformIStartsWithNr   r   r   r   r   r     r   r   c                   @   r   )KeyTransformEndsWithNr   r   r   r   r   r     r   r   c                   @   r   )KeyTransformIEndsWithNr   r   r   r   r   r      r   r   c                   @   r   )KeyTransformRegexNr   r   r   r   r   r     r   r   c                   @   r   )KeyTransformIRegexNr   r   r   r   r   r   
  r   r   c                       r   )KeyTransformNumericLookupMixinc                    s0   t  ||\}}|jjsdd |D }||fS )Nc                 S   s   g | ]}t |qS r   )r>   r?   )r   rA   r   r   r   r     s    z>KeyTransformNumericLookupMixin.process_rhs.<locals>.<listcomp>)r   rr   r/   r   r   r   r   r   rr     s   z*KeyTransformNumericLookupMixin.process_rhs)rX   rY   rZ   rr   r`   r   r   r   r   r     r   r   c                   @   r   )KeyTransformLtNr   r   r   r   r   r     r   r   c                   @   r   )KeyTransformLteNr   r   r   r   r   r     r   r   c                   @   r   )KeyTransformGtNr   r   r   r   r   r      r   r   c                   @   r   )KeyTransformGteNr   r   r   r   r   r   $  r   r   c                   @   r   )rJ   c                 C   s
   || _ d S rH   )r   )r   r   r   r   r   r   ;  rU   zKeyTransformFactory.__init__c                 O   s   t | jg|R i |S rH   )r<   r   )r   r7   r   r   r   r   __call__>  s   zKeyTransformFactory.__call__N)rX   rY   rZ   r   r   r   r   r   r   rJ   :  s    rJ   )T)Gr>   djangor   django.corer   r   	django.dbr   r   r   django.db.modelsr   django.db.models.lookupsr	   r
   django.utils.translationr   r\   rc   r   mixinsr   __all__r   rj   rl   r   r   r   r   r   r   r   r   r   	IContainsr   register_lookupr<   r   r   IsNullr   Inr   r   IExactr   r   
StartsWithr   IStartsWithr   EndsWithr   	IEndsWithr   Regexr   IRegexr   r   LessThanr   LessThanOrEqualr   GreaterThanr   GreaterThanOrEqualr   rJ   r   r   r   r   <module>   s    
q@	






8
(


















