+
    {:jF                    L   R t ^ RIHt ^ RIt^ RIt^ RIt^ RIt^ RIt^ RIH	t	 ^ RI
HtHtHtHt ^ RIt^ RIHt ^ RIHtHtHtHtHt ^ RIHt ^ RIHtHtHtHtHt ^ R	IH t  ^ R
I!H"t"H#t#H$t$H%t% ]'       d	   ^RI&H't'H(t( ^RI)H*t* ]PV                  ! ],4      t-Rt.Rs/ ! R R]4      t0R# )z.
Use sqlalchemy+postgresql instead of sqlite.
)annotationsN)Path)TYPE_CHECKINGAnyIterableIterator)OperationalError)
Connectionctejoinor_select)insert)BaseCondaIndexCacheIndexedPackagesIndexedShardclear_newline_charspack_record)	MinimalFS)	ICON_PATHPATH_TO_TABLETABLE_NO_CACHEcacher)ChangedPackageHasChecksumsAndSize)modelz^[a-zA-Z0-9]*$c            
         a  ] tR t^2tRRRRRRR. RR/R V 3R	 llltR
 t]R 4       t]R 4       t	R R lt
R R ltR R ltR R ltR!R]/R R llltR R ltR R ltR R ltR R ltRtV ;t# )"	PsqlCachefsNchannel_urlupstream_stageinclude_stagesdb_urlz8postgresql://conda_index_test@localhost/conda_index_testc               0    V ^8  d   QhRRRRRRRRR	RR
R/# )   channel_rootz
Path | strsubdirstrr   zMinimalFS | Noner   
str | Noner    r!   z	list[str] )formats   ":lib/python3.14/site-packages/conda_index/postgres/cache.py__annotate__PsqlCache.__annotate__3   sF     $ $ $ $
 $  $ $ "$    c               	  < \         S	V `  ! VV3R VRVRVRV/VB  V P                  R,          R,          V n        Wpn        V P                  P                  4       '       g   V P                  P                  P                  RR7       V P                  P                  \        P                  ! R\        P                  ! ^4      P                  4       /4      4       RV n        MR	V n        \        P                  ! V P                  P!                  4       4      R,          V n        \$        P&                  ! \(        V P"                  4      '       g&   \+        V P                   R
