

_V(                 @   s  d  Z  d d l 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 d d l m Z m Z y( d d l Z d d l Z d d l Z Wn5 e k
 rZ z e d e   WYd d Z [ Xn Xd d   Z e   Z e d  k  r?e d e j   n  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. e j Z e j/ Z/ e j0 j1 e j0 j2  e j0 j1 e j0 j3  e j0 j4 e e j0 j5  e j0 j4 e e j0 j5  e j6 j7   d Z8 e j0 j9 e8 f d e j0 j2  Z: e j0 j1 e:  Gd d   d e	  Z; d S)!za
PostgreSQL database backend for Django.

Requires psycopg 2: http://initd.org/projects/psycopg2
    N)settings)ImproperlyConfigured)DEFAULT_DB_ALIAS)BaseDatabaseWrapper)BaseDatabaseValidation)DatabaseError)	force_str)cached_property)	SafeBytesSafeTextz!Error loading psycopg2 module: %sc              C   s9   t  j j d d  d }  t d d   |  j d  D  S)N    r   c             s   s'   |  ] } | j    r t |  Vq d  S)N)isdigitint).0v r   D/tmp/pip-build-ghmbqnp_/Django/django/db/backends/postgresql/base.py	<genexpr>   s    z#psycopg2_version.<locals>.<genexpr>.)psycopg2__version__splittuple)versionr   r   r   psycopg2_version   s    r            z8psycopg2_version 2.4.5 or newer is required; you have %sr   )DatabaseClient)DatabaseCreation)DatabaseFeatures)DatabaseIntrospection)DatabaseOperations)DatabaseSchemaEditor)utc_tzinfo_factory)get_versioni  	INETARRAYc                   s.  e  Z d  Z d Z i d d 6d d 6d d 6d d	 6d d
 6d d 6d d 6d d 6d d 6d d 6d d 6d d 6d d 6d d 6d d 6d d 6d d 6d d 6d d  6d! d" 6d d# 6d! d$ 6d% d& 6d' d( 6d) d* 6Z i d+ d  6d+ d" 6Z i d, d- 6d. d/ 6d0 d1 6d2 d3 6d4 d5 6d6 d7 6d8 d9 6d: d; 6d< d= 6d> d? 6d0 d@ 6d0 dA 6d2 dB 6d2 dC 6Z dD Z i dE d1 6dF d3 6dG d@ 6dH dB 6dI dA 6dJ dC 6Z e	 Z	 e
 Z   f dK dL   Z dM dN   Z dO dP   Z dQ dR   Z dS dT   Z dU dV   Z dW dX dY  Z dZ d[   Z e   f d\ d]    Z e d^ d_    Z e d` da    Z   S)bDatabaseWrapperZ
postgresqlserialZ	AutoFieldZbyteaZBinaryFieldbooleanZBooleanFieldzvarchar(%(max_length)s)Z	CharFieldZCommaSeparatedIntegerFielddateZ	DateFieldztimestamp with time zoneZDateTimeFieldz+numeric(%(max_digits)s, %(decimal_places)s)ZDecimalFieldintervalZDurationFieldZ	FileFieldZFilePathFieldzdouble precisionZ
FloatFieldintegerZIntegerFieldZbigintZBigIntegerFieldZinetZIPAddressFieldZGenericIPAddressFieldZNullBooleanFieldZOneToOneFieldZPositiveIntegerFieldZsmallintZPositiveSmallIntegerFieldZ	SlugFieldZSmallIntegerFieldtextZ	TextFieldtimeZ	TimeFielduuidZ	UUIDFieldz"%(column)s" >= 0z= %sexactz= UPPER(%s)ZiexactzLIKE %scontainszLIKE UPPER(%s)Z	icontainsz~ %sregexz~* %sZiregexz> %sgtz>= %sgtez< %sltz<= %slte
startswithendswithZistartswithZ	iendswithz@REPLACE(REPLACE(REPLACE({}, '\', '\\'), '%%', '\%%'), '_', '\_')zLIKE '%%' || {} || '%%'zLIKE '%%' || UPPER({}) || '%%'zLIKE {} || '%%'zLIKE UPPER({}) || '%%'zLIKE '%%' || {}zLIKE '%%' || UPPER({})c                sw   t  t |   j | |   t |   |  _ t |   |  _ t |   |  _ t	 |   |  _
 t |   |  _ t |   |  _ d  S)N)superr(   __init__r!   featuresr#   opsr   clientr    creationr"   introspectionr   Z
validation)selfargskwargs)	__class__r   r   r;      s    zDatabaseWrapper.__init__c             C   s   |  j  } | d d k r( t d   n  i | d p8 d d 6} | j | d  | j d d   | d r{ | d | d	 <n  | d
 r t | d
  | d <n  | d r | d | d <n  | d r | d | d <n  | S)NNAME zJsettings.DATABASES is improperly configured. Please supply the NAME value.ZpostgresZdatabaseOPTIONSisolation_levelUSERuserZPASSWORDpasswordZHOSThostZPORTport)settings_dictr   updatepopr   )rA   rN   conn_paramsr   r   r   get_connection_params   s"    	



z%DatabaseWrapper.get_connection_paramsc             C   sz   t  j |   } |  j d } y | d |  _ Wn t k
 rM | j |  _ Yn) X|  j | j k rv | j d |  j  n  | S)NrG   rH   )DatabaseconnectrN   rH   KeyErrorZset_session)rA   rQ   
connectionoptionsr   r   r   get_new_connection   s    z"DatabaseWrapper.get_new_connectionc          
   C   s   |  j  j d  |  j  j d  } | |  j k r |  j  j   } z# | j |  j j   |  j g  Wd  | j   X|  j	   s |  j  j
   q n  d  S)NUTF8ZTimeZone)rV   Zset_client_encodingZget_parameter_statusZtimezone_namecursorexecuter=   Zset_time_zone_sqlcloseZget_autocommitcommit)rA   Zconn_timezone_namerZ   r   r   r   init_connection_state   s    #z%DatabaseWrapper.init_connection_statec             C   s+   |  j  j   } t j r t n d  | _ | S)N)rV   rZ   r   ZUSE_TZr%   Ztzinfo_factory)rA   rZ   r   r   r   create_cursor   s    zDatabaseWrapper.create_cursorc          	   C   s    |  j   | |  j _ Wd  QXd  S)N)Zwrap_database_errorsrV   
autocommit)rA   r`   r   r   r   _set_autocommit   s    
zDatabaseWrapper._set_autocommitNc             C   s*   |  j    j d  |  j    j d  d S)z
        To check constraints, we set constraints to immediate. Then, when, we're done we must ensure they
        are returned to deferred.
        zSET CONSTRAINTS ALL IMMEDIATEzSET CONSTRAINTS ALL DEFERREDN)rZ   r[   )rA   Ztable_namesr   r   r   check_constraints   s    z!DatabaseWrapper.check_constraintsc             C   s>   y |  j  j   j d  Wn t j k
 r5 d SYn Xd Sd  S)NzSELECT 1FT)rV   rZ   r[   rS   Error)rA   r   r   r   	is_usable   s
    	zDatabaseWrapper.is_usablec                s   t  t |   j } y | j   Wns t t f k
 r t j d t  |  j	 j
   } t j t d | d <|  j |  j	 j
   d |  j d d } Yn X| S)Na/  Normally Django will use a connection to the 'postgres' database to avoid running initialization queries against the production database when it's not needed (for example, when running tests). Django was unable to create a connection to the 'postgres' database and will use the default database instead.rE   aliasZallow_thread_sharingF)r:   r(   _nodb_connectionZensure_connectionr   WrappedDatabaseErrorwarningswarnRuntimeWarningrN   copyr   Z	DATABASESr   rD   re   )rA   Znodb_connectionrN   )rD   r   r   rf      s    	z DatabaseWrapper._nodb_connectionc             C   s   t  S)N)PSYCOPG2_VERSION)rA   r   r   r   r     s    z DatabaseWrapper.psycopg2_versionc          	   C   s$   |  j     t |  j  SWd  QXd  S)N)Ztemporary_connectionr&   rV   )rA   r   r   r   
pg_version  s    zDatabaseWrapper.pg_version)__name__
__module____qualname__vendorZ
data_typesZdata_type_check_constraints	operatorsZpattern_escZpattern_opsrS   r$   ZSchemaEditorClassr;   rR   rX   r^   r_   ra   rb   rd   propertyrf   r	   r   rm   r   r   )rD   r   r(   C   s   




	r(   )r   r   r   )<__doc__rh   Zdjango.confr   Zdjango.core.exceptionsr   Z	django.dbr   Zdjango.db.backends.base.baser   Z"django.db.backends.base.validationr   Zdjango.db.utilsr   rg   Zdjango.utils.encodingr   Zdjango.utils.functionalr	   Zdjango.utils.safestringr
   r   r   rS   Zpsycopg2.extensionsZpsycopg2.extrasImportErrorer   rl   r   r>   r   r?   r    r<   r!   r@   r"   
operationsr#   Zschemar$   utilsr%   r   r&   ZIntegrityError
extensionsZregister_typeUNICODEZUNICODEARRAYZregister_adapterZQuotedStringextrasZregister_uuidZINETARRAY_OIDZnew_array_typer'   r(   r   r   r   r   <module>   sT   #				