o
    hv\                     @   s  d dl mZ d dlmZ d dlmZmZmZmZ d dl	m
Z
mZmZ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
dlmZmZmZmZ d
dl m!Z!m"Z" d
dl#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z) d
dl*m+Z+m,Z,m-Z-m.Z.m/Z/ ddl0m1Z1m2Z2m3Z3m4Z4 ddl#m5Z5m6Z6m7Z7m8Z8m9Z9m:Z: G dd dZ;G dd dZ<G dd dZ=G dd de=Z>G dd de2Z?G dd de?Z@G dd  d e3ZAG d!d" d"e1ZBeBZCd#S )$    )OrderedDict)reduce)NotSupportedErrorconnectionsroutertransaction)AvgCountFManagerQ	TextField)
LOOKUP_SEP)CastLength)OperationalError)	force_str)cached_property   )AutocompleteFieldRelatedFieldsSearchFieldget_indexed_models)
IndexEntrySQLiteFTSIndexEntry)AndMatchAllNotOrPhrase	PlainText)ADDMULORget_content_type_pk!get_descendants_content_types_pks   )BaseSearchBackendBaseSearchQueryCompilerBaseSearchResultsFilterFieldError   )BM25AndNotLexemeMatchExpressionSearchQueryExpression	normalizec                   @   sb   e Zd ZdZdd Zdd Zdd Zedd	 Zed
d Z	edd Z
edd ZdddZdS )ObjectIndexerzW
    Responsible for extracting data from an object to be inserted into the index.
    c                 C   s   || _ | | _|j| _d S N)objget_search_fieldssearch_fieldsconfig)selfr4   backend r:   n/var/www/html/ndineBlogger/venv/lib/python3.10/site-packages/wagtail/search/backends/database/sqlite/sqlite.py__init__0   s   
zObjectIndexer.__init__c                    s^   t |tr|S t |trd fdd|D S t |tr+d fdd| D S t|S )Nz, c                 3       | ]}  |V  qd S r3   prepare_value.0itemr8   r:   r;   	<genexpr>:       z.ObjectIndexer.prepare_value.<locals>.<genexpr>c                 3   r=   r3   r>   r@   rC   r:   r;   rD   =   rE   )
isinstancestrlistjoindictvaluesr   )r8   valuer:   rC   r;   r?   5   s   


zObjectIndexer.prepare_valuec                 c   s    t |tr|| ||fV  d S t |tr%|| ||fV  d S t |tr]||}|d u r5d S t |tr?| }n
t|rF| }|g}|D ]}|j	D ]}| 
||E d H  qPqKd S d S r3   )rF   r   r?   	get_valuer   r   r   allcallablefieldsprepare_field)r8   r4   fieldsub_objsub_objs	sub_fieldr:   r:   r;   rQ   A   s(   






zObjectIndexer.prepare_fieldc                 C   s   t | jjS )zO
        Returns the value to use as the ID of the record in the index
        )r   r4   pkrC   r:   r:   r;   idZ   s   zObjectIndexer.idc                 C   sP   g }| j D ]}| | j|D ]\}}t|tr!|jdkr!|| qqd|S )z
        Returns all values to index as "title". This is the value of all SearchFields that have the field_name 'title'
        title r6   rQ   r4   rF   r   
field_nameappendrI   r8   textsrR   current_fieldrL   r:   r:   r;   rX   a      