V P"                   R24      hR# )r   r   r    r!   z.cachez
cache.jsonT)parents
channel_idFz contains invalid channel_id=""N)super__init__r%   db_filenamer"   existsparentmkdir
write_textjsondumpsosurandomhexcache_is_brand_newloads	read_textr1   rematchCHANNEL_ID_PATTERN
ValueError)
selfr%   r&   r   r   r    r!   r"   kwargs	__class__s
   &&&$$$$$,r+   r4   PsqlCache.__init__3   sJ    		
 	
 $		

 *	
 *	
 	
  ,,x7,F &&((##))$)7''

L"**Q-BSBSBU3V(WX&*D#&+D#**T%5%5%?%?%AB<Pxx*DOO<<##$$B4??BSSTU  =r.   c                v    V P                    Uu/ uF  qR9  g   K  WP                   V,          bK   	  up# u upi )z$
Remove db connection when pickled.
)engine)__dict__)rF   ks   & r+   __getstate__PsqlCache.__getstate__Y   s4    
 .2]]S]{>R#==##]SSSs   66c                N    V P                    RV P                  ;'       g    R R2# )z.
All paths must be prefixed with this string.
/_ROOT)r1   r&   )rF   s   &r+   database_prefixPsqlCache.database_prefix`   s)     //"!DKK$:$:7#;1==r.   c                	    \         '       d   \         # \        P                  ! V P                  R R7      p\        P
                  ! V4       Vs V# )F)echo)_engine
sqlalchemycreate_enginer"   r   create)rF   rK   s   & r+   rK   PsqlCache.enginei   s:    
 7N))$++EBVr.   c                J    \         P                  V P                   R24       R# )z&
Load filesystem cache into database.
z.convert() is not implementedN)logwarningrH   )rF   forces   &&r+   convertPsqlCache.convertu   s    
 	t~~&&CDEr.   c                    V ^8  d   QhRRRR/# )r$   stager(   listdir_statzIterable[dict[str, Any]]r)   )r*   s   "r+   r,   r-   |   s      /Gr.   c                B   T;'       g    V P                   pV P                  P                  4       ;_uu_ 4       p\        P                  P
                  pV P                  '       gv   VP                  VP                  4       P                  VP                  P                  V8H  VP                  P                  P                  V P                  RR7      4      4       V Uu. uF  p/ VCRV/CNK  	  ppV'       d   \        V4      pVP                  VP!                  VP                  P                  VP                  P                  .RVP"                  P$                  RVP"                  P&                  /R7      V4       RRR4       R# u upi   + '       g   i     R# ; i)z*
Write {path, mtime, size} into database.
T
autoescaperc   mtimesizeindex_elementsset_N)r    rK   beginr   Stat	__table__update_onlyexecutedeletewherecrc   path
startswithrS   r   on_conflict_do_updateexcludedrh   ri   )rF   rc   rd   
connectionstatitemitemsinsert_statements   &&&     r+   store_stat_statePsqlCache.store_stat_state|   sM    ,,,,[[  J::''D###""KKM''-..t/C/CPT.U ;GG,$--gu-,EG#)$< ""$::(,dffkk'B#%5%>%>%D%D"$4$=$=$B$B ;  	 !  H !  s   B&FF0BFFF	c               (    V ^8  d   QhRRRRRRRR/# )	r$   fnr'   ri   intmemberszdict[str, str | bytes]
index_jsonr   r)   )r*   s   "r+   r,   r-      s8     S SS S
 (S (Sr.   c                L   V P                  V4      pV P                  P                  4       ;_uu_ 4       pV EF  p\        V,          p	V	\        9   g   V	R8X  d   K%  \
        P                  P                  P                  V	,          p
RR/P                  W4      pRVWP                  V4      /pV\        8X  d   M(W,          e   \        P                  ! W,          4      W&   \        V
4      pVP                  ! R/ VB P                  V
P                   P"                  .WP$                  V,          /R7      p VP'                  V4       EK  	  Rp	\
        P                  P                  P                  V	,          p\        V4      pVP'                  \        V4      P                  WeR7      P                  VP                   P"                  .WP$                  P.                  /R7      4       \
        P                  P                  P                  R	,          pRVR
RRVRVRVR,          RVR,          /p\        V4      pVP'                  VP                  VP                   P"                  VP                   P0                  .RVP$                  P2                  RVP$                  P4                  RVP$                  P6                  RVP$                  P8                  /R7      V4       RRR4       R#   \(         d    \*        P-                  RY4       h i ; i  + '       g   i     R# ; i)z/
Write cache for a single package to database.
r   iconicon_pngru   Nrj   ztable=%s parameters=%s)ru   r   rz   rc   indexedrh   ri   sha256md5r)   )database_pathrK   rm   r   r   r   Basemetadatatablesgetr   r:   r@   r   valuesrw   rt   ru   rx   rq   r   r]   	exceptionr   rc   rh   ri   r   r   )rF   r   ri   rh   r   r   r   ry   	have_pathtable	table_objdata_column
parameters
insert_objqueryindex_json_table
stat_tabler   stat_inserts   &&&&&&             r+   storePsqlCache.store   s    **2.[[  J$	*95N*e|.C!JJ//66u=	%z266uDMY!7

 	)&2
 )-

:3D(EJ%#I.
"))7J7MM$-KK$4$4#5%':':;'GH N 
&&u-; %D !E$zz2299%@ 01J+,VVF**(8(:(:(?(?'@#%8%8%C%CD + 		 ,,33F;J*X.z%(F !,K11$.LL$5$5z||7I7I#J!5!5!;!; 4 4 9 9 +"6"6"="={3377	 2  w ! > ( MM":EN? !  s%   DL8K,	FL,#L	LL#	c                   V ^8  d   QhRR/# )r$   returnzlist[ChangedPackage]r)   )r*   s   "r+   r,   r-      s     * *"6 *r.   c                   \         P                  P                  p\        \	        V4      P                  VP                  P                  V P                  8H  4      R4      p\        \	        V4      P                  VP                  P                  R8H  4      R4      p\	        V4      P                  \        VVVP                  P                  VP                  P                  8H  RR7      4      P                  VP                  P                  P                  V P                  RR7      4      P                  \        VP                  P                  VP                  P                  8g  VP                  P                   VP                  P                   8g  VP                  P                  R8H  4      4      pV P"                  P%                  4       ;_uu_ 4       pVP'                  V4       Uu. uF/  p\)        VP                  VP                   VP                  R7      NK1  	  upuuRRR4       # u upi   + '       g   i     R# ; i)	zv
Compare upstream to 'indexed' state.

Return packages in upstream that are changed or missing compared to 'indexed'.
stat_fsr   stat_indexedTisouterrf   N)ru   ri   rh   )r   rn   ro   r
   r   rs   rt   rc   r    select_fromr   ru   rv   rS   r   rh   ri   rK   rm   rq   dict)rF   r   r   r   r   ry   rows   &      r+   changed_packagesPsqlCache.changed_packages   s    ZZ))
:$$Z\\%7%74;N;N%NO
 :$$Z\\%7%79%DE
 7O[ IINNlnn&9&99 	 U799>>,,T-A-Ad,STUIIOO|~~';';;IINNlnn&9&99 NN''4/ 	* [[  J &--e44C #((C4 !  !  s   H/(5H*H/*H//I 	r   c                    V ^8  d   QhRRRR/# )r$   desiredzset[str] | Noner   zIterator[IndexedShard]r)   )r*   s   "r+   r,   r-     s     +  + &+ 	+ r.   c          
   #  h  "   V P                  RR7      pV P                  P                  4       ;_uu_ 4       p\        P                  ! VP                  V4      R 4       F  w  rVR/ R/ R/ /p\        VVR,          VR,          VR,          R7      pV Ff  p	V	w  rrT;'       g    / VR&   V P                  V4      pV P                  V4      pVf   \        P                  R
V4       KU  V! V4      W~,          V&   Kh  	  V'       d	   WQ9   g   K  Vx  K  	  R	R	R	4       R	#   + '       g   i     R	# ; i5i)a8  
Yield (package name, all packages with that name) from database ordered
by name, path i.o.w. filename.

:param desired: If not None, set of desired package names.
:param pack_record: Function passed each record, returning a modified
    record. Override to change the default hex to bytes hash
    conversions.
Tinclude_run_exportsc                    V P                   # N)name)rM   s   &r+   <lambda>*PsqlCache.indexed_shards.<locals>.<lambda>2  s    !&&r.   packagespackages.condapackages.whl)r   r   packages_condapackages_whlrun_exportsN%s has unsupported extension)_indexed_records_queryrK   rm   	itertoolsgroupbyrq   r   
plain_pathpackage_section_for_pathr]   r^   )rF   r   r   r   ry   r   rows
shard_dictshardr   _ru   recordr   keys   &&$            r+   indexed_shardsPsqlCache.indexed_shards  s!     +++E [[  J'//""5) 
 )".>NTVW
$'
3#-.>#?!+N!;	  C360AV,7,=,=2F=)??40D77=C{$BDI  -8,?JOD)   $/K3 !   s)   5D2CDDD
D2D/	)	D2c                   V ^8  d   QhRR/# )r$   r   boolr)   )r*   s   "r+   r,   r-   K  s     #
 #
T #
r.   c                  \         P                  P                  P                  R,          p\         P                  P                  P                  R,          pVP                  P
                  VP                  P                  VP                  P                  .p\        VVVP                  P                  VP                  P                  8H  4      pV'       d   \         P                  P                  P                  R,          pVP                  VP                  P                  4       \        VVVP                  P                  VP                  P                  8H  RR7      pV P                  .V P                  ,           p\        V!  P                  V4      P                  VP                  P                   P#                  V4      4      P                  VP                  P                  P%                  V P&                  RR7      4      P)                  VP                  P
                  VP                  P                  4      # )zO
Query package records from index_json + stat, optionally joining run_exports.
r   rz   r   Tr   rf   )r   r   r   r   rt   r   ru   r   r   appendr   r    r!   r   r   rs   rc   in_rv   rS   order_by)rF   r   r   r   columnsfrom_clauserun_exports_tablecheck_stagess   &$      r+   r    PsqlCache._indexed_records_queryK  s    !::..55lCZZ((//7
 ####))

 ##z||'8'88
  %

 3 3 : := INN,..::;! ""''+<+>+>+C+CC	K ++,t/B/BBG[%U:<<%%)),78U:<<$$//0D0DQU/VWX&((--/?/A/A/F/FG	
r.   c                   V ^8  d   QhRR/# )r$   r   r   r)   )r*   s   "r+   r,   r-   p  s     
 
/ 
r.   c                   R/ R/ R/ /pV P                  RR7      pV P                  P                  4       ;_uu_ 4       pVP                  V4       F`  pV P	                  VP
                  4      pV P                  V4      pVf   \        P                  RV4       KK  VP                  W,          V&   Kb  	  RRR4       \        VR,          VR,          VR,          R7      #   + '       g   i     L3; i)	z)
