o
    [hU]                     @   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mZ d dlmZ d dlmZ d dlmZ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dNddZG dd deeZG dd de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-e-j.Z/G d*d+ d+Z0G d,d- d-ej1Z2G d.d/ d/ej3Z4G d0d1 d1e(Z5G d2d3 d3e&e0ej6Z7G d4d5 d5e&e0ej)Z8G d6d7 d7e0ej9Z:G d8d9 d9e&e0ej;Z<G d:d; d;e0ej=Z>G d<d= d=e&e0ej?Z@G d>d? d?e0ejAZBG d@dA dAe&e0ejCZDG dBdC dCZEG dDdE dEeEejFZGG dFdG dGeEejHZIG dHdI dIeEejJZKG dJdK dKeEejLZMe,+e4 e,+e5 e,+e7 e,+e2 e,+e8 e,+e: e,+e< e,+e> e,+e@ e,+eB e,+eD e,+eG e,+eI e,+eK e,+eM G dLdM dMZNdS )O    N)forms)checks
exceptions)NotSupportedErrorconnectionsrouter)expressionslookups)
LOOKUP_SEP)	TextField)FieldGetDbPrepValueMixin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dZ f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__)selfZverbose_namenamer   r   kwargs	__class__ /home/ubuntu/experiments/live_experiments/Pythonexperiments/Otree/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   Zallow_migrate_modelmodelr   _metaZrequired_db_vendorvendorZrequired_db_featuresfeaturesr)   appendr   Errordisplay_name)r   r#   r(   db
connectionr!   r!   r"   r'   4   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   L   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_valueT   s   zJSONField.from_db_valuec                 C   s   dS )Nr   r!   r   r!   r!   r"   get_internal_type`   s   zJSONField.get_internal_typec                 C   s   |s|  |}|j|| jS N)Zget_prep_valueopsZadapt_json_valuer   )r   r@   r4   preparedr!   r!   r"   get_db_prep_valuec   s   
zJSONField.get_db_prep_valuec                    s@   |d u r|S t |tjr|jd u rt |jtrd }t ||S rE   )r:   r   Valuer@   output_fieldr   r   get_db_prep_save)r   r@   r4   r   r!   r"   rK   h   s   


zJSONField.get_db_prep_savec                    s   t  |}|r
|S t|S rE   )r   get_transformKeyTransformFactory)r   r   	transformr   r!   r"   rL   x   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 )Nr8   r   r@   )codeparams)	r   validater=   dumpsr   	TypeErrorr   ZValidationErrorZerror_messages)r   r@   Zmodel_instancer   r!   r"   rQ   ~   s   zJSONField.validatec                 C   s
   |  |S rE   )Zvalue_from_object)r   r*   r!   r!   r"   value_to_string      
zJSONField.value_to_stringc                    s$   t  jdi tj| j| jd|S )N)Z
form_classr   r   r!   )r   	formfieldr   r   r   r   )r   r   r   r!   r"   rV      s   
zJSONField.formfield)NNNN)F)__name__
__module____qualname__Zempty_strings_allowed_descriptionZdefault_error_messagesZ_default_hintr   r$   r'   r5   rB   rD   rH   rK   rL   rQ   rT   rV   __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=   rR   join)key_transformsinclude_rootr6   key_transformnumr!   r!   r"   compile_json_path   s   

rf   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/   Zsupports_json_field_containsr   process_lhsprocess_rhstupler   compilerr4   lhs
lhs_paramsrhs
rhs_paramsrP   r!   r!   r"   as_sql      zDataContains.as_sqlNrW   rX   rY   lookup_namepostgres_operatorru   r!   r!   r!   r"   rh          rh   c                   @   rg   )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.rj   rk   ro   r!   r!   r"   ru      rv   zContainedBy.as_sqlNrw   r!   r!   r!   r"   r{      rz   r{   c                       sZ   e Zd ZdZdd Zd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=   rR   r   rd   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}t |ttfs-|g}|D ].}t |tr@|||^ }	}
n|g}
|
^ }
}t|
dd}|| 	|7 }|||| fV  q/d S )Nr]   Frc   )
r:   rq   r;   preprocess_lhsrf   rl   rs   listrn   r~   )r   rp   r4   lhs_sqlrr   Zlhs_key_transformsZlhs_json_pathrs   keyrZ   rhs_key_transformsZ	final_keyrhs_json_pathr!   r!   r"   _as_sql_parts   s(   



zHasKeyLookup._as_sql_partsc                 C   s    | j rd| j | S d|S )Nz(%s)r_   )logical_operatorra   )r   partsr!   r!   r"   _combine_sql_parts   s   
zHasKeyLookup._combine_sql_partsc           	      C   sT   g }g }|  ||D ]\}}}|||df  |||g  q
| |t|fS )N%sr   r0   r&   r   rn   	r   rp   r4   templateZ	sql_partsrP   r   rr   r   r!   r!   r"   ru      s   zHasKeyLookup.as_sqlc                 C      | j ||ddS )Nz!JSON_CONTAINS_PATH(%s, 'one', %s)r   ru   r   rp   r4   r!   r!   r"   as_mysql      zHasKeyLookup.as_mysqlc           	      C   sR   d}g }g }|  ||D ]\}}}||||f  || q| |t|fS )Nu   JSON_EXISTS(%s, q'￿%s￿')r   r   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:   rs   r;   r   rq   r   as_postgresql)r   rp   r4   rZ   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_sqliterE   )rW   rX   rY   r   r~   r   r   ru   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 )HasKeyZhas_key?FN)rW   rX   rY   rx   ry   Zprepare_rhsr!   r!   r!   r"   r         r   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      g | ]}t |qS r!   )r<   ).0itemr!   r!   r"   
<listcomp>!      z+HasKeys.get_prep_lookup.<locals>.<listcomp>)rs   rC   r!   r!   r"   get_prep_lookup   s   zHasKeys.get_prep_lookupN)rW   rX   rY   rx   ry   r   r   r!   r!   r!   r"   r     s
    r   c                   @   r   )
HasAnyKeysZhas_any_keysz?|z OR N)rW   rX   rY   rx   ry   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   )rf   r}   r!   r!   r"   r~   +  s   z.HasKeyOrArrayIndex.compile_json_path_final_keyN)rW   rX   rY   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   rl   r.   )r   rp   r4   rq   rr   r   r!   r"   rl   7     
z CaseInsensitiveMixin.process_lhsc                    r   r   )r   rm   r.   r   rp   r4   rs   rt   r   r!   r"   rm   =  r   z CaseInsensitiveMixin.process_rhs)rW   rX   rY   __doc__rl   rm   r\   r!   r!   r   r"   r   /  s    r   c                       s(   e Zd ZdZ fddZ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 )Nr   nullr   JSON_EXTRACT(%s, '$'))r   rm   r.   lenrn   )r   rp   r4   rs   rt   funcr   r!   r"   rm   G  s   
zJSONExact.process_rhsc                 C   s`   |  ||\}}| ||\}}|jjr d| d}d| d}d| d| dg ||R fS )NzJSON()zJSON_EQUAL(z, z ERROR ON ERROR))rl   rm   r/   !supports_primitives_in_json_field)r   rp   r4   rq   rr   rs   rt   r!   r!   r"   r   Q  s    zJSONExact.as_oracle)rW   rX   rY   Zcan_use_none_as_rhsrm   r   r\   r!   r!   r   r"   r   D  s    
r   c                   @      e Zd ZdS )JSONIContainsNrW   rX   rY   r!   r!   r!   r"   r   Z      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 rE   )r   r   r<   key_name)r   r   r7   r   r   r!   r"   r   k  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   x  s    z/KeyTransform.preprocess_lhs.<locals>.<listcomp>)r   rq   r:   r;   insertcompiler.   )r   rp   r4   rb   previousrq   rP   r!   r!   r"   r   o  s   



