
    u*e)                         d Z ddlZddlZddlZddlZddlZddlZddlmZ ddl	m
Z
  ej        e          ZdZ ej        dej                  Zh dZg dZd	 Zd
 Zdej        fdZd ZddiZdZddZd ZddZdS )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)ichunked   )commonz
    (?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+$))
    )>   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 clones)abouticon
index_jsonpost_install
recipe_logreciperun_exportsc                    |                      d           |                      d           |                      d           |                      d           |                      d           |                      d           |                      d           |                      d           |                      d	           |                      d
           dS )z:
    Create schema. Safe to call on every connection.
    zDCREATE TABLE IF NOT EXISTS about (path TEXT PRIMARY KEY, about BLOB)zNCREATE TABLE IF NOT EXISTS index_json (path TEXT PRIMARY KEY, index_json BLOB)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)a;  CREATE TABLE IF NOT EXISTS stat (
                stage TEXT NOT NULL DEFAULT 'indexed',
                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)execute)conns    ?lib/python3.11/site-packages/conda_index/index/convert_cache.pycreater   @   s    	LLWXXX
 	LLX   	LLP   	LLX   	LLZ   	LL\   	LLP   	LL		   	LLSTTTLLRSSSSS    c                     |                      d                                          d         }|t          k    rt          d          |dk    rdS t	          |            |                      d           dS )zh
    Call on every connection to ensure we have the correct schema.

    Call inside a transaction.
    zPRAGMA user_versionr   zEconda-index cache is too new: version {user_version} > {USER_VERSION}NzPRAGMA user_version=1)r   fetchoneUSER_VERSION
ValueErrorremove_prefix)r   user_versions     r   migrater%   u   s     << 566??AA!DLl""S
 
 	
 a$ 	LL()))))r   r   c                    t                               d           d }	 |                     dd|d           n(# t          $ r |                     dd|           Y nw xY wt          dgz   D ]}|                     d	| d
           dS )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                 f    t          | t                    s| S |                     d          d         S )N/)
isinstancestrrsplit)paths    r   basenamezremove_prefix.<locals>.basename   s0    $$$ 	K{{3##r   migrate_basenamer   T)nargfuncdeterministic)r0   r1   statzUPDATE OR IGNORE z7 SET path=migrate_basename(path) WHERE INSTR(path, '/')N)loginfocreate_function	TypeErrorTABLE_NAMESr   )r   r.   tables      r   r#   r#      s     HH   $ $ $
HQXT 	 	
 	
 	
 	
  H H H/ahGGGGGH x' 
 
^^^^	
 	
 	
 	

 
s   9 "AAc              #     K   t          |                               d          sJ |  d            t          j        |           D ]\  }}}t                              dt          j                            |                      |D ]}t          j                            ||          }d                    |	                    t          j
                            }t                              |          }|rc	 t          |d          5 }||fV  ddd           n# 1 swxY w Y   # t          $ r&}	t                              d||	           Y d}	~	d}	~	ww xY wԐdS )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walkr4   r5   r-   r.   joinsplitsep	PATH_INFOsearchopenPermissionErrorwarn)
r-   root_filesfilefullpath	posixpath	path_infoentryes
             r   extract_cache_filesystemrQ      s      t99h''GGD)G)G)GGGG'$-- E Ea4BG,,T2244555 		E 		EDw||D$//H!7!788I!((33I EEh-- /'..../ / / / / / / / / / / / / / /& E E EHH6!DDDDDDDDE	E			EE Es<   :D)
DD)D!!D)$D!%D))
E3EEindexr   i   c                     | d          S )zk
    Convert match to a database primary key. Retain the option to implement
    globally unique keys.
    r.    )matchoverride_channels     r   db_pathrW      s    
 J!!r   c           
         t          t          |t                              D ]\  }}t                              d|            | 5  |D ]\  }}|d         dk    r]|                     d           t          j        |                                          D ] \  }}||d<   |                     d|           !o|d         dk    rt          
                    |d         |d                   }	 |                     d	| d
