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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 ddlZdd ZdddZG dd dejZG dd de
jZdS )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                 C   s   dj | dS )zReturns a field reference name.

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

  Returns:
    A field reference name.
  z	f{column}column)formatr
    r   C/tmp/google-cloud-sdk/lib/googlecloudsdk/core/cache/sqlite_cache.py	_FieldRef'   s   	r   c                 C   s   g }| rCt t| D ]8}| | }|du rq
t|tjr6|dddddd}|djt||d	 q
|d
jt||d q
|sGdS dd	| S )aZ  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.
  N*%._"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   r   r   r   _Where3   s"   

r#   c                       sR   e Zd ZdZ		d fdd	Zdd Zd	d
 Zdd ZdddZdddZ	  Z
S )_TableaX  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.
     r   Fc              	      s   d | _ tt| j|||||||d |r| jj| ddd t|D | _	ddg| | _
d| _| jjr@| | jj|< d S d S )N)columnskeystimeoutmodified
restricted, c                 S      g | ]}t |qS r   r   .0ir   r   r   
<listcomp>f       z#_Table.__init__.<locals>.<listcomp>?F)_rowssuperr$   __init___cache_restrictedaddr   r	   _fields_valuesdeleted	_metadata_tables)selfcachenamer&   r'   r(   r)   r*   	__class__r   r   r6   ^   s   z_Table.__init__c                 C   sJ   |    | jjdj| jd | jj  | jj	| jfg d| _
dS )zDeletes the table.zDROP TABLE "{table}"tableTN)
Invalidater7   cursorexecuter   rA   _dbcommitr=   
DeleteRowsr<   r?   r   r   r   Deletem   s   
z_Table.Deletec                 C   sz   | j r;d| _ | jrd| _| jj| jfg | jj| j= dS | jjtj	j
| j| j| j| j| j| j| jjdg dS dS )z#Commits changed/deleted table data.F)rA   r&   r'   r(   r)   r*   versionN)changedr<   r7   r=   rK   rA   r>   AddRowsr   MetadataRowr&   r'   r(   r)   r*   rN   rL   r   r   r   _Commitw   s$   z_Table._Commitc                 C   s<   |  | | jjdj| j| j| jd| | jj	  dS )z#Adds each row in rows to the table.z=INSERT OR REPLACE INTO "{table}" ({fields}) VALUES ({values}))rE   fieldsvaluesN)

_CheckRowsr7   rG   executemanyr   rA   r:   r;   rI   rJ   )r?   rowsr   r   r   rP      s   
z_Table.AddRowsNc                 C   s`   |r|  | |D ]}| jjdj| jt|d q	n| jjdj| jd | jj  dS )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)	_CheckRowTemplatesr7   rG   rH   r   rA   r#   rI   rJ   )r?   row_templatestemplater   r   r   rK      s   

z_Table.DeleteRowsc                 C   sj   |dur
|  |g |s| js| jstd| jj| j| jj	dj| j
| jt|d | jj S )z?Returns the list of rows that match row_template, None for all.Nz"[{}] cache table [{}] has expired.z%SELECT {fields} FROM "{table}"{where})rT   rE   rY   )rZ   r*   r)   r   CacheTableExpiredr   r7   rA   rG   rH   r:   r#   fetchall)r?   r    ignore_expirationr   r   r   Select   s   
z_Table.Select)r%   r%   r   r   FN)NF)__name__
__module____qualname____doc__r6   rM   rS   rP   rK   r`   __classcell__r   r   rB   r   r$   Q   s    


r$   c                       sP   e Zd ZdZdZd fdd	Zdd Zd	d
 Zdd ZdddZ	dd Z
  ZS )Cachea  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 3TNc                    s4  t t| jt||||d d| _z0t|}|t| j	}|| j	kr-t
d| jW d    n1 s7w   Y  d| _W n% tjyU   |sSt
d| jY n tjye   t
d| jw t|| _| j | _tdg| _i | _d | _t | _z|   W d S  t
jy   | jdd  w )N)creater(   rN   Fz[{}] is not a persistent cache.Tz Persistent cache [{}] not found.__lock__rJ   )r5   rg   r6   r$   _persistentr   BinaryFileReaderreadr   _EXPECTED_MAGICr   CacheInvalidr   rA   MissingFileErrorCacheNotFoundErrorsqlite3connectrI   rG   setr8   r>   r=   r   Now_startInitializeMetadataClose)r?   rA   rh   r(   rN   factual_magicrB   r   r   r6      sJ   







zCache.__init__c              
   C   sN   z	t | j W dS  ty& } z|jtjtjfvr W Y d}~dS d}~ww )z.Permanently deletes the persistent cache file.N)osremoverA   OSErrorerrnoENOENTEISDIR)r?   er   r   r   _DeleteCacheFile   s   zCache._DeleteCacheFilec                 C   s   | j dd |   dS )z4Closes and permanently deletes the persistent cache.Frj   N)ry   r   rL   r   r   r   rM      s   zCache.Deletec                 C   sH   dd | j  D D ]}|  q
| jjr| j  | j  d| _dS )z(Commits all operations up to this point.c                 S   s   g | ]}|j r|qS r   )rO   )r/   xr   r   r   r1      s    z Cache.Commit.<locals>.<listcomp>TN)r>   rU   rS   r=   rO   rI   rJ   rk   )r?   rE   r   r   r   Commit   s   



zCache.Commitc                 C   sX   | j r&|r	|   | `| j   d| _ td d| _|s(| js*|   dS dS dS dS )z~Closes the cache, optionally committing any changes.

    Args:
      commit: Commits any changes before closing if True.
    N   )	rI   r   rG   closegccollectr>   rk   r   )r?   rJ   r   r   r   ry      s   


	zCache.Closec                 C   sl   dd t |D }dd t |pdD }|djd|d djd|d	}| jd
j||d dS )z-sqlite3 implementation specific _CreateTable.c                 S   r,   r   r-   r.   r   r   r   r1     r2   z4Cache._ImplementationCreateTable.<locals>.<listcomp>c                 S   r,   r   r-   r.   r   r   r   r1     r2   r%   zPRIMARY KEY ({keys})r+   )r'   z
({fields}))rT   z,CREATE TABLE IF NOT EXISTS "{name}" {fields})rA   rT   N)r	   r   r   r   rG   rH   )r?   rA   r&   r'   
field_listkey_listrT   r   r   r   _ImplementationCreateTable  s   z Cache._ImplementationCreateTable)TNN)T)rb   rc   rd   re   rn   r6   r   rM   r   ry   r   rf   r   r   rB   r   rg      s    "

rg   ra   )re   
__future__r   r   r   r   r   r|   googlecloudsdk.core.cacher   r   r   googlecloudsdk.core.utilr   r   	six.movesr	   rs   r   r#   Tabler$   CacheUsingMetadataTablerg   r   r   r   r   <module>   s$   
_