
    +j}                      t   d Z ddlmZ ddlmZ ddlmZ ddlmZmZ ddl	Z
ddl	mZmZ ddlmZ dd	lmZ dd
lmZmZ ddlmZmZmZmZmZ ddlmZmZmZmZmZm Z m!Z! ddl"m#Z#m$Z$ d Z%de&de'de(fdZ)de&de*e(         fdZ+dede&dedz  fdZ,dede&de&defdZ-dede&dedz  fdZ.dede&de&de'fdZ/dede&de0fdZ1dede&de0fdZ2	 	 	 	 djdede&d!e&de&de&dz  d"e'dz  d#e&dz  dedz  fd$Z3	 	 	 	 djdede&d!e&de&de&dz  d"e'dz  d#e&dz  de4ee0f         fd%Z5	 dkded&ed#e&dz  ddfd'Z6	 	 	 	 	 	 	 	 	 	 	 dldede&d)e'd*e'd+e&dz  d,ee&         dz  d-ee&         dz  d.e(dz  d/e&dz  d0e&dz  d1e7dz  d2e&dz  de4e*e         e(e&e*e&         f         e'f         fd3Z8	 dmdede&de&de4eee*e&         f         dz  fd4Z9	 dmdede&de&de4eef         dz  fd5Z:	 	 dndede&d7edz  d8e0ddf
d9Z;dede&d!e&ddfd:Z<	 dkdede&d7edz  ddfd;Z=ded<eddfd=Z>	 dkdede&d>e(dz  ddfd?Z?	 dkdede&d@e(dz  ddfdAZ@dede&de&de0fdBZAdede&de&de0fdCZB	 dkdede&dDe&dz  ddfdEZC G dF dGe          ZDdede&dee         fdHZEdede&de*e&         fdIZF	 dmdede&de&d!e&d"e'de&de4e0e0f         fdJZGdedKe*e&         de'fdLZHdedMe*e&         de'fdNZIdede*e&         fdOZJdedPe*e&         de'fdQZKdRdSdedTe*e&         dUe0de*eD         fdVZLdedWe*e&         dXe0de'fdYZMdedWe*e&         dXe0de'fdZZNdede&dXe0de'fd[ZOdedWe*e&         de'fd\ZPdede&de0fd]ZQ G d^ d_e          ZR	 	 dodedTe*e&         dae'd)e'de*eR         f
dbZSdedWe*e&         dce'de'fddZTdedee*e(         ddfdfZUdedge(e&e&f         deVe&         fdhZWdedWe*e&         deVe&         fdiZXdS )pzQuery functions for the unified AssetReference table.

This module replaces the separate asset_info.py and cache_state.py query modules,
providing a unified interface for the merged asset_references table.
    )defaultdict)datetime)Decimal)
NamedTupleSequenceN)deleteselect)sqlite)IntegrityError)Sessionnoload)AssetAssetReferenceAssetReferenceMetaAssetReferenceTagTag)MAX_BIND_PARAMSapply_metadata_filterapply_tag_filtersbuild_prefix_like_conditionsbuild_visible_owner_clausecalculate_rows_per_statementiter_chunks)escape_sql_like_stringget_utc_nowc                     | dS t          | t                    rdS t          | t          t          t          t
          f          rdS dS )NTF
isinstanceboolintfloatr   str)vs    K/home/wildlama/comfy/ComfyUI/app/assets/database/queries/asset_reference.py_check_is_scalarr%   %   sH    yt!T t!c5'3/00 t5    keyordinalreturnc                 J   t          |t                    r| |t          |          dS t          |t          t          t          f          r9t          |t                    r|nt	          t          |                    }| ||dS t          |t
                    r| ||dS | ||dS )z1Convert a scalar value to a typed projection row.)r'   r(   val_bool)r'   r(   val_num)r'   r(   val_strr'   r(   val_jsonr   )r'   r(   valuenums       r$   _scalar_to_rowr2   /   s    % IwDKKHHH%#ug.// @!%11Jeews5zz7J7Jw3???% Bw5AAA7>>>r&   c                 $    |g S t          |          rt           d|          gS t          |t                    rOt	          d |D                       r fdt          |          D             S  fdt          |          D             S  d|dgS )z5Turn a metadata key/value into typed projection rows.Nr   c              3   4   K   | ]}t          |          V  d S N)r%   ).0xs     r$   	<genexpr>z+convert_metadata_to_rows.<locals>.<genexpr>D   s+      22q""222222r&   c                 <    g | ]\  }}|t          ||          S r5   )r2   r6   ir7   r'   s      r$   
