U
    h#                     @   sh  d dl Z d dlZd dlZd dlT d dlmZ d dlmZ d dlmZ d dlmZ d dlmZ d dlm	Z	 d d	lm
Z
 d d
lmZ d dlmZ z,d dlmZ d dlmZ d dlmZ eZW n$ ek
r   d Z Z ZZY nX ejd  dkreZdZdZG dd deZG dd deZG dd deZG dd deZ G dd deZ!d ddZ"G dd dee Z#dS )!    N)*)_atomic)_manual)ColumnMetadata)EnclosedNodeList)Entity)ForeignKeyMetadata)IndexMetadata)NodeList)_PooledPostgresqlDatabase)
ArrayField)BinaryJSONField)IntervalField   i a  CockroachDB does not support nested transactions. You may alternatively use the @transaction context-manager/decorator, which only wraps the outer-most block in transactional logic. To run a transaction with automatic retries, use the run_transaction() helper.c                   @   s   e Zd ZdS )ExceededMaxAttemptsN__name__
__module____qualname__ r   r   9/tmp/pip-unpacked-wheel-5j60pwdk/playhouse/cockroachdb.pyr   #   s    r   c                       s    e Zd ZdZ fddZ  ZS )UUIDKeyFieldTc                    sJ   | drtdt|  tdg|d< |dd tt| j|| d S )Nconstraints%s cannot specify constraints.zDEFAULT gen_random_uuid()Zprimary_keyT)get
ValueErrortypeSQL
setdefaultsuperr   __init__selfargskwargs	__class__r   r   r    )   s
    
zUUIDKeyField.__init__)r   r   r   Zauto_incrementr    __classcell__r   r   r%   r   r   &   s   r   c                       s    e Zd ZdZ fddZ  ZS )
RowIDFieldINTc                    s>   | drtdt|  tdg|d< tt| j|| d S )Nr   r   zDEFAULT unique_rowid())r   r   r   r   r   r(   r    r!   r%   r   r   r    4   s    
zRowIDField.__init__)r   r   r   Z
field_typer    r'   r   r   r%   r   r(   1   s   r(   c                       s   e Zd Zej Zeddi dZ fddZ fddZ	dd	d
Z
d  fdd	Zdd Z fddZdd Zdd Zd! fdd	Zd" fdd	Z fddZd#ddZd$ddZ  ZS )%CockroachDatabaseZBLOBZBYTESTc                    sJ   d|kr.|r.| ds.|dd |dd tt| j|f|| d S )NZdsnzpostgresql://userrootportif  )
startswithr   r   r*   r    )r"   Zdatabaser#   r$   r%   r   r   r    C   s    zCockroachDatabase.__init__c                    sj   |  }|d | \}td|}|d k	rVdtdd | D  }t|| _nt	t
| | d S )Nzselect version()z#^CockroachDB.+?v(\d+)\.(\d+)\.(\d+)z
%d%02d%02dc                 s   s   | ]}t |V  qd S N)int).0ir   r   r   	<genexpr>R   s     z8CockroachDatabase._set_server_version.<locals>.<genexpr>)cursorexecutefetchonerematchtuplegroupsr0   server_versionr   r*   _set_server_version)r"   connZcursrawZ	match_objcleanr%   r   r   r<   L   s    

z%CockroachDatabase._set_server_versionNc                 C   s2   d}|  |||pddf}| }|r.|d p0d S )NzSELECT constraint_name FROM information_schema.table_constraints WHERE table_name = %s AND table_schema = %s AND constraint_type = %spubliczPRIMARY KEYr   )execute_sqlr6   )r"   tableschemaqueryr4   rowr   r   r   _get_pk_constraintX   s    z$CockroachDatabase._get_pk_constraintc                    s0   t t| ||}| ||  fdd|D S )Nc                    s   g | ]} r|j  kr|qS r   )name)r1   idxZpkcr   r   
<listcomp>g   s      
 z1CockroachDatabase.get_indexes.<locals>.<listcomp>)r   r*   get_indexesrF   )r"   rB   rC   Zindexesr%   rI   r   rK   b   s    zCockroachDatabase.get_indexesc                 C   s8   |j s
d S |j  }|dkr$tdS |dkr4tdd S )NreplaceZupsertZUPSERT)ignorenothingupdatezfUn-supported action for conflict resolution. CockroachDB supports REPLACE (UPSERT), IGNORE and UPDATE.)_actionlowerr   r   )r"   Zon_conflictrD   actionr   r   r   conflict_statementi   s     
z$CockroachDatabase.conflict_statementc                    s   |j r|j  nd}|dkr\tdg}|jrF|tdd |jD  |td t|S |dkrhd S |jrvtdt	t
| ||S )	N )rN   rO   zON CONFLICTc                 S   s"   g | ]}t |trt|n|qS r   )
isinstance
basestringr   )r1   colr   r   r   rJ   y   s   z5CockroachDatabase.conflict_update.<locals>.<listcomp>z
DO NOTHINGrL   zWCockroachDB does not support the usage of a constraint name. Use the column(s) instead.)rQ   rR   r   Z_conflict_targetappendr   r
   Z_conflict_constraintr   r   r*   conflict_update)r"   ocrD   rS   partsr%   r   r   rZ   t   s    

