U
    楡ck#                     @   s   d Z ddlmZmZmZ ddlmZ ddlmZm	Z	 ddl
mZ ddlmZ dZG dd	 d	ZG d
d dZG dd dZG dd dZdd ZG dd deeeZdS )z8Contains implementations of database retrieveing objects    )join	LazyMixin
hex_to_bin)
force_text)	BadObjectAmbiguousObjectName)chain)reduce)	ObjectDBR	ObjectDBW
FileDBBase
CompoundDB	CachingDBc                   @   s@   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dS )r
   zkDefines an interface for object database lookup.
    Objects are identified either by their 20 byte bin shac                 C   s   | j S N)Zhas_objselfsha r   1/tmp/pip-unpacked-wheel-jjg5dubb/gitdb/db/base.py__contains__   s    zObjectDBR.__contains__c                 C   s   t ddS )z
        Whether the object identified by the given 20 bytes
            binary sha is contained in the database

        :return: True if the object identified by the given 20 bytes
            binary sha is contained in the databaseTo be implemented in subclassNNotImplementedErrorr   r   r   r   
has_object"   s    zObjectDBR.has_objectc                 C   s   t ddS )zW :return: OInfo instance
        :param sha: bytes binary sha
        :raise BadObject:r   Nr   r   r   r   r   info+   s    zObjectDBR.infoc                 C   s   t ddS )z[:return: OStream instance
        :param sha: 20 bytes binary sha
        :raise BadObject:r   Nr   r   r   r   r   stream1   s    zObjectDBR.streamc                 C   s
   t  dS )z+:return: amount of objects in this databaseNr   r   r   r   r   size7   s    zObjectDBR.sizec                 C   s
   t  dS )zGReturn iterator yielding 20 byte shas for all objects in this data baseNr   r   r   r   r   sha_iter;   s    zObjectDBR.sha_iterN)
__name__
__module____qualname____doc__r   r   r   r   r   r   r   r   r   r   r
      s   	r
   c                   @   s0   e Zd ZdZdd Zdd Zdd Zdd	 Zd
S )r   z6Defines an interface to create objects in the databasec                 O   s
   d | _ d S r   Z_ostream)r   argskwargsr   r   r   __init__F   s    zObjectDBW.__init__c                 C   s   | j }|| _ |S )ab  
        Adjusts the stream to which all data should be sent when storing new objects

        :param stream: if not None, the stream to use, if None the default stream
            will be used.
        :return: previously installed stream, or None if there was no override
        :raise TypeError: if the stream doesn't have the supported functionalityr#   )r   r   Zcstreamr   r   r   set_ostreamJ   s    zObjectDBW.set_ostreamc                 C   s   | j S )z
        Return the output stream

        :return: overridden output stream this instance will write to, or None
            if it will write to the default streamr#   r   r   r   r   ostreamV   s    zObjectDBW.ostreamc                 C   s   t ddS )a  
        Create a new object in the database
        :return: the input istream object with its sha set to its corresponding value

        :param istream: IStream compatible instance. If its sha is already set
            to a value, the object will just be stored in the our database format,
            in which case the input stream is expected to be in object format ( header + contents ).
        :raise IOError: if data could not be writtenr   Nr   )r   Zistreamr   r   r   store^   s    	zObjectDBW.storeN)r   r    r!   r"   r&   r'   r(   r)   r   r   r   r   r   B   s
   r   c                       s0   e Zd ZdZ fddZdd Zdd Z  ZS )r   z}Provides basic facilities to retrieve files of interest, including
    caching facilities to help mapping hexsha's to objectsc                    s   t    || _dS )aY  Initialize this instance to look for its files at the given root path
        All subsequent operations will be relative to this path
        :raise InvalidDBRoot:
        **Note:** The base will not perform any accessablity checking as the base
            might not yet be accessible, but become accessible before the first
            access.N)superr&   
_root_path)r   	root_path	__class__r   r   r&   q   s    
zFileDBBase.__init__c                 C   s   | j S )z':return: path at which this db operates)r+   r   r   r   r   r,   |   s    zFileDBBase.root_pathc                 C   s   t | jt|S )z~
        :return: the given relative path relative to our database root, allowing
            to pontentially access datafiles)r   r+   r   )r   Z	rela_pathr   r   r   db_path   s    zFileDBBase.db_path)r   r    r!   r"   r&   r,   r/   __classcell__r   r   r-   r   r   l   s   r   c                   @   s   e Zd ZdZdddZdS )r   z/A database which uses caches to speed-up accessFc                 C   s   dS )ar  
        Call this method if the underlying data changed to trigger an update
        of the internal caching structures.

        :param force: if True, the update must be performed. Otherwise the implementation
            may decide not to perform an update if it thinks nothing has changed.
        :return: True if an update was performed as something change indeedNr   )r   forcer   r   r   update_cache   s    zCachingDB.update_cacheN)F)r   r    r!   r"   r2   r   r   r   r   r      s   r   c                 C   sT   t | trF|  }|dd |D  dd |D D ]}t|| q4n