<listcomp>z,convert_metadata_to_rows.<locals>.<listcomp>E   s*    \\\$!QamN31--mmmr&   c                 &    g | ]\  }}|||dS )Nr.    r:   s      r$   r<   z,convert_metadata_to_rows.<locals>.<listcomp>F   s-    hhhdaZ[Zgq99ZgZgZgr&   r.   )r%   r2   r   listall	enumerate)r'   r0   s   ` r$   convert_metadata_to_rowsrB   ;   s    }	 /sAu--..% i22E22222 	]\\\\)E:J:J\\\\hhhhiPUFVFVhhhhA599::r&   sessionreference_idc                 8    |                      t          |          S r5   )getr   )rC   rD   s     r$   get_reference_by_idrG   M   s     ;;~|444r&   owner_idc                     t          | |          }|r|j        t          d| d          |j        r|j        |k    rt	          d          |S )zFetch a reference and verify ownership.

    Raises:
        ValueError: if reference not found or soft-deleted
        PermissionError: if owner_id doesn't match
    )rD   NAssetReference 
 not foundz	not owner)rG   
deleted_at
ValueErrorrH   PermissionError)rC   rD   rH   refs       r$   get_reference_with_owner_checkrP   T   si     gL
A
A
AC E#.,C<CCCDDD
| +00k***Jr&   	file_pathc                     |                      t          t                                        t          j        |k                                  d                                                                                    S )z!Get a reference by its file path.   )executer	   r   whererQ   limitscalarsfirst)rC   rQ   s     r$   get_reference_by_file_pathrY   g   s^     	>""(()AY)NOOUUVWXX	
 	
 
	r&   asset_idexclude_reference_idc                     |                      t                                        t          j        |k    t          j        |k    t          j                            d                                                    S )zKCount active (non-deleted) references to an asset, excluding one reference.N)queryr   filterrZ   idrL   is_count)rC   rZ   r[   s      r$   count_active_siblingsrb   u   s]     	n%%	#x/!55%))$//

 


 
r&   c                    t          t          j        d                                        t                                        t          j        |k                                  t          j                            d                     	                    d          }| 
                    |                                          d uS )NTrS   )r	   saliteralselect_fromr   rU   rZ   rL   r`   rV   rT   rX   )rC   rZ   qs      r$   reference_exists_for_asset_idrh      s    
 	rz$  	^	$	$	~&(2	3	3	~(,,T22	3	3	q  ??1##%%T11r&   c                    t          t          j        d                                        t                                        t          j        |k                                  t          j                            d                    	                    d          }| 
                    |                                          duS )zGReturn True if a reference with the given ID exists (not soft-deleted).TNrS   )r	   rd   re   rf   r   rU   r_   rL   r`   rV   rT   rX   )rC   rD   rg   s      r$   reference_existsrj      s     	rz$  	^	$	$	~ L0	1	1	~(,,T22	3	3	q  ??1##%%T11r&    namemtime_ns
preview_idc                 $   t                      }	 |                                 5  t          |||||||||	  	        }|                     |           |                                  |cddd           S # 1 swxY w Y   dS # t
          $ r Y dS w xY w)zHInsert a new AssetReference. Returns None if unique constraint violated.)	rZ   rl   rH   rQ   rm   rn   
