
    tUi@k                     <   d dl Z d dlZd dlZd dlZd dl d dlmZ d dlmZ d dlmZ d dlmZ d dlm	Z	 d dlm
Z
 d d	lmZ d d
lmZ d dlmZ d dlmZ d dlmZ d dlmZ d dlmZ d dlmZ dZdZeej,                  dd dk\  rdndZndZdZ G d de      Z G d de      Z G d de      Z G d de      Z G d d e      Z  G d! d"e      Z! G d# d$e!      Z" G d% d&e#      Z$ G d' d(e$      Z% G d) d*e&      Z' G d+ d,e(      Z) G d- d.e*      Z+ G d/ d0e+      Z, G d1 d2e,      Z-d3Z. e/d4       e/e.      z   e/e.ja                               z   e/ e1d5      f      z  Z2 e/d6  e3d7      D              Z4[.[2 ejj                  d8      Z6 G d9 d:e,      Z7d;e_8        d< Z9y)=    N)*)
ColumnBase)EnclosedNodeList)Entity)
Expression)Insert)Node)NodeList)OP)VirtualField)
merge_dict)sqlite3)JSON)RANK)register_udf_groupspcxpcnalx   )r         r   )r   	   r   c                   .     e Zd ZdZdxZxZZ fdZ xZS )
RowIDFieldTrowidc                     || j                   k7  r$t        t        |       d| j                   d      t        t        |   ||g|  y )Nz must be named "z".)required_name
ValueErrortypesuperr   bind)selfmodelnameargs	__class__s       G/home/agent/.local/lib/python3.12/site-packages/playhouse/sqlite_ext.pyr    zRowIDField.bind&   sH    4%%%"4j$*<*<> ? ?j$$UD848    )	__name__
__module____qualname__auto_incrementcolumn_namer#   r   r    __classcell__r%   s   @r&   r   r   "   s!    N)00K0$9 9r'   r   c                       e Zd ZdxZxZZy)
DocIDFielddocidN)r(   r)   r*   r,   r#   r    r'   r&   r0   r0   -   s    )00K0$r'   r0   c                        e Zd Z fdZ xZS )AutoIncrementFieldc                 V    t         t        |   |      }t        |t	        d      f      S )NAUTOINCREMENT)r   r4   ddlr
   SQL)r!   ctx	node_listr%   s      r&   r7   zAutoIncrementField.ddl2   s*    ,d7<	C$89::r'   )r(   r)   r*   r7   r-   r.   s   @r&   r4   r4   1   s    ; ;r'   r4   c                       e Zd ZdZd Zy)TDecimalFieldTEXTc                      y Nr2   r!   s    r&   get_modifierszTDecimalField.get_modifiers9   s    r'   N)r(   r)   r*   
field_typerA   r2   r'   r&   r<   r<   7   s
    J!r'   r<   c                       e Zd Zg dZd Zy)ISODateTimeField)z%Y-%m-%dT%H:%M:%S.%f%zz%Y-%m-%dT%H:%M:%S%zz%Y-%m-%dT%H:%M:%S.%fz%Y-%m-%dT%H:%M:%Sz%Y-%m-%dc                 (    |r|j                         S y r?   )	isoformatr!   values     r&   db_valuezISODateTimeField.db_valueE   s    ??$$ r'   N)r(   r)   r*   formatsrI   r2   r'   r&   rD   rD   <   s    G%r'   rD   c                        e Zd Zd fd	Zd Zed        Zd ZddZddZ	ddZ
ddZdd	Zd
 Zd Zd Zd Zd Zd Zd Z xZS )JSONPathc                 N    t         t        |           || _        |xs d| _        y Nr2   )r   rL   __init___field_path)r!   fieldpathr%   s      r&   rO   zJSONPath.__init__K   s"    h&(ZR
