a
    %0_&                     @   s   d dl mZ d dl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 ZG dd	 d	ejZG d
d dejjjZdS )    )absolute_importN)pycompat   )indexapic                 C   s6   |  dd} |  dd} | dr2| d d d } | S )N   _s   \_   %s   \%   *)replaceendswith)pattern r   @/usr/lib/python3/dist-packages/hgext/infinitepush/sqlindexapi.py_convertbookmarkpattern   s
    
r   c                       s   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 Zdd Zdd Zdd Zdd Zdd Z  ZS )sqlindexapiz<
    Sql backend for infinitepush index. See schema.sql
    ,  x   c                    st   t t|   || _|||||d| _d | _d | _|s<tj}t	j
|d t	 | _| j| d| _|	| _|
| _d S )N)s   hosts   ports   databases   users   password)filenameF)superr   __init__reponamesqlargssqlconn	sqlcursorosdevnullloggingZbasicConfigZ	getLoggerlogZsetLevel
_connected_waittimeout_locktimeout)selfr   ZhostZportZdatabaseuserZpasswordZlogfileZloglevelwaittimeoutZlocktimeout	__class__r   r   r   #   s$    
zsqlindexapi.__init__c                 C   s   | j rtd| jr tdd}z2tjjf i | j| _ | j t	 d| j _
W qW q$ tjjjy   |d8 }|dkr| td Y q$0 q$| j jd| j }| j  | _| jd	|  | jd
| j  d| _d S )Ns   SQL connection already opens*   SQL cursor already open without connection   Fr   r   g?s   %ss   SET wait_timeout=%ss   SET innodb_lock_wait_timeout=%sT)r   r   Zindexexceptionr   mysql	connectorZconnectr   Zset_converter_classCustomConverterZ
autocommiterrorsErrortimesleepZ	converterescaper   Zcursorexecuter    r   )r!   Zretryr#   r   r   r   
sqlconnectD   s0    
zsqlindexapi.sqlconnectc                 C   sV   t  . t d | j  | j  W d   n1 s<0    Y  d| _d| _dS )z(Cleans up the metadata store connection.s   ignoreN)warningscatch_warningssimplefilterr   closer   r!   r   r   r   r4   h   s    


(zsqlindexapi.closec                 C   s   | j s|   | S N)r   r0   r5   r   r   r   	__enter__q   s    zsqlindexapi.__enter__c                 C   s"   |d u r| j   n
| j   d S r6   )r   ZcommitZrollback)r!   exc_typeZexc_valZexc_tbr   r   r   __exit__v   s    zsqlindexapi.__exit__c           	      C   s   | j s|   | jd| j|f  | jjd|| jfd |D ]}| jjd| || jfd | }|	 }|
d|	 }t| d }t|
d|}| jjd| | |  |  ||||| jf	d q>d S )	Ns   ADD BUNDLE %r %rs5   INSERT INTO bundles(bundle, reponame) VALUES (%s, %s)paramsss   INSERT INTO nodestobundle(node, bundle, reponame) VALUES (%s, %s, %s) ON DUPLICATE KEY UPDATE bundle=VALUES(bundle)s	   committerr   s   committer_dates   INSERT IGNORE INTO nodesmetadata(node, message, p1, p2, author, committer, author_date, committer_date, reponame) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s))r   r0   r   infor   r   r/   hexextrar"   getintdateZdescriptionZp1Zp2)	r!   ZbundleidZnodesctxctxr>   Zauthor_nameZcommitter_nameZauthor_dateZcommitter_dater   r   r   	addbundle|   s<    

zsqlindexapi.addbundlec                 C   sB   | j s|   | jd| j||f  | jjd||| jfd dS )zRTakes a bookmark name and hash, and records mapping in the metadata
        store.s&   ADD BOOKMARKS %r bookmark: %r node: %rss   INSERT INTO bookmarkstonode(bookmark, node, reponame) VALUES (%s, %s, %s) ON DUPLICATE KEY UPDATE node=VALUES(node)r:   Nr   r0   r   r<   r   r   r/   )r!   bookmarknoder   r   r   addbookmark   s    

