
    &                         S r SSKJr  SSKJr  SSKJr  SSKrSSKrSSKrSSKJ	r	  SSKJ
r
  SSKJr  SS	KJr  SSKrSS
KJr  SSKrS rSS jr " S S\R(                  5      r " S S\
R,                  5      rg)znA persistent cache implementation using sqlite3.

See the persistent_cache module for a detailed description.
    )absolute_import)division)unicode_literalsN)
exceptions)metadata_table)persistent_cache_base)files)rangec                      SR                  U S9$ )z~Returns a field reference name.

Args:
  column: The field column number counting from 0.

Returns:
  A field reference name.
z	f{column}column)formatr   s    -lib/googlecloudsdk/core/cache/sqlite_cache.py	_FieldRefr   '   s     
		6		**    c                    / nU (       a  [        [        U 5      5       H  nX   nUc  M  [        U[        R                  5      (       a\  UR                  SS5      R                  SS5      R                  SS5      nUR                  SR                  [        U5      US95        M  UR                  S	R                  [        U5      US
95        M     U(       d  gSSR                  U5      -   $ )aL  Returns a WHERE clause for the row template.

Column string matching supports * and ? match ops.

Args:
  row_template: A template row tuple. A column value None means match all
    values for this column. A None value for row means all rows.

Returns:
  A WHERE clause for the row template or the empty string if there is no none.
*%._"z""z{field} LIKE "{pattern}")fieldpatternz{field} = {term})r   term z WHERE z AND )
r
   len
isinstancesixstring_typesreplaceappendr   r   join)row_templatetermsindexr   r   s        r   _Wherer&   3   s     %s<() d		D#**	+	+,,sC(00c:BB3M/66E"G 7 5 	6 	'..E" / / 	0 * 

gll5)
))r   c                   Z   ^  \ rS rSrSr  S
U 4S jjrS rS rS rSS jr	SS jr
S	rU =r$ )_TableQ   aF  A persistent cache table.

Attributes:
  name: The table name.
  deleted: Table was deleted if True.
  modified: Table modify timestamp.
  timeout: Tables older than timeout are invalid.
  _cache: The parent cache object.
  _fields: The f1,... fields name string.
  _values: The ?,... parameter replacement string for INSERT.
c           
        > S U l         [        [        U ]  XX4XVUS9  U(       a%  U R                  R
                  R                  U5        SR                  [        U5       Vs/ s H  n[        U5      PM     sn5      U l
        SR                  S/U-  5      U l        SU l        U R                  R                  (       a  X R                  R                  U'   g g s  snf )N)columnskeystimeoutmodified
restricted, ?F)_rowssuperr(   __init___cache_restrictedaddr"   r
   r   _fields_valuesdeleted	_metadata_tables)
selfcachenamer+   r,   r-   r.   r/   i	__class__s
            r   r4   _Table.__init__^   s    DJ	&$ g)0,6 ! 8 
kk!!$'99E'NCNqilNCDDL99cUW_-DLDL{{"&kk$ 	 Ds   !Cc                 T   U R                  5         U R                  R                  R                  SR	                  U R
                  S95        U R                  R                  R                  5         U R                  R                  R                  U R
                  4/5        SU l
        g)zDeletes the table.zDROP TABLE "{table}"tableTN)
Invalidater5   cursorexecuter   r?   _dbcommitr;   
DeleteRowsr:   r=   s    r   Delete_Table.Deletem   sv    OOKK%%DII%68 	KKOOKK$$tyyl^4DLr   c                 <   U R                   (       Ga
  SU l         U R                  (       aZ  SU l        U R                  R                  R	                  U R
                  4/5        U R                  R                  U R
                  	 gU R                  R                  R                  [        R                  R                  U R
                  U R                  U R                  U R                  U R                  U R                  U R                  R                   S9/5        gg)z#Commits changed/deleted table data.F)r?   r+   r,   r-   r.   r/   versionN)changedr:   r5   r;   rK   r?   r<   AddRowsr   MetadataRowr+   r,   r-   r.   r/   rP   rL   s    r   _Commit_Table._Commitw   s    |||dl	((499,8KK		*%%$$((YYYY??++ ) - .	/ r   c                    U R                  U5        U R                  R                  R                  SR	                  U R
                  U R                  U R                  S9U5        U R                  R                  R                  5         g)z#Adds each row in rows to the table.z=INSERT OR REPLACE INTO "{table}" ({fields}) VALUES ({values}))rE   fieldsvaluesN)

_CheckRowsr5   rG   executemanyr   r?   r8   r9   rI   rJ   )r=   rowss     r   rR   _Table.AddRows   se    OODKK""G))DLL 	 	G	
 	KKOOr   c           	         U(       aa  U R                  U5        U HI  nU R                  R                  R                  SR	                  U R
                  [        U5      S95        MK     O<U R                  R                  R                  SR	                  U R
                  S95        U R                  R                  R                  5         g)z@Deletes each row in the table matching any of the row_templates.zDELETE FROM "{table}"{where})rE   wherezDELETE FROM "{table}" WHERE 1rD   N)	_CheckRowTemplatesr5   rG   rH   r   r?   r&   rI   rJ   )r=   row_templatestemplates      r   rK   _Table.DeleteRows   s    
m,#(""*11iivh'7 2 9	: $
 kk  
)
0
0tyy
0
ACKKOOr   c           	         Ub  U R                  U/5        U(       df  U R                  (       dU  U R                  (       dD  [        R                  " SR                  U R                  R                  U R                  5      5      eU R                  R                  R                  SR                  U R                  U R                  [        U5      S95        U R                  R                  R                  5       $ )z?Returns the list of rows that match row_template, None for all.z"[{}] cache table [{}] has expired.z%SELECT {fields} FROM "{table}"{where})rX   rE   r_   )r`   r/   r.   r   CacheTableExpiredr   r5   r?   rG   rH   r8   r&   fetchall)r=   r#   ignore_expirations      r   Select_Table.Select   s    
|n-T__T]]((
.
5
5kk		+, , 	KK/66<<tyy|8L 	7 	NO ;;&&((r   )r8   r2   r9   rQ   r:   )   rj   r   r   FN)NF)__name__
__module____qualname____firstlineno____doc__r4   rM   rU   rR   rK   rh   __static_attributes____classcell__rA   s   @r   r(   r(   Q   s5    
 JK'/() )r   r(   c                   V   ^  \ rS rSrSrSrSU 4S jjrS rS rS r	SS jr
S	 rS
rU =r$ )Cache   a  A persistent cache object.

Attributes:
  cursor: The _db operations cursor.
  name: The db path name. Created/removed by this object. May be a file or
    directory. In this implementation its a file.
  timeout: The default table timeout.
  version: A caller defined version string that must match the version string
    stored when the persistent object was created.
  _db: The db connection.
  _metadata: The metadata restricted _Table.
  _persistent: True if the persistent object has been committed at least once.
  _restricted: The set of restricted table names.
  _start: The cache instance start time.
  _tables: The map of open table objects.
s   SQLite format 3c                   > [         [        U ]  [        XX4S9  SU l         [
        R                  " U5       nUR                  [        U R                  5      5      nX`R                  :w  a/  [        R                  " SR                  U R                  5      5      e S S S 5        SU l        ["        R$                  " U5      U l        U R&                  R)                  5       U l        [+        S/5      U l        0 U l        S U l        [2        R4                  " 5       U l         U R9                  5         g ! , (       d  f       N= f! [
        R                   a9    U(       d/  [        R                  " SR                  U R                  5      5      e N[
        R                    a0    [        R                  " SR                  U R                  5      5      ef = f! [        R                    a    U R;                  SS9  e f = f)N)creater-   rP   Fz[{}] is not a persistent cache.Tz Persistent cache [{}] not found.__lock__rJ   )r3   ru   r4   r(   _persistentr	   BinaryFileReaderreadr   _EXPECTED_MAGICr   CacheInvalidr   r?   MissingFileErrorCacheNotFoundErrorsqlite3connectrI   rG   setr6   r<   r;   r   Now_startInitializeMetadataClose)r=   r?   rx   r-   rP   factual_magicrA   s          r   r4   Cache.__init__   s   	%W   GD?!!$'1vvc$"6"678///''/66tyyAC C 0 (
 d t$DH((//#DKJ<(DDLDN'++-DK
) (' !! B&&.55dii@B 	B  ;; ?##
+
2
2499
=? ??  
jjjs7   E  A#D/E  G /
D=9E   A
GAG%G7c                      [         R                  " U R                  5        g! [         a9  nUR                  [        R
                  [        R                  4;  a  e  SnAgSnAff = f)z.Permanently deletes the persistent cache file.N)osremover?   OSErrorerrnoENOENTEISDIR)r=   es     r   _DeleteCacheFileCache._DeleteCacheFile   sH    ii		 	
u||4	4 
5s    # 
A&/A!!A&c                 B    U R                  SS9  U R                  5         g)z4Closes and permanently deletes the persistent cache.Frz   N)r   r   rL   s    r   rM   Cache.Delete   s    JJeJr   c                 b   U R                   R                  5        Vs/ s H  oR                  (       d  M  UPM     sn H  nUR                  5         M     U R                  R                  (       a  U R                  R                  5         U R
                  R                  5         SU l        gs  snf )z(Commits all operations up to this point.TN)r<   rY   rQ   rU   r;   rI   rJ   r{   )r=   xrE   s      r   CommitCache.Commit   ss     "\\002@2ii!2@mmo A~~
nnHHOOD As
   B,B,c                 *   U R                   (       a  U(       a  U R                  5         U ?U R                   R                  5         SU l         [        R
                  " S5        SU l        U(       d#  U R                  (       d  U R                  5         gggg)zrCloses the cache, optionally committing any changes.

Args:
  commit: Commits any changes before closing if True.
N   )	rI   r   rG   closegccollectr<   r{   r   )r=   rJ   s     r   r   Cache.Close   sh     xx	
+
hhnndhjjmdlD,, 	 -V r   c                    [        U5       Vs/ s H  n[        U5      PM     nn[        U=(       d    S5       Vs/ s H  n[        U5      PM     nnUR                  SR                  SR	                  U5      S95        SR                  SR	                  U5      S9nU R
                  R                  SR                  XS95        g	s  snf s  snf )
z-sqlite3 implementation specific _CreateTable.rj   zPRIMARY KEY ({keys})r0   )r,   z
({fields}))rX   z,CREATE TABLE IF NOT EXISTS "{name}" {fields})r?   rX   N)r
   r   r!   r   r"   rG   rH   )r=   r?   r+   r,   r@   
field_listkey_listrX   s           r   _ImplementationCreateTable Cache._ImplementationCreateTable  s    (-g71)A,J7&+DIA&67&6	!&6H7,3389L3MN  		*(= >FKK6== 	> 	&'	 87s
   CC)rI   r;   r{   r6   r   r<   rG   )TNN)T)rl   rm   rn   ro   rp   r~   r4   r   rM   r   r   r   rq   rr   rs   s   @r   ru   ru      s3    " '/ D
 (' 'r   ru   rk   )rp   
__future__r   r   r   r   r   r   googlecloudsdk.core.cacher   r   r   googlecloudsdk.core.utilr	   r   	six.movesr
   r   r   r&   Tabler(   CacheUsingMetadataTableru    r   r   <module>r      sg    
 '  '  	 	 0 4 ; * 
  	+*<\)"(( \)~i'N22 i'r   