3
[{+                 @   s  d Z ddl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 yddlZddlZddlZW n. ek
r Z zede W Y ddZ[X nX dd Ze Zedk redej 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+j,eej+j- ej.j/  dZ0ej+j1e0fdej+j2Z3ej+j4e3 G dd de
Z5dS )za
PostgreSQL database backend for Django.

Requires psycopg 2: http://initd.org/projects/psycopg2
    N)settings)ImproperlyConfigured)connections)BaseDatabaseWrapper)DatabaseError)cached_property)SafeText)get_version_tuplez!Error loading psycopg2 module: %sc              C   s   t jjddd } t| S )N    r   )psycopg2__version__splitr	   )version r   F/tmp/pip-install-j7i95hgp/django/django/db/backends/postgresql/base.pypsycopg2_version   s    r            z8psycopg2_version 2.5.4 or newer is required; you have %sr   )DatabaseClient)DatabaseCreation)DatabaseFeatures)DatabaseIntrospection)DatabaseOperations)DatabaseSchemaEditor)utc_tzinfo_factoryi  	INETARRAYc                   s  e Zd ZdZdZddddddd	d
ddddddddddddddddddZdddZdddddddddd ddddd!Zd"Zd#d$d%d&d'd(d)Z	e
Z
eZeZeZeZeZeZd*Zd+d, Zd-d. Zd/d0 Zd1d2 ZdBd4d5Zd6d7 Zd8d9 ZdCd:d;Zd<d= Z e! fd>d?Z"e#d@dA Z$  Z%S )DDatabaseWrapper
postgresqlZ
PostgreSQLserialZ	bigserialZbyteabooleanzvarchar(%(max_length)s)dateztimestamp with time zonez+numeric(%(max_digits)s, %(decimal_places)s)intervalzdouble precisionintegerZbigintZinetZsmallinttexttimeuuid)Z	AutoFieldZBigAutoFieldZBinaryFieldZBooleanFieldZ	CharFieldZ	DateFieldZDateTimeFieldZDecimalFieldZDurationFieldZ	FileFieldZFilePathFieldZ
FloatFieldZIntegerFieldZBigIntegerFieldZIPAddressFieldZGenericIPAddressFieldZNullBooleanFieldZOneToOneFieldPositiveIntegerFieldPositiveSmallIntegerFieldZ	SlugFieldZSmallIntegerFieldZ	TextFieldZ	TimeFieldZ	UUIDFieldz"%(column)s" >= 0)r(   r)   z= %sz= UPPER(%s)zLIKE %szLIKE UPPER(%s)z~ %sz~* %sz> %sz>= %sz< %sz<= %s)exactZiexactcontains	icontainsregexZiregexgtZgteltZlte
startswithendswithistartswith	iendswithz@REPLACE(REPLACE(REPLACE({}, '\', '\\'), '%%', '\%%'), '_', '\_')zLIKE '%%' || {} || '%%'zLIKE '%%' || UPPER({}) || '%%'zLIKE {} || '%%'zLIKE UPPER({}) || '%%'zLIKE '%%' || {}zLIKE '%%' || UPPER({}))r+   r,   r0   r2   r1   r3   r   c             C   s   | j }|d dkrtdt|d p&d| jj krXtd|d t|d | jj f d|d pddi|d }|jdd  |d	 r|d	 |d
< |d r|d |d< |d r|d |d< |d r|d |d< |S )NNAME zJsettings.DATABASES is improperly configured. Please supply the NAME value.zThe database name '%s' (%d characters) is longer than PostgreSQL's limit of %d characters. Supply a shorter NAME in settings.DATABASES.ZdatabasepostgresOPTIONSisolation_levelUSERuserZPASSWORDpasswordZHOSThostZPORTport)settings_dictr   lenopsZmax_name_lengthpop)selfr>   conn_paramsr   r   r   get_connection_params   s,    

z%DatabaseWrapper.get_connection_paramsc             C   s`   t jf |}| jd }y|d | _W n tk
r@   |j| _Y nX | j|jkr\|j| jd |S )Nr7   r8   )r8   )Databaseconnectr>   r8   KeyErrorZset_session)rB   rC   
connectionoptionsr   r   r   get_new_connection   s    
z"DatabaseWrapper.get_new_connectionc          
   C   sX   | j   | jjd}| j}|rT||krT| jj }|j| jj |g W d Q R X dS dS )NZTimeZoneTF)ensure_connectionrH   Zget_parameter_statustimezone_namecursorexecuter@   Zset_time_zone_sql)rB   Zconn_timezone_namerL   rM   r   r   r   ensure_timezone   s    zDatabaseWrapper.ensure_timezonec             C   s.   | j jd | j }|r*| j s*| j j  d S )NUTF8)rH   Zset_client_encodingrO   Zget_autocommitcommit)rB   Ztimezone_changedr   r   r   init_connection_state   s
    z%DatabaseWrapper.init_connection_stateNc             C   s:   |r| j j|d| j jd}n
| j j }tjr0tnd |_|S )NF)Z
scrollableZwithhold)rH   rM   
autocommitr   ZUSE_TZr   Ztzinfo_factory)rB   namerM   r   r   r   create_cursor   s
    
zDatabaseWrapper.create_cursorc             C   s*   |  j d7  _ | jdtj j| j f dS )Nr   z_django_curs_%d_%d)rT   )_named_cursor_idxZ_cursor	threadingcurrent_threadident)rB   r   r   r   chunked_cursor   s
    zDatabaseWrapper.chunked_cursorc          	   C   s   | j  || j_W d Q R X d S )N)Zwrap_database_errorsrH   rS   )rB   rS   r   r   r   _set_autocommit   s    zDatabaseWrapper._set_autocommitc             C   s    | j  jd | j  jd dS )zl
        Check constraints by setting them to immediate. Return them to deferred
        afterward.
        zSET CONSTRAINTS ALL IMMEDIATEzSET CONSTRAINTS ALL DEFERREDN)rM   rN   )rB   Ztable_namesr   r   r   check_constraints   s    z!DatabaseWrapper.check_constraintsc             C   s4   y| j j jd W n tjk
r*   dS X dS d S )NzSELECT 1FT)rH   rM   rN   rE   Error)rB   r   r   r   	is_usable   s
    zDatabaseWrapper.is_usablec                s   t  j}y|j  W nr tjtfk
r   tjdt xJt	j
 D ]>}|jdkr@|jd dkr@| j| jd|jd i| jddS q@W Y nX |S )Na8  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 first PostgreSQL database instead.r   r4   r6   F)aliasZallow_thread_sharing)super_nodb_connectionrK   rE   r   WrappedDatabaseErrorwarningswarnRuntimeWarningr   allvendorr>   	__class__r_   )rB   Znodb_connectionrH   )rh   r   r   ra     s    z DatabaseWrapper._nodb_connectionc          	   C   s   | j  
 | jjS Q R X d S )N)Ztemporary_connectionrH   Zserver_version)rB   r   r   r   
pg_version  s    
zDatabaseWrapper.pg_version)N)N)&__name__
__module____qualname__rg   Zdisplay_nameZ
data_typesZdata_type_check_constraints	operatorsZpattern_escZpattern_opsrE   r   ZSchemaEditorClassr   Zclient_classr   Zcreation_classr   Zfeatures_classr   Zintrospection_classr   Z	ops_classrV   rD   rJ   rO   rR   rU   rZ   r[   r\   r^   propertyra   r   ri   __classcell__r   r   )rh   r   r   =   s    
	



	r   )r   r   r   )6__doc__rW   rc   Zdjango.confr   Zdjango.core.exceptionsr   Z	django.dbr   Zdjango.db.backends.base.baser   Zdjango.db.utilsr   rb   Zdjango.utils.functionalr   Zdjango.utils.safestringr   Zdjango.utils.versionr	   r   rE   Zpsycopg2.extensionsZpsycopg2.extrasImportErrorer   ZPSYCOPG2_VERSIONr   clientr   Zcreationr   featuresr   Zintrospectionr   
operationsr   Zschemar   utilsr   
extensionsZregister_adapterQuotedStringextrasZregister_uuidZINETARRAY_OIDZnew_array_typeUNICODEr   Zregister_typer   r   r   r   r   <module>   sH   