zObjectIndexer.titlec                 C   sP   g }| j D ]}| | j|D ]\}}t|tr!|jdks!|| qqd|S )zr
        Returns all values to index as "body". This is the value of all SearchFields excluding the title
        rX   rY   rZ   r]   r:   r:   r;   bodyq   r`   zObjectIndexer.bodyc                 C   sF   g }| j D ]}| | j|D ]\}}t|tr|| qqd|S )zl
        Returns all values to index as "autocomplete". This is the value of all AutocompleteFields
        rY   )r6   rQ   r4   rF   r   r\   rI   r]   r:   r:   r;   autocomplete   s   



zObjectIndexer.autocompleteFc                 C   s&   dd |D }dd |D }d |S )zW
        Converts an array of strings into a SearchVector that can be indexed.
        c                 S   s   g | ]
\}}|  |fqS r:   )striprA   textweightr:   r:   r;   
<listcomp>       z+ObjectIndexer.as_vector.<locals>.<listcomp>c                 S   s   g | ]
\}}|r||fqS r:   r:   rd   r:   r:   r;   rg      rh   rY   )rI   )r8   r^   for_autocompleter:   r:   r;   	as_vector   s   
zObjectIndexer.as_vectorNF)__name__
__module____qualname____doc__r<   r?   rQ   r   rW   rX   ra   rb   rj   r:   r:   r:   r;   r2   +   s    



r2   c                   @   sf   e Zd Zdd Zdd Zdd Zddd	Zd
d Zdd Zdd Z	dd Z
dd Zdd Zdd ZdS )Indexc                 C   s`   || _ | j j| _ttt | _ttt | _	| jj
dks$| j	j
dkr(tdtj | _d S )NsqlitezCYou must select a SQLite database to use the SQLite search backend.)r9   
index_namenamer   r   db_for_readr   read_connectiondb_for_writewrite_connectionvendorr   _default_managerrN   entriesr8   r9   r:   r:   r;   r<      s   
zIndex.__init__c                 C      d S r3   r:   r8   modelr:   r:   r;   	add_model      zIndex.add_modelc                 C   r|   r3   r:   rC   r:   r:   r;   refresh   r   zIndex.refreshFc                 C   sn   | j jtddjddtdd }|r| j }n| j jdd}|jtddjddj|td d d	S )
a  
        Refreshes the value of the title_norm field.

        This needs to be set to 'lavg/ld' where:
         - lavg is the average length of titles in all documents (also in terms)
         - ld is the length of the title field in this document (in terms)
        rX   )title_lengthr   )title_length__gtr   title_length__avg      ?)
title_normN)rz   annotater   filter	aggregater   updater
   )r8   fulllavgrz   r:   r:   r;   _refresh_title_norms   s   

zIndex._refresh_title_normsc                 C   sF   |j jtdt dd}t|}| jj|dj|d}|	  d S )NrV   	object_idr   )content_type_id__inobject_id__in)
ry   r   r   r   rK   r%   rz   r   excludedelete)r8   r~   existing_pkscontent_types_pksstale_entriesr:   r:   r;   delete_stale_model_entries   s   
z Index.delete_stale_model_entriesc                 C   s"   t  D ]}|jjs| | qd S r3   )r   _metaparentsr   r}   r:   r:   r;   delete_stale_entries   s
   

zIndex.delete_stale_entriesc                 C   s   |  |jj|g d S r3   )	add_itemsr   r~   r8   r4   r:   r:   r;   add_item   s   zIndex.add_itemc              
   C   s   i }|D ]}|j |j|jf||j< q| jj|d}t|j| djddd}|D ]}|| \}}	}
|j|dj	||	|
d q*g }| D ]}||vr_|| \}}	}
|
t||||	|
d qF| j| |   d S )	N)content_type_idr   r   T)flatr   )rX   rb   ra   )r   r   rX   rb   ra   )rX   rb   ra   rW   rz   r   	frozensetkeysvalues_listr   r\   r   bulk_creater   )r8   content_type_pkindexersids_and_dataindexerindex_entries_for_ctindexed_ids
indexed_idrX   rb   ra   to_be_createdr   r:   r:   r;   add_items_update_then_create   sB   
z"Index.add_items_update_then_createc                    sF   |  }|sd S  fdd|D }|r!t|} j}||| d S d S )Nc                    s   g | ]}t | jqS r:   )r2   r9   rA   r4   rC   r:   r;   rg     s    z#Index.add_items.<locals>.<listcomp>)r5   r$   r   )r8   r~   objsr6   r   r   update_methodr:   rC   r;   r   
  s   zIndex.add_itemsc                 C   s   |j  j| jjd d S )Nusing)index_entriesrN   _raw_deleterw   alias)r8   rB   r:   r:   r;   delete_item  s   zIndex.delete_itemc                 C   s   | j S r3   )rs   rC   r:   r:   r;   __str__     zIndex.__str__Nrk   )rl   rm   rn   r<   r   r   r   r   r   r   r   r   r   r   r:   r:   r:   r;   rp      s    

'rp   c                   @   s$   e Zd Zdd Zdd Zdd ZdS )SQLiteSearchRebuilderc                 C   s
   || _ d S r3   )indexr8   r   r:   r:   r;   r<         
zSQLiteSearchRebuilder.__init__c                 C   s   | j   | j S r3   )r   r   rC   r:   r:   r;   start#  s   
zSQLiteSearchRebuilder.startc                 C   s   | j jdd d S )NTr   )r   r   rC   r:   r:   r;   finish'  s   zSQLiteSearchRebuilder.finishN)rl   rm   rn   r<   r   r   r:   r:   r:   r;   r     s    r   c                       s8   e Zd Z fddZ fddZdd Zdd Z  ZS )	SQLiteSearchAtomicRebuilderc                    s(   t  | tj|jjd| _d| _d S )Nr   F)superr<   r   atomicrw   r   transaction_openedr   	__class__r:   r;   r<   ,  s   
z$SQLiteSearchAtomicRebuilder.__init__c                    s   | j   d| _t  S NT)r   	__enter__r   r   r   rC   r   r:   r;   r   1  s   