created_at
updated_atlast_access_timeN)r   begin_nestedr   addflushr   )	rC   rZ   rl   rH   rQ   rm   rn   nowrO   s	            r$   insert_referencerw      s     --C!!## 	 	 !!#!%!$
 
 
C KKMMOOO	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	    tts5   B AA4'B 4A88B ;A8<B 
BBc           
          t          | ||||||          }|r|dfS |rt          | |          }n|                     t          t                                        t          j        |k    t          j        |k    t          j        |k    t          j	        
                    d                                        d                                                                                    }|st          d          |dfS )a  Get existing or create new AssetReference.

    For filesystem references (file_path is set), uniqueness is by file_path.
    For API references (file_path is None), we look for matching
    asset_id + owner_id + name.

    Returns (reference, created).
    )rZ   rl   rH   rQ   rm   rn   TNrS   z4Failed to find AssetReference after insert conflict.F)rw   rY   rT   r	   r   rU   rZ   rl   rH   rQ   r`   rV   uniquescalar_one_or_noneRuntimeError)	rC   rZ   rl   rH   rQ   rm   rn   rO   existings	            r$   get_or_create_referencer}      s   "   C  Dy  
-gyAA OO~&&"+x7"'4/"+x7",0066	  q	 	 VXX!! 	  SQRRRU?r&   	referencec                 X    t                      }|r|j        |k    r||_        ||_        dS )zGUpdate timestamps and optionally preview_id on existing AssetReference.N)r   rn   rq   )rC   r~   rn   rv   s       r$   update_reference_timestampsr      s8     --C *i*j88)	Ir&   d   rV   offsetname_containsinclude_tagsexclude_tagsmetadata_filtersortorderafter_cursor_valueafter_cursor_idc                 :   t          t                                        t          t          j        t          j        k                                  t          |                                        t          j        dk                                  t          j	        
                    d                                        t          t          j                            }|rJt          |          \  }}|                    t          j                            d| d|                    }t#          |||          }t%          ||          }|pd                                }|	pd                                }	t          j        t          j        t          j        t          j        t          j        d}|                    |t          j                  }|	dk    }|
||r?t3          j        ||
k     t3          j        ||
k    t          j        |k                         }n>t3          j        ||
k    t3          j        ||
k    t          j        |k                        }|                    |          }|rt          j                                        nt          j                                        }|r|                                n|                                }|                    ||                              |          }||                     |          }t          t2          j!        "                                          #                    t                                        t          t          j        t          j        k                                  t          |                                        t          j        dk                                  t          j	        
                    d                    }|rJt          |          \  }}|                    t          j                            d| d|                    }t#          |||          }t%          ||          }tI          | %                    |          &                                pd          }| %                    |          '                                (                                )                                }d	 |D             }tU          tV                    }|r| %                    t          tX          j-        t\          j                                      t\          t\          j        tX          j/        k                                  tX          j-        0                    |                                        tX          j/                                                            }|)                                D ] \  }}||         1                    |           !tW          |          ||fS )
u,  List references with pagination, filtering, and sorting.

    When ``after_cursor_value``/``after_cursor_id`` are supplied the query uses
    keyset pagination — ``offset`` is ignored and a WHERE clause selects rows
    strictly after the given ``(sort_col, id)`` position in the active sort
    direction. The cursor value must already be typed for the column
    (datetime for time sorts, int for size, str for name); the caller decodes
    the opaque cursor string and resolves to the typed value.

    Returns (references, tag_map, total_count).
    FN%)escaperp   desc)rl   rp   rq   rr   sizer   c                     g | ]	}|j         
S r>   )r_   )r6   rs     r$   r<   z(list_references_page.<locals>.<listcomp>b  s    ---1!$---r&   )2r	   r   joinr   r_   rZ   rU   r   
is_missingrL   r`   optionsr   tagsr   rl   iliker   r   lowerrp   rq   rr   
size_bytesrF   rd   or_and_r   ascorder_byrV   r   funcra   rf   r    rT   
scalar_onery   rW   r@   r   r?   r   asset_reference_idr   tag_namein_append)rC   rH   rV   r   r   r   r   r   r   r   r   r   baseescapedescsort_mapsort_col
descendingkeysetid_expsort_exp
count_stmttotalrefsid_listtag_maprowsref_idr   s                                r$   list_references_pager     s   4 	~	eUX!88	9	9	)(33	4	4	~(E1	2	2	~(,,T22	3	3	+,,	-	- 	  Q-m<<zz.-33NNNN33OOPPT<>>D 77D L''))D_f##%%E#$/$/*;  H ||D.";<<H&J %/*E 		V--$668IO8[\\ FF
 V--$668IO8[\\ F zz&!! *4P^##%%%9J9N9N9P9PF",@x}}(,,..H==6**0077D{{6"" 	rw}}	^	$	$	eUX!88	9	9	)(33	4	4	~(E1	2	2	~(,,T22	3	3   
-m<<%%%%n'nnnS%AA
 

 #:|\JJJ&z?CCJ
++6688=A>>E??4  ''))11337799D-----G$/$5$5G -$7BBT#sx#4#==>>U$7;;GDDEEX'0446677	
 
 !%

 	- 	-FHFO""8,,,,::w%%r&   c                    t          t          t          t          j                                      t          t          j        t          j        k                                  t          t          j	        t          j        k    d                              t          t          j        t          j
        k    d                              t          j        |k    t          j                            d           t          |                                        t!          t          j                                                t          j                                                  }|                     |                                          }|sd S |d         \  }}}g }t-                      }	|D ]6\  }
}}|r.||	vr*|	                    |           |                    |           7|||fS )NT)isouterr   )r	   r   r   r   rl   r   r_   rZ   r   r   r   rU   rL   r`   r   r   r   r   r   r   rT   r@   setrt   r   )rC   rD   rH   stmtr   	first_reffirst_asset_r   seen_ref_assetr   s                r$   fetch_reference_asset_and_tagsr   q  s    	~uch//	eUX!88	9	9	0N4EE 
 

 


 
c380994	H	H	-%))$//&x00

 


 
+,,	-	-	#(,,..	!	! 	$ ??4  $$&&D t $QI{ADUUD"& " "fh 	",,HHXKK!!!k4''r&   c                 "   t          t          t                                        t          t          j        t          j        k                                  t          j        |k    t          j                            d           t          |                    
                    d                              t          t          j                            }|                     |                                          }|sd S |d         |d         fS )NrS   r   )r	   r   r   r   r_   rZ   rU   rL   r`   r   rV   r   r   r   rT   rX   )rC   rD   rH   r   pairs        r$   fetch_reference_and_assetr     s     	~u%%	eUX!88	9	9	-%))$//&x00

 


 