Return package sections from the cache.
r   r   r   Fr   Nr   )r   r   r   )r   rK   rm   rq   r   ru   r   r]   r^   r   r   )rF   r   r   ry   r   ru   r   s   &      r+   indexed_packagesPsqlCache.indexed_packagesp  s     !"&6NBO
+++F [[  J!))%0sxx033D9;KK >E(+
% 1 ! 
+%&67#N3
 	
 ! s   A6CC.	c                   V ^8  d   QhRR/# )r$   r   r'   r)   )r*   s   "r+   r,   r-     s     Y Yc Yr.   c                   V P                   P                  4       ;_uu_ 4       p \        P                  P                  P
                  R,          pVP                  \        V4      P                  VP                  P                  V P                  8H  VP                  P                  V P                  V4      8H  4      4      P                  4       pV'       g   \        V4      hVP                   p\        P                  P                  P
                  pTR,          pTR,          pTR,          p	TR,          p
TR,          pTP'                  TR	TP                  P                  TP                  P                  8H  R
7      P'                  T	R	TP                  P                  T	P                  P                  8H  R
7      P'                  T
R	TP                  P                  T
P                  P                  8H  R
7      P'                  TR	TP                  P                  TP                  P                  8H  R
7      pTP                  \        T4      P                  TP                  P                  T P                  T4      8H  4      4      P                  4       pTf   / uuRRR4       # / pR F_  p\)        YN4      ;p'       g   K  \+        T\,        4      '       g!   \"        P%                  RT RT RT 24       KN  TP/                  T4       Ka  	  Y]R&   TP1                  R/ 4      p TP/                  TP3                  4        UUu/ uF  w  ppRT,           TbK  	  upp4       \7        TR4       \7        TR4       T'       d   \)        TR/ 4      M/ TR&   RRR4       T#   \         d&    \"        P%                  RT4       / u uuRRR4       # i ; iu uppi   \4         d     Li ; i  + '       g   i     X# ; i)z
Load package data into a single dict for channeldata.

:param fn: filename from channeldata.json; can be missing from database.
rz   z%s mtime not found in cacheNr   aboutpost_installreciper   T)r   onclausezscalar z
 found in z for rh   sourcesource_descriptionsummary)r   r   r   r   )rK   rm   r   r   r   r   rq   r   rs   rt   rc   r    ru   r   firstKeyErrorrh   r]   r^   r   getattr