r'   c                 8    | j                   j                  |      S r?   )rP   python_valuerG   s     r&   
_converterzJSONPath._converterP   s    {{''..r'   c                 P    t        ddj                  | j                        z        S )Nz$%s )ValuejoinrQ   r@   s    r&   rS   zJSONPath.pathS   s    URWWTZZ0011r'   c                     t        |t              s|dk(  rd|z  }nd|z  } t        |       | j                  | j                  |fz         S )N#z[%s]z.%s)
isinstanceintr   rP   rQ   )r!   idxitems      r&   __getitem__zJSONPath.__getitem__W   sF    c33#:C<D3;DtDz$++tzzTG';<<r'   c                     |st        |t        t        f      r.t        j	                  | j
                  j                  |            }t        j                  | j
                  | d   j                  |      S Nr\   )	r]   listdictfnjsonrP   _json_dumpsjson_setrS   r!   rH   as_jsons      r&   appendzJSONPath.append^   sN    jt5GGDKK33E:;E{{4;;S	>>r'   c                     |st        |t        t        f      r.t        j	                  | j
                  j                  |            } || j
                  | j                  |      S r?   )r]   rd   re   rf   rg   rP   rh   rS   r!   funcrH   rk   s       r&   _json_operationzJSONPath._json_operationc   sF    jt5GGDKK33E:;EDKKE22r'   c                 D    | j                  t        j                  ||      S r?   )rp   rf   json_insertrj   s      r&   insertzJSONPath.inserth   s    ##BNNE7CCr'   c                 D    | j                  t        j                  ||      S r?   )rp   rf   ri   rj   s      r&   setzJSONPath.setk   s    ##BKK@@r'   c                 D    | j                  t        j                  ||      S r?   )rp   rf   json_replacerj   s      r&   replacezJSONPath.replacen       ##BOOUGDDr'   c                 ~    | j                  t        j                  | | j                  j	                  |                  S r?   )ru   rf   
json_patchrP   rh   rG   s     r&   updatezJSONPath.updateq   s+    xxdDKK,C,CE,JKLLr'   c                 V    t         j                  | j                  | j                        S r?   )rf   json_removerP   rS   r@   s    r&   removezJSONPath.removet   s    ~~dkk49955r'   c                 V    t         j                  | j                  | j                        S r?   )rf   	json_typerP   rS   r@   s    r&   r   zJSONPath.json_typew       ||DKK33r'   c                 V    t         j                  | j                  | j                        S r?   )rf   json_array_lengthrP   rS   r@   s    r&   lengthzJSONPath.lengthz   s    ##DKK;;r'   c                 V    t         j                  | j                  | j                        S r?   )rf   	json_eachrP   rS   r@   s    r&   childrenzJSONPath.children}   r   r'   c                 V    t         j                  | j                  | j                        S r?   )rf   	json_treerP   rS   r@   s    r&   treezJSONPath.tree   r   r'   c                     |j                  | j                  r.t        j                  | j                  | j
                              S | j                        S r?   )sqlrQ   rf   json_extractrP   rS   r!   r9   s     r&   __sql__zJSONPath.__sql__   sC    ww** t{{DII> 7 	7*.++7 	7r'   r?   )r(   r)   r*   rO   rV   propertyrS   ra   rl   rp   rs   ru   rx   r|   r   r   r   r   r   r   r-   r.   s   @r&   rL   rL   J   sf     
/ 2 2=?
3
DAEM64<447r'   rL   c                   F    e Zd Zd
dZd
dZd
dZd
dZd
dZd Zd Z	d	 Z
y)	JSONBPathNc                     |st        |t        t        f      r.t        j	                  | j
                  j                  |            }t        j                  | j
                  | d   j                  |      S rc   )	r]   rd   re   rf   jsonbrP   rh   	jsonb_setrS   rj   s      r&   rl   zJSONBPath.append   sN    jt5HHT[[44U;<E||DKKc??r'   c                     |st        |t        t        f      r.t        j	                  | j
                  j                  |            } || j
                  | j                  |      S r?   )r]   rd   re   rf   r   rP   rh   rS   rn   s       r&   rp   zJSONBPath._json_operation   sF    jt5HHT[[44U;<EDKKE22r'   c                 D    | j                  t        j                  ||      S r?   )rp   rf   jsonb_insertrj   s      r&   rs   zJSONBPath.insert   ry   r'   c                 D    | j                  t        j                  ||      S r?   )rp   rf   r   rj   s      r&   ru   zJSONBPath.set   s    ##BLL%AAr'   c                 D    | j                  t        j                  ||      S r?   )rp   rf   jsonb_replacerj   s      r&   rx   zJSONBPath.replace   s    ##B$4$4eWEEr'   c                 ~    | j                  t        j                  | | j                  j	                  |                  S r?   )ru   rf   jsonb_patchrP   rh   rG   s     r&   r|   zJSONBPath.update   s+    xxtT[[-D-DU-KLMMr'   c                 V    t         j                  | j                  | j                        S r?   )rf   jsonb_removerP   rS   r@   s    r&   r   zJSONBPath.remove   s    t{{DII66r'   c                     |j                  | j                  r.t        j                  | j                  | j
                              S | j                        S r?   )r   rQ   rf   jsonb_extractrP   rS   r   s     r&   r   zJSONBPath.__sql__   sE    ww** ''TYY? 7 	7*.++7 	7r'   r?   )r(   r)   r*   rl   rp   rs   ru   rx   r|   r   r   r2   r'   r&   r   r      s/    @
