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mZ ddl	Z	ddl
Z	dd Ze	ejG d	d
 d
eZe	ejG dd deZdS )a  The Cloud SDK persistent cache abstract base classes.

A persistent cache is a long-lived object that contains cache data and metadata.
Cache data is organized into zero or more named tables. Table data is an
unordered list of row tuples of fixed length. Column value types within a row
are fixed and may be one of string (basestring or unicode), floating point, or
integer.

    +-----------------------+
    | persistent cache      |
    | +-------------------+ |
    | | table             | |
    | | (key,...,col,...) | |
    | |        ...        | |
    | +-------------------+ |
    |          ...          |
    +-----------------------+

A persistent cache is implemented as a Cache object that contains Table objects.
Each table has a timeout and last modified time attribute. Read access on a
table that has expired is an error. The rows in a table have a fixed number of
columns specified by the columns attribute. The keys attribute is the count of
columns in a table row, left to right, that forms the primary key. The primary
key is used to differentiate rows. Adding a row that already exists is not an
error. The row is simply replaced by the new data.

A Table object can be restricted and hidden from cache users. These tables
must be instantiated when the Cache object is instantiated, before the first
user access to the cache. This allows a cache implementation layer to have
tables that are hidden from the layers above it.

The table select and delete methods match against a row template. A template may
have fewer columns than the number of columns in the table. Omitted template
columns or columns with value None match all values for that column. '*' and '?'
matching operators are supported for string columns. It is not an error to
select or delete a row that does not exist.

HINTS for IMPLEMENTERS

By default the Cache and Table constructors create the objects if they don't
exist. The create=False kwarg disables this and raises an exception if the
object does not exist. In addition, the Select ignore_expiration=True kwarg
disables expiry check. These can be used by meta commands/functions to view
and debug cache data without modifying the underlying persistent data.
    )absolute_import)division)unicode_literalsN)
exceptionsc                   C   s   t   S )z4Returns the current time in seconds since the epoch.)time r   r   L/tmp/google-cloud-sdk/lib/googlecloudsdk/core/cache/persistent_cache_base.pyNowK   s   r	   c                   @   s   e Zd ZdZ		dddZedd Zed	d
 Zdd Z	dd Z
dd ZdddZejdd Zejdd ZejdddZejdddZdS )Tablea  A persistent cache table object.

  This object should only be instantiated by a Cache object.

  The AddRows and DeleteRows methods operate on lists of rows rather than a
  single row. This accomodates sqlite3 (and possibly other implementation
  layers) that batch rows ops. Restricting to a single row would rule out
  batching.

  Attributes:
    cache: The parent cache object.
    changed: Table data or metadata changed if True.
    name: The table name.
    modified: Table modify Now() (time.time()) value. 0 for expired tables.
    restricted: True if Table is restricted.
    timeout: A float number of seconds. Tables older than (modified+timeout)
      are invalid. 0 means no timeout.
     r   Fc                 C   sb   || _ || _|| _|| _d| _|pd| _|| _|| _|r+|r-|| t k r/| 	  d S d S d S d S )NFr   )
_cachename
restrictedmodifiedchangedtimeoutcolumnskeysr	   
Invalidate)selfcacher   r   r   r   r   r   r   r   r   __init__e   s   
zTable.__init__c                 C   s   | j  S )a%  True if the table data has expired.

    Expired tables have a self.modified value of 0. Expiry is currently
    computed once when the table object is instantiated. This property shields
    callers from that implementation detail.

    Returns:
      True if the table data has expired.
    )r   r   r   r   r   
is_expiredv   s   zTable.is_expiredc                 C   s&   |s
t d|tjjj|dS )a1  Returns name encoded for file system path compatibility.

    A table name may be a file name. alnum and '_.-' are not encoded.

    Args:
      name: The cache name string to encode.

    Raises:
      CacheTableNameInvalid: For invalid table names.

    Returns:
      Name encoded for portability.
    z!Cache table name [{}] is invalid.z!@+,)r   CacheTableNameInvalidformatsixmovesurllibparsequote)clsr   r   r   r   
EncodeName   s
   zTable.EncodeNamec                 C   s8   |D ]}t || jkrtd| jt || jqdS )a	  Raise an exception if the size of any row in rows is invalid.

    Each row size must be equal to the number of columns in the table.

    Args:
      rows: The list of rows to check.

    Raises:
      CacheTableRowSizeInvalid: If any row has an invalid size.
    6Cache table [{}] row size [{}] is invalid. Must be {}.N)lenr   r   CacheTableRowSizeInvalidr   r   )r   rowsrowr   r   r   