q	+,,	-	- 	 ??4  &&((D t7DGr&   Ttsonly_if_newerc                    |pt                      }t          j        t                                        t          j        |k              }|rS|                    t          j        t          j                            d           t          j        |k                         }| 	                    |
                    |                     d S )N)rr   )r   rd   updater   rU   r_   r   rr   r`   rT   values)rC   rD   r   r   r   s        r$   update_reference_access_timer     s     
	{}}B9^$$**>+<+LMMD 
zzF/33D99/"4 
 
 OODKKK4455555r&   c                     t                      }|                     t          j        t                                        t          j        |k                                  ||                     dS )z%Update the name of an AssetReference.)rl   rq   Nr   rT   rd   r   r   rU   r_   r   )rC   rD   rl   rv   s       r$   update_reference_namer     s`     --COO
	.!!	~ L0	1	1	Tc	*	*    r&   c                     |pt                      }|                     t          j        t                                        t          j        |k                                  |                     dS )z5Update the updated_at timestamp of an AssetReference.)rq   Nr   )rC   rD   r   s      r$   update_reference_updated_atr     sc     
	{}}BOO
	.!!	~ L0	1	1	2		    r&   rO   c                    |                      t          t                                        t          j        |j        k                         |                                  i |j        pi |j        pi }|sdS g }|	                                D ]\  }}t          ||          D ]}|                    t          |j        |d         t          |d                   |                    d          |                    d          |                    d          |                    d                               |r+|                     |           |                                  dS dS )	zDelete and rebuild AssetReferenceMeta rows from merged system+user metadata.

    The merged dict is ``{**system_metadata, **user_metadata}`` so user keys
    override system keys of the same name.
    Nr'   r(   r-   r,   r+   r/   )r   r'   r(   r-   r,   r+   r/   )rT   r   r   rU   r   r_   ru   system_metadatauser_metadataitemsrB   r   r    rF   add_all)rC   rO   mergedr   kr#   r   s          r$   rebuild_metadata_projectionr     sw    OO!""((1SV;	
 	
  
 MMOOOI$*I0A0GRIF %'D  1)!Q// 	 	AKK"'*v%)--EE),,EE),,UU:..UU:..  
 
 
 
	   r&   r   c                     |                      t          |          }|st          d| d          |pi |_        t	                      |_        |                                  t          | |           d S )NrJ   rK   )rF   r   rM   r   r   rq   ru   r   )rC   rD   r   rO   s       r$   set_reference_metadatar     su    
 ++nl