3
EBFN77r'   r   c                       e Zd ZdZdZeZd fd	Zd Zd Z	d Z
 e
ej                        Z e
ej                        Z e
ej                         Z e
ej$                        Z e
ej(                        Z e
ej,                        Zej2                  Zd Zd Zd	 Zd
 ZddZddZddZ ddZ!d Z"d Z#d Z$ddZ%d Z&d Z' xZ(S )	JSONFieldr   Fc                     |xs t         j                  | _        |xs t         j                  | _        t        t        |   di | y rN   )rg   dumpsrh   loads_json_loadsr   r   rO   )r!   
json_dumps
json_loadskwargsr%   s       r&   rO   zJSONField.__init__   s7    %3%3i'1&1r'   c                 Z    |	 | j                  |      S y # t        t        f$ r |cY S w xY wr?   )r   	TypeErrorr   rG   s     r&   rU   zJSONField.python_value   s>    ''..  z* s    **c                 t    |6t        |t              s$t        j                  | j	                  |            }|S y r?   )r]   r	   rf   rg   rh   rG   s     r&   rI   zJSONField.db_value   s5    eT* 0 0 78L r'   c                       fd}|S )Nc                 v    t        |t        t        f      rt        || j                        }t        | |      S r?   )r]   rd   re   AsIsrI   r   )r!   rhsops     r&   innerzJSONField._e.<locals>.inner   s0    #d|,3.dB,,r'   r2   )r   r   s   ` r&   _ezJSONField._e   s    	- r'   c                 *    | j                  |       |   S r?   )Path)r!   r`   s     r&   ra   zJSONField.__getitem__   s    yyt$$r'   c                 l    |D cg c]  }t        |d       }}t        j                  | g| S c c}w NF	converter)rY   rf   r   r!   pathsps      r&   extractzJSONField.extract   s5    49:qqE*::t,e,, ;   1c                 2    t        | dt        |d            S )Nz->Fr   r   rY   r!   rS   s     r&   extract_jsonzJSONField.extract_json   s    $eDE&BCCr'   c                 2    t        | dt        |d            S )Nz->>Fr   r   r   s     r&   extract_textzJSONField.extract_text   s    $uTU'CDDr'   c                 D    | j                  |       j                  ||      S r?   )r   rl   rj   s      r&   rl   zJSONField.append       yy%%eW55r'   c                 D    | j                  |       j                  ||      S r?   )r   rs   rj   s      r&   rs   zJSONField.insert   r   r'   c                 D    | j                  |       j                  ||      S r?   )r   ru   rj   s      r&   ru   zJSONField.set   s    yy""5'22r'   c                 D    | j                  |       j                  ||      S r?   )r   rx   rj   s      r&   rx   zJSONField.replace   s    yy&&ug66r'   c                 B    | j                  |       j                  |      S r?   )r   r|   )r!   datas     r&   r|   zJSONField.update   s    yy%%d++r'   c                 p    |s| j                  |       j                         S t        j                  | g| S r?   )r   r   rf   r~   r!   r   s     r&   r   zJSONField.remove   s0    99T?))++~~d+U++r'   c                 ,    t         j                  |       S r?   )rf   r   r@   s    r&   r   zJSONField.json_type       ||D!!r'   c                 8    |r| |fn| f}t        j                  | S r?   )rf   r   )r!   rS   r$   s      r&   r   zJSONField.length   s"    #d|$##T**r'   c                 ,    t         j                  |       S )a?  
        Schema of `json_each` and `json_tree`:

        key,
        value,
        type TEXT (object, array, string, etc),
        atom (value for primitive/scalar types, NULL for array and object)
        id INTEGER (unique identifier for element)
        parent INTEGER (unique identifier of parent element or NULL)
        fullkey TEXT (full path describing element)
        path TEXT (path to the container of the current element)
        json JSON hidden (1st input parameter to function)
        root TEXT hidden (2nd input parameter, path at which to start)
        )rf   r   r@   s    r&   r   zJSONField.children   s     ||D!!r'   c                 ,    t         j                  |       S r?   )rf   r   r@   s    r&   r   zJSONField.tree  r   r'   )NNr?   ))r(   r)   r*   rB   unpackrL   r   rO   rU   rI   r   r   EQ__eq__NE__ne__GT__gt__GTE__ge__LT__lt__LTE__le__Field__hash__ra   r   r   r   rl   rs   ru   rx   r|   r   r   r   r   r   r-   r.   s   @r&   r   r      s    JFD2
 YFYFYFZFYFZF~~H%-DE6637,,