z!SQLiteSearchAtomicRebuilder.startc                 C   s(   | j jdd | jd d d  d| _d S )NTr   F)r   r   r   __exit__r   rC   r:   r:   r;   r   6  s   
z"SQLiteSearchAtomicRebuilder.finishc                 C   s   | j rd| j_|   d S d S r   )r   r   needs_rollbackr   rC   r:   r:   r;   __del__<  s   z#SQLiteSearchAtomicRebuilder.__del__)rl   rm   rn   r<   r   r   r   __classcell__r:   r:   r   r;   r   +  s
    r   c                       s   e Zd ZdZdZeZddgZ fddZdd Z	d	d
 Z
d#ddZd#ddZd#ddZd$ddZdd Zdd Zdd Zd#ddZdd Zdd  Zd!d" Z  ZS )%SQLiteSearchQueryCompilerANDFrX   ra   c                    sJ   t  j|i |   jd u r _d S  fddjD _d S )Nc                    s   i | ]
}|j | d qS ))rP   )get_search_field)rA   field_lookuplocal_search_fieldsr8   r:   r;   
<dictcomp>T  s    z6SQLiteSearchQueryCompiler.__init__.<locals>.<dictcomp>)r   r<   get_search_fields_for_modelrP   r6   )r8   argskwargsr   r   r;   r<   I  s   

z"SQLiteSearchQueryCompiler.__init__c                 C      |j S r3   r7   r{   r:   r:   r;   
get_config[  r   z$SQLiteSearchQueryCompiler.get_configc                 C      | j j S r3   )querysetr~   get_searchable_search_fieldsrC   r:   r:   r;   r   ^     z5SQLiteSearchQueryCompiler.get_search_fields_for_modelNc                 C   s~   |d u r| j }t|v r|td\}}nd }|D ]$}t|| jr)|j|kr)|  S t|tr<|j|kr<| ||j  S qd S )Nr+   )	r6   r   splitrF   TARGET_SEARCH_FIELD_TYPEr[   r   r   rP   )r8   r   rP   sub_field_namerR   r:   r:   r;   r   a  s   

z*SQLiteSearchQueryCompiler.get_search_fieldc                    s  t |tr8|j }|sdS | }t|jd}|D ]}t|}|j dkr-||M }q||O }qt	| dS t |t
rBt	|jS t |tr_j|j d}j|j d}	||	d}
|
S t |ttfr fdd|jD }t |t}|rtdd	 |S td
d	 |S td|jj )z~
        Takes a SearchQuery and returns another SearchQuery object, which can be used to construct the query in SQL.
        N)prefixr   r   NOTc                    s   g | ]	}j | d qS r   )build_search_query_contentrA   subqueryr7   r8   r:   r;   rg     s    zHSQLiteSearchQueryCompiler.build_search_query_content.<locals>.<listcomp>c                 S   s   | |@ S r3   r:   abr:   r:   r;   <lambda>      zFSQLiteSearchQueryCompiler.build_search_query_content.<locals>.<lambda>c                 S   s   | |B S r3   r:   r   r:   r:   r;   r     r   3`%s` is not supported by the SQLite search backend.)rF   r    query_stringr   popr.   LAST_TERM_IS_PREFIXoperatorupperr0   r   r-   r   
subquery_a
subquery_b_combiner   r   
subqueriesr   NotImplementedErrorr   rl   )r8   queryr7   terms	last_termlexemesterm
new_lexemer   r   combined_querysubquery_lexemesis_andr:   r   r;   r   w  sL   







z4SQLiteSearchQueryCompiler.build_search_query_contentc                 C   sF   t |tr|S t |tr|j}t| j||d}|S | j||d}|S )Nr   )rF   r   r   r   build_search_queryr   )r8   r   r7   unwrapped_querybuilt_queryr:   r:   r;   r     s   

z,SQLiteSearchQueryCompiler.build_search_queryr   c                    s   t |tttfrt } dkr| 9 }|S t |tr+t fdd|jD d S t |trFt	 fdd|jD t
|jpDd S td|jj )Nr   c                 3   s&    | ]}d j | d V  qdS )r+   r7   boostNbuild_tsrankr   r  r7   r8   vectorr:   r;   rD     s
    