3
3C EC<CCCDDD%+C ]]CNMMOOO-----r&   r   c                     |                      t          |          }|st          d| d          |pi |_        t	                      |_        |                                  t          | |           dS )zESet system_metadata on a reference and rebuild the merged projection.rJ   rK   N)rF   r   rM   r   r   rq   ru   r   )rC   rD   r   rO   s       r$   set_reference_system_metadatar     su     ++nl
3
3C EC<CCCDDD)/RC ]]CNMMOOO-----r&   c                     t          j        t                                        t          j        |k    t          |                    }t          |                     |          j        pd          dk    S )Nr   )	rd   r   r   rU   r_   r   r    rT   rowcount)rC   rD   rH   r   s       r$   delete_reference_by_idr     sb    
 9^$$**\)"8,, D wt$$-233a77r&   c                 l   t                      }t          j        t                                        t          j        |k    t          j                            d          t          |                    	                    |          }t          |                     |          j        pd          dk    S )zMark a reference as soft-deleted by setting deleted_at timestamp.

    Returns True if the reference was found and marked deleted.
    N)rL   r   )r   rd   r   r   rU   r_   rL   r`   r   r   r    rT   r   )rC   rD   rH   rv   r   s        r$   soft_delete_reference_by_idr   +  s     --C
	.!!	-%))$//&x00

 


 
3		 	 wt$$-233a77r&   preview_reference_idc                 2   |                      t          |          }|st          d| d          |d|_        n5|                      t          |          st          d| d          ||_        t	                      |_        |                                  dS )zCSet or clear preview_id and bump updated_at. Raises on unknown IDs.rJ   rK   NzPreview AssetReference )rF   r   rM   rn   r   rq   ru   )rC   rD   r   rO   s       r$   set_reference_previewr   A  s     ++nl
3
3C EC<CCCDDD#{{>+?@@ 	YW7KWWWXXX- ]]CNMMOOOOOr&   c                   l    e Zd ZU dZeed<   eed<   edz  ed<   eed<   eed<   edz  ed<   edz  ed	<   dS )
CacheStateRowz/Row from reference query with cache state data.rD   rQ   Nrm   needs_verifyrZ   
asset_hashr   )__name__
__module____qualname____doc__r"   __annotations__r    r   r>   r&   r$   r   r   V  sr         99NNNDjMMMd
d
r&   r   c                    |                      t          t                                        t          j        |k                                  t          j        dk                                  t          j                            d                                         t          j	        
                                                                                                                    S )NF)rT   r	   r   rU   rZ   r   rL   r`   r   r_   r   rW   r@   rC   rZ   s     r$   list_references_by_asset_idr   b  s    
 	>""U>*h677U>,566U>,006677Xn'++--..	
 	
 
	
r&   c           	      ^   t          |                     t          t          j                                      t          j        |k                                  t          j                            d                                                              	                                          S )zReturn every file_path for an asset, including soft-deleted/missing refs.

    Used for orphan cleanup where all on-disk files must be removed.
    N)
r?   rT   r	   r   rQ   rU   rZ   isnotrW   r@   r   s     r$   list_all_file_paths_by_asset_idr   s  s|     >+,,U>*h677U>+11$7788	
 	

 
	  r&   c                    t                      }||||t          |          d|||d	} t          j        t                    j        d	i |                    t          j        g          }|                     |          }	t          |	j	        pd          dk    }