| dt          |          |                                d           # t          j        $ r:}	t                              d|                    d          |	           Y d}	~	'd}	~	ww xY w|d         dk    r:|                     dt          |          |                                d           ut                              d|                                           	 ddd           n# 1 swxY w Y   dS )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='indexed'z_INSERT OR REPLACE INTO stat (path, mtime, size, stage) VALUES (:path, :mtime, :size, 'indexed')extz.jsonkindz/
                        INSERT OR IGNORE INTO  (path, zN)
                        VALUES (:path, json(:data))
                        )r-   datazSQL error. Not JSON? %s %sr   Nr   z
                    INSERT OR IGNORE INTO icon (path, icon_png)
                    VALUES (:path, :data)
                    zUnhandled %r)	enumerater   
CHUNK_SIZEr4   r5   r   jsonloaditems	TABLE_MAPgetrW   readsqlite3OperationalErrorrG   groups	groupdict)
r   cache_generatorichunkrU   memberkeyvaluer9   rP   s
             r   convert_cachero      s    h
CCDD 1@ 1@5###$$$ /	@ /	@!& .@ .@v=K// LL!IJJJ&*i&7&7&=&=&?&?  
U(+f}!    5\W,,
 &MM%-vGGES/4 >C  
 )0(. 	 	 	 	 #3 S S S!=u||APQRRRRRRRRS 6]f,,LL
 %,ENN$*KKMM 	 	 	 	 HH^U__->->????].@/	@ /	@ /	@ /	@ /	@ /	@ /	@ /	@ /	@ /	@ /	@ /	@ /	@ /	@ /	@1@ 1@s>   B%G<.?D.-G<.E7	=/E2	,G<2E7	7A8G<<H 	H 		merged.dbc                    ddl m} t          j                            |           }t
                              d|            t          j        |          }|5  t          |           ddd           n# 1 swxY w Y   |D ]y}t          j        
                    | |dd          }t          j                            |          sE| d| d}t
                              dt          j                            |t          j                            |                      d	|            |                    d
|f           t          D ]}ddi                    ||          }	|dk    r!d| d|	 d|	 d| d|	 d|	 d|	 d|	 d}
	 |5  |                    |
|f           ddd           n# 1 swxY w Y   o# t"          j        $ r t
                              d|
            w xY w|                    d           {dS )z
    Combine {channel_root}/*/.cache/cache.db databases into a single database.
    Useful for queries. Not used by any part of the indexing process.
    r   )DEFAULT_SUBDIRSzMerge caches for channel Nr;   zcache.dbr(   zMerge z as zATTACH DATABASE ? AS subdirr   icon_pngzINSERT INTO main.r[   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.utilsrr   r>   r-   r.   r4   r5   r   connectr   r@   existsrelpathdirnamer   r8   rc   re   rf   error)channel_root	output_dbrr   channel_namecombined_dbsubdircache_dbchannel_prefixr9   columnquerys              r   merge_index_cacher   
  s
   
 2111117##L11LHH777888.++K	  {              ! 6 67<<fh
KKw~~h'' 	(446444cRW__Xrw|/L/LMMccSacc	
 	
 	
 	9H;GGG  	 	E j)--eU;;F%    % 49 .4 BH    )/  E
  B B''/@AAAB B B B B B B B B B B B B B B+   		2E::: 	4555596 6sB   A55A9<A9F7F+F7+F//F72F/3F77,G#)N)rp   )__doc__r_   loggingr>   os.pathrere   more_itertoolsr   r   r   	getLogger__name__r4   r!   compileVERBOSErC   TYPICAL_DIRECTORIESr8   r   r%   
Connectionr#   rQ   rb   r^   rW   ro   r   rT   r   r   <module>r      sn      				  				  # # # # # #      g!! BJ	 J	 		     2T 2T 2Tj* * *,
* 
 
 
 
:E E E, l#	
" " " "<@ <@ <@~(6 (6 (6 (6 (6 (6r   