"+"""r'   r   c                   ,    e Zd ZdZeZd Zd Zd Zd Z	y)
JSONBFieldJSONBc                 t    |6t        |t              s$t        j                  | j	                  |            }|S y r?   )r]   r	   rf   r   rh   rG   s     r&   rI   zJSONBField.db_value
  s5    eT*!1!1%!89L r'   c                 ,    t         j                  |       S r?   )rf   rg   r@   s    r&   rg   zJSONBField.json  s    wwt}r'   c                 l    |D cg c]  }t        |d       }}t        j                  | g| S c c}w r   )rY   rf   r   r   s      r&   r   zJSONBField.extract  s7    49:qqE*::-u-- ;r   c                 p    |s| j                  |       j                         S t        j                  | g| S r?   )r   r   rf   r   r   s     r&   r   zJSONBField.remove  s0    99T?))++t,e,,r'   N)
r(   r)   r*   rB   r   r   rI   rg   r   r   r2   r'   r&   r   r     s     JD.-r'   r   c                   D     e Zd Zd fd	Zd Zed        Zd ZddZ xZ	S )SearchFieldc                 d    |rt        dt        |      z        t        t        |   ||d       y )Nz8SearchField does not accept these keyword arguments: %s.T)	unindexedr,   null)r   sortedr   r   rO   )r!   r   r,   kr%   s       r&   rO   zSearchField.__init__  s@     .06q	: ; ;k4)I6A 	* 	Nr'   c                     t        | |      S r?   )match)r!   terms     r&   r   zSearchField.match%  s    T4  r'   c                 
   t        | d      sg| j                  j                  j                  D cg c]  }t	        |t
              r|j                    }}|j                  | j                        | _        | j                  S c c}w )N_fts_column_index)	hasattrr"   _metasorted_fieldsr]   r   r#   indexr   )r!   fsearch_fieldss      r&   fts_column_indexzSearchField.fts_column_index(  so    t01-1ZZ-=-=-K-K < *1k : VV <M <%2%8%8%CD"%%%<s   #B c                     | j                   }t        j                  | j                  j                  j
                  |||      S r?   )r   rf   	highlightr"   r   entity)r!   leftright
column_idxs       r&   r   zSearchField.highlight0  s2    **
||DJJ,,33ZuMMr'   c                     d|cxk  rdk  st        d       t        d      | j                  }t        j                  | j                  j
                  j                  |||||      S )Nr   A   z/max_tokens must be between 1 and 64 (inclusive))r   r   rf   snippetr"   r   r   )r!   r  r  over_length
max_tokensr  s         r&   r  zSearchField.snippet4  se    J##NOO $NOO**
zz$****11:tU%z3 	3r'   )FN)z...   )
r(   r)   r*   rO   r   r   r   r   r  r-   r.   s   @r&   r   r     s-    N! & &N3r'   r   c                   (     e Zd ZddZd fd	Z xZS )VirtualTableSchemaManagerc                    | j                   j                  t        | j                   j                  j                  |            }| j                         }|j                  d       |r|j                  d       |j                  | j                         j                  d       | j                   j                  j                  }t        |t              r|j                  |      S |j                  t        |            j                  d       g }| j                   j                  }|j                  r2|j                  |j                  D cg c]  }t        |       c}       |j                  D ]u  }t        |t              s|j                   r t#        |j$                        g}	|j&                  r|	j)                  t        d             |j)                  t+        |	             w |j,                  r2|j                  |j,                  D cg c]  }t        |       c}       |r |j                  | j/                  |             |j                  t1        |            S c c}w c c}w )NzCREATE VIRTUAL TABLE zIF NOT EXISTS z USING  	UNINDEXED)r"   clean_optionsr   r   options_create_contextliteralr   extension_moduler]   r	   r8   prefix_argumentsextendr   r   _hiddenr   r,   r   rl   r
   	arguments_create_table_option_sqlr   )
r!   safer  r9   
ext_moduler  metaarR   	field_defs
             r&   _create_virtual_tablez/VirtualTableSchemaManager._create_virtual_table=  s   ****tzz''//9; ""$+,KK()	
#djj/
')
ZZ%%66
j$'77:&&J ((-	zz  d.C.CDc!fDE '' 	2E%*.%-- 1 123I  [!12Xi01	2 >>dnn=c!f=>T::7CDww'	233! E >s   	I I%c                     t        | j                  t              r | j                  |fi |S t	        t
        |   |fi |S r?   )
