U
    楡c                     @   s   d dl mZmZmZ d dlmZmZ d dlmZm	Z	m
Z
mZ d dlmZmZ d dlmZmZmZmZmZmZmZmZmZmZmZmZmZmZ d dlmZm Z m!Z!m"Z" d dl#m$Z$ d dl%Z%d dl&Z&d dl'Z'd	Z(G d
d deeeZ)dS )    )
FileDBBase	ObjectDBR	ObjectDBW)	BadObjectAmbiguousObjectName)DecompressMemMapReaderFDCompressedSha1WriterFDStream
Sha1Writer)OStreamOInfo)file_contents_ro_filepathENOENT
hex_to_bin
bin_to_hexexistschmodisdirisfileremovemkdirrenamedirnamebasenamejoin)
chunk_sizeloose_object_header_infowrite_objectstream_copy)force_bytesN)LooseObjectDBc                       s   e Zd ZdZeZeddZej	dkr.eddZ fddZ
dd	 Zd
d Zdd Zdd Z fddZdd Zdd Zdd Zdd Zdd Zdd Z  ZS )r    z/A database which operates on loose object filesZ444   ntZ644c                    s&   t  | t | _ttdd| _d S )N	O_NOATIMEr   )super__init__dict_hexsha_to_filegetattros_fd_open_flags)self	root_path	__class__ 2/tmp/pip-unpacked-wheel-jjg5dubb/gitdb/db/loose.pyr%   M   s    zLooseObjectDB.__init__c                 C   s   t |dd |dd S )z{
        :return: path at which the object with the given hexsha would be stored,
            relative to the database rootN   )r   )r+   hexshar/   r/   r0   object_pathV   s    zLooseObjectDB.object_pathc                 C   sT   z| j | W S  tk
r    Y nX | | |}t|rH|| j |< |S t|dS )z
        :return: readable object path to the object identified by hexsha
        :raise BadObject: If the object file does not existN)r'   KeyErrordb_pathr3   r   r   )r+   r2   pathr/   r/   r0   readable_db_object_path\   s    
z%LooseObjectDB.readable_db_object_pathc                 C   sL   d}|   D ]*}t|t|r|dk	r2t||}q|dkrHt||S )z:return: 20 byte binary sha1 string which matches the given name uniquely
        :param name: hexadecimal partial name (bytes or ascii string)
        :raise AmbiguousObjectName:
        :raise BadObject: N)sha_iterr   
startswithr   r   r   )r+   Zpartial_hexsha	candidatebinshar/   r/   r0   partial_to_complete_sha_hexn   s    z)LooseObjectDB.partial_to_complete_sha_hexc                 C   s   |  | t|}zt|| jdW S  tk
r } z`|jtkrzt|W  W Y DS  tk
r~ } zt||W 5 d}~X Y nX d| _n
t||W 5 d}~X Y nX dS )z~
        :return: memory map of that file to allow random read access
        :raise BadObject: if object could not be located)flagsNr   )	r5   r3   r   r   r*   OSErrorerrnor   r   )r+   shar5   eZnew_er/   r/   r0   _map_loose_object   s    
zLooseObjectDB._map_loose_objectc                    s,   |dk	r t |ts tdtj t |S )zI:raise TypeError: if the stream does not support the Sha1Writer interfaceNz,Output stream musst support the %s interface)
isinstancer
   	TypeError__name__r$   set_ostream)r+   streamr-   r/   r0   rF      s    zLooseObjectDB.set_ostreamc              	   C   s@   |  |}zt|\}}t|||W S t|dr:|  X d S )Nclose)rB   hasattrrH   r   r   )r+   r@   mtypsizer/   r/   r0   info   s    

zLooseObjectDB.infoc                 C   s,   |  |}tj|dd\}}}t||||S )NT)Zclose_on_deletion)rB   r   newr   )r+   r@   rJ   typerL   rG   r/   r/   r0   rG      s    
zLooseObjectDB.streamc                 C   s0   z|  t| W dS  tk
r*   Y dS X d S )NTF)r7   r   r   )r+   r@   r/   r/   r0   
has_object   s
    zLooseObjectDB.has_objectc                 C   s>  d}|   }|dkrDtjd| jd\}}|jdkr<t|}nt|}zVzB|jdk	rjt|j	|j
tj| j nt|j|j|j	|j
| jd W 5 |r|  X W n   |rt|  Y nX d}|jr|j}n|jdd}|r0| | |}t|}t|st| t|rt| n
t|| t|| j t||_|S )z.note: The sha we produce will be hex by natureNobj)prefixdir)r   T)Zas_hex)ZostreamtempfilemkstempZ
_root_pathr;   r   r	   rH   r   readwritesysmaxsizestream_chunk_sizer   rO   rL   r)   r   r2   r@   r5   r3   r   r   r   r   r   r   new_objects_moder   )r+   ZistreamZtmp_pathwriterfdr2   Zobj_pathZobj_dirr/   r/   r0   store   sF    









zLooseObjectDB.storec                 c   sZ   t |  D ]F\}}}t|}t|dkr.q|D ] }t|dkrDq2t|| V  q2qd S )Nr1   &   )r)   walkr,   r   lenr   )r+   rootdirsfilesZ	root_basefr/   r/   r0   r8      s    zLooseObjectDB.sha_iterc                 C   s   t t|  S )N)ra   tupler8   )r+   r/   r/   r0   rL     s    zLooseObjectDB.size)rE   
__module____qualname____doc__r   rZ   intr[   r)   namer%   r3   r7   r<   rB   rF   rM   rG   rP   r^   r8   rL   __classcell__r/   r/   r-   r0   r    ?   s"   


	
@r    )*Zgitdb.db.baser   r   r   Z	gitdb.excr   r   Zgitdb.streamr   r   r	   r
   Z
gitdb.baser   r   Z
gitdb.utilr   r   r   r   r   r   r   r   r   r   r   r   r   r   Z	gitdb.funr   r   r   r   Zgitdb.utils.encodingr   rT   r)   rX   __all__r    r/   r/   r/   r0   <module>   s   @