z!CockroachDatabase.conflict_updatec                 C   s   t ||S r/   )fnextract)r"   Z	date_part
date_fieldr   r   r   extract_date   s    zCockroachDatabase.extract_datec                 C   s   | d dS )Nr0   Ztimestamptz)cast)r"   r_   r   r   r   from_timestamp   s    z CockroachDatabase.from_timestampc                    s^   t t|   |d k	r(|  d|f |d k	rZ| }|dkrHtd|  d|  d S )Nz$SET TRANSACTION AS OF SYSTEM TIME %s)lownormalhighz$priority must be low, normal or highzSET TRANSACTION PRIORITY %s)r   r*   beginr4   r5   rR   r   r"   system_timepriorityr%   r   r   rf      s    
zCockroachDatabase.beginc                    s8   |   r|   | jtk r&t| ||S tt| ||S r/   )	is_closedconnectr;   NESTED_TX_MIN_VERSION_crdb_atomicr   r*   atomicrg   r%   r   r   rn      s
     
zCockroachDatabase.atomicc                    s0   |   r|   | jtk r"tttt|  S r/   )	rj   rk   r;   rl   NotImplementedErrorTXN_ERR_MSGr   r*   	savepointr"   r%   r   r   rq      s
     
zCockroachDatabase.savepointc                    s    fdd}|S )Nc                    s"   t   fdd}|S )Nc                      s   t  S r/   run_transactionr   )cbmax_attemptsri   r"   rh   r   r   new_fn   s    
zACockroachDatabase.retry_transaction.<locals>.deco.<locals>.new_fn)	functoolswraps)ru   rw   rv   ri   r"   rh   )ru   r   deco   s    z1CockroachDatabase.retry_transaction.<locals>.decor   )r"   rv   rh   ri   r{   r   rz   r   retry_transaction   s    z#CockroachDatabase.retry_transactionc                 C   s   t | ||||S r/   rs   )r"   ru   rv   rh   ri   r   r   r   rt      s    z!CockroachDatabase.run_transaction)N)N)NN)NN)NNN)NNN)r   r   r   PostgresqlDatabaseZfield_typescopyrP   Zrelease_after_rollbackr    r<   rF   rK   rT   rZ   r`   rb   rf   rn   rq   r|   rt   r'   r   r   r%   r   r*   ;   s.   
 	

  

  r*   c                       s   e Zd Z fddZ  ZS )rm   c                    s4   | j  dkr&t| j  ts&tttt| 	 S )Nr   )
dbZtransaction_depthrV   Ztop_transactionr   ro   rp   r   rm   	__enter__rr   r%   r   r   r      s    z_crdb_atomic.__enter__)r   r   r   r   r'   r   r   r%   r   rm      s   rm   c                 C   s   |pd}| j ||d}| d |dkrz$|| }| d |W W  5 Q R  S  tk
r } z,|jjdkr|d8 }| d W Y q" W 5 d	}~X Y q"X q"W 5 Q R X td	d
d	S )a  
    Run transactional SQL in a transaction with automatic retries.

    User-provided `callback`:
    * Must accept one parameter, the `db` instance representing the connection
      the transaction is running under.
    * Must not attempt to commit, rollback or otherwise manage transactions.
    * May be called more than once.
    * Should ideally only contain SQL operations.

    Additionally, the database must not have any open transaction at the time
    this function is called, as CRDB does not support nested transactions.
    )rh   ri   zSAVEPOINT cockroach_restartr   z#RELEASE SAVEPOINT cockroach_restartZ40001   z'ROLLBACK TO SAVEPOINT cockroach_restartNzunable to commit transaction)rn   rA   OperationalErrororigZpgcoder   )r   callbackrv   rh   ri   Ztxnresultexcr   r   r   rt      s    


 rt   c                   @   s   e Zd ZdS )PooledCockroachDatabaseNr   r   r   r   r   r      s   r   )NNN)$rx   r7   sysZpeeweer   r   r   r   r   r   r	   r
   Zplayhouse.poolr   Zplayhouse.postgres_extr   r   r   Z	JSONFieldImportErrorversion_infostrrW   rl   rp   r   r   Z	UUIDFieldr   Z	AutoFieldr(   r}   r*   rm   rt   r   r   r   r   r   <module>   s@   
{  
 