issubclassr"   VirtualModelr  r   r  _create_table)r!   r  r  r%   s      r&   r"  z'VirtualTableSchemaManager._create_tableh  sI    djj,/-4--d>g>>.C 	r'   T)r(   r)   r*   r  r"  r-   r.   s   @r&   r  r  <  s    )4V r'   r  c                   0    e Zd Z G d d      Zed        Zy)r!  c                        e Zd ZdZdZdZdZeZy)VirtualModel.MetaNF)	r(   r)   r*   r  r  r  primary_keyr  schema_manager_classr2   r'   r&   Metar&  q  s    	8r'   r)  c                     |S r?   r2   )clsr  s     r&   r  zVirtualModel.clean_optionsx  s    r'   N)r(   r)   r*   r)  classmethodr  r2   r'   r&   r!  r!  p  s     9 9  r'   r!  c                       e Zd Zed        Zy)BaseFTSModelc                 z   |j                  d      }|j                  d      }|j                  d      }|j                  d      }t        |t              r|dk(  rd|d<   nGt        |t              r7t	        |j
                  j                  j                  |j                        |d<   |||d<   |rUt        |t        t        f      r(dj                  |D cg c]  }t        |       c}      }d|j                  d	      z  |d<   |r/| j                  j                  j                         d
k(  rd|z  |d<   |S c c}w )Ncontentprefixtokenizecontent_rowidrX   z'',z'%s'z' fts5z"%s")getr]   strr   r   r"   r   
table_namer,   rd   tuplerZ   stripr  lower)r+  r  r0  r1  r2  r3  is          r&   r  zBaseFTSModel.clean_options~  s   ++i(X&;;z*O4gs#2!%GI'!'(;(;(F(F(/(;(;"=GI $'4GO$&4-06":a3q6":; &d); ;GH		2288:fD #)8"3GJ #;s   D8N)r(   r)   r*   r,  r  r2   r'   r&   r.  r.  }  s     r'   r.  c                   N   e Zd ZdZ e       Z G d d      Zed        Zed        Z	ed        Z
ed        Zedd       Zedd	       Zed
        Zed        Zed        Zed        Zed        Zed        Ze	 	 dd       Ze	 	 dd       Ze	 	 dd       Ze	 	 dd       Zy)FTSModelz
    VirtualModel class for creating tables that use either the FTS3 or FTS4
    search extensions. Peewee automatically determines which version of the
    FTS extension is supported and will use FTS4 if possible.
    c                       e Zd Zdez  Zy)FTSModel.MetazFTS%sN)r(   r)   r*   FTS_VERSIONr  r2   r'   r&   r)  r@    s    "[0r'   r)  c           	          | j                   j                  }| j                   j                  j                  d|d|d|d      }|j	                         S )NzINSERT INTO (z
) VALUES('z');)r   r8  databaseexecute_sqlfetchone)r+  cmdtblress       r&   _fts_cmdzFTSModel._fts_cmd  sB    ii""ii  ,,25sC@B||~r'   c                 $    | j                  d      S NoptimizerJ  r+  s    r&   rM  zFTSModel.optimize      ||J''r'   c                 $    | j                  d      S NrebuildrN  rO  s    r&   rS  zFTSModel.rebuild      ||I&&r'   c                 $    | j                  d      S )Nintegrity-checkrN  rO  s    r&   integrity_checkzFTSModel.integrity_check  s    ||-..r'   c                 0    | j                  d|d|      S )Nzmerge=r4  rN  )r+  blockssegmentss      r&   mergezFTSModel.merge  s    ||VX>??r'   c                 :    | j                  d|xr dxs dz        S )Nzautomerge=%s10rN  )r+  states     r&   	automergezFTSModel.automerge  s    ||Nem.BsCDDr'   c                 B    t        | j                  j                  |      S zU
        Generate a `MATCH` expression appropriate for searching this table.
        r   r   r   r+  r   s     r&   r   zFTSModel.match      
 SYY%%t,,r'   c                     t         j                  | j                  j                  t              }t        j
                  |g| S r?   )rf   	matchinfor   r   FTS3_MATCHINFOfts_rank)r+  weightsrg  s      r&   rankzFTSModel.rank  s0    LL!1!1>B	{{9/w//r'   c                     t         j                  | j                  j                  t              }t        j
                  |g| S r?   )rf   rg  r   r   FTS4_MATCHINFOfts_bm25r+  rj  
match_infos      r&   bm25zFTSModel.bm25  s0    \\#))"2"2NC
{{:000r'   c                     t         j                  | j                  j                  t              }t        j
                  |g| S r?   )rf   rg  r   r   rm  	fts_bm25fro  s      r&   bm25fzFTSModel.bm25f  s0    \\#))"2"2NC
||J111r'   c                     t         j                  | j                  j                  t              }t        j
                  |g| S r?   )rf   rg  r   r   rm  
fts_lucenero  s      r&   lucenezFTSModel.lucene  s0    \\#))"2"2NC
}}Z2'22r'   c                    |s |       }nut        |t              r`g }| j                  j                  D ]?  }	|j	                  |	|j	                  |	j
                  d            }
|j                  |
       A  || }n || }d}|}|r| |j                  |      f}|r|st        |      } | j                  | j                  | j                  |            j                  |      S )N      ?r2   )r]   re   r   r   r6  r#   rl   aliasr8   selectwherer   order_by)r+  r   rj  
with_scorescore_aliasscore_fnexplicit_orderingrk  weight_argsrR   field_weight	selectionr}  s                r&   _searchzFTSModel._search  s     :D&K00 1  '{{5'++ejj#2NO""<0	1
 [)DW%D	djj56I/;'H$syy'(#	%r'   Nc                 B    | j                  ||||| j                  |      S 'Full-text search using selected `term`.)r  rk  r+  r   rj  r~  r  r  s         r&   searchzFTSModel.search  +     {{HH 	r'   c                 B    | j                  ||||| j                  |      S z:Full-text search for selected `term` using BM25 algorithm.)r  rq  r  s         r&   search_bm25zFTSModel.search_bm25  r  r'   c                 B    | j                  ||||| j                  |      S r  )r  rt  r  s         r&   search_bm25fzFTSModel.search_bm25f  s+     {{II 	r'   c                 B    | j                  ||||| j                  |      S r  )r  rw  r  s         r&   search_lucenezFTSModel.search_lucene  s+     {{JJ 	r'   )      r#  NFscoreF)r(   r)   r*   __doc__r0   r1   r)  r,  rJ  rM  rS  rW  r[  r`  r   rk  rq  rt  rw  r  r  r  r  r  r2   r'   r&   r>  r>    sv    LE1 1   ( ( ' ' / / @ @ E E - - 0 0 1 1 2 2 3 3 % %6 FM!&	 	 8=;@	 	 9><A	 	 :?=B	 	r'   r>  abcdefghijklmnopqrstuvwxyzz	 ,"(){}*:_+0123456789   c              #   V   K   | ]!  }t        |      t        vst        |       # y wr?   )chr	_alphanum).0r   s     r&   	<genexpr>r  1  s     K3q63JSVKs   ))   z [^\s"]+|"[^"\\]*(?:\\.[^"\\]*)*"c                      e Zd ZdZ e       Z G d d      ZddddZed        Z	ed	        Z
ed
        Ze ed      fd       Zed        Zed        Zed        Ze	 	 dd       Ze	 	 dd       Zed        Zed        Zed        Zed        Zed        Zed        Zed        Zed        Zed        Zedd       Zed d       Zy)!	FTS5Modelan  
    Requires SQLite >= 3.9.0.

    Table options:

    content: table name of external content, or empty string for "contentless"
    content_rowid: column name of external content primary key
    prefix: integer(s). Ex: '2' or '2 3 4'
    tokenize: porter, unicode61, ascii. Ex: 'porter unicode61'

    The unicode tokenizer supports the following parameters:

    * remove_diacritics (1 or 0, default is 1)
    * tokenchars (string of characters, e.g. '-_'
    * separators (string of characters)

    Parameters are passed as alternating parameter name and value, so:

    {'tokenize': "unicode61 remove_diacritics 0 tokenchars '-_'"}

    Content-less tables:

    If you don't need the full-text content in it's original form, you can
    specify a content-less table. Searches and auxiliary functions will work
    as usual, but the only values returned when SELECT-ing can be rowid. Also
    content-less tables do not support UPDATE or DELETE.

    External content tables:

    You can set up triggers to sync these, e.g.

    -- Create a table. And an external content fts5 table to index it.
    CREATE TABLE tbl(a INTEGER PRIMARY KEY, b);
    CREATE VIRTUAL TABLE ft USING fts5(b, content='tbl', content_rowid='a');

    -- Triggers to keep the FTS index up to date.
    CREATE TRIGGER tbl_ai AFTER INSERT ON tbl BEGIN
      INSERT INTO ft(rowid, b) VALUES (new.a, new.b);
    END;
    CREATE TRIGGER tbl_ad AFTER DELETE ON tbl BEGIN
      INSERT INTO ft(fts_idx, rowid, b) VALUES('delete', old.a, old.b);
    END;
    CREATE TRIGGER tbl_au AFTER UPDATE ON tbl BEGIN
      INSERT INTO ft(fts_idx, rowid, b) VALUES('delete', old.a, old.b);
      INSERT INTO ft(rowid, b) VALUES (new.a, new.b);
    END;

    Built-in auxiliary functions:

    * bm25(tbl[, weight_0, ... weight_n])
    * highlight(tbl, col_idx, prefix, suffix)
    * snippet(tbl, col_idx, prefix, suffix, ?, max_tokens)
    c                       e Zd ZdZy)FTS5Model.Metar5  N)r(   r)   r*   r  r2   r'   r&   r)  r  q  s    !r'   r)  zQBesides the implicit `rowid` column, all columns must be instances of SearchFieldz3Secondary indexes are not supported for FTS5 modelsz4FTS5 models must use the default `rowid` primary key)rB   r   pkc                    | j                   j                  j                  dk7  rt        | j                  d         | j                   j
                  j                         D ]0  }t        |t        t        f      rt        | j                  d          | j                   j                  rt        | j                  d         y )Nr   r  rB   r   )r   r'  r#   ImproperlyConfigured_error_messagesfieldsvaluesr]   r   r   indexes)r+  rR   s     r&   validate_modelzFTS5Model.validate_model{  s     99  %%0&s':':4'@AAYY%%,,. 	NEek:%>?*3+>+>|+LMM	N 99&s':':7'CDD r'   c                    t         j                  d d t        k  ryt        j                  d      }	 |j	                  d       |j                          y#  	 |j                  d       |j                  d       | j                  j                  j                  d       n#  Y Y |j                          yxY wY vxY w# |j                          w xY w)Nr   Fz:memory:z0CREATE VIRTUAL TABLE fts5test USING fts5 (data);Tr5  )