_CheckRows   s   zTable._CheckRowsc                 C   s`   |D ]+}dt |  kr| jks-n | jdkrd}nd| j}td| jt ||qdS )a;  Raise an exception if the size of any row template in rows is invalid.

    Each row template must have at least 1 column and no more than the number
    of columns in the table.

    Args:
      rows: The list of rows to check.

    Raises:
      CacheTableRowSizeInvalid: If any row template size is invalid.
    r   1z>= 1 and <= {}r#   N)r$   r   r   r   r%   r   )r   r&   r'   limitsr   r   r   _CheckRowTemplates   s   
zTable._CheckRowTemplatesc                 C   s   d| _ d| _dS )z,Invalidates the table by marking it expired.Tr   N)r   r   r   r   r   r   r      s   
zTable.InvalidateNc                 C   s$   |dur	|pd| _ t | _d| _dS )z'Validates the table and resets the TTL.Nr   T)r   r	   r   r   )r   r   r   r   r   Validate   s   

zTable.Validatec                 C      dS )zDeletes the table.Nr   r   r   r   r   Delete      zTable.Deletec                 C   r-   )zAdds each row in rows to the table. Existing rows are overwritten.

    The number of columns in each row must be equal to the number of columns
    in the table.

    Args:
      rows: A list of rows to add. Existing rows are overwritten.
    Nr   )r   r&   r   r   r   AddRows      
zTable.AddRowsc                 C   r-   )a  Deletes each row in the table matching any of the row_templates.

    Args:
      row_templates: A list of row templates. See Select() below for a detailed
        description of templates. None deletes all rows and is allowed for
        expired tables.
    Nr   )r   row_templatesr   r   r   
DeleteRows   s   	zTable.DeleteRowsc                 C   r-   )a  Returns the list of rows that match row_template.

    Args:
      row_template: A row template. The number of columns in the template must
        not exceed the number of columns in the table. An omitted column or
        column with value None matches all values for the column. A None value
        for row_template matches all rows. Each string column may contain these
        wildcard characters:
          * - match zero or more characters
          ? - match any character
      ignore_expiration: Disable table expiration checks if True.

    Raises:
      CacheTableExpired: If the table has expired.

    Returns:
      The list of rows that match row_template.
    Nr   )r   row_templateignore_expirationr   r   r   Select      zTable.Select)r   r   r   r   FN)NF)__name__
__module____qualname____doc__r   propertyr   classmethodr"   r(   r+   r   r,   abcabstractmethodr.   r0   r3   r6   r   r   r   r   r
   P   s*    






r
   c                   @   s   e Zd ZdZdddZdd Zdd	 Zed
d Ze	j
dd Zdd Ze	j
dd Ze	j
dddZe	j
dddZe	j
dddZdS )Cachea.  A persistent cache object.

  This class is also a context manager. Changes are automaticaly committed if
  the context exits with no exceptions. For example:

    with CacheImplementation('my-cache-name') as c:
      ...

  Attributes:
    name: The persistent cache name. Created/removed by this object. Internally
      encoded by Cache.EncodeName().
    timeout: The default table timeout in seconds. 0 for no timeout.
    version: A caller defined version string that must match the version string
      stored when the persistent object was created.
  TNc                 C   s   t || _~|| _|| _d S r8   )rA   r"   r   r   version)r   r   creater   rB   r   r   r   r     s   
zCache.__init__c                 C   s   | S r8   r   r   r   r   r   	__enter__  s   zCache.__enter__c                 C   s   | j |d u d d S )N)commit)Close)r   typvalue	tracebackr   r   r   __exit__  s   zCache.__exit__c                 C   sT   t |d|dd }||d std||d| t||d  S )ab  Returns name encoded for filesystem portability.

    A cache name may be a file path. The part after the rightmost of
    ('/', '\\') is encoded with Table.EncodeName().

    Args:
      name: The cache name string to encode.

    Raises:
      CacheNameInvalid: For invalid cache names.

    Returns:
      Name encoded for filesystem portability.
    /\r   NzCache name [{}] is invalid.)maxrfindr   CacheNameInvalidr   r
   r"   )r!   r   basename_indexr   r   r   r"     s   zCache.EncodeNamec                 C   r-   )zPermanently deletes the cache.Nr   r   r   r   r   r.   1  r/   zCache.Deletec                 C   s    |   D ]	}| |  qdS )z8Invalidates the cache by invalidating all of its tables.N)r6   r
   r   r   r   r   r   r   r   6  s   zCache.Invalidatec                 C   r-   )z%Commits all changes up to this point.Nr   r   r   r   r   Commit;  r/   zCache.Commitc                 C   r-   )z~Closes the cache, optionally committing any changes.

    Args:
      commit: Commits any changes before closing if True.
    Nr   )r   rE   r   r   r   rF   @  s   zCache.Closer   c                 C   r-   )a  Returns the Table object for existing table name.

    Args:
      name: The table name.
      create: If True creates the table if it does not exist.
      columns: The number of columns in the table. Must be >= 1.
      keys: The number of columns, starting from 0, that form the primary
        row key. Must be 1 <= keys <= columns. The primary key is used to
        differentiate rows in the AddRows and DeleteRows methods.
      timeout: The table timeout in seconds, 0 for no timeout.

    Raises:
      CacheTableNameInvalid: name is not a valid table name.
      CacheTableNotFound: If the table does not exist.

    Returns:
      A Table object for name.
    Nr   )r   r   rC   r   r   r   r   r   r   r
   I  r7   zCache.Tablec                 C   r-   )a	  Returns the list of table names matching name.

    Args:
      name: The table name pattern to match, None for all tables. The pattern
        may contain these wildcard characters:
          * - match zero or more characters
          ? - match any character
    Nr   rQ   r   r   r   r6   _  r1   zCache.Select)TNN)T)Tr   r   Nr8   )r9   r:   r;   r<   r   rD   rJ   r>   r"   r?   r@   r.   r   rR   rF   r
   r6   r   r   r   r   rA      s$    



rA   )r<   
__future__r   r   r   r?   r   googlecloudsdk.core.cacher   r   six.moves.urllib.parser	   add_metaclassABCMetaobjectr
   rA   r   r   r   r   <module>   s   .
 
-