|
rdS t          j        t                                        t          j        |k                                  t          j        t          j        |k    t          j                            d          t          j        t          |          k    t          j        dk    t          j                            d                                                  |t          |          dd|          }|                     |          }t          |j	        pd          dk    }d|fS )
zUpsert a reference by file_path. Returns (created, updated).

    Also restores references that were previously marked as missing.
    F)	rZ   rQ   rl   rH   rm   r   rp   rq   rr   index_elementsr   )TFNT)rZ   rm   r   rL   rq   r>   )r   r    r
   insertr   r   on_conflict_do_nothingrQ   rT   r   rd   r   rU   r   rZ   rm   r`   r   rL   r   )rC   rZ   rQ   rl   rm   rH   rv   valsinsrescreatedupdres2updateds                 r$   upsert_referencer     s    --CMM
 
D	n%%		 		 			0H/I		J	J 
 //#

C#,#!$$q(G { 		.!!	~'94	5	5	F'83'++D11'3x==8)T1)//55 

 

 
H% 
 

 

 " ??3D$-$1%%)G'>r&   valid_prefixesc                    |sdS t          |          }t          j        | }|                     t          j        t
                                        t
          j                            d                                        t
          j	        
                    d                                        |                               t
          j        dk                                  d                    }|j        S )zMark references as missing when file_path doesn't match any valid prefix.

    Returns number of references marked as missing.
    r   NFTr   )r   rd   r   rT   r   r   rU   rQ   r   rL   r`   r   r   r   )rC   r   condsmatches_valid_prefixresults        r$   (mark_references_missing_outside_prefixesr    s      q(88E65>__
	.!!	~'--d33	4	4	~(,,T22	3	3	$$	%	%	~(E1	2	2	4	 	  F ?r&   
file_pathsc                    |sdS d}t          |t                    D ]}|                     t          j        t
                                        t
          j                            |                                        t
          j	        dk                                  t
          j
                            d                                        d                    }||j        z  }|S )zkRestore references that were previously marked as missing.

    Returns number of references restored.
    r   TNFr   )r   r   rT   rd   r   r   rU   rQ   r   r   rL   r`   r   r   )rC   r  r   chunkr  s        r$   restore_references_by_pathsr    s    
  qEZ99 ! !In%%U>+//6677U>,455U>,006677VuV%%
 
 	 Lr&   c                    t          j        t          j        d                                        t          j        t          j        k                                  t          j        dk                                  t          j	        
                    d                                        t                                                    }t          j        t          j                                      t          j        
                    d          |           }d |                     |                                          D             S )zGet IDs of unhashed assets (hash=None) with no active references.

    An asset is considered unreferenced if it has no references,
    or all its references are marked as missing.

    Returns list of asset IDs that are unreferenced.
    rS   FNc                     g | ]
}|d          S )r   r>   r6   rows     r$   r<   z7get_unreferenced_unhashed_asset_ids.<locals>.<listcomp>  s    GGGsCFGGGr&   )rd   r	   re   rU   r   rZ   r   r_   r   rL   r`   	correlateexistshashrT   r@   )rC   active_ref_existsunreferenced_subqs      r$   #get_unreferenced_unhashed_asset_idsr    s     		"*Q--  	~&%(2	3	3	~(E1	2	2	~(,,T22	3	3	5			  	%(++11
t00  HGgoo.?@@DDFFGGGGr&   	asset_idsc                    |sdS d}t          |t                    D ]}|                     t          j        t
                                        t
          j                            |                               |                     t          j        t                                        t          j
                            |                              }||j        z  }|S )zUDelete assets and their references by ID.

    Returns number of assets deleted.
    r   )r   r   rT   rd   r   r   rU   rZ   r   r   r_   r   )rC   r  r   r  r  s        r$   delete_assets_by_idsr    s    
  qEY88 ! !In%%++N,C,G,G,N,NOO	
 	
 	
 5!1!1!7!7U8K8K!L!LMM Lr&   F)include_missingprefixesr  c          	         |sg S t          |          }t          j        t          j        t          j        t          j        t          j        t          j        t          j
        t          j                                      t          t          j        t          j        k                                  t          j                            d                                        t          j                            d                                        t          j        |           }|s#|                    t          j        dk              }|                     |                    t          j                                        t          j                                                                                            }d |D             S )aO  Get all references with file paths matching any of the given prefixes.

    Args:
        session: Database session
        prefixes: List of absolute directory prefixes to match
        include_missing: If False (default), exclude references marked as missing

    Returns:
        List of cache state rows with joined asset data
    NFc                     g | ]Y}t          |d          |d         |d         |d         |d         |d         |d         t          |d                   nd          ZS )	r   rS                  N)rD   rQ   rm   r   rZ   r   r   )r   r    r
  s     r$   r<   z/get_references_for_prefixes.<locals>.<listcomp>?  s}         	Q!fVQV1v&)!f&8s3q6{{{d	
 	
 	
  r&   )r   rd   r	   r   r_   rQ   rm   r   rZ   r   r  r   r   rU   r   rL   r`   r   r   rT   r   r   r@   )rC   r  r  r   r]   r   s         r$   get_references_for_prefixesr    s\      	(22E 		$#'#J	
 	
 
eUX!88	9	9	~'--d33	4	4	~(,,T22	3	3	rvu~		 
   @N5>????~.2244n6G6K6K6M6MNN 	cee 	     r&   reference_idsr0   c                 6   |sdS d}t          |t                    D ]|}|                     t          j        t
                                        t
          j                            |                    	                    |                    }||j
        z  }}|S )zXSet needs_verify flag for multiple references.

    Returns: Number of rows updated
    r   )r   r   r   rT   rd   r   r   rU   r_   r   r   r   rC   r  r0   r   r  r  s         r$   bulk_update_needs_verifyr#  M  s      qE]O<< ! !In%%U>$((//00VV''
 

 	 Lr&   c                 6   |sdS d}t          |t                    D ]|}|                     t          j        t
                                        t
          j                            |                    	                    |                    }||j
        z  }}|S )zVSet is_missing flag for multiple references.

    Returns: Number of rows updated
    r   r   r!  r"  s         r$   bulk_update_is_missingr%  a  s      qE]O<< ! !In%%U>$((//00VuV%%
 

 	 Lr&   c                 2   |                      t          j        t                                        t          j        |k                                  t          j                            d                                        |                    }|j	        S )zgSet is_missing flag for ALL references belonging to an asset.

    Returns: Number of rows updated
    Nr   )
rT   rd   r   r   rU   rZ   rL   r`   r   r   )rC   rZ   r0   r  s       r$   update_is_missing_by_asset_idr'  u  sp     __
	.!!	~&(2	3	3	~(,,T22	3	3	5	!	!	 F ?r&   c                    |sdS d}t          |t                    D ]h}|                     t          j        t
                                        t
          j                            |                              }||j	        z  }i|S )zIDelete references by their IDs.

    Returns: Number of rows deleted
    r   )