r   sqlite_version_infoFTS5_MIN_SQLITE_VERSIONconnectexecuteenable_load_extensionload_extensionr   rD  close)r+  tmp_dbs     r&   fts5_installedzFTS5Model.fts5_installed  s    &&r*-DD ,	NNMN LLN	::,,T2%%f- 		""11&9 LLN :LLNs;   A B9"B9&B9B4!B9"B< 4B97B< <Cc                     t         j                  |       }|D ]9  }|j                  d      r|j                  d      r&t	        |      t
        z  s9 y y)z
        Simple helper function to indicate whether a search query is a
        valid FTS5 query. Note: this simply looks at the characters being
        used, and is not guaranteed to catch all problematic queries.
        "FT)	_quote_refindall
startswithendswithru   _invalid_ascii)querytokenstokens      r&   validate_queryzFTS5Model.validate_query  sS     ""5) 	E$)<5zN*		
 r'   r  c                 X   g }d}t         j                  |       }|D ]x  }|j                  d      r#|j                  d      r|j	                  |       7t        |      }|t        z  }|rd}|D ]  }|j                  ||      } |j	                  |       z |rdj                  |      S | S )z2
        Clean a query of invalid tokens.
        Fr  Tr  )	r  r  r  r  rl   ru   r  rx   rZ   )	r  rx   accumany_invalidr  r  	token_setinvalid_for_tokencs	            r&   clean_queryzFTS5Model.clean_query  s    
 ""5) 
	 E$)<U#E