zKeyTransform.preprocess_lhsc                 C   s0   |  ||\}}}t|}d| t||f fS )NzJSON_EXTRACT(%s, %%s))r   rf   rn   )r   rp   r4   rq   rP   rb   	json_pathr!   r!   r"   r   {  s   zKeyTransform.as_mysqlc                 C   sH   |  ||\}}}t|}|jjrd}nd}|||fd  t|d fS )NuR   COALESCE(JSON_VALUE(%s, q'￿%s￿'),JSON_QUERY(%s, q'￿%s￿' DISALLOW SCALARS))uA   COALESCE(JSON_QUERY(%s, q'￿%s￿'),JSON_VALUE(%s, q'￿%s￿'))   )r   rf   r/   r   rn   )r   rp   r4   rq   rP   rb   r   sqlr!   r!   r"   r     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_operatorrn   r`   r   r   ry   )r   rp   r4   rq   rP   rb   r   lookupr!   r!   r"   r     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     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   rf   ra   rF   jsonfield_datatype_valuesrn   )r   rp   r4   rq   rP   rb   r   Zdatatype_valuesr!   r!   r"   r     s   
zKeyTransform.as_sqlite)rW   rX   rY   ry   r   r   r   r   r   r   r   r\   r!   r!   r   r"   r;   g  s    r;   c                       s6   e Zd ZdZdZe Z fddZedd Z	  Z
S )KeyTextTransformz->>z#>>c                    sT   |j rt ||\}}d| |fS | ||\}}}t|}d| t||f fS )NJSON_UNQUOTE(%s)z(%s ->> %%s))mysql_is_mariadbr   r   r   rf   rn   )r   rp   r4   r   rP   rq   rb   r   r   r!   r"   r     s   zKeyTextTransform.as_mysqlc                 C   s2   | t^}}|std|D ]}| ||}q|S )Nz,Lookup must contain key or index transforms.)splitr
   r   )r9   r   rN   keysr   r!   r!   r"   from_lookup  s   zKeyTextTransform.from_lookup)rW   rX   rY   ry   r   r   rJ   r   classmethodr   r\   r!   r!   r   r"   r     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                    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;   rS   r   r   Zsource_expressionsextrar   r   )r   rd   r7   r   Zkey_text_transformr   r!   r"   r     s   
z$KeyTransformTextLookupMixin.__init__)rW   rX   rY   r   r   r\   r!   r!   r   r"   r     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   rq   r   r   rs   r   rn   )r   rp   r4   r   rP   rq   rr   rZ   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   )rs   r   rq   r   ru   )r   rp   r4   r   r!   r!   r"   r     s   zKeyTransformIsNull.as_sqliteN)rW   rX   rY   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 )Nru   r   9%s(JSON_OBJECT('value' VALUE %%s FORMAT JSON), '$.value')
JSON_QUERY
JSON_VALUEr   sqliter   r   r   )r   resolve_expression_parameterhasattrr/   has_native_json_fieldr.   r=   r>   r:   r   r   rF   r   r   )r   rp   r4   r   paramrP   r@   r   r!   r"   r     s.   





z+KeyTransformIn.resolve_expression_parameter)rW   rX   rY   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:   rs   r;   r   r	   Exactrm   r.   r=   r>   r   r   r0   rn   rF   r   )r   rp   r4   rs   rt   r   r   r@   r   r!   r"   rm     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   rm   r   rq   r   r   Z
get_lookupru   rn   )r   rp   r4   rs   rt   Zhas_key_exprZhas_key_sqlZhas_key_paramsZis_null_exprZis_null_sqlZis_null_paramsr   r!   r"   r   0  s   

zKeyTransformExact.as_oracle)rW   rX   rY   rm   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   E  r   r   c                   @   r   )KeyTransformStartsWithNr   r!   r!   r!   r"   r   K  r   r   c                   @   r   )KeyTransformIStartsWithNr   r!   r!   r!   r"   r   O  r   r   c                   @   r   )KeyTransformEndsWithNr   r!   r!   r!   r"   r   U  r   r   c                   @   r   )KeyTransformIEndsWithNr   r!   r!   r!   r"   r   Y  r   r   c                   @   r   )KeyTransformRegexNr   r!   r!   r!   r"   r   _  r   r   c                   @   r   )KeyTransformIRegexNr   r!   r!   r!   r"   r   c  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   r@   r!   r!   r"   r   m  s    z>KeyTransformNumericLookupMixin.process_rhs.<locals>.<listcomp>)r   rm   r/   r   r   r   r!   r"   rm   j  s   z*KeyTransformNumericLookupMixin.process_rhs)rW   rX   rY   rm   r\   r!   r!   r   r"   r   i  r   r   c                   @   r   )KeyTransformLtNr   r!   r!   r!   r"   r   q  r   r   c                   @   r   )KeyTransformLteNr   r!   r!   r!   r"   r   u  r   r   c                   @   r   )KeyTransformGtNr   r!   r!   r!   r"   r   y  r   r   c                   @   r   )KeyTransformGteNr   r!   r!   r!   r"   r   }  r   r   c                   @   r   )rM   c                 C   s
   || _ d S rE   )r   )r   r   r!   r!   r"   r     rU   zKeyTransformFactory.__init__c                 O   s   t | jg|R i |S rE   )r;   r   )r   r7   r   r!   r!   r"   __call__  s   zKeyTransformFactory.__call__N)rW   rX   rY   r   r   r!   r!   r!   r"   rM     s    rM   )T)Or=   djangor   Zdjango.corer   r   Z	django.dbr   r   r   Zdjango.db.modelsr   r	   Zdjango.db.models.constantsr
   Zdjango.db.models.fieldsr   Zdjango.db.models.lookupsr   r   r   Zdjango.utils.translationr   rZ   r_   r   Zmixinsr   __all__r   rf   rh   r{   r|   r   r   r   r   r   r   r   Z	IContainsr   Zregister_lookupr;   r   r   KTr   ZIsNullr   Inr   r   ZIExactr   r   Z
StartsWithr   ZIStartsWithr   ZEndsWithr   Z	IEndsWithr   Regexr   ZIRegexr   r   ZLessThanr   ZLessThanOrEqualr   ZGreaterThanr   ZGreaterThanOrEqualr   rM   r!   r!   r!   r"   <module>   s     
S	






I
(


