isinstancer   updater   r|   AttributeErrorr   )rF   r   ry   r   r   rh   r   r   r   r   r   r   BIG_JOINdatacolumncolumn_datar   rM   vs   &&                 r+   load_all_from_cachePsqlCache.load_all_from_cache  sp    [[  J"ZZ0077?
 ((:&,,"**d.A.AA"))T-?-?-CC
 %'  "2,&		
 ZZ((//F-J7OE!.1LH%F /K  '\\..%'',,>   
   '\\..,..2E2EE  
  '\\..&((--?  
  '\\..+--2D2DD  ! . $$x &&z||'8'8D<N<Nr<R'RSeg  {o ! r D L")#"66;66%k488gk]*VHERTQU$VW KK, L "MXXh+F&,,.I.$!QY]A-.IJ  m4i0 FI'#}b"AbD_ !b K  92>	 ! v J! Q ! b ss   O"C	N.F)O""O">A!O" O>OO2O"#O;O"OO"OOO"OO""O3	c                   V ^8  d   QhRR/# )r$   r   zIterator[tuple[str, dict]]r)   )r*   s   "r+   r,   r-     s     I I7 Ir.   c              #    "   \         P                  P                  P                  R,          p\         P                  P                  P                  R,          pVP	                  W!P
                  P                  VP
                  P                  8H  RR7      pV P                  P                  4       ;_uu_ 4       pVP                  \        V4      P                  VP
                  P                  V P                  8H  4      4       F6  pV P                  VP                  4      VP                  ;'       g    / 3x  K8  	  RRR4       R#   + '       g   i     R# ; i5i)z\
Query returning run_exports data, to be formatted by
ChannelIndex.build_run_exports_data()
rz   r   T)r   r   N)r   r   r   r   r   rt   ru   rK   rm   rq   r   rs   rc   r    r   r   )rF   rz   r   r   ry   r   s   &     r+   r   PsqlCache.run_exports  s     
 zz""))&1jj))00?		&&++1C1C"CT  
 [[  J!))u##DFFLLD4G4G$GH sxx0#//2G2GRHH !   s%   B7E9A:E4
E>
EE		E)r?   r1   r5   r"   )Fr   )__name__
__module____qualname____firstlineno__r4   rN   propertyrS   r   rK   r`   r~   r   r   r   r   r   r   r   r   __static_attributes____classcell__)rH   s   @r+   r   r   2   s    $
  $$ #'$ #$ %'$ J$ $LT > > 	 	FBSj*X+ >I+  + Z#
J
0YvI Ir.   r   )1__doc__
__future__r   r   r:   loggingr<   rB   pathlibr   typingr   r   r   r   rX   psycopg2r   r	   r
   r   r   r   sqlalchemy.dialects.postgresqlr   conda_index.index.cacher   r   r   r   r   conda_index.index.fsr   conda_index.index.sqlitecacher   r   r   r   index.cacher   r    r   	getLoggerr   r]   rD   rW   r   r)   r.   r+   <module>r     s    #    	 	  9 9  % 9 9 1  +  A ! '  @I# @Ir.   