I )N : "* 6A!MM!W5E6LL
	  88E?"r'   c                 B    t        | j                  j                  |      S rb  rc  rd  s     r&   r   zFTS5Model.match  re  r'   c                 :    |r | j                   | S t        d      S )Nrk  )rq  r8   )r+  r$   s     r&   rk  zFTS5Model.rank  s    "&xsxx7CK7r'   c                 V    t        j                  | j                  j                  g| S r?   )rf   rq  r   r   )r+  rj  s     r&   rq  zFTS5Model.bm25  s     wwsyy''2'22r'   Nc                 R    | j                  t        j                  |      ||||      S r  )r  r  r  r  s         r&   r  zFTS5Model.search  s/     !!$' 	r'   c           
         |st        d      }nt        |t              rg }| j                  j                  D ][  }t        |t
              s|j                  r!|j                  |j                  ||j                  |j                  d                   ] t        j                  | j                  j                  g| }n*t        j                  | j                  j                  g| }d}	|}
|r| |j                  |      f}	|r|st        |      }
 | j                  |	 j                  | j!                  t"        j%                  |                  j'                  |
      S )r  rk  ry  r2   )r8   r]   re   r   r   r   r   rl   r6  r#   rf   rq  r   rz  r{  r|  r   r  r  r}  )r+  r   rj  r~  r  r  rk  r  rR   r  r}  s              r&   r  zFTS5Model.search_bm25  s"    v;D&K00 Je[1%//&&E7;;uzz3+GHJJ 77399++:k:D77399++6g6D	djj56I/;'H$syy!6!6t!<=>(#	%r'   c           	      P   | j                   j                  }|g}|g}|j                         D ]0  \  }}|j                  t	        |             |j                  |       2 t        t        d      | j                   j                  t        |      t        d      t        |      f      S )NzINSERT INTOVALUES)r   r   itemsrl   r   r
   r8   r   )r+  rG  extra_paramsrH  columnsr  keyrH   s           r&   _fts_cmd_sqlzFTS5Model._fts_cmd_sql  s    ii%&,,. 	!JCNN6#;'MM% 	! IIW%MV$& ' 	'r'   c                 r     | j                   |fi |}| j                  j                  j                  |      S r?   )r  r   rD  r  )r+  rG  r  r  s       r&   rJ  zFTS5Model._fts_cmd	  s4       55yy!!))%00r'   c                 l    d|cxk  rdk  st        d       t        d      | j                  d|      S )Nr   r	  zlevel must be between 0 and 16r`  rk  )r   rJ  )r+  levels     r&   r`  zFTS5Model.automerge  s?    U b =>> !=>>||Ke|44r'   c                 (    | j                  d|      S )Nr[  r  rN  )r+  npagess     r&   r[  zFTS5Model.merge  s    ||G&|11r'   c                 $    | j                  d      S rL  rN  rO  s    r&   rM  zFTS5Model.optimize  rP  r'   c                 $    | j                  d      S rR  rN  rO  s    r&   rS  zFTS5Model.rebuild  rT  r'   c                 (    | j                  d|      S )Npgszr  rN  )r+  r  s     r&   set_pgszzFTS5Model.set_pgsz   s    ||F|..r'   c                 (    | j                  d|      S )Nrk  r  rN  )r+  rank_expressions     r&   set_rankzFTS5Model.set_rank$  s    ||F|99r'   c                 $    | j                  d      S )Nz