z9SQLiteSearchQueryCompiler.build_tsrank.<locals>.<genexpr>r+   c                 3   s"    | ]}j | d V  qdS )r  Nr  r   r  r:   r;   rD     s
    
r   )rF   r   r    r   r,   r   r"   r   r   r!   lenr   r   rl   )r8   r  r   r7   r  rank_expressionr:   r  r;   r    s.   

z&SQLiteSearchQueryCompiler.build_tsrankc                 C   s   t dt dft ddfgS )Nindex_entries__titleindex_entries__title_normindex_entries__bodyr   r
   rC   r:   r:   r;   get_index_vectors  s   
z+SQLiteSearchQueryCompiler.get_index_vectorsc                 C   s   |   S r3   )r  rC   r:   r:   r;   get_search_vectors     z,SQLiteSearchQueryCompiler.get_search_vectorsc                    s:    fdd|D }|d }|dd  D ]}||7 }q|S )Nc                    s&   g | ]\}}j |j d | qS r   )r  r   )rA   r  r  r   r:   r;   rg     s    zDSQLiteSearchQueryCompiler._build_rank_expression.<locals>.<listcomp>r   r+   r:   )r8   vectorsr7   rank_expressionsr
  other_rank_expressionr:   r   r;   _build_rank_expression  s   
z0SQLiteSearchQueryCompiler._build_rank_expressionc              
   C   s  t | j}t|tr| j|| S t|tr!t|jtr!| j S t|tr,|j}d}nd}| j||d}| 	 }| 
||}	|d d }
|dd  D ]\}}|
|dd}
qKt| jp]| j|}tj|djt| jjd}| jr}|t  }n|jjs|d	}td
}	ddlm} ddlm} |tj|d}z	dd |D }W n' t y } zt t!|d |"|jd  t!|"|jd  |d }~ww |s| jj|d}n| jj#|d}|d ur|j$di ||	i}||| S )NTFr   r   r+   rY   index_entry)index_entry__content_type__inz-pkrV   )
connection)InsertQueryc                 S   s   g | ]}|j jqS r:   )r  r   r   r:   r:   r;   rg   *  s    z4SQLiteSearchQueryCompiler.search.<locals>.<listcomp>z The original query was: )id__inr:   )%r1   r   rF   r   r   r   r   noner   r  r  r   r/   rP   FTS_TABLE_FIELDSr   objectsr   select_relatedr%   r~   order_by_relevanceorder_byr,   descr
   	django.dbr  django.db.models.sql.subqueriesr  r   get_compilerr   rG   compiler   r   )r8   r7   r   stopscore_fieldnormalized_querynegatedsearch_queryr  r
  combined_vectorr  r  exprr   r   r  r  compilerobj_idser:   r:   r;   search  s   







z SQLiteSearchQueryCompiler.searchc                 C   s(   | | jjd | }tdi ||iS )N__r:   )get_attnamer   r~   r   )r8   rR   lookuprL   lhsr:   r:   r;   _process_lookupC  s   z)SQLiteSearchQueryCompiler._process_lookupc                 C   s
   t g dS )N)pk__inr   rC   r:   r:   r;   _process_match_noneG  r   z-SQLiteSearchQueryCompiler._process_match_nonec                 C   s@   |dkr	t | }n|dkrtdd |D }nd S |r| }|S )Nr   r#   c                 S   s   g | ]}t |qS r:   r7  )rA   filr:   r:   r;   rg   O  s    z>SQLiteSearchQueryCompiler._connect_filters.<locals>.<listcomp>)r   r#   )r8   filters	connectorr)  qr:   r:   r;   _connect_filtersJ  s   
z*SQLiteSearchQueryCompiler._connect_filtersr3   )Nr   )rl   rm   rn   DEFAULT_OPERATORr   r   r   r  r<   r   r   r   r   r   r  r  r  r  r0  r5  r8  r=  r   r:   r:   r   r;   r   C  s&    


8