zsqlindexapi.addbookmarkc                 C   sh   | j s|   g }g }t|D ]$\}}|d |||| jf q d|}| jj	d| |d d S )Ns   (%s, %s, %s)   ,si   INSERT INTO bookmarkstonode(bookmark, node, reponame) VALUES %s ON DUPLICATE KEY UPDATE node=VALUES(node)r:   )
r   r0   r   Z	iteritemsappendextendr   joinr   r/   )r!   	bookmarksargsvaluesrE   rF   r   r   r   addmanybookmarks   s    

zsqlindexapi.addmanybookmarksc                 C   sJ   | j s|   | jd|  |D ]"}t|}| jjd|| jfd q"dS )zAccepts list of bookmark patterns and deletes them.
        If `commit` is set then bookmark will actually be deleted. Otherwise
        deletion will be delayed until the end of transaction.
        s   DELETE BOOKMARKS: %ssF   DELETE from bookmarkstonode WHERE bookmark LIKE (%s) and reponame = %sr:   N)r   r0   r   r<   r   r   r/   r   )r!   Zpatternsr   r   r   r   deletebookmarks   s    zsqlindexapi.deletebookmarksc                 C   s   | j s|   | jd| j|f  | jjd|| jfd | j }t|dks`t|d dkrp| jd dS |d d }| jd|  |S )	zAReturns the bundleid for the bundle that contains the given node.s   GET BUNDLE %r %rsB   SELECT bundle from nodestobundle WHERE node = %s AND reponame = %sr:   r   r   s   No matching nodeNs   Found bundle %r	r   r0   r   r<   r   r   r/   fetchalllen)r!   rF   resultZbundler   r   r   	getbundle   s    
zsqlindexapi.getbundlec                 C   s   | j s|   | jd| j|f  | jjd|| jfd | j }t|dks`t|d dkrp| jd dS |d d }| jd|  |S )	zBReturns the node for the given bookmark. None if it doesn't exist.s"   GET NODE reponame: %r bookmark: %rsF   SELECT node from bookmarkstonode WHERE bookmark = %s AND reponame = %sr:   r   r   s   No matching bookmarkNs   Found node %rrQ   )r!   rE   rT   rF   r   r   r   getnode   s     
zsqlindexapi.getnodec                 C   s   | j s|   | jd| j|f  t|}| jjd| j|fd | j }i }|D ]2}t	|dkrv| jd|  qT|d ||d < qT|S )Ns&   QUERY BOOKMARKS reponame: %r query: %rsS   SELECT bookmark, node from bookmarkstonode WHERE reponame = %s AND bookmark LIKE %sr:      s   Bad row returned: %sr   r   )
r   r0   r   r<   r   r   r   r/   rR   rS   )r!   ZqueryrT   rL   rowr   r   r   getbookmarks   s$    
zsqlindexapi.getbookmarksc                 C   sB   | j s|   | jd| j||f  | jjd|| j|fd d S )NsH   INSERT METADATA, QUERY BOOKMARKS reponame: %r node: %r, jsonmetadata: %ssP   UPDATE nodesmetadata SET optional_json_metadata=%s WHERE reponame=%s AND node=%sr:   rD   )r!   rF   Zjsonmetadatar   r   r   saveoptionaljsonmetadata  s    

z$sqlindexapi.saveoptionaljsonmetadata)r   r   )__name__
__module____qualname____doc__r   r0   r4   r7   r9   rC   rG   rO   rP   rU   rV   rY   rZ   __classcell__r   r   r$   r   r      s      !$	'r   c                   @   s.   e Zd ZdZd	ddZd
ddZdddZdS )r)   ziEnsure that all values being returned are returned as python string
    (versus the default byte arrays).Nc                 C   s   t |S r6   strr!   valueZdscr   r   r   _STRING_to_python#  s    z!CustomConverter._STRING_to_pythonc                 C   s   t |S r6   r`   rb   r   r   r   _VAR_STRING_to_python&  s    z%CustomConverter._VAR_STRING_to_pythonc                 C   s   t |S r6   r`   rb   r   r   r   _BLOB_to_python)  s    zCustomConverter._BLOB_to_python)N)N)N)r[   r\   r]   r^   rd   re   rf   r   r   r   r   r)     s   

r)   )Z
__future__r   r   r   r,   r1   Zmysql.connectorr'   Z	mercurialr    r   r   r   r(   
conversionZMySQLConverterr)   r   r   r   r   <module>   s     