delete-allrN  rO  s    r&   
delete_allzFTS5Model.delete_all(  s    ||L))r'   c                 (    | j                  d|      S )NrV  r  rN  )r+  rk  s     r&   rW  zFTS5Model.integrity_check,  s    ||-D|99r'   c           	          dvrt        d      dz  }t         |      s G  fdd      }t        t              t	               t	               t               |d}dk(  rt        t              |d<   ndk(  rt        t              |d	<   d
 j                  z  }t         |t        |t        f|             t         |      S )N)rowcolinstancez5table_type must be either "row", "col" or "instance".z_vocab_model_%sc                       e Zd ZW  j                  j                  ZW xs W  j                  j
                  dz   Zej                  W  j                  j                   e	W             Z
y)"FTS5Model.VocabModel.<locals>.Meta_vN)r(   r)   r*   r   rD  r8  rf   	fts5vocabr   r8   r  )r+  table
table_types   r&   r)  r  9  sN    99--"Acii&:&:T&A
#%<<II$$
O$% r'   r)  )r   doccntr   r)  r  r  offsetz%sVocab)r   r   r   	TextFieldIntegerFieldr   r(   setattrr   r!  getattr)r+  r  r  attrr)  attrs
class_names   ```    r&   
VocabModelzFTS5Model.VocabModel0  s    77 + , , !:-sD!% % %Y/#~#~#E U"+I6ez)".|"<h"S\\1JCtJGHsD!!r'   r  )r   )r  N)r(   r)   r*   r  r   r   r)  r  r,  r  r  staticmethodr  r  r  r   rk  rq  r  r  r  rJ  r`  r[  rM  rS  r  r  r  rW  r  r2   r'   r&   r  r  7  s   4n LE" "5FD	O E E  *   #&r7  . - - 8 8 3 3 FM!&  8=;@% %6 ' ' 1 1 5 5
 2 2 ( ( ' ' / / : : * * : : " "r'   r  MATCHc                 8    t        | t        j                  |      S r?   )r   r   r  )lhsr   s     r&   r   r   T  s    c288S))r'   ):rg   resyswarningspeeweer   r   r   r   r   r	   r
   r   r   r   r   playhouse.sqlite_udfr   r   r   rh  rm  r  rA  r  	AutoFieldr   r0   r4   DecimalFieldr<   DateTimeFieldrD   rL   r   r  r   r   r   r   SchemaManagerr  Modelr!  r.  r>  	_alphabetru   upperr  r  ranger  compiler  r  r  r   r2   r'   r&   <module>r     s    	 
    #          % % 4 
222A6)C!KK# 9 91 1; ;"L "
%} %;7z ;7z7 7>]"	 ]"@- -.3% 3>1 1h
5 
< @L| L^ )	*+^"#$ #b'_	 KU3ZKKBJJ:;	X" X"v *r'   