o
    "                     @   s   d Z ddlmZ ddlmZ ddlm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 ddl	mZ dd	lmZ ddlZdd
lmZ G dd dejZG dd dejZdS )zlA persistent cache implementation using files.

See the persistent_cache module for a detailed description.
    )absolute_import)division)unicode_literalsN)
exceptions)metadata_table)persistent_cache_base)files)rangec                       sj   e Zd ZdZ		d fdd	Zdd Zd	d
 Zdd Zdd Zdd Z	dd Z
dddZdddZ  ZS )_TableaC  A persistent cache table.

  Attributes:
    name: The table name.
    deleted: Table was deleted if True.
    restricted: Table is restricted if True.
    modified: Table modify timestamp.
    timeout: Tables older than timeout are invalid.
    _cache: The parent cache object.
    _rows: The list of rows in the table.
     r   Fc           	   	      s   d | _ tt| j|||||||d |r| jj| d| _zt	t
j| jj| |}W n tjy>   d }d| _Y n	 tjyF    w |rUdd t|D | _ ng | _ | jjrd| | jj|< d S d S )N)columnskeystimeoutmodified
restrictedFTc                 S   s   g | ]}t |qS  )tuple).0rr   r   A/tmp/google-cloud-sdk/lib/googlecloudsdk/core/cache/file_cache.py
<listcomp>G   s    z#_Table.__init__.<locals>.<listcomp>)_rowssuperr
   __init___cache_restrictedadddeletedr   ReadFileContentsospathjoinname
EncodeNameMissingFileErrorchangedErrorjsonloads	_metadata_tables)	selfcacher"   r   r   r   r   r   contents	__class__r   r   r   4   s0   
z_Table.__init__c                 C   s.   |    |   | jj| jfg d| _dS )zDeletes the table.TN)
Invalidate
DeleteRowsr   r)   r"   r   r+   r   r   r   DeleteN   s   
z_Table.Deletec                 C   s   | j rsd| _ tj| jj| | j}| jrLd| _| jj	| jfg | jj
| j= zt| W dS  tyK } z|jtjkr@ W Y d}~dS d}~ww | jjtjj| j| j| j| j| j| j| jjdg t|t| j dS dS )z5Commits changed/deleted table data to the table file.FN)r"   r   r   r   r   r   version)r%   r   r    r!   r   r"   r#   r   r)   r1   r*   removeOSErrorerrnoENOENTAddRowsr   MetadataRowr   r   r   r   r   r4   r   WriteFileContentsr'   dumpsr   )r+   r    er   r   r   _CommitV   s8   	z_Table._Commitc                 C   s   |d| j  |d| j  kS )z/Returns True if rows a and b have the same key.Nr   )r+   abr   r   r   	_RowEqualr   s   z_Table._RowEqualc                 C   sx   |r:t t|D ]1}|| dur9t|| tjr.t|| tjr.t|| || s- dS q|| || kr9 dS qdS )z)Returns True if row_template matches row.NFT)r	   len
isinstancesixstring_typesfnmatch)r+   row_templaterowir   r   r   	_RowMatchv   s   z_Table._RowMatchc                 C   s    |D ]}|  ||r dS qdS )z:Returns True if any template in row_templates matches row.TF)rL   )r+   row_templatesrJ   rI   r   r   r   _AnyRowMatch   s
   z_Table._AnyRowMatchc                    s     | d _t jt|  fddd}g  _d}|t|k rb|t|d k rN || ||d  rN|d7 }|t|d k rN || ||d  s6 j||  |d7 }|t|k s"dS dS )z#Adds each row in rows to the table.Tc                    s   | d  j  S Nr@   )xr2   r   r   <lambda>   s    z _Table.AddRows.<locals>.<lambda>)keyr   r   N)
_CheckRowsr%   sortedr   listrD   rC   append)r+   rowsrK   r   r2   r   r9      s   
((z_Table.AddRowsNc                 C   sN   d| _ |r"| | g }| jD ]}| ||s|| q|| _dS g | _dS )z@Deletes each row in the table matching any of the row_templates.TN)r%   _CheckRowTemplatesr   rN   rV   )r+   rM   keeprJ   r   r   r   r1      s   




z_Table.DeleteRowsc                 C   sj   |dur
|  |g |s| js| jstd| jj| jg }| jD ]}|r2| 	||r2|
| q#|S )z?Returns the list of rows that match row_template, None for all.Nz"[{}] cache table [{}] has expired.)rX   r   r   r   CacheTableExpiredformatr   r"   r   rL   rV   )r+   rI   ignore_expirationmatchedrJ   r   r   r   Select   s   


z_Table.Select)r   r   r   r   FrO   )NF)__name__
__module____qualname____doc__r   r3   r?   rC   rL   rN   r9   r1   r^   __classcell__r   r   r.   r   r
   '   s    
r
   c                       s<   e Zd ZdZd fdd	Zdd Zdd	 Zdd
dZ  ZS )Cachea  A persistent cache object.

  Attributes:
    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.
    _lock: The cache lock object. None if no files have been committed yet.
    _lock_path: The cache lock meta file.
    _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.
  TNc                    s   t t| jt||||d d}t|g| _i | _d | _t	 | _
tj| j|| _d | _d| _tj| jsB|sAtd| jn!tj| jsRtd| jd| _tj| jdd| _| j  z|   W d S  tjyy   | jdd	  w )
N)creater   r4   __lock__Fz Persistent cache [{}] not found.z[{}] is not a persistent cache.T   timeout_secscommit)r   rd   r   r
   setr   r*   r)   r   Now_startr   r    r!   r"   
_lock_path_lock_persistentexistsr   CacheNotFoundr[   CacheInvalidr   FileLockLockInitializeMetadatar&   Close)r+   r"   re   r   r4   	lock_namer.   r   r   r      s<   





zCache.__init__c                 C   s,   | j dd | jrt| j d| _dS dS )z)Permanently deletes the persistent cache.Frj   N)rx   rq   r   RmTreer"   r2   r   r   r   r3      s
   
zCache.Deletec                 C   sv   | j st| jd d| _tj| jdd| _ | j   t	dd | j
 D D ]}|  q'| jjr9| j  dS dS )z(Commits all operations up to this point.i  Trg   rh   c                 S   s   g | ]}|j r|qS r   )r%   )r   rP   r   r   r   r      s    z Cache.Commit.<locals>.<listcomp>N)rp   r   mkdirr"   rq   r   ru   ro   rv   rU   r*   valuesr?   r)   r%   )r+   tabler   r   r   Commit   s   

zCache.Commitc                 C   s2   |r|    | jr| j  d| _d| _d| _dS )z~Closes the cache, optionally committing any changes.

    Args:
      commit: Commits any changes before closing if True.
    N)r~   rp   Unlockr)   r*   )r+   rk   r   r   r   rx      s   

zCache.Close)TNN)T)	r_   r`   ra   rb   r   r3   r~   rx   rc   r   r   r.   r   rd      s    rd   )rb   
__future__r   r   r   r7   rH   r'   r   googlecloudsdk.core.cacher   r   r   googlecloudsdk.core.utilr   rF   	six.movesr	   Tabler
   CacheUsingMetadataTablerd   r   r   r   r   <module>   s"    