+
    {:j-                     *   R t ^ RIt^ RIt^ RIt^ RIt^ RIt^ RIt^ RIHtH	t	 ^RI
Ht ^RIHt ]P                  ! ]4      t^t]P$                  ! R]P&                  4      t0 Rmt. ROtR tR tR	 R
 ltR R ltR tRR/tRtRR ltR tR t RR lt!R# )a  
Given a conda <subdir>/.cache directory or a .tar.bz2 of that directory,

Create a sqlite database with the same data.

Intended to be used as a transition between the older format and a newer version
of `conda-build index`, or as the foundation of a package database.
N)chainislice)common)IndexedStagesz
    (?P<channel>[^/]*)/
    (?P<subdir>[^/]*)/
    .cache/
    (?P<path>(stat.json|
        (?P<kind>recipe|index|icon|about|recipe_log|run_exports|post_install)/(?P<basename>\S*?)(?P<ext>.\w+$))
    )
index_jsonc                   V P                  R4       V P                  R4       V P                  R4       V P                  R4       V P                  R4       V P                  R4       V P                  R4       V P                  R\        P                  P                   R	24       V P                  R
4       V P                  R4       R# )z2
Create schema. Safe to call on every connection.
zDCREATE TABLE IF NOT EXISTS about (path TEXT PRIMARY KEY, about BLOB)z
        CREATE TABLE IF NOT EXISTS index_json (
            path TEXT PRIMARY KEY, index_json BLOB,
            name AS (json_extract(index_json, '$.name')),
            sha256 AS (json_extract(index_json, '$.sha256'))
        )
        zFCREATE TABLE IF NOT EXISTS recipe (path TEXT PRIMARY KEY, recipe BLOB)zNCREATE TABLE IF NOT EXISTS recipe_log (path TEXT PRIMARY KEY, recipe_log BLOB)zPCREATE TABLE IF NOT EXISTS run_exports (path TEXT PRIMARY KEY, run_exports BLOB)zRCREATE TABLE IF NOT EXISTS post_install (path TEXT PRIMARY KEY, post_install BLOB)zFCREATE TABLE IF NOT EXISTS icon (path TEXT PRIMARY KEY, icon_png BLOB)zOCREATE TABLE IF NOT EXISTS stat (
                stage TEXT NOT NULL DEFAULT 'z',
                path TEXT NOT NULL,
                mtime NUMBER,
                size INTEGER,
                sha256 TEXT,
                md5 TEXT,
                last_modified TEXT,
                etag TEXT
            )z@CREATE UNIQUE INDEX IF NOT EXISTS idx_stat ON stat (path, stage)z?CREATE INDEX IF NOT EXISTS idx_stat_stage ON stat (stage, path)N)executer   INDEXED_STAGEvalue)conns   &?lib/python3.14/site-packages/conda_index/index/convert_cache.pycreater   @   s     	LLWX
 	LL	 	LLP 	LLX 	LLZ 	LL\ 	LLP 	LL..;.I.I.O.O-P Q		 	LLSTLLRS    c                "   V P                  R4      P                  4       ^ ,          pV\        8  d   \        RV R\         24      hV^8  d   \	        V 4       V P                  R4       V^8  d   \        V 4       V P                  R4       R# R# )z\
Call on every connection to ensure we have the correct schema.

Call inside a transaction.
zPRAGMA user_versionz&conda-index cache is too new: version z > zPRAGMA user_version=1zPRAGMA user_version=2N)r   fetchoneUSER_VERSION
ValueErrorremove_prefixadd_computed_name)r   user_versions   & r   migrater   {   s     << 56??A!DLl"4\N#l^T
 	
 ad,-a$,- r   c                8    V ^8  d   QhR\         P                  /# )   r   sqlite3
Connection)formats   "r   __annotate__r      s     
 
** 
r   c                    \         P                  R4       R pV P                  R^VRR7       \        R.,            F  pV P	                  RV R24       K  	  R	# )
z
Store bare filenames in database instead of {channel}/{subdir}/{fn}

Could add a view or a virtual column to restore globally-unique paths.