r   r   rT   rd   r   r   rU   r_   r   r   )rC   r  r   r  r  s        r$   delete_references_by_idsr)    s    
  qE]O<< ! !In%%++N,=,A,A%,H,HII
 
 	 Lr&   c                    |                      t          |          }|sdS |j        dS |                     t	          j        t                                        t          j        |k                         |                     |           dS )zDelete a seed asset (hash is None) and its references.

    Returns: True if asset was deleted, False if not found or has a hash
    FNT)	rF   r   r  rT   rd   r   r   rU   rZ   )rC   rZ   assets      r$   delete_orphaned_seed_assetr,    s    
 KKx((E uzuOO
	.!!''(?8(KLL   NN54r&   c                   <    e Zd ZU dZeed<   eed<   eed<   eed<   dS )UnenrichedReferenceRowz&Row for references needing enrichment.rD   rZ   rQ   enrichment_levelN)r   r   r   r   r"   r   r    r>   r&   r$   r.  r.    sB         00MMMNNNr&   r.    	max_levelc                    |sg S t          |          }t          j        t          j        t          j        t          j        t          j                                      t          j        	                    d                                        t          j
                            d                                        t          j        |                               t          j        dk                                  t          j        |k                                  t          j                                                                      |          }|                     |                                          }d |D             S )a~  Get references that need enrichment (enrichment_level <= max_level).

    Args:
        session: Database session
        prefixes: List of absolute directory prefixes to scan
        max_level: Maximum enrichment level to include (0=stubs, 1=metadata done)
        limit: Maximum number of rows to return

    Returns:
        List of unenriched reference rows with file paths
    NFc           	      d    g | ]-}t          |d          |d         |d         |d                   .S )r   rS   r  r  )rD   rZ   rQ   r/  )r.  r
  s     r$   r<   z-get_unenriched_references.<locals>.<listcomp>  sU         	QV!f V		
 	
 	
  r&   )r   rd   r	   r   r_   rZ   rQ   r/  rU   r   rL   r`   r   r   r   r   rV   rT   r@   )rC   r  r1  rV   r   r]   r   s          r$   get_unenriched_referencesr4    s0   "  	(22E 		#$+		
 	
 
~'--d33	4	4	~(,,T22	3	3	rvu~			~(E1	2	2	~.);	<	<	.#''))	*	*	u 
  ??5!!%%''D     r&   levelc                     |sdS |                      t          j        t                                        t          j                            |                                        |                    }|j        S )zZUpdate enrichment level for multiple references.

    Returns: Number of rows updated
    r   )r/  )	rT   rd   r   r   rU   r_   r   r   r   )rC   r  r5  r  s       r$   bulk_update_enrichment_levelr7    sh      q__
	.!!	~ $$]33	4	4		'	' F
 ?r&   r   c                    |sdS d |D             }t          j        t                                        t          j        g          }t          |t          d                    D ]}|                     ||           dS )zBulk insert reference rows with ON CONFLICT DO NOTHING on file_path.

    Each dict should have: id, asset_id, file_path, name, owner_id, mtime_ns, etc.
    The is_missing field is automatically set to False for new inserts.
    Nc                     g | ]
}i |d diS )r   Fr>   r
  s     r$   r<   z;bulk_insert_references_ignore_conflicts.<locals>.<listcomp>  s(    BBBc11\511BBBr&   r      )r
   r   r   r   rQ   r   r   rT   )rC   r   enriched_rowsr   r  s        r$   'bulk_insert_references_ignore_conflictsr<    s      BBTBBBM
-
'
'
>
>&01 ?  C ],H,L,LMM $ $U####$ $r&   path_to_assetc                 "   |st                      S t          |                                          }t                      }t          |t          dz            D ]}t          j        t          j        t          j	                  
                    |          }|                     t          t          j                                      |                    }|                    |                                                                           |S )zQuery references to find paths where our asset_id won the insert.

    Args:
        path_to_asset: Mapping of file_path -> asset_id we tried to insert

    Returns:
        Set of file_paths where our asset_id is present
    r  )r   r?   r   r   r   rd   tuple_r   rQ   rZ   r   rT   r	   rU   r   rW   r@   )rC   r=  pairswinnersr  pairwiser  s          r$   %get_references_by_paths_and_asset_idsrC    s      uu$$&&''EG UOq$899 / /9^5~7NOOSS
 
 >+,,228<<
 
 	v~~''++--....Nr&   c                    |st                      S t                      }t          |t                    D ]}|                     t	          t
          j                                      t
          j                            |                              }|	                    |
                                                                           |S )z8Query to find which reference IDs exist in the database.)r   r   r   rT   r	   r   r_   rU   r   r   rW   r@   )rC   r  foundr  r  s        r$   get_reference_ids_by_idsrF  &  s    
  uueeE]O<< - ->$%%++N,=,A,A%,H,HII
 
 	V^^%%))++,,,,Lr&   )rk   NNNr5   )rk   r   r   NNNNNNNN)rk   )NT)r   r0  )Yr   collectionsr   r   decimalr   typingr   r   
sqlalchemyrd   r   r	   sqlalchemy.dialectsr
   sqlalchemy.excr   sqlalchemy.ormr   r   app.assets.database.modelsr   r   r   r   r   "app.assets.database.queries.commonr   r   r   r   r   r   r   app.assets.helpersr   r   r%   r"   r    dictr2   r?   rB   rG   rP   rY   rb   r   rh   rj   rw   tupler}   r   objectr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r  r  r#  r%  r'  r)  r,  r.  r4  r7  r<  r   rC  rF  r>   r&   r$   <module>rT     s    $ # # # # #             ' ' ' ' ' ' ' '     % % % % % % % % & & & & & & ) ) ) ) ) ) * * * * * * * *                               C B B B B B B B  	? 	?c 	?T 	? 	? 	? 	?;# ;d ; ; ; ;$555 d5 5 5 5  	   & d     		   "222 
2 2 2 2222 
2 2 2 2&  !   	
 Tz Dj d
 d   F  !1 111 1 	1
 Tz1 Dj1 d
1 >4 1 1 1 1n "	 			 d
	 
		 	 	 	  $)-)-#'(,"&l& l&l&l& l& 	l&
 :l& 3-$&l& 3-$&l& D[l& *l& :l& l& 4Zl& 4c49n!5s:;l& l& l& l&d "( "("("( "( >5$s)+,t3	"( "( "( "(P    >5 !D(	   2 	6 666 	46 	6
 
6 6 6 6$  
	   "   	4 
	   ! !~ !$ ! ! ! !N "&. ... $;. 
	. . . .& $(. ... D[. 
	. . . ."	8	8	8 	8 
		8 	8 	8 	8888 8 
	8 8 8 82 (,  * 
	   *	 	 	 	 	J 	 	 	 n   " 
#Y   2 6 666 6 	6
 6 6 4:6 6 6 6rI 	   0 d3i C    *H HT#Y H H H H,' d3i C    * "	7 7 773i7 	7
 
-7 7 7 7t%)#Y7;   (%)#Y7;   ( #,0    g d3i C      3 4    "    Z    	/ //3i/ / 	/
 

 !/ / / /d9  		   &$$
t*$ 
$ $ $ $&S> 	X   >9 	X     r&   