||  dS )zfFill output list with database from db, in order. Deals with Loose, Packed
    and compound databases.c                 s   s   | ]}t |ts|V  qd S r   
isinstancer   .0dbr   r   r   	<genexpr>   s     
 z'_databases_recursive.<locals>.<genexpr>c                 s   s   | ]}t |tr|V  qd S r   r3   r5   r   r   r   r8      s     
 N)r4   r   	databasesextend_databases_recursiveappend)ZdatabaseoutputZdbsZcdbr   r   r   r;      s    
r;   c                       sj   e Zd ZdZ fddZ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 Z  ZS )r   zA database which delegates calls to sub-databases.

    Databases are stored in the lazy-loaded _dbs attribute.
    Define _set_cache_ to update it with your databasesc                    s4   |dkrt  | _n|dkr$t | _nt | d S )N_dbs	_db_cache)listr>   dictr?   r*   _set_cache_)r   attrr-   r   r   rB      s
    

zCompoundDB._set_cache_c                 C   sV   z| j | W S  tk
r    Y nX | jD ] }||r(|| j |< |  S q(t|dS )zL:return: database containing the given 20 byte sha
        :raise BadObject:N)r?   KeyErrorr>   r   r   )r   r   r7   r   r   r   	_db_query   s    



zCompoundDB._db_queryc                 C   s,   z|  | W dS  tk
r&   Y dS X d S )NTF)rE   r   r   r   r   r   r      s
    
zCompoundDB.has_objectc                 C   s   |  ||S r   )rE   r   r   r   r   r   r      s    zCompoundDB.infoc                 C   s   |  ||S r   )rE   r   r   r   r   r   r      s    zCompoundDB.streamc                 C   s   t dd dd | jD dS )z.:return: total size of all contained databasesc                 S   s   | | S r   r   )xyr   r   r   <lambda>       z!CompoundDB.size.<locals>.<lambda>c                 s   s   | ]}|  V  qd S r   )r   r5   r   r   r   r8      s     z"CompoundDB.size.<locals>.<genexpr>r   )r	   r>   r   r   r   r   r      s    zCompoundDB.sizec                 C   s   t dd | jD  S )Nc                 s   s   | ]}|  V  qd S r   )r   r5   r   r   r   r8      s     z&CompoundDB.sha_iter.<locals>.<genexpr>)r   r>   r   r   r   r   r      s    zCompoundDB.sha_iterc                 C   s
   t | jS )z7:return: tuple of database instances we use for lookups)tupler>   r   r   r   r   r9      s    zCompoundDB.databasesFc                 C   s6   | j   d}| jD ]}t|tr|||O }q|S )NF)r?   clearr>   r4   r   r2   )r   r1   statr7   r   r   r   r2      s    


zCompoundDB.update_cachec              	   C   s   t  }t| | t|}t|}|d dkr:t|d }nt|}d}|D ]d}d}z&t|drj||}n|||}W n tk
r   Y qJY nX |rJ|r||krt	||}qJ|st||S )z
        :return: 20 byte binary sha1 from the given less-than-40 byte hexsha (bytes or str)
        :param partial_hexsha: hexsha with less than 40 byte
        :raise AmbiguousObjectName:    r   0Npartial_to_complete_sha_hex)
r@   r;   r   lenr   hasattrrO   Zpartial_to_complete_shar   r   )r   Zpartial_hexshar9   Zlen_partial_hexshaZpartial_binsha	candidater7   Zfull_bin_shar   r   r   rO      s.    


z&CompoundDB.partial_to_complete_sha_hex)F)r   r    r!   r"   rB   rE   r   r   r   r   r   r9   r2   rO   r0   r   r   r-   r   r      s   
r   N)r"   Z
gitdb.utilr   r   r   Zgitdb.utils.encodingr   Z	gitdb.excr   r   	itertoolsr   	functoolsr	   __all__r
   r   r   r   r;   r   r   r   r   r   <module>   s   )*