Call inside a transaction.
zMigrate databasec                 b    \        V \        4      '       g   V # V P                  R 4      R,          # )/)
isinstancestrrsplit)paths   &r   basenameremove_prefix.<locals>.basename   s(    $$$K{{3##r   migrate_basenameT)deterministicstatzUPDATE OR IGNORE z7 SET path=migrate_basename(path) WHERE INSTR(path, '/')N)loginfocreate_functionTABLE_NAMESr   )r   r&   tables   &  r   r   r      s]     HH $ 	+QMx''w&]^	
 (r   c                8    V ^8  d   QhR\         P                  /# )r   dbr   )r   s   "r   r   r      s     
 
',, 
r   c                    \        R V P                  R4       4       4      pRV9  d   V P                  R4       RV9  d   V P                  R4       R# R# )z-
Add helpful computed columns to index_json.
c              3   2   "   T F  q^,          x  K  	  R# 5i)   N ).0rows   & r   	<genexpr>$add_computed_name.<locals>.<genexpr>   s     Q$PSa&&$Ps   zPRAGMA table_xinfo(index_json)namezNALTER TABLE index_json ADD COLUMN name AS (json_extract(index_json, '$.name'))sha256zRALTER TABLE index_json ADD COLUMN sha256 AS (json_extract(index_json, '$.sha256'))N)setr   )r1   columnss   & r   r   r      sS     QBJJ/O$PQQGW


\	
 w


`	
 r   c           	   #    "   \        V 4      P                  R4      '       g   Q V  R24       h\        P                  ! V 4       F  w  rp\        P                  R\        P                  P                  V4       24       V F  p\        P                  P                  W4      pRP                  VP                  \        P                  4      4      p\        P                  V4      pV'       g   Ko   \        VR4      ;_uu_ 4       pWx3x  RRR4       K  	  K  	  R#   + '       g   i     K  ; i  \         d"   p	\        P                  RYY4        Rp	?	K  Rp	?	ii ; i5i)z
Yield interesting (match, <bytes>) members of filesystem at path.

path should be an individual cache directory, e.g. <channel-name>/linux-64/.cache
.cachez must end with .cachezCONVERT r    rbNzPermission error: %s %s)r#   endswithoswalkr+   r,   r%   r&   joinsplitsep	PATH_INFOsearchopenPermissionErrorwarning)
r%   root_filesfilefullpath	posixpath	path_infoentryes
   &         r   extract_cache_filesystemrU      s     t9h''GD61F)GG'''$-8BGG,,T2345Dww||D/H!78I!((3IyHh--'.. .-  ( .--& HKK 98GGHsT   C(E0D0D	
D0
ED-'D0+E-D00E;EEEEindexi   c                    V R,           # )z_
Convert match to a database primary key. Retain the option to implement
globally unique keys.
r&   r5   )matchoverride_channels   &&r   db_pathrZ      s    
 J !r   c              #  h   "   \        V 4      pV F  p\        \        V.V4      V4      x  K  	  R# 5i)zK
Break iterable into n-item iterables.

Lazier than Python 3.12 batched().
N)iterr   r   )iterablensourceitems   &&  r   ichunkedra      s0      (^FUD66*A.. s   02c                L   \        \        V\        4      4       EF  w  r#\        P	                  RV 24       T ;_uu_ 4        V EFn  w  rEVR,          R8X  d   V P                  R\        P                  P                   R24       \        P                  ! V4      P                  4        F7  w  rgWgR&   V P                  R\        P                  P                   R2V4       K9  	  K  VR,          R	8X  d]   \        P                  VR
,          VR
,          4      p V P                  RV RV R2R\        V4      RVP                  4       /4       EK  VR
,          R8X  d1   V P                  RR\        V4      RVP                  4       /4       EKJ  \        P%                  RVP)                  4       4       EKq  	  RRR4       EK  	  R#   \         P"                   d3   p	\        P%                  RTP'                  ^ 4      T	4        Rp	?	EK  Rp	?	ii ; i  + '       g   i     EK	  ; i)z
Convert old style `conda index` cache to sqlite cache.

conn: sqlite3 connection
cache_generator: extract_cache() or extract_cache_filesystem()
override_channel: if channel_name is not in path

Commits own transactions.
zBEGIN BATCH r%   z	stat.jsonzDELETE FROM stat WHERE stage=''zVINSERT OR REPLACE INTO stat (path, mtime, size, stage) VALUES (:path, :mtime, :size, 'z')extz.jsonkindz/
                        INSERT OR IGNORE INTO  (path, zN)
                        VALUES (:path, json(:data))
                        datazSQL error. Not JSON? %s %sNiconz
                    INSERT OR IGNORE INTO icon (path, icon_png)
                    VALUES (:path, :data)
                    zUnhandled %r)	enumeratera   
CHUNK_SIZEr+   r,   r   r   r	   r
   jsonloaditems	TABLE_MAPgetrZ   readr   OperationalErrorrK   groups	groupdict)
r   cache_generatorichunkrX   memberkeyr
   r/   rT   s
   &&        r   convert_cachery      s    h
CD<s#$T!&=K/ LL89T9T9Z9Z8[[\] '+ii&7&=&=&?
(+ft  vC  vQ  vQ  vW  vW  uX  XZ  [! '@ 5\W,
 &MM%-vGEV!//4gXeW E
 !' &	 6]f,LL
 #GEN"FKKM	 KK0AB_ "' T ED #33 V$@%,,q/STUUVA TTs8   CH4GA*HH&H	H	HHH#c                   ^ RI Hp \        P                  P	                  V 4      p\
        P                  RV 24       \        P                  ! V4      pV;_uu_ 4        \        V4       RRR4       V EF8  p\        P                  P                  WRR4      p\        P                  P                  V4      '       g   KL  V RV R2p\
        P                  R\        P                  P                  V\        P                  P                  V 4      4       RV 24       VP                  R	V34       \         F`  pR
R/P!                  W4      p	VR
8X  d   K  RV RV	 RV	 RV RV	 RV	 RV	 RV	 R2p
 V;_uu_ 4        VP                  W34       RRR4       Kb  	  VP                  R4       EK;  	  R#   + '       g   i     ELR; i  + '       g   i     K  ; i  \"        P$                   d    \
        P'                  RT
4       h i ; i)z
Combine {channel_root}/*/.cache/cache.db databases into a single database.
Useful for queries. Not used by any part of the indexing process.
)DEFAULT_SUBDIRSzMerge caches for channel Nr?   zcache.dbr    zMerge z as zATTACH DATABASE ? AS subdirrh   icon_pngzINSERT INTO main.rf   z )
            SELECT ? || path, z FROM subdir.zS WHERE true -- avoid syntax ambiguity
            ON CONFLICT (path) DO UPDATE SET z = excluded.z
            WHERE z != excluded.z% -- does this avoid work
            zOperationalError on %szDETACH DATABASE subdir)conda_index.utilsr{   rB   r%   r&   r+   r,   r   connectr   rD   existsrelpathdirnamer   r.   ro   r   rq   error)channel_root	output_dbr{   channel_namecombined_dbsubdircache_dbchannel_prefixr/   columnquerys   &&         r   merge_index_cacher   (  s   
 277##L1LHH(78..+K	{ 
!77<<h
Kww~~h''(>6(!4RWW__Xrww|/LMNdSaRbc	
 	9H;G E j)--e;F)% A%hmE7 ;..4X\& J(-x 0E
 [''/@A ![ !$ 	459 " 
0 ![[++ 		2E:s6   F32
G<G	G3G	GGG-H>    clonesclones/conda-forgeclones/conda-forge/linux-64"clones/conda-forge/linux-64/.cache'clones/conda-forge/linux-64/.cache/icon(clones/conda-forge/linux-64/.cache/about(clones/conda-forge/linux-64/.cache/index)clones/conda-forge/linux-64/.cache/recipe-clones/conda-forge/linux-64/.cache/recipe_log.clones/conda-forge/linux-64/.cache/run_exports/clones/conda-forge/linux-64/.cache/post_install)aboutrh   r   post_install
recipe_logreciperun_exports)N)z	merged.db)"__doc__rk   loggingrB   os.pathrer   	itertoolsr   r   r   r   cacher   	getLogger__name__r+   r   compileVERBOSErG   TYPICAL_DIRECTORIESr.   r   r   r   r   rU   rn   rj   rZ   ra   ry   r   r5   r   r   <module>r      s      	  	  #   ! JJ	 JJ		 8Tv..
2
H, l#	
"/=C@(6r   