Tr   c                   @   s2   e Zd ZdZeZdgZdd Zdd Zdd Z	d	S )
SQLiteAutocompleteQueryCompilerTrb   c                 C   r   r3   )autocomplete_configr{   r:   r:   r;   r   _  r   z*SQLiteAutocompleteQueryCompiler.get_configc                 C   r   r3   )r   r~   get_autocomplete_search_fieldsrC   r:   r:   r;   r   b  r   z;SQLiteAutocompleteQueryCompiler.get_search_fields_for_modelc                 C   s   t ddfgS )Nindex_entries__autocompleter   r  rC   r:   r:   r;   r  e     z1SQLiteAutocompleteQueryCompiler.get_index_vectorsN)
rl   rm   rn   r   r   r   r  r   r   r  r:   r:   r:   r;   r?  Z  s    r?  c                   @   s2   e Zd ZdddZdd Zdd ZdZd	d
 ZdS )SQLiteSearchResultsFc                 C   s:   |rd }d }n| j }| j}| jj| j| j||| jdS )N)r'  )r   r&  query_compilerr0  r   r9   _score_field)r8   	for_countr   r&  r:   r:   r;   get_querysetj  s   z SQLiteSearchResults.get_querysetc                 C   s   t |  S r3   )rH   rH  rC   r:   r:   r;   
_do_searchy  r   zSQLiteSearchResults._do_searchc                 C   s   | j dd S )NT)rG  )rH  countrC   r:   r:   r;   	_do_count|  s   zSQLiteSearchResults._do_countTc                    s   | j  }|d u r td  d   d | j jjj d  d| j | j | jd d }|	 j
tddd}t fd	d
|D S )Nz(Cannot facet search results with field "z!". Please add index.FilterField('z') to z.search_fields.r[   rV   rJ  z-countc                    s   g | ]
}|  |d  fqS rM  r:   )rA   resultrL  r:   r;   rg     rh   z-SQLiteSearchResults.facet.<locals>.<listcomp>)rE  _get_filterable_fieldr*   r   r~   rl   r0  r   r9   rK   r   r	   r   r   )r8   r[   rR   r   resultsr:   rL  r;   facet  s4   
zSQLiteSearchResults.facetNrk   )rl   rm   rn   rH  rI  rK  supports_facetrQ  r:   r:   r:   r;   rD  i  s    
rD  c                       sp   e Zd ZeZeZeZe	Z
eZ 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dd Z  ZS )SQLiteSearchBackendc                    sB   t  | |dd| _d | _d | _|ddr| j| _d S d S )NINDEXdefaultATOMIC_REBUILDF)r   r<   getrr   r7   r@  atomic_rebuilder_classrebuilder_class)r8   paramsr   r:   r;   r<     s   zSQLiteSearchBackend.__init__c                 C   s   t | S r3   )rp   r}   r:   r:   r;   get_index_for_model  r  z'SQLiteSearchBackend.get_index_for_modelc                 C   s   |  |jjS r3   )r[  r   r~   r   r:   r:   r;   get_index_for_object  rC  z(SQLiteSearchBackend.get_index_for_objectc                 C   s0   dd t  D D ]}tj j|jd q	d S )Nc                 S   s   g | ]	}|j d kr|qS )rq   )rx   )rA   r  r:   r:   r;   rg     s
    
z3SQLiteSearchBackend.reset_index.<locals>.<listcomp>r   )r   rN   r   ry   r   r   )r8   r  r:   r:   r;   reset_index  s
   
zSQLiteSearchBackend.reset_indexc                 C   r|   r3   r:   r}   r:   r:   r;   add_type  r   zSQLiteSearchBackend.add_typec                 C   r|   r3   r:   rC   r:   r:   r;   refresh_index  r   z!SQLiteSearchBackend.refresh_indexc                 C      |  || d S r3   )r\  r   r   r:   r:   r;   add     zSQLiteSearchBackend.addc                 C   s"   |r|  |d || d S d S )Nr   )r\  r   )r8   r~   obj_listr:   r:   r;   add_bulk  s   zSQLiteSearchBackend.add_bulkc                 C   r`  r3   )r\  r   r   r:   r:   r;   r     rb  zSQLiteSearchBackend.delete)rl   rm   rn   r   query_compiler_classr?  !autocomplete_query_compiler_classrD  results_classr   rY  r   rX  r<   r[  r\  r]  r^  r_  ra  rd  r   r   r:   r:   r   r;   rS    s    rS  N)Dcollectionsr   	functoolsr   r"  r   r   r   r   django.db.modelsr   r	   r
   r   r   r   django.db.models.constantsr   django.db.models.functionsr   r   django.db.utilsr   django.utils.encodingr   django.utils.functionalr   r   r   r   r   r   modelsr   r   r   r   r   r   r   r   r    utilsr!   r"   r#   r$   r%   baser'   r(   r)   r*   r,   r-   r.   r/   r0   r1   r2   rp   r   r   r   r?  rD  rS  SearchBackendr:   r:   r:   r;   <module